2013年3月15日金曜日

磯野ー!2Dゲーム開発しようぜー! HTML5編 その2

今回はHTML5でのゲーム開発を解説するシリーズの第二回である。前回は以下。

磯野ー!2Dゲーム開発しようぜー! HTML5編 その1

今回からコードを使って解説していく。内容はCoffeeScriptをもとに説明するけれど、javascriptsフォルダ内に対応するJavaScriptファイルがあるのでCoffeeScriptになじみがない方はそちらを参照してほしい。

index.html
<body>
<canvas id="c" width="480" height="320"></canvas>
</body>
なぜかCSSからのサイズ指定が行えないのでCanvasタグに直接widthとheightを指定している。


coffeescripts/contentManager.coffee
class ContentManager
 manifest:[
  {src:'images/Background02.png', id:'background'},
  {src:'images/BlueShip.png', id:'ship'},
  {src:'images/WalkingSquare.png', id:'square'}
 ]
 constructor: (@stage, width, height, @downloadCompleteCallback)->
  @preload = new createjs.PreloadJS false # useXHR=false ローカルからファイルを読み込むのでimageタグを強要する
            # xhrはCross Origin Resource Sharingを許可しない
  @preload.onError = @handleElementError
  @preload.onFileLoad = @handleElementLoad
  @downloadProgress = new createjs.Text "-- %", "bold 18px Arial", "#fff"
  @downloadProgress.x = (width / 2)
  @downloadProgress.y = (height / 2)
  @elementLoadedCount = 0
 startDownload: ->
  @preload.loadManifest @manifest
  @stage.addChild @downloadProgress
  createjs.Ticker.addListener this
  createjs.Ticker.setInterval 50
 handleElementError: (e)=>
  alert "画像読み込み失敗 : #{e.src}"
 handleElementLoad: (e)=>
  @[e.id] = e.result
  @elementLoadedCount += 1
  if @elementLoadedCount is @manifest.length
   @stage.removeChild @downloadProgress
   createjs.Ticker.removeListener this
   @downloadCompleteCallback()
 tick: =>
  @downloadProgress.text = Math.round((@elementLoadedCount/@manifest.length) * 100) + " %"
  @stage.update()
window.ContentManager = ContentManager
何はともあれ画像がないとはじまらないのでPreloadJSを使用して画像を読み込む。
・2行目、読み込む対象画像へのパスを指定する。ここで指定しているidが11行目のonFileLoadイベントの引数e.idとして渡ってくる
・8行目、PreloadJSのコンストラクタにuseXHR=falseを指定している。この引数はPreloadJSにXHRではなくimageタグでの画像取得を行わせるための設定。今回のサンプルはローカルファイルからの読み込みなのでXHRでの取得ができない
・10行目、画像取得時にエラーが発生した場合のコールバックを設定する
・11行目、各画像取得完了時のコールバックを設定する
・17行目、PreloadJSに画像の読み込みを指示する
・19行目、createjs.Tickerのイベントリスナーを登録する。ここで登録したオブジェクトのtickメソッドが定期的に呼び出される。このtickメソッドがいわゆるゲーム開発におけるメインループとなる
・24行目、取得の完了した画像のidをプロパティ名として画像内容を設定する。このidは2行目で設定していたものと同一
・28行目、すべての画像の取得が完了したのでTickerのイベントリスナーを忘れずにはずしておく
・32行目、stage.update()で画面のリフレッシュを行う。stageについては後述する

とざっくりとだがPreloadJSの機能説明をした。簡単に言うと画像の取得が楽、という一言に尽きる。ちなみにPreloadJSを使わずに画像取得をする場合は以下のようになる。
var image = new Image();
image.onload = function() {
 context.drawImage(image, 10, 10);
};
image.src = "http://hoge/test.jpg";
上記のコードを汎用的に使いやすい形にするとPreloadJSになるのが理解できるかと思う。


coffeescripts/index.coffee
$(document).ready ()->
 isCanvasSupported = ->
  elem = document.createElement('canvas')
  return !!(elem.getContext && elem.getContext('2d'))
 unless isCanvasSupported()
  return alert "あなたのブラウザはCanvasが使えないです"

 canvas = $('#c')[0]
 stage = new createjs.Stage canvas

 contentManager = new ContentManager stage, canvas.width, canvas.height, ->
  platform = new GamePlatform(stage, canvas.width, canvas.height, this)
  platform.startGame()
 contentManager.startDownload()
使用しているブラウザがCanvasをサポートしているかチェックしてから先ほどのContentManagerで画像の取得を行っている。全画像取得完了時のコールバックでGamePlatform(後述)をインスタンス化しゲーム本編へと移行する。
・9行目、Stageをインスタンス化している。BitmapオブジェクトやBitmapAnimationオブジェクトなどの描画したいオブジェクトをstage.addChild(Obj)で追加する。stage.update()で追加されたオブジェクトのリストをコンストラクタで指定されたCanvasへと描画する。

EaselJSではTickerとStageが開発の基礎となる。

長くなったので続きは次回

0 件のコメント:

コメントを投稿