LoginSignup
6
4

More than 3 years have passed since last update.

[Processing]紙飛行機を飛ばそう

Last updated at Posted at 2020-03-12

こんな

PaperPlane2.gif

操作方法

操作 キー
視線移動 方向キー
加速 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;
  }

}

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4