#操作方法
操作 | キー |
---|---|
視線移動 | 方向キー |
加速 | A |
減速 | Z |
ズーム | 左クリック |
視点切り替え | 右クリック |
紙飛行機 | 1 |
お楽しみ | 2 |
#プログラム
PaperPlane.java
//画角
float fov = 3;
//視点切り替え
boolean cameraView = true;
//飛行機クラス生成
PaperPlane pp = new PaperPlane();
void setup(){
size(800,800,P3D);
frameRate(30);
}
void draw(){
background(50,50,100);
perspective(PI/fov,(float)width/height,10,10000);
//モードで視点切り替え
if(cameraView){
camera(150,-500,1000,
pp.x,pp.y,pp.z,
0,1,0);
}
else{
camera(pp.x,pp.y,pp.z-0.1f,
pp.nextX,pp.nextY,pp.z + pp.speed * cos(pp.rx) * cos(pp.ry),
-sin(pp.rz)*Sign(cos(pp.ry)),cos(pp.rz),0);
}
pushMatrix();
rotateX(PI/2);lights();
popMatrix();
fill(255);
pp.Draw();
//床
fill(0,150,0);noStroke();
for(int i= -5;i<= 5;i++){
for(int j= -10;j<=10;j++){
pushMatrix();
translate(i*200,0,j*200);
box(180,10,180);
popMatrix();
}
}
}
class PaperPlane{
float x,y,z; //位置
float nextX,nextY,nextZ;//次のフレーム時の位置
float speed; //移動速度
float rx,ry,rz; //回転
float wx,wy,wr; //翼の位置,回転角
float wingR = PI/45; //翼のはばたき速度
int mode; // 飛行機の種類
PaperPlane(){
Reset();
}
void Draw(){
//キーボード入力で操作
if(keyPressed){
if(key == 'r') Reset();
if(key == 'a') speed += 0.1f;
if(key == 'z'){
if(speed > 0.1f) speed -= 0.05f;
else speed = 0;
}
if(key == CODED){
if(keyCode == UP) rx -= PI/180f;
if(keyCode == DOWN) rx += PI/180f;
if(keyCode == RIGHT){
ry -= PI/360f;
if(rz > -PI/2)
rz -= PI/360f;
}
if(keyCode == LEFT) {
ry +=PI/360f;
if(rz < PI/2)
rz += PI/360f;
}//if(keyCode == LEFT)
}//if(key == CODED)
if(key == '1') mode = 1;
if(key == '2') mode = 2;
}//if(keyPressed){
else
{
if(abs(rz) < PI/180) rz = 0;//機体を水平に戻す
else if(rz > 0) rz -= PI/90f;
else if(rz < 0) rz += PI/90f;
if(abs(rx%PI) < PI/180) rx = 0;//機体を水平に戻す
else if(rx > 0) rx -= PI/360f;
else if(rx < 0) rx += PI/360f;
}
if(abs(rx) > 2 * PI) rx = 0;
if(abs(ry) > 2 * PI) ry = 0;
//ポジション移動
x = nextX;
y = nextY;
z = nextZ;
nextX = x + speed * sin(ry);
nextY = y + speed * sin(rx);
nextZ = z + speed * cos(rx) * cos(ry);
pushMatrix();
translate(x,y,z);
rotateX(rx * Sign(cos(ry)) * -1);
rotateY(ry);
rotateZ(rz);
switch(mode){
case 1: paperPlane();break;
case 2: paperClane();break;
}
popMatrix();
}
void paperPlane(){
beginShape(TRIANGLE_FAN);
vertex(0,0,0);
vertex(-30,5,-50);
vertex(-5,0,-50);
vertex(0,20,-50);
vertex(5,0,-50);
vertex(30,5,-50);
endShape();
}
//おりづる
void paperClane(){
//ツバサバサバサ
wr += wingR * speed * 0.5f;
if(abs(wr) > radians(30)){
wingR *= -1;
wr += wingR;
}
wx = 40 * cos(wr);
wy = 40 * sin(wr);
//頭
beginShape(TRIANGLE_FAN);
vertex(0,0,20);
vertex(-2,-7,5);
vertex(0,-5,2);
vertex(2,-7,5);
endShape();
//首
beginShape(QUAD_STRIP);
vertex(-2,-7,5);
vertex(-3,10,-2);
vertex(0,-5,2);
vertex(0,7,-4);
vertex(2,-7,5);
vertex(3,10,-2);
endShape();
//左右胴体
for(int i=-1;i<=1;i+=2){
beginShape(QUAD_STRIP);
vertex(0,17,-7);
vertex(0,7,-4);
vertex(3*i,17,-5);
vertex(3*i,10,-2);
vertex(2*i,17,-13);
vertex(4*i,10,-13);
vertex(3*i,17,-21);
vertex(3*i,10,-23);
vertex(0,17,-20);
vertex(0,7,-22);
endShape();
}
//背中のとんがり
beginShape(TRIANGLE_FAN);
vertex(0,6,-13);
vertex(0,7,-4);
vertex(3,10,-2);
vertex(4,10,-13);
vertex(3,10,-23);
vertex(0,7,-22);
vertex(-3,10,-23);
vertex(-4,10,-13);
vertex(-3,10,-2);
vertex(0,7,-4);
endShape();
//下側
beginShape(TRIANGLE_FAN);
vertex(0,17,-13);
vertex(0,17,-7);
vertex(3,17,-5);
vertex(2,17,-13);
vertex(3,17,-21);
vertex(0,17,-20);
vertex(-3,17,-21);
vertex(-2,17,-13);
vertex(-3,17,-5);
vertex(0,17,-7);
endShape();
//尾
beginShape(TRIANGLE_FAN);
vertex(0,-10,-30);
vertex(3,10,-23);
vertex(0,7,-22);
vertex(-3,10,-22);
endShape();
//翼
for(int i=-1;i<=1;i+=2){
pushMatrix();
translate(0,10,0);
beginShape(TRIANGLE_FAN);
vertex(wx*i,wy,-13);
vertex(3*i,0,-2);
vertex(4*i,0,-13);
vertex(3*i,0,-23);
endShape();
popMatrix();
}
}
void Reset(){
rx = ry = rz = speed = wy = wr = 0;
wx = 30;
nextX = 0;
nextY = -300;
nextZ = -1000;
mode = 1;
}
}
float Sign(float a){
if(a > 0) return 1;
else if(a < 0) return -1;
else return 0;
}
void mousePressed(){
//画角切り替え
if(mouseButton == LEFT) {
if(fov == 18) fov = 3;
else fov = 18;
}
//視点切り替え
if(mouseButton == RIGHT){
cameraView = !cameraView;
}
}