7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2020-03-12

追記

諸事情によりJavaではなくJavascriptになりました

こんな

PaperPlane2.gif

操作方法

操作 キー
視線移動 方向キー
加速 A
減速 Z
ズーム 左クリック
視点切り替え 右クリック
紙飛行機 1
お楽しみ 2

プログラム

PaperPlane.js


//画角
let fov = 3
//視点切り替え
let cameraView = true
//紙飛行機クラス
let pp
// カメラ視点
let camera

let cloudPosArray = []

function setup() {
	createCanvas(600, 600, WEBGL)
	background(100)
	
	pp = new PaperPlane()
	camera = createCamera()
	
	let length = 100
	for(let i=0; i<length;i++){
		cloudPosArray.push(new createVector(random(0,TWO_PI), random(-5000,500), random(2000,3000)));
	}
}

function draw() {
  background(50,50,100)
	
	//モードで視点切り替え
	
  if(cameraView)
	{
		camera.setPosition(150, -500, 1000)
		camera.lookAt(pp.pos.x, pp.pos.y, pp.pos.z)
		let dis = pp.pos.copy().sub(150, -500, 1000).mag()
  	perspective(PI/max(2,min(10,dis/100)), width/height,10,10000)
  }
  else
	{
		camera.setPosition(pp.pos.x, pp.pos.y, pp.pos.z)
		camera.lookAt(pp.nextPos.x, pp.nextPos.y, pp.nextPos.z + (pp.speed === 0 ? 1 : 0))
  	perspective(PI/3, width/height,10,10000)
  }
	
  push()
    rotateX(PI/2)
		lights()
  pop()
	
	
	let inputDire = createVector()
	
	if(keyIsPressed){
		switch(key){
			case "a":
				pp.SpeedUp()
				break
			case "z":
				pp.SpeedDown()
				break
			case "ArrowUp":
				inputDire.y += 1
				break
			case "ArrowRight":
				inputDire.x += 1
				break
			case "ArrowDown":
				inputDire.y -= 1
				break
			case "ArrowLeft":
				inputDire.x -= 1
				break
			case "r":
				pp.Reset()
				break
			case "1":
				pp.SetMode(1)
				break
			case "2":
				pp.SetMode(2)
				break
		}
	}
	
	pp.Control(inputDire)
	
	pp.Move()
	pp.Draw()
	
	drawEnv()
	
}

function drawEnv() {
	drawFlor()
	drawCloud()
	
	//床
	function drawFlor(){
		fill(0,150,0)
		strokeWeight(1)
		for(let i= -5;i<= 5;i++){
			for(let j= -10;j<=10;j++){
				push()
				translate(i*300,0,j*300)
				box(180,10,180)
				pop()
			}
		}
	}
	
	function drawCloud(){
		//雲
		fill(255)
		strokeWeight(1)
		for(let i=0; i<cloudPosArray.length;i++){
			push()
			let pos = cloudPosArray[i]
			rotateY(pos.x)
			translate(0,pos.y,pos.z)
			box(200,50,100)
			pop()
		}
	}
}

function ClampPI(rotate){
	// 半回転したら逆からの回転値を返す
	// 例:[3.15 => -3.13 ] = sign(-x) * (3.14 - (abs(x)-3.14)) =sign(-x) * (3.14 -abs(x) + 3.14)) =sign(-x) * (2*PI-abs(x))
	if(abs(rotate) >= PI) return Sign(-rotate) * (2 * PI - abs(rotate))
	return rotate
}

function Sign(a){
  if(a > 0) return 1
  else if(a < 0) return -1
  else return 0
}

function mousePressed(){
  //画角切り替え
  if(mouseButton === LEFT) {
    if(fov == 36) fov = 3;
    else fov = 36;
  }
  //視点切り替え
  if(mouseButton === RIGHT){
    cameraView = !cameraView;
  }
}

// コンテキストメニューを無効化する
document.oncontextmenu = (e) => {
    e.preventDefault();
}
paperPlane.js
class PaperPlane{
	
	constructor(){
		this.Reset()
	}
	
  Reset(){
    this.pos = createVector(0, -300 , -1000)
		this.nextPos = this.pos.copy()
		this.direction = createVector(0,0,0.01)
		this.rotate = createVector()
		this.speed = this.wy = this.wr = 0
    this.wx = 30
		this.wingR = PI/90//翼のはばたき速度
    this.mode = 1
  }
	
	SpeedUp(){
		this.speed += 0.05
	}
	SpeedDown(){
		if(this.speed > 0.1) this.speed -= 0.05
		else this.speed = 0
	}
	
	SetMode(num){
		switch(num){
			case 1:
			case 2:
				this.mode = num
				break
			default:
				console.log("対応してないモードです")
				break
		}
	}
	
	Control(inputVec){
		if(inputVec.magSq() < 1){
			//水平との誤差が1度なら(2*PI/360=PI/180)機体を水平とする
			if(abs(this.rotate.x) < PI/180) this.rotate.x = 0
			else this.rotate.x -= Sign(this.rotate.x) * PI / 360
			
      if(abs(this.rotate.z) < PI/180) this.rotate.z = 0
      else this.rotate.z -= Sign(this.rotate.z) * PI / 360
		}else{
			// 入力と回転がずれてるのでxにyで減算する
			this.rotate.x -= inputVec.y * PI / 180
			this.rotate.y -= inputVec.x * PI / 180	
			// 傾きを与える
			if(abs(this.rotate.z) < PI/3) this.rotate.z -= Sign(inputVec.x) * PI/360
			
			// PIを超えた回転を修正
			this.rotate.x = ClampPI(this.rotate.x)
			this.rotate.y = ClampPI(this.rotate.y)
			this.rotate.z = ClampPI(this.rotate.z)
		}
		
		this.direction.x = sin(this.rotate.y)
		this.direction.y = sin(this.rotate.x)
		this.direction.z = cos(this.rotate.x) * cos(this.rotate.y)
	}
	
	Move(){
    //位置移動
		let dire = this.direction.copy().normalize()
    this.pos = this.pos.add(dire.mult(this.speed)) 
		
    this.nextPos = this.pos.copy().add(dire.mult(max(this.speed,1))) 

	}
	
	Draw(){
		
    push()
      translate(this.pos)
      rotateX(this.rotate.x * Sign(cos(this.rotate.y)) * -1)
      rotateY(this.rotate.y)
      rotateZ(this.rotate.z)
			strokeWeight(0.5)
      switch(this.mode){
        case 1: this.paperPlane()
					break
        case 2: this.paperClane()
					break
      }
    pop()
		
  }

  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()
  }

  //おりづる
  paperClane(){

    //ツバサバサバサ
    this.wr += this.wingR * this.speed * 0.5
    if(abs(this.wr) > radians(30)){
      this.wingR *= -1
      this.wr += this.wingR
    }

    this.wx = 40 * cos(this.wr)
    this.wy = 40 * sin(this.wr)

    //頭
    beginShape(TRIANGLE_FAN)
      vertex(0,0,10)
      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(let 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(let i=-1;i<=1;i+=2){
      push()
        translate(0,10,0)
        beginShape(TRIANGLE_FAN)
          vertex(this.wx*i,this.wy,-13)
          vertex(3*i,0,-2)
          vertex(4*i,0,-13)
          vertex(3*i,0,-23)
        endShape()
      pop()
    }

  }
}
7
4
1

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
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?