レッスン 14

中間課題:エアホッケーをつくろう

これまでの知識を活用して、エアホッケーゲームをつくります

チャプター1このレッスンのゴール

このレッスンでは、これまで学んだことを活用して、エアホッケーゲームを作ります。

このレッスンで完成させるものを確認しよう

チャプター2必要な変数を全て書き出そう

このチャプターでは、必要な変数を全て書き出します。

2. 1 写してみよう

//ボールサイズ
var ballSize = 20;
var radius = ballSize/2;

//ボールの移動
var bx;
var by;
var bvx;
var bvy;

//自分のバーサイズ
var p_barwidth = 100;
var p_barheight = 10;

//自分の移動
var px;
var py;
var pvx;

//敵のバーサイズ
var e_barwidth = 200;
var e_barheight = 10;

//敵の移動
var ex;
var ey;
var evx;

//スコア
var p_score = 0;
var e_score = 0;

2. 2 コードの解説

必要な要素を変数で書き出しました。通常はプログラムを書きながら必要な時に書き加えていくケースが多いです。最初から全てを見通すことは大事ですが、完璧である必要はありません。

チャプター3コートを描こう

このチャプターではコートを書きます。基本の図形である円と線を組み合わせて次のようにしましょう。

function setup() {
  createCanvas(400, 500);
  
}

function draw() {
  background(0);
  
  //背景
  stroke(255);
  strokeWeight(1);
  noFill();
  line(0, height/2, width, height/2);
  ellipse(width/2,height/2,width/6,width/6);
  
}

コードがかけたら実行してみよう。キャンバスの中心に横線と円がかけていればOKだよ。

チャプター4自分のバーの動きをつくろう

このチャプターでは自分のバーの動きを作ります。

4. 1 変更しよう

function setup() {
  createCanvas(400, 500);
  
  //自分のバー初期位置,速度
  rectMode(CENTER);
  px = width/2;
  py = height-p_barheight/2
  pvx = 2;
  
}

function draw() {
  background(0);
  
  //背景
  stroke(255);
  strokeWeight(1);
  noFill();
  line(0, height/2, width, height/2);
  ellipse(width/2,height/2,width/6,width/6);
  
  //自分のバー
  fill(255);
  rect(px, py, p_barwidth, p_barheight);
  
  //自分のバーをキーで操作
  if (keyCode === RIGHT_ARROW) {
    px += pvx;
  } else if (keyCode === LEFT_ARROW) {
    px -= pvx;
  }
  
  //自分のバーの端制御
  if(px-p_barwidth/2<=0){
    px = px+5;
  }
  if(width<=px+p_barwidth/2){
    px = px-5;
  }
  
}

コードが変更できたら実行して確認しよう。自分のバーがキーボードの矢印で動けばOKだよ。

4. 2 コードの解説

バーの大きさの半分を右端と左端から引いて、バーのx座標、y座標に制限をかけているよ。

チャプター5敵のバーの動きをつくろう

このチャプターでは敵のバーの動きをつくります。

function setup() {
  createCanvas(400, 500);

  //自分のバー初期位置,速度
  rectMode(CENTER);
  px = width / 2;
  py = height - p_barheight / 2
  pvx = 2;

  //敵のバー初期位置,速度
  ex = width / 2;
  ey = e_barheight / 2;
  evx = 2;

}

function draw() {
  background(0);

  //背景
  stroke(255);
  strokeWeight(1);
  noFill();
  line(0, height / 2, width, height / 2);
  ellipse(width / 2, height / 2, width / 6, width / 6);

  //自分のバー
  fill(255);
  rect(px, py, p_barwidth, p_barheight);

  //自分のバーをキーで操作
  if (keyCode === RIGHT_ARROW) {
    px += pvx;
  } else if (keyCode === LEFT_ARROW) {
    px -= pvx;
  }

  //自分のバーの端制御
  if (px - p_barwidth / 2 <= 0) {
    px = px + 5;
  }
  if (width <= px + p_barwidth / 2) {
    px = px - 5;
  }
  //敵のバー
  rect(ex, ey, e_barwidth, e_barheight);
  //ex += evx
  ex += evx; //

  if (ex - e_barwidth / 2 <= 0 || ex + e_barwidth / 2 >= width) {
    evx *= -1
  }

}

コードがかけたら実行してみよう。敵のバーが一定のスピードで左右に動いていればOKだよ。

5. 1 コードの解説

自分のバーと同じで右端と左端の制御を加えます。

チャプター6ボールの動きをつくろう

このチャプターではボールの動きをつくります。

function setup() {
  createCanvas(400, 500);
  
  //自分のバー初期位置,速度
  rectMode(CENTER);
  px = width/2;
  py = height-p_barheight/2
  pvx = 2;
  
  //敵のバー初期位置,速度
  ex = width/2;
  ey = e_barheight/2;
  evx = 2;
  
  //ボール初期位置,速度
  bx = width / 2;
  by = height / 2;
  bvx = 4;
  bvy = 3;
 
}

function draw() {
  background(0);
  
  //背景
  stroke(255);
  strokeWeight(1);
  noFill();
  line(0, height/2, width, height/2);
  ellipse(width/2,height/2,width/6,width/6);
  
  //自分のバー
  fill(255);
  rect(px, py, p_barwidth, p_barheight);
  
  //自分のバーをキーで操作
  if (keyCode === RIGHT_ARROW) {
    px += pvx;
  } else if (keyCode === LEFT_ARROW) {
    px -= pvx;
  }
  
  //自分のバーの端制御
  if(px-p_barwidth/2<=0){
    px = px+5;
  }
  if(width<=px+p_barwidth/2){
    px = px-5;
  }
  
  //敵のバー
  rect(ex, ey, e_barwidth, e_barheight);
  //ex += evx
  ex += evx //* noise(dt)*3;
  //dt += 0.1
  if(ex-e_barwidth/2 <= 0 || ex + e_barwidth/2 >= width){
    evx *= -1
  }
  
  //ボール
  fill(255);
  ellipse(bx, by, ballSize, ballSize);
  bx += bvx
  by += bvy
  
  //ボールの左右反射
  if(bx<=0 || bx >=width){
    bvx *= -1;
  }
  
  //自分のバーとの反射
  if(by>=height-p_barheight-radius){
    if(px-p_barwidth/2+ballSize/2<bx && bx<px+p_barwidth/2-ballSize/2){
      bvy *= -1
    }
  }
  
  //敵のバーとの反射
  if(by<=0+e_barheight+radius){
    if(ex-e_barwidth/2<bx && bx<ex+e_barwidth/2){
      bvy *= -1
      bvx = random(-3,3);
    }
  }
}

コードがかけたら実行してみよう。ボールがバーや左右で反射していればOKだよ。

6. 1 コードの解説

左右の反射はbxをマイナス1倍(反対向きにする)、バーでの反射はbyをマイナス1倍にすればいいことを覚えておこう。また、ゲームを面白くするために、見本ではバーでの反射の際に乱数を使っています。

(使わない方がより自然なのですが、ボールが同じ場所をぐるぐる行ったりきたりするようになると、ゲームが退屈になるため乱数を設けています。)

チャプター7得点を表示させよう

このチャプターでは得点の表示をつくります。合わせて、リスタートについても設定します。

  //リスタート
  if(by<-10 || height+10<by){
    if(by<-10){
      p_score +=1;
    }else{
      e_score +=1;
  }
    bx = width/2;
    by = height/2;
    bvx = -int(random(-2,2));
    bvy = int(random(4,8));
  }
  

  // スコア表示
  text(p_score, 0, height/2+50);
  text(e_score, 0, height/2+-50);

コードがかけたら、実行してみよう。完成だね。

7. 1 コードの解説

ボールが上下にはみ出してしまった場合に、中央からボールがでるように
設定しています。

チャプター8完成形

//ボールサイズ
var ballSize = 20;
var radius = ballSize/2;

//ボールの移動
var bx;
var by;
var bvx;
var bvy;

//自分のバーサイズ
var p_barwidth = 100;
var p_barheight = 10;

//自分の移動
var px;
var py;
var pvx;

//敵のバーサイズ
var e_barwidth = 200;
var e_barheight = 10;

//敵の移動
var ex;
var ey;
var evx;

//スコア
var p_score = 0;
var e_score = 0;

function setup() {
  createCanvas(400, 500);
  
  //ボール初期位置,速度
  bx = width / 2;
  by = height / 2;
  bvx = 4;
  bvy = 3;
  
  //自分のバー初期位置,速度
  rectMode(CENTER);
  px = width/2;
  py = height-p_barheight/2
  pvx = 2;
  
  //敵のバー初期位置,速度
  ex = width/2;
  ey = e_barheight/2;
  evx = 2;
}

function draw() {
  background(0);
  // スコア表示
  text(p_score, 0, height/2+50);
  text(e_score, 0, height/2+-50);
  
  //背景
  stroke(255);
  strokeWeight(1);
  noFill();
  line(0, height/2, width, height/2);
  ellipse(width/2,height/2,width/6,width/6);
  
  //ボール
  fill(255);
  ellipse(bx, by, ballSize, ballSize);
  bx += bvx
  by += bvy
  
  //ボールの左右反射
  if(bx<=0 || bx >=width){
    bvx *= -1;
  }
  
  //自分のバーの移動
  rect(px, py, p_barwidth, p_barheight);
  
  //自分のバーをキーで操作
  if (keyCode === RIGHT_ARROW) {
    px += pvx;
  } else if (keyCode === LEFT_ARROW) {
    px -= pvx;
  }
  
  //自分のバーの端制御
  if(px-p_barwidth/2<=0){
    px = px+5;
  }
  if(width<=px+p_barwidth/2){
    px = px-5;
  }
  
  //自分のバーとの反射
  if(by>=height-p_barheight-radius){
    if(px-p_barwidth/2+ballSize/2<bx && bx<px+p_barwidth/2-ballSize/2){
      bvy *= -1
    }
  }
  
  //敵のバー
  rect(ex, ey, e_barwidth, e_barheight);
  //ex += evx
  ex += evx //* noise(dt)*3;
  //dt += 0.1
  if(ex-e_barwidth/2 <= 0 || ex + e_barwidth/2 >= width){
    evx *= -1
  }
  
  //敵のバーとの反射
  if(by<=0+e_barheight+radius){
    if(ex-e_barwidth/2<bx && bx<ex+e_barwidth/2){
      bvy *= -1
      bvx = random(-3,3);
    }
  }
  
  //リスタート
  if(by<-10 || height+10<by){
    if(by<-10){
      p_score +=1;
    }else{
      e_score +=1;
  }
    bx = width/2;
    by = height/2;
    bvx = -int(random(-2,2));
    bvy = int(random(4,8));
  }
}
チャプターを全部クリアしよう!