体験授業

講師:大森田不可止

シューティングゲーム

Webサーバ

ブラウザ

IE, FireFox, Chrome, Safari, ...

JavaScript

enchant.js

jsbin.com の使い方

index.html

JavaScript プログラムのひな形

enchant();  // enchant.js を使えるようにする

window.onload = function() {  // ブラウザにデータが全て読み込まれたら
  var width = 480, height = 640;  // ゲーム画面のサイズを変数に
  var core = new Core( width, height );  // ゲーム画面を作る
  core.rootScene.backgroundColor = "#000000"; // 背景は真っ黒
  core.fps = 30;  // 1秒間に30回更新
  // 事前に画像ファイルは読み込んでおく。別のサーバに置かれている。
  core.preload( 'http://techc.omorita.com/img/ship.png' );
  core.keybind(0x20, 'a');  // space キーに名前を与える

  // メイン処理.
  core.onload = function() {  // 準備が完了したら開始
    // ここに初期化処理を書いていく.

    core.addEventListener('enterframe', function() {
      // ループ処理

    });
  };

  // ゲームをスタート.
  core.start();
};
        

グラフィック素材

MyShipの表示

core.onload = function() { の行の直後に以下を追加。

  // メイン処理.
  core.onload = function() {
    // ここに初期化処理を書いていく.

    // MyShip
    var myship = new Sprite(60, 60);  // 60x60 のスプライト作る
    myship.image = core.assets['http://techc.omorita.com/img/ship.png'];
    myship.y = height - 30;
    myship.x = width/2 - 30;
    myship.frame = [6, 7];   // 6番目と7番目のパターンを交互に表示
    myship.status = 0;
    core.rootScene.addChild( myship );
        

jsbin: ここまでのプログラム

敵の表示

myship表示プログラムの直後に以下を追加。

    // Enemy
    var enemy = new Sprite(60, 60);
    enemy.image = core.assets['http://techc.omorita.com/img/ship.png'];
    enemy.y = 0;
    enemy.x = width/2 - 30;
    enemy.vx = 0;
    enemy.vy = 0;
    enemy.frame = [0, 1];
    enemy.status = 0;
    enemy.rotation = 180;  // 180度回転してこっち向きに
    core.rootScene.addChild( enemy );
        

jsbin: ここまでのプログラム

MyShipを矢印キーで左右に動かす

core.addEventListener('enterframe', function() { の行の直後に以下を追加。ここに書いたプログラムは毎秒30回呼び出される。

    core.addEventListener('enterframe', function() {
      // ループ処理

      // MyShip
      var myshipSpd = 4;
      if( myship.status === 0){
        if (core.input.right) {
          myship.x += myshipSpd;
          if( myship.x > width - 60 ) {
            myship.x = width - 60;
          }
        }
        if (core.input.left) {
          myship.x -= myshipSpd;
          if(myship.x < 0) {
            myship.x = 0;
          }
        }
      }
        

jsbin: ここまでのプログラム

敵を動かす

myshipを動かすプログラムの直後に以下を追加。

    // move Enemy
    enemy.y += 8;
    if( enemy.y >= 640 ){
      enemy.y = -60;
      enemy.x = Math.floor(Math.random() * 420);
    }
        

jsbin: ここまでのプログラム

Bulletの表示

enemy表示プログラムの直後に以下を追加。

    // bullet
    var bullet = new Sprite(15,15);
    bullet.image = core.assets['http://techc.omorita.com/img/ship.png'];
    bullet.frame = 12*16;
    bullet.y = -15;  // out of range
    core.rootScene.addChild( bullet );
        

Bulletの発射

enemyの動きプログラムの直後に以下を追加。

      // move bullet & fire
      if( bullet.y <= -15 ){
        if (core.input.a) {  // Fire
          bullet.y = myship.y;
          bullet.x = myship.x+22;
        }
      } else {
        bullet.y -= 12;
      }
        

jsbin: ここまでのプログラム

衝突判定

bulletの動きプログラムの直後に以下を追加。

      // 衝突判定 enemy & bullet
      if( bullet.y > -15 && enemy.status == 0 ){
        if( bullet.within( enemy, 37 )){
          enemy.frame = [8,9,10,11,13,null];
          enemy.status = 6;
          bullet.y = -15;
        }
      }
        

Enemy の動きプログラムの修正

enemy のstatusを見て動作を変える。

      // move Enemy
      if(enemy.status > 0){
        if(--enemy.count == 0){
          enemy.frame = [0,1];
          enemy.y = 640;
        }
      } else {
        enemy.y += 8;
        if( enemy.y >= 640 ){
          enemy.y = -60;
          enemy.x = Math.floor(Math.random() * 420);
        }
      }
        

jsbin: ここまでのプログラム

第二段階

Spriteクラスの拡張

enchant.Class を使って、Sprite クラスに機能を追加した ExSprite クラスを作る。

var ExSprite = Class.create(Sprite, { // Spriteを継承したクラスを作成する
  initialize: function(size, frame, px, py, rotation, visible) { // コンストラクタを上書きする
      Sprite.call(this, size, size); // 継承元のコンストラクタを適用する
      this.image = core.assets['http://techc.omorita.com/img/ship.png'];
      this.frame = frame;
      this.x = px;
      this.y = py;
      this.rotation = rotation;
      this.wait = 0;
      this.visible = visible;
      return this;
    },
  setpos: function(px, py, velocity, rotation){
      this.x = px;
      this.y = py;
      this.velocity = velocity;
      this.rotation = rotation;
      this.visible = true;
    },
  move(){
      this.y = -Math.cos(this.rotation/180*Math.PI) * this.velocity;
      this.x = Math.sin(this.rotation/180*Math.PI) * this.velocity;
      if(this.checkOut()){
        this.visible = false;
      }
    },
  checkOut(){
    if(this.x < -this.width || this.x >= 480 + this.width){
      return true;
    }
    if(this.y < -this.height || this.y >= 640 + this.height){
      return true;
    }
    return false;
  }
});

少し手を加えたサンプル

シューティングゲームの骨組みだけ

参考リンク

/