JS と Canvas で作る
シューティングゲーム
自己紹介
• HN: さい
• Twitter: @sairoutine
• Webアプリケーションエンジニア
• 東方Projectが大好きです
• JavaScript 1年生
シューティングゲームが作りたい
Unity とか UnrealEngine とか使うと、
最近は手軽に作ることができる
らしいですね
新しいことを覚えるのが面倒くさい
(注) ソフトウェアエンジニアとして
相当死んでる発言です
JavaScript でゲームが
作れるらしいぞ!
マジか!
偉大なる先人
https://github.com/takahirox/toho-like-js
すげぇ!
俺も作る!
DEMO
使ったツール
Browserify
Gulp
画面
Canvas API
音/効果音
Web Audio API
フレームワーク
なし!
基本的な流れ
Game.prototype.run = function(){
// シーン更新
this.scenes[ this.state ].run();
this.scenes[ this.state ].updateDisplay();
// SEを再生
this.runPlaySound();
// 経過フレーム数更新
this.frame_count++;
// 押下されたキーを保存しておく
this.before_keyflag = this.keyflag;
// 次の描画タイミングで再呼び出ししてループ
requestAnimationFrame(this.run.bind(this));
};
シーンの流れ
StageScene.prototype.run = function(){
// 自機
this.character.run();
// 自機弾
this.shotmanager.run();
// 敵
this.enemymanager.run();
// 敵弾
this.bulletmanager.run();
// アイテム
this.itemmanager.run();
// エフェクト
this.effectmanager.run();
// ボム
this.bombmanager.run();
// アイテムと自機の衝突判定
this.itemmanager.checkCollisionWithCharacter(this.character);
// 自機弾と敵の衝突判定
this.shotmanager.checkCollisionWithEnemies(this.enemymanager);
// 敵と自機の衝突判定
this.enemymanager.checkCollisionWithCharacter(this.character);
// 敵弾と自機の衝突判定
this.bulletmanager.checkCollisionWithCharacter(this.character);
キーボード入力①
// キー押下
Game.prototype.handleKeyDown = function(e){
this.keyflag |= this._keyCodeToBitCode(e.keyCode);
e.preventDefault( ) ;
};
// キー押下解除
Game.prototype.handleKeyUp = function(e){
this.keyflag &= ~this._keyCodeToBitCode(e.keyCode);
e.preventDefault( ) ;
};
キーボード入力②
// 指定のキーが押下状態か確認する
Game.prototype.isKeyDown = function(flag) {
return this.keyflag & flag;
};
// 指定のキーが押下されたか確認する
Game.prototype.isKeyPush = function(flag) {
// 1フレーム前に押下されておらず、現フレームで押下さ
れてるなら true
return !(this.before_keyflag & flag) && this.keyflag & flag;
};
当たり判定
// オブジェクトとオブジェクトの衝突判定を行う
ObjectBase.prototype.checkCollision = function(obj) {
if( this.inCollisionArea(obj.getCollisionLeftX(), obj.getCollisionUpY()) ||
this.inCollisionArea(obj.getCollisionLeftX(), obj.getCollisionBottomY()) ||
this.inCollisionArea(obj.getCollisionRightX(), obj.getCollisionUpY()) ||
this.inCollisionArea(obj.getCollisionRightX(), obj.getCollisionBottomY())
||
this.inCollisionArea(obj.x, obj.y)
) {
return true ;
}
return false ;
};
敵/敵弾の動きを記述する
var __enemyBulletsParams = [
[
{
'v': { 'r': 5, 'theta': 165, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
{
'v': { 'r': 5, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
{
'v': { 'r': 5, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
{
'v': { 'r': 5, 'theta': 75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
{
'v': { 'r': 5, 'theta': 45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
{
'v': { 'r': 5, 'theta': 15, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
},
角度と速度から移動先の(x, y)座標を
求める方法は、
高校の教科書にお任せします!
まとめ
1/60秒ごとに画面全部のオブジェクトの座標/オ
ブジェクト同士の当たり判定を行ってるが、古い
PCでも特に処理落ちの様子はなし
→ Chrome の V8 エンジン優秀
WebGL でより表現が広がるので次は試してみたい
ありがとうございました!

JS と Canvas で作るシューティングゲーム