ウニボールのソース
// 主人公の向き
var RpgDirection = {
South:0
, SouthWest:3
, West:6
, SouthEast:9
, East:12
, NorthWest:15
, North:18
, NorthEast:21
};
// イガイガを避けるゲームのコンストラクタ
var clsSample01 = function()
{
// ゲームエンジン生成
this.GameUtl = new clsGameUtl();
// 主人公チップの幅
this.ExpCx = 40;
// 主人公チップの高さ
this.ExpCy = 56;
// 主人公の進行方向
this.ExpDirection = RpgDirection.South;
// 主人公ロード
this.Explorer = this.GameUtl.LoadImage('./explorer.png');
// ボールロード
this.Ball = this.GameUtl.LoadImage('./uball.png');
}
// 実行
clsSample01.prototype.Run = function()
{
// キー入力イベントの設定
window.addEventListener('keydown', this.KeyDown.bind(this));
// ゲームエンジン初期化
this.GameUtl.Initialize(this);
// グリッドレイア
this.GameUtl.CreateLayer(this.EnterGrid, true, false);
// 主人公レイア
this.Hero = this.GameUtl.CreateLayer(this.EnterHero, true, false);
// ボールレイア
this.GameUtl.CreateLayer(this.EnterBall, true, false);
}
// グリッドレイアの描画
clsSample01.prototype.EnterGrid = function(ctx, p)
{
if (!p.EnterGrid) {
// レイアのサイズを得る
var sz = this.GameUtl.GetSize();
// 背景を塗りつぶす
ctx.fillStyle = "#ccffff";
ctx.fillRect(0, 0, sz.cx, sz.cy);
// 水平線
for (var sy = 0; sy < sz.cy; sy += this.ExpCy) {
ctx.moveTo(0, sy);
ctx.lineTo(sz.cx, sy);
ctx.stroke();
}
// 垂直線
for (var sx = 0; sx < sz.cx; sx += this.ExpCx) {
ctx.moveTo(sx, 0);
ctx.lineTo(sx, sz.cy);
ctx.stroke();
}
// 描画は一度のみ
p.EnterGrid = true;
}
}
// 主人公レイアの描画
clsSample01.prototype.EnterHero = function(ctx, p)
{
if (this.Explorer.complete) {
// fps からフレーム番号を得る
var frame = this.GameUtl.GetNextFrame(p, 256, this.ExpFrameNum);
// 描画するコマが変化したなら...
if (p.Frame != frame) {
// フレーム番号を記憶する
p.Frame = frame;
// レイアのサイズを得る
var sz = this.GameUtl.GetSize();
// キャンバスクリア
ctx.clearRect(0, 0, sz.cx, sz.cy);
// 画像位置の転送元の位置を設定
var sx = ((this.ExpDirection % 2) == 0 ? 0 : this.ExpCx * 3) + (p.Frame * this.ExpCx);
var sy = Math.floor(this.ExpDirection / 6) * this.ExpCy;
// 画像位置の転送先の位置を設定
var dx = this.ExpCol * this.ExpCx;
var dy = this.ExpRow * this.ExpCy;
// 主人公描画
if (dx >= 0 && dx < sz.cx && dy >= 0 && dy < sz.cy)
ctx.drawImage(this.Explorer, sx, sy, this.ExpCx, this.ExpCy, dx, dy, this.ExpCx, this.ExpCy);
}
}
}
// ボールレイアの描画
clsSample01.prototype.EnterBall = function(ctx, p)
{
if (this.Ball.complete) {
// fps からフレーム番号を得る
var frame = this.GameUtl.GetNextFrame(p, this.ExpBallSpeed, 4096);
// 描画するコマが変化したなら...
if (p.Frame != frame) {
// フレーム番号を記憶する
p.Frame = frame;
// レイアのサイズを得る
var sz = this.GameUtl.GetSize();
// 行列の最大値を設定
var maxRow = Math.floor(sz.cy / this.ExpCy) - 1;
var maxCol = Math.floor(sz.cx / this.ExpCx) - 1;
// ボールの位置を初期化
if (!p.BallPos) {
p.BallPos = {row:maxRow, col:this.Random(0, maxCol), vect:this.Random(0, 3) };
p.BallAddR = [ -1, 1, 1, -1 ];
p.BallAddC = [ 1, 1, -1, -1 ];
}
// 移動後の行列を得る
var row = p.BallPos.row + p.BallAddR[p.BallPos.vect];
var col = p.BallPos.col + p.BallAddC[p.BallPos.vect];
// 枠外に飛び出したフラグ
var bBound = (row < 0 || row > maxRow || col < 0 || col > maxCol);
// 枠外に飛び出したら枠内の位置にリセット
if (bBound) {
p.BallPos.row = (this.Random(0, 1) == 0 ? 0 : maxRow);
p.BallPos.col = this.Random(0, maxCol);
p.BallPos.vect = (p.BallPos.row == 0 ? this.Random(1, 2) : (this.Random(0, 1) == 0 ? 0 : 3));
// 得点を加算
$('#score').text(++this.Scored);
}
else {
// 行列を移動
p.BallPos.row += p.BallAddR[p.BallPos.vect];
p.BallPos.col += p.BallAddC[p.BallPos.vect];
// 画像位置の転送先の位置を設定
var dx = p.BallPos.col * this.ExpCx;
var dy = p.BallPos.row * this.ExpCy;
// キャンバスクリア
ctx.clearRect(0, 0, sz.cx, sz.cy);
// ボールを描画
ctx.drawImage(this.Ball, dx, dy, this.ExpCx, this.ExpCy);
// ゲームオーバー判定
var bGameOver = (p.BallPos.row == this.ExpRow && p.BallPos.col == this.ExpCol);
// ゲームオーバーならその旨を表示
if (bGameOver) {
this.GameUtl.aryLayer[this.Hero].prm.Frame = this.ExpFrameNum + 1;
this.GameUtl.DrawLayer(this.Hero);
this.GameUtl.CanRenderer = false;
$('#msg').text(" ★ゲームオーバー★");
}
}
}
else
p.Frame = -1;
}
}
// キー入力
clsSample01.prototype.KeyDown = function(e)
{
// レイアのサイズを得る
var sz = this.GameUtl.GetSize();
// 行列の最大値を設定
var maxRow = Math.floor(sz.cy / this.ExpCy) - 1;
var maxCol = Math.floor(sz.cx / this.ExpCx) - 1;
// テンキーは小文字で表現される
var ch = String.fromCharCode(e.keyCode);
// キー分岐
switch (ch) {
case '2': case 'C':case 'b': // 下
this.ExpDirection = RpgDirection.South;
this.ExpRow += (this.ExpRow + 1 > maxRow ? 0 : 1);
break;
case '1': case 'X': case 'a': // 左下
this.ExpDirection = RpgDirection.SouthWest;
this.ExpRow += (this.ExpRow + 1 > maxRow ? 0 : 1);
this.ExpCol += (this.ExpCol - 1 < 0 ? 0 : -1);
break;
case '4': case 'S': case 'd': // 左
this.ExpDirection = RpgDirection.West;
this.ExpCol += (this.ExpCol - 1 < 0 ? 0 : -1);
break;
case '3': case 'V': case 'c': // 右下
this.ExpDirection = RpgDirection.SouthEast;
this.ExpRow += (this.ExpRow + 1 > maxRow ? 0 : 1);
this.ExpCol += (this.ExpCol + 1 > maxCol ? 0 : 1);
break;
case '6': case 'F': case 'f': // 右
this.ExpDirection = RpgDirection.East;
this.ExpCol += (this.ExpCol + 1 > maxCol ? 0 : 1);
break;
case '7': case 'W': case 'g': // 左上
this.ExpDirection = RpgDirection.NorthWest;
this.ExpRow += (this.ExpRow - 1 < 0 ? 0 : -1);
this.ExpCol += (this.ExpCol - 1 < 0 ? 0 : -1);
break;
case '8': case 'E': case 'h': // 上
this.ExpDirection = RpgDirection.North;
this.ExpRow += (this.ExpRow - 1 < 0 ? 0 : -1);
break;
case '9': case 'R': case 'i': // 右上
this.ExpDirection = RpgDirection.NorthEast;
this.ExpCol += (this.ExpCol + 1 > maxCol ? 0 : 1);
this.ExpRow += (this.ExpRow - 1 < 0 ? 0 : -1);
break;
case ' ':
// ゲーム停止
this.GameUtl.Stop();
// ボール速度
this.ExpBallSpeed = parseInt($('#speed').val());
// 主人公の行位置
this.ExpRow = Math.floor(sz.cy / 2 / this.ExpCy);
// 主人公の列位置
this.ExpCol = Math.floor(sz.cx / 2 / this.ExpCx);
// 主人公フレーム数
this.ExpFrameNum = 3;
// 得点
this.Scored = 0;
// テキスト部クリア
$('#score').text(this.Scored);
$('#msg').text(" ");
// 描画可能を設定
this.GameUtl.CanRenderer = true;
// ゲーム開始
this.GameUtl.DoGame();
break;
}
// デフォルトイベントをキャンセルする
e.preventDefault();
}
// min から max までの乱整数を返す関数
clsSample01.prototype.Random = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}