p5js 占いPongを作ろう

一発目の課題は

一発目の課題をどうすべきか悩みました。
初心者でも分かるようにしたいし、シンプル過ぎても退屈ですし。

とりあえず、ビデオゲームを広めた Pong(ポン)に決めました。
(1972年に作られた古いゲームです)
ただ、そのままでは簡単すぎるので、占い要素も入れていきます。

100個の玉が散らばり、吉凶へ入った数で占います。
上下にあるパドルを操作して、凶へ入ることを阻止できます。
(もはや占いではない)

占い要素のあるpong

こんな感じのものを作っていきます。

 

2つの四角

前のページでスケッチに Fortune pong という名前を付けましたね。
このスケッチを変更していきます。
新しくスケッチを作ってもOKです。

さっそく、プログラムを次のように変更しましょう。

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

function draw() {
  background(10);
  fill('#4169e1');
  rect(0, 0, 300, 40);
  fill('#b22222');
  rect(0, 360, 30, 20);
}

fill はこれから描くものの色を指定します。
rect は四角を描きます。

 

実行結果です。上下に四角が表示されました。

2つの四角を描く

いきなり問題です。
下部の赤い四角を上部の青い四角と同じに大きさにしてください。
ヒント:rect ( x座標, y座標, 幅, 高さ )
実行結果は次のようになります。

2つの四角を同じ大きさにする
function setup() {
  createCanvas(300, 400);
}

function draw() {
  background(10);
  fill('#4169e1');
  rect(0, 0, 300, 40);
  fill('#b22222');
  rect(0, 360, 300, 40);
}
rect の幅と高さを同じにします。

 

fill では 16進数でカラーコードを指定しています。
色の番号を知りたいときはカラーコード 16進数で検索しましょう。

 

 

テキストの表示

つぎはテキストを表示させます。
準備として、変数の宣言とテキストサイズの指定を行います。

下のようにプログラムを追加してください。
色の付いた行が追加するコードです。

let good = 0;
let bad = 0;
let balls = [];

function setup() {
  createCanvas(300, 400);
  textSize(28);
}

 

それでは問題です。
下図と同じ結果になるように下記のプログラムを追加してください。
ヒント:後から描いたほうが表示優先は高くなります。

テキストを表示する

追加するプログラム。

  fill(240);
  text('大吉', 100, 31);
  text(good, 170, 31);
  text('大凶', 100, 390);
  text(bad, 170, 390);
let good = 0;
let bad = 0;
let balls = [];

function setup() {
  createCanvas(300, 400);
  textSize(28);
}

function draw() {
  background(10);
  fill('#4169e1');
  rect(0, 0, 300, 40);
  fill('#b22222');
  rect(0, 360, 300, 40);
  fill(240);
  text('大吉', 100, 31);
  text(good, 170, 31);
  text('大凶', 100, 390);
  text(bad, 170, 390);
}
表示優先を考えて、四角より後に処理を組み込みます。

 

fill でテキストの色も指定できます。
fill(240) のように1つの数で指定するときはグレイスケールとなります。
黒:0 から白:255 の間で指定します。

 

 

マウスでパッドを動かす

玉を打ち返すパッドを表示します。
同時にマウスで操作できるようにします。

draw() のところに組み込みましょう。

function draw() {
  background(10);
  fill(200);
  rect(mouseX, 50, 100, 10);
  rect(mouseX, 350, 50, 10);

  fill('#4169e1');
  rect(0, 0, 300, 40);

 

実行すると上下にパドルが表示されます。
マウスカーソルを動かすと、それに合わせて左右に動きます。

ちょっと待ってください。
よく見るとカーソルと四角の左端が基準になっています。
これではゲームとして都合が悪いですね。
四角の中央を基準に操作できるようにします。

四角の中央でマウス操作できるようにする

 

問題です。
下にある2つの命令を使って、中央で揃えて操作できるようにしてください。
rectMode とは、描画のとき基点となる場所を指定します。
ヒント: 指定しないとき rectMode(CORNER) がデフォルトで設定されています。

  rectMode(CORNER);     // 左上で揃える(デフォルト)
  rectMode(CENTER);     // 中央で揃える
let good = 0;
let bad = 0;
let balls = [];

function setup() {
  createCanvas(300, 400);
  textSize(28);
}

function draw() {
  background(10);
  fill(200);
  rectMode(CENTER);     // 中央で揃える
  rect(mouseX, 50, 100, 10);
  rect(mouseX, 350, 50, 10);
  rectMode(CORNER);     // 左上で揃える(デフォルト)

  fill('#4169e1');
  rect(0, 0, 300, 40);
  fill('#b22222');
  rect(0, 360, 300, 40);
  fill(240);
  text('大吉', 100, 31);
  text(good, 170, 31);
  text('大凶', 100, 390);
  text(bad, 170, 390);
}
少し難しかったですね。パッドの四角は中央を基点とし、上下の四角は左上が基点となります。

 

ゲームを作るときは基本的に rectMode(CENTER) を setup() の中で行い、描画の基点を中央で統一する方が良いと思います。

 

 

玉の表示

玉を表示します。
プログラムは下のボタンをクリックすると表示されるので、コピー&ペーストしましょう。
追加した行には色を付けています。

let good = 0;
let bad = 0;
let balls = [];

function setup() {
  createCanvas(300, 400);
  textSize(28);
  
  for (let i = 0; i < 100; i++) {
    balls[i] = new Ball();
  }
}

function draw() {
  background(10);
  fill(200);
  rectMode(CENTER);     // 中央で揃える
  rect(mouseX, 50, 100, 10);
  rect(mouseX, 350, 50, 10);
  fill(255);
  for (let i = 0; i < 100; i++) {
    balls[i].disp();
  }
  rectMode(CORNER);     // 左上で揃える(デフォルト)

  fill('#4169e1');
  rect(0, 0, 300, 40);
  fill('#b22222');
  rect(0, 360, 300, 40);
  fill(240);
  text('大吉', 100, 31);
  text(good, 170, 31);
  text('大凶', 100, 390);
  text(bad, 170, 390);
}

class Ball {
  constructor() {
    this.x = width / 2;
    this.y = height / 2;
  }
  disp() {  // 玉の表示
    rect(this.x, this.y, 13, 13);
  }
  move() {  // 玉の移動と当り判定
  }
}

 

実行すると、中央に小さい四角が表示されます。

玉を表示する

 

Ball というクラスを作りました。
クラスにすることで、データ(座標や移動量など)とメソッド(表示処理や移動処理など)をまとめて管理することができます。
今回、たくさんの玉を表示するのでクラスにした方が扱い易くなります。

 

まず、クラスからインスタンスを作ります。
クラスは設計図のようなもので、実際に処理するための実体(インスタンス)が必要です。
ここでは100個のインスタンスを作りました。

function setup() {
  createCanvas(300, 400);
  textSize(28);
  
  for (let i = 0; i < 100; i++) {
    balls[i] = new Ball();
  }
}

 

draw() の中で玉の表示を行っています。
用意したインスタンスの表示処理 disp() を実行します。

  for (let i = 0; i < 100; i++) {
    balls[i].disp();
  }

 

Ball クラスは次のようになっています。
(未完成です。これから機能を付け足していきます)
コンストラクタ constructor はインスタンス化したときに実行されます。
width と height には createCanvas(300, 400) の 300 と 400 が入ってます。
これを2で割っているので、中央の座標が x と y に入ります。
なお、this を付けることでこのクラスの内部データとして扱われます。

class Ball {
  constructor() {
    this.x = width / 2;
    this.y = height / 2;
  }
  disp() {  // 玉の表示
    rect(this.x, this.y, 13, 13);
  }
  move() {  // 玉の移動と当り判定
  }
}

 

次回、玉の移動と当り判定を作って完成させます。

 

 

p5.js で遊ぶ

  1. オンラインエディタ
  2. 占いPongを作ろう
  3. 占いPong (完)
  4. ミサイル占いを作ろう
  5. OBJの表示と移動
  6. 当たり判定とリザルト