「重力」はどうやってプログラミングする?- パート❶:まずは「クラス」で物体を表現してみよう - JavaScriptでやる1分間プログラミング
これまでp5.jsエディタを使って、まずは円や四角など簡単な図形を描き、次に図形を一方向に動かし、そしてキャンバス内を動き回るロジックについて解説してきました。
ところが、モノが永遠に動き続けるというのはある意味コンピューターゲームの中だけの話です。現実には摩擦や抵抗、重力、加速などが存在しているため、モノの動きというのはもっと複雑です。
「ジャンプ」の動きをプログラミングする
そこで、もうちょっとリアルなものの動きをプログラミングで表現してみます。今回のベースとなるCoding Trainのチュートリアルはこれです。
ここではDinosaur Gameという、恐竜のキャラクターがジャンプして障害物(サボテン)をクリアするという簡単なゲームをp5.jsで再現しています。
この「物体がジャンプする」という動きをプログラミングでどう処理しているのか、今回はそれを詳しく理解してみましょう。
ジャンプさせるのはYの数字を減らせばよい
ここまでp5.jsを使って物体(四角や円)をX軸とY軸の値を変化させて動かす原理については理解できたと思います。物体のジャンプを再現するには次の2つを実行すればよいのです。
1.物体をキャンバスの下の方(地面だと考えます)に描画
2.物体のYの値を減らす(つまり上に行く)
まずは物体を作って下の方に置きます。これまでと同様、ピンクの円をキャンバスの下に配置します。
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
fill(200, 0, 200);
circle(100, height - 25, 50);
}
直径50の大きさの円で、これを半径の分(50の半分で25)を”浮かせる”(上にずらす)ようにYの値をheight - 25としています。
さて、これをジャンプさせるにはどうしたらよいでしょうか。
物体を「クラス」で表現する
これまで円や四角を描く際にはそのままcircleやrectなどを使ってきました。今回のプログラミングでは、物体を表現するのに今は円を使っていますが、最終的には恐竜の絵(画像)を表示させることになります。円から画像へと外見が変わるだけではなく、ジャンプさせて場所を移動させるような処理をするのでこの物体に関する「情報」や「データ」を自由に変えることができるようにしないといけません。そこでプログラミングではclass(クラス)という仕組みを使っていろいろなものを表現するようにします。
キャンバスで動かすものは常にclassで
なんだか本格的に”プログラミング的な話”になってきていますが、ここは単純に考えて、まず「キャンバスに表示し動かしたいものはすべてclassを使って”定義する」と覚えておいてください。
例えば今回は恐竜のキャラクターをジャンプさせます。そこで恐竜がどんなもので(例:形、大きさ、位置など)、どのような動作をするか(例:前に進む、ジャンプする、消えるなど)をいろいろと決めないといけません。それをclassというものを作って行います。では一つ一つ手順を見ていきます。
ステップ❶:classの定義
ビデオでは別のjsファイルを作成してそこにクラスを定義していますが、ここではsketch.jsに直接クラスのコードを書いていきます。
恐竜はビデオ通りにUnicorn(ユニコーン)という名前を付けます。クラスの定義はclassというタイプで始め、そこにUnicornという名前を入れるだけです。あとはfunctionと同じように中括弧を加えます。
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
fill(200, 0, 200);
circle(100, height-25, 50);
}
//ステップ1⃣:ユニコーンのクラス
class Unicorn {
}
このままプログラムを実行してもエラーは出ませんが何の変化もなく同じように円が現れます。
ステップ❷:クラスの”データ”を指定する
最初にやることはUnicornクラスの位置や大きさなどを設定します。つまりここで「ユニコーンがどこにどの大きさで表示されるか」を決めるということです。クラスのコードのところに次の「constructor コンストラクタ」とある4行を加えてください。
//ユニコーンのクラス
class Unicorn {
//ステップ2⃣:コンストラクタのコードを書く
constructor (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
}
このコードをみてもちんぷんかんぷんかもしれませんが、今は全く構いません。まずはこの部分のポイントだけおさえておいてください。
ざっと見て分かるのはx, y, r(X軸の位置、Y軸の位置、大きさ)を指定しているということです。constructor(コンストラクタ)というのは「建築会社」という意味がありますが、そんな感じで「何かを造るもの」というように考えてください。このconstructorの中でUnicornクラスでできた実際の物体が出来上がった(constructされた)時の位置や大きさをセットするわけです。どうやってXやYの値がセットされるかは後で解説します。
それにしても、やっぱりちんぷんかんぷんですよね。でも大丈夫です。次のステップでもっと分かるようになるはずです。
ステップ❸;クラスを表示させる関数を書く
ではユニコーンを表示させるコードを加えます。そこでクラス内にshowという関数を加えます。その中に円を描くコードを書いてみましょう。
//ユニコーンのクラス
class Unicorn {
//コンストラクタ
constructor (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
//ステップ3⃣:クラスの表示
show() {
circle (this.x, this.y, this.r);
}
}
「あれ?なんで円なの?」と思ったでしょうが、キャラクタの画像を表示させる前に、まずはユニコーンは円だとして表示させてみましょう。なのでここはおなじみのcircleを使います。そしてx, y, rの値ですが、どうしてthis.x, this.yのようにthisが入るのかは今は気にしないでください。
これで最小限のユニコーンクラスが完成です!ではそれを使って表示させてみましょう。
ステップ❹;クラスを作って表示する
「クラス」というのは「物体の設計図」みたいなものです。なので、この設計図を使ってクラスを”作る”という操作をしないと何も現れません。クラスは設計図を使って物体は何個でも作ることができますが、ここではまず1つだけ作ってみましょう。
まずは次のステップに沿ってコードを書きます。
1⃣ クラスを使って作る物体を入れておく変数を定義する
2⃣ クラスを作って物体を作り、それを用意しておいた変数に入れる
3⃣ クラスのshow関数を呼び出して表示させる
それぞれのコードに同じ番号を付けておいたので、次の中で追加された3行をみてください。混乱がないようにsketch.js全部を掲載しています。
let unicorn; //1⃣ ユニコーン変数を作る
function setup() {
createCanvas(400, 400);
//2⃣ ユニコーンを一つ作る
unicorn = new Unicorn(100, height-25, 50);
}
function draw() {
background(220);
fill(200, 0, 200);
unicorn.show(); //3⃣ ユニコーンを表示させる
}
//ユニコーンのクラス
class Unicorn {
//コンストラクタ
constructor (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
//クラスの表示
show() {
circle (this.x, this.y, this.r);
}
}
追加した3行はこんな意味を持っています。
❶ まずlet unicornでunicornという変数の入れ物ができます。まだこの段階では空っぽの入れ物があるだけです。
❷ 次にUnicornクラスの”実体”を作るにはnew Unicornというコードを書きます。そこの括弧の中にはクラスで指定したX、Y、Rの値をいれます。最初の円と同様にxは100、yはheight-25、rは50にします。このnewによって文字通り新しいUnicornが一つ誕生します。それをunicorn変数に入れておくわkです。
❸ そこでunicornにはshowという関数があり、それでユニコーン(今は単なる円ですが)が表示されます。unicorn.show()というコードで呼び出すだけです。
このコードを実行すると、最初に書いたコードと同様にピンクの円が一つだけ表示されます。
ステップ❺:クラスを動かす
「円を表示させるだけでどうしてこんなめんどうなことをするの?」というのが正直な疑問だと思います。ここでは単に円を描いたのではなく、「Unicornクラスによって作ったユニコーンを表示させた」のです。
ではクラスの”パワー”を実感するために、ユニコーンをジャンプさせるプログラムを書いてみましょう。
まずはユニコーンクラスに「move 動かす」関数を追加してみます。
//動く ⇒ 4⃣ 動くメソッドを加える
move() {
this.y -= 5;
}
つまりmoveが呼び出されるとyの値が5だけ減少する(つまり上に移動する)ということになります(❹)。
これをshowで表示させる前に呼び出してユニコーンを移動させます(❺)。
では変更を加えたコードを再掲載します。
let unicorn; //1⃣ ユニコーン変数を作る
function setup() {
createCanvas(400, 400);
//2⃣ ユニコーンを一つ作る
unicorn = new Unicorn(100, height-25, 50);
}
function draw() {
background(220);
fill(200, 0, 200);
unicorn.move(); //5⃣ ユニコーンを動かす.
unicorn.show(); //3⃣ ユニコーンを表示させる
}
//ユニコーンのクラス
class Unicorn {
//コンストラクタ
constructor (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
//動く ⇒ 4⃣ 動くメソッドを加える
move() {
this.y -= 5;
}
//クラスの表示
show() {
circle (this.x, this.y, this.r);
}
}
Good-by, unicorn!
さて、これを実行すると円が上に移動していきます。でも上昇し続けると画面から消えてしまいます。ビデオでShiffman先生が"Oh, good-by, unicorn..."と言う場面がこれです。
でもよく見るとこれは「ジャンプの前半の動き」とも考えられませんが?ジャンプというのはまずは上に上昇していきますよね。でも今のコードがジャンプでないのは上昇し続ける点です。これがもし上昇のペースがだんだん遅くなって、しまいには逆に下に落ちてくるようになると”ジャンプ”になります。それがまさに「重力が加味された状態」なのです。
では次回パート❷ではmoveに重力を織り込んだコードにして「ジャンプ」をプログラミングで表現してみます。
この記事が気に入ったらサポートをしてみませんか?