40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

quicktigame2dの使い方学ぶために簡易なシューティングゲームを作りはじめた

f:id:h5y1m141:20120217072706p:plain

何故ゲーム開発?

一年位前だと、TitaniumMobileではリアルタイムな処理が要求されるようなゲームにはちょっと厳しいという話をちらほら聞いていたのと、自分自身そんなにゲームをやらなくなったこともあってゲーム開発に関連する勉強は放置してました。

ただ、最近の求人案件動向見てると個人的な好みは別としてゲーム開発で期待されるスキルセットは簡単なものでも抑えておいたほう良いのかなと漠然と感じるようになりました。
幸い、quicktigame2dという素敵なTitaniumMobile向けのモジュールが登場したことで、「これだったら、一度自分で手を動かしてみよう」という気持ちになったのでチャレンジしてみました

サンプルは?

ゲーム開発に必要な知識がないので、何か参考になる書籍をベースにしようと思いました。ただ今のところ、TitaniumMobileの書籍でゲーム開発をとりあげた書籍がないので、スマフォ向けのゲーム開発の書籍がないか探ることにしました。
いきなり購入するのは、自分のお小遣い的に厳しいので、図書館で探し、WindowsPhone向けですがこれを見つけました。

Windows Phoneゲーム プログラミング
田中 達彦
ソフトバンククリエイティブ
売り上げランキング: 194419

書籍の中でシューティングゲームをとりあげているところがあったのでそれをquicktigame2d使って実装することにしました。

現在の実装状況

WindowsPhone向けなので、上記書籍内のサンプルコード(*)はC#だし、そもそもゲーム開発なんて全くやったことない状況でしたが、自分としては上記書籍はわわかりやすく感じました。C#全くしらないけど、C#らしい機能をつかっているわけでもないので、意外とすんなり理解出来ました。

ひとまず、砲台と敵と弾を表示するだけの処理しか実装してないけど、quicktigame2d使って100行程度のコードで済むのはすごく便利。

var win1 = Titanium.UI.createWindow({
    title:'Tab 1',
    backgroundColor:'#fff'
});

var quicktigame2d = require('com.googlecode.quicktigame2d');
var game = quicktigame2d.createGameView();
var scene = quicktigame2d.createScene();
var transform  = quicktigame2d.createTransform();
game.screen = {width:320, height:480};
game.fps = 30;
game.color(0, 0, 0);
game.pushScene(scene);

var MAXALIENS = 10;   // 敵の表示最大数の設定
var MAXBULLETS = 15; // 弾の最大数
var sprites = [];
var bullets = [];
var tank = quicktigame2d.createSprite({image:'images/tank.png'});

/*
  横位置:画面下辺の中央に設置するために画面横幅の半分を取得
  さらに画像の幅の半分を引くことで描画する位置のX座標が計算可能

  縦位置:画面の高さから画像の高さ分を引くことで計算可能
*/
tank.x = (320/2) - (tank.width/2);
tank.y = 480 - tank.height;
var back = quicktigame2d.createSprite({image:'images/back.png'});
back.x = (320/2) - (back.width/2);
back.y = 480 - back.height;
scene.add(back);
scene.add(tank);

//敵と砲台から出る弾の初期化
for(var i=0;i<MAXALIENS;i++){
  sprites[i]= quicktigame2d.createSprite({image:'images/alien1.png'});
  scene.add(sprites[i]);
}
for(var j=0;j<MAXBULLETS;j++){
  bullets[j]= quicktigame2d.createSprite({image:'images/bullet.png'});
  bullets[j].x = tank.x + (bullets[j].width*2);
  bullets[j].y = tank.y - (bullets[j].height);
  scene.add(bullets[j]);
}


var transform_block_rotate = quicktigame2d.createTransform();
var transform_block_move   = quicktigame2d.createTransform();

game.addEventListener('onload', function(e) {
  // place sprites at random position
  for (var i = 0; i < MAXALIENS; i++) {
    sprites[i].x = Math.random() * game.screen.width;
    sprites[i].y = -100;
  }
  game.start();
});
game.addEventListener('enterframe', function(e) {
  updateAliensPosition();
  updateBulletPosition();
});
game.addEventListener('touchstart', function(e) {
  startTransformBlock();
});
win1.add(game);
win1.open();

function updateAliensPosition(){
  for (var i = 0; i < MAXALIENS; i++) {
    sprites[i].y += Math.random()*30;
    if(sprites[i].y > 480){
      sprites[i].y = -100;
    }
    transform.duration = 1000;
    transform.easing = quicktigame2d.ANIMATION_CURVE_LINEAR;
    sprites[i].transform(transform);

  }
}
function updateBulletPosition(){
  for (var i = 0; i < MAXBULLETS; i++) {
    Ti.API.info('x:'+bullets[i].x+ 'y:'+bullets[i].y);
    bullets[i].x += Math.random()*10;
    bullets[i].y -= Math.random()*30;
    // 弾が画面外に出た時にはタンクの砲台位置に弾を再設定

    if(bullets[i].x < 0 ||bullets[i].x > 320 || bullets[i].y < 0 || bullets[i].y > 480){
      bullets[i].x = tank.x + (bullets[i].width*2);
      bullets[i].y = tank.y - (bullets[i].height);
    }

    transform.duration = 5000;
    transform.easing = quicktigame2d.ANIMATION_CURVE_LINEAR;
    bullets[i].transform(transform);
  }

}

※書籍内のC#サンプルコードはこちらからダウンロード出来ます。