Canvasを使った衝突判定
ストライク、ボール、ヒット、アウトといったゲームの判定処理もCanvasを使って実装しています。エリアごとに色を塗った衝突判定用のフィールド画像を用意し、「赤の領域はアウト」「緑の領域は1ベースヒット」「黄緑の領域はホームラン」などと定義しておきます。ボールが投球されたら、このフィールド画像の色とボールの位置を比較して衝突判定します。
衝突判定の処理を抜粋したコードが以下になります。
(function(){
var AreaColor = {
OUT:0xff0000,
FOUL:0xaa0000,
STRIKE:0xdd0000,
BALL:0x550000,
OBJ:0x0000ff,
HIT1:0x005500,
HIT2:0x00aa00,
HIT3:0x00dd00,
HOMERUN:0x00ff00,
BAT:0xffff00,
RANDOM:0x555555
};
var hitareaImg = document.getElementById('hitareaImg');
var hitareaCanvas = document.createElement('canvas');
var w = hitareaImg.width;
var h = hitareaImg.height;
hitareaCanvas.width = w;
hitareaCanvas.height = h;
var hitareaCtx = hitareaCanvas.getContext('2d');
hitareaCtx.drawImage(hitareaImg,0,0);
var bytes = hitareaCtx.getImageData(0,0,w,h).data;
var ball = {x:0,y:0,v:3,radian:Math.PI/2};
(function(){
var nextx = ball.x + Math.cos(ball.radian) * ball.v;
var nexty = ball.y + Math.sin(ball.radian) * ball.v;
var index = (nextx | 0) + (nexty | 0) * w * 4;
var rgb = bytes[index] << 16 | bytes[index+1] << 8 | bytes[index+2];
if(rgb == AreaColor.OUT){
//アウトの処理
}else if(rgb == AreaColor.FOUL){
//ファールの処理
}else if(rgb == AreaColor.STRIKE){
//ストライクの処理
}/*以下省略 色ごとに処理*/
else{
//衝突していない場合、ボールを移動させる
ball.x = nextx;
ball.y = nexty;
}
setTimeout(arguments.callee,34);
})();
})();
context.getImageData(x,y,w,h).dataには1ピクセルあたりRGBAの4つのデータが1次元配列で入っています。ボールの座標からCanvasのindexを計算し、そのindexのRGBの値を取得します。
たとえば、(width,height) = (5,3)のCanvasに対して、位置(x,y) = (3,2)のindexは、
index = x * 4 + y * width * 4
= 3 * 4 + 2 * 5 * 4
= 52
になります。indexから後ろ4つの値が、その座標の色情報です。入っている順番は赤、緑、青、アルファです。それぞれの色を1つの値として取り出すためにビット演算を使ってrbgの値を求めます。求めた値をAreaColorのそれぞれの色情報と比較してその座標の衝突を判定しています。
バットとボールとの衝突も同様にCanvasを使って判定しています。バットはスウィングのアニメーションがあるので少々複雑ですが、同じような考え方で実装できます。
◆
背景とボール、バットの描画にはCanvasを使っていますが、ランナーが走るアニメーションはCSSアニメーションで実装しています。次回は、CSSアニメーションとJavaScriptの連携、Handy Stadiumで作成したライブラリーについて説明します。
著者:ハン☆スタ制作委員会/マインドフリー株式会社
日々切磋琢磨する大阪のイノベーター集団マインドフリー。先端Techとフリーなマインドを武器に「Fun!」なものづくりを目指してます。今回も新しい技術や開発言語が大好き!なSuperフレッシュエンジニア“やんぎー”(Facebookアプリ「Profile Photo Mosaic」を開発)が「世界を驚かせる!?計画」のひとつとして、Webアプリ開発の極みに迫るため「ハン☆スタ」をつくってみました。Let's play baseball♪
フロントエンドエンジニア 5509のnori も技術協力しています。