目次
JavaScriptのみでゲーム作成に臨む
JavaScript が好きな miya と申します。
唐突ですが、ライブラリーを使わずに JavaScript のみでゲーム作りに挑戦してみました。
以下がデモページです。
注意:
Chrome のみで動作します。
デザインの部分でCSSフレームワークのBootstrapを使っています。
アニメーションはパラパラ漫画
フルスクラッチでゲームを作るにあたって、まずはゲームがどんな仕組みで成り立っているのかを考えてみました。
ゲームは、アニメーションにゲーム特有の処理を追加したものといえます。
たとえば、キー操作によってキャラクターの位置を移動させたり、キャラクター同士が衝突したかを判定したり、衝突によって体力を減らしたりする処理です。
では、アニメーションとは何かというと、ぱらぱら漫画のようなものです。
1秒間に何回も絵を描画し、それぞれの絵が少しずつ違うと、動いているように見えます。
アニメーションとゲームの処理をまとめてみて、コードの処理の流れを以下のようにしてみました。
- 画面をきれいにクリア
- 描画するオブジェクトの位置を移動、当たり判定などのゲームに必要な処理を実行
- オブジェクトを描画
- 以降 1、2、3 をループ。
ゲームを構成する主な要素
それでは実際にゲームをつくるにあたって、登場人物を考えます。
今回は3人の登場人物でゲームを構成しました。
Game オブジェクト
ゲームの舞台をつくる裏方さん。
Game オブジェクトがいないと、何もはじまりません。
いわゆるゲームエンジンと呼ばれるものです。
今回の Game オブジェクトの主な仕事は以下です。
- キャラクターを動かす
- 衝突判定と衝突時のアクションを実行する
- キャラクターを描画する
- 時間を計る
Player オブジェクト
続いて、プレイヤーとなる Player オブジェクトです。
役割は以下です。
- プレイヤーの移動速度、位置、体力を管理する
- プレイヤーを移動する
Enemy オブジェクト
最後に、敵となる Enemy オブジェクトです。
役割は以下です。
- 敵の移動速度、位置を管理する。
- プレイヤーと衝突した際のアクションを実行する
- 敵を移動する
ここで、Game オブジェクトの「キャラクターを動かす」と、Player オブジェクトと Enemy オブジェクトの「XXを移動する」が重複していることに気が付くと思います。
これは、Game オブジェクトが、各 Player オブジェクトと Enemy オブジェクトがもつ移動処理を呼び出しているため、このような書き方にしました。
移動処理自体は、Player オブジェクトと Enemy オブジェクトが持っており、
Game オブジェクトは、それらを呼び出して実行しているだけ、という構成になります。
図で書くとこんな感じです。
また、移動と同様に、プレイヤーと敵が衝突したときのアクションも、Enemy オブジェクトにメソッドとして定義します。
衝突が起きた時に、プレイヤーのHPから-1する、などの処理を書きます。
キーボード操作によって、Player を動かす
キーボード操作によってプレイヤーを動かせるようにします。
キーがおされた時と、キーがもとに戻った時に処理をバインドします。
バインドする関数を定義
KeyUpFunc = function(e){
if(e.keyCode == 87 || e.keyCode == 38){
myplayer.w_f = false;
}
if(e.keyCode == 65 || e.keyCode == 37){
myplayer.a_f = false;
}
if(e.keyCode == 68 || e.keyCode == 39){
myplayer.d_f = false;
}
if(e.keyCode == 83 || e.keyCode == 40){
myplayer.s_f = false;
}
};
KeyDownFunc = function(e){
if(e.keyCode == 87 || e.keyCode == 38){
myplayer.w_f = true;
}
if(e.keyCode == 65 || e.keyCode == 37){
myplayer.a_f = true;
}
if(e.keyCode == 68 || e.keyCode == 39){
myplayer.d_f = true;
}
if(e.keyCode == 83 || e.keyCode == 40){
myplayer.s_f = true;
}
};
関数をイベントにバインド
document.addEventListener("keydown", KeyDownFunc);
document.addEventListener("keyup", KeyUpFunc);
プレイヤーの移動処理
Player.prototype = {
//処理移動
move: function(cW, cH, fps){
var
dummyZoneX = 20, //プレイヤーが入れない端っこの領域 X
dummyZoneY = 20 //プレイヤーが入れない端っこの領域 Y
;
if(this.w_f){
if(this.pY + (this.speedY/fps) >= 0 + dummyZoneY) {
this.pY = this.pY - (this.speedY/fps);
}
}
if(this.s_f){
if(this.pY + (this.speedY/fps) <= cH - dummyZoneY) {
this.pY = this.pY + (this.speedY/fps);
}
}
if(this.a_f){
if(this.pX + (this.speedX/fps) >= 0 + dummyZoneX) {
this.pX = this.pX - (this.speedX/fps);
}
}
if(this.d_f){
if(this.pX + (this.speedX/fps) <= cW - dummyZoneX) {
this.pX = this.pX + (this.speedX/fps);
}
}
}
};
キーが押されたときは、keydown イベントが発生するので、このイベントに KeyDownFunc という関数をバインドします。
KeyDownFunc では、プレイヤーオブジェクトがもつフラグを true にします。
wが上、aが左、dが右、sが下方向に移動だとすると、w が押されたときに w_f というフラグを true にします。
そして、Game オブジェクトがプレイヤーオブジェクト移動させる処理の際に、このフラグをみてプレイヤーオブジェクトを移動させるかどうか決定します。
反対に、キーが離されたタイミングではフラグを false にするようにします。
今回はここまでです。
次回は簡単な衝突の判定処理や、いろいろなタイプの敵を作成する流れをご紹介する予定です。