こんなんで簡単なブロック崩しゲームが作れます。
一度皆さんもやってみてはいかがでしょうか
index.html
<html>
<head>
<meta charset="utf-8" />
<title>test </title>
<style>
html {
font-size: 62.5%;
}
body {
color: #444;
background-color: hsl(0, 0%, 96%);
}
h1 {
font-size: 1.8rem;
}
</style>
</head>
<body>
<script src="http://cdn.rawgit.com/phi-jp/phina.js/v0.2.0/build/phina.js"></script>
<script>
phina.globalize();//phina.game.GameAppのように階層的に定義されているクラスをGameAppだけで呼び出せるようにする処理などをしています。
var BLOCK_WIDTH = 40 * 2;
var BLOCK_HEIGHT = 60 / 2;
var PADDLE_WIDTH = BLOCK_WIDTH * 1.5;
var PADDLE_HEIGHT = BLOCK_HEIGHT;
var BALL_RADIUS = BLOCK_WIDTH / 8;
/*
* メインシーン
*/
phina.define("MainScene", {//phina.defineは、クラスを定義する関数です。
// 継承
superClass: 'DisplayScene',//phina.defineは、クラスを定義する関数です。
// コンストラクタ
init: function() {//init関数は、いわゆるコンストラクタです。
// 親クラス初期化
this.superInit();//this.superInitで親クラスのコンストラクタを呼び出しています。この後に、実際のゲーム処理コードを書いていくことになります。
this.backgroundColor = 'black'; // 背景色
this.blockGroup = DisplayElement().addChildTo(this);// ブロックグループ
this.dummyGroup = DisplayElement().addChildTo(this); // ダミーブロックグループ
var screenRect = Rect(0, 0, 640, 960); // 位置判定用のRect
var self = this;
// Gridを利用してブロック設置
Array.range(2, 16, 2).each(function(spanX) {
Array.range(1, 4, 0.5).each(function(spanY) {
Block().addChildTo(self.blockGroup)
.setPosition(self.gridX.span(spanX), self.gridY.span(spanY));
});
});
// パドル移動ライン
var paddleY = this.gridY.span(14.5);
// パドル設置
var paddle = Paddle().addChildTo(this)
.setPosition(this.gridX.center(), paddleY);
// 画面上でのタッチ移動時
this.onpointmove = function(e) {
// タッチ位置に移動
paddle.setPosition(e.pointer.x | 0, paddleY);
// 画面はみ出し防止
if (paddle.left < screenRect.left) { paddle.left = screenRect.left; }
if (paddle.right > screenRect.right) { paddle.right = screenRect.right; }
};
// 画面上でタッチが離れた時
this.onpointend = function() {
if (self.status === 'ready') {
// ボール発射
self.ball.vy = -self.ball.speed;
self.status = 'move';
}
};
// スコア
this.score = 0;
var scoreLabel = Label({
text: this.score + '',
fill: 'lime',
fontSize: 64,
}).addChildTo(this);
scoreLabel.setPosition(this.gridX.center(), this.gridY.center());
scoreLabel.alpha = 0.6;
// 連続ヒット数
this.hitNumber = 0;
// ボール作成
this.ball = Ball().addChildTo(this);
// シーン全体から参照可能にする
this.paddle = paddle;
this.screenRect = screenRect;
this.scoreLabel = scoreLabel;
// ゲーム状態
this.status = 'ready';
},
// 毎フレーム更新
update: function() {
var ball = this.ball;
var paddle = this.paddle;
var screenRect = this.screenRect;
// ボール待機中
if (this.status === 'ready') {
// ボールはパドルの真上
ball.vx = ball.vy = 0;
ball.x = paddle.x;
ball.bottom = paddle.top;
}
// ボール移動中
if (this.status === 'move') {
// ボール移動
ball.moveBy(ball.vx, ball.vy);
// 画面端反射
// 上
if (ball.top < screenRect.top) {
ball.top = screenRect.top;
ball.vy = -ball.vy;
}
// 左
if (ball.left < screenRect.left) {
ball.left = screenRect.left;
ball.vx = -ball.vx;
}
// 右
if (ball.right > screenRect.right) {
ball.right = screenRect.right;
ball.vx = -ball.vx;
}
// 落下
var self = this;
if (ball.top > screenRect.bottom) {
// ゲームオーバー表示
var label = Label({
text: 'GAME OVER',
fill: 'yellow',
fontSize: 64,
}).addChildTo(this);
label.setPosition(this.gridX.center(), this.gridY.center());
// 少し待ってからタイトル画面へ
label.tweener.clear()
.wait(2000)
.call(function() {
self.nextLabel = 'title';
self.exit();
});
}
// パドルとの反射
if (ball.hitTestElement(paddle) && ball.vy > 0) {
ball.bottom = paddle.top;
ball.vy = -ball.vy;
// 当たった位置で角度を変化させる
var dx = paddle.x - ball.x;
ball.vx = -dx / 5;
}
// ブロックとの反射
this.blockGroup.children.some(function(block) {
// ヒットなら
if (ball.hitTestElement(block)) {
// 左上かど
if (ball.top < block.top && ball.left < block.left) {
// 位置補正
ball.right = block.left;
ball.bottom = block.top;
// 移動方向設定
ball.vx = -ball.speed;
ball.vy = -ball.speed;
// ブロック消去
self.disableBlock(block);
return true;
}
// 右上かど
if (block.top < ball.top && block.right < ball.right) {
ball.left = block.right;
ball.bottom = block.top;
ball.vx = ball.speed;
ball.vy = -ball.speed;
self.disableBlock(block);
return true;
}
// 左下かど
if (block.bottom < ball.bottom && ball.left < block.left) {
ball.right = block.left;
ball.top = block.bottom;
ball.vx = -ball.speed;
ball.vy = ball.speed;
self.disableBlock(block);
return true;
}
// 右下かど
if (block.bottom < ball.bottom && block.right < ball.right) {
ball.left = block.right;
ball.top = block.bottom;
ball.vx = ball.speed;
ball.vy = ball.speed;
self.disableBlock(block);
return true;
}
// 左側
if (ball.left < block.left) {
ball.right = block.left;
ball.vx = -ball.vx;
self.disableBlock(block);
return true;
}
// 右側
if (block.right < ball.right) {
ball.left = block.right;
ball.vx = -ball.vx;
self.disableBlock(block);
return true;
}
// 上側
if (ball.top < block.top) {
ball.bottom = block.top;
ball.vy = -ball.vy;
self.disableBlock(block);
return true;
}
// 下側
if (block.bottom < ball.bottom) {
ball.top = block.bottom;
ball.vy = -ball.vy;
self.disableBlock(block);
return true;
}
}
});
}
// クリアチェック
if (this.blockGroup.children.length === 0) {
// スコアをリザルトシーンに渡す
this.exit({
score: this.score,
});
}
},
// ブロックの消去処理
disableBlock: function(block) {
// 消去アニメーション用のダミーブロック
var dummy = Block().addChildTo(this.dummyGroup);
// 属性コピー
dummy.x = block.x;
dummy.y = block.y;
// ブロック削除
block.remove();
// 縮小して消えるアニメーション
dummy.tweener.clear()
.to({scaleX: 0.1, scaleY: 0.1}, 200)
.call(function() {
dummy.remove();
});
// スコア加算
this.addScore();
},
// スコア加算処理
addScore: function() {
this.hitNumber++;
this.score += this.hitNumber * 10;
this.scoreLabel.text = this.score;
},
});
/*
* ブロッククラス
*/
phina.define('Block', {
// 親クラス指定
superClass: 'RectangleShape',
// コンストラクタ
init: function() {
// 親クラス初期化
this.superInit({
width: BLOCK_WIDTH,
height: BLOCK_HEIGHT,
});
},
});
/*
* パドルクラス
*/
phina.define('Paddle', {
// 親クラス指定
superClass: 'RectangleShape',
// コンストラクタ
init: function() {
// 親クラス初期化
this.superInit({
width: PADDLE_WIDTH,
height: PADDLE_HEIGHT,
fill: 'silver',
});
},
});
/*
* ボールクラス
*/
phina.define('Ball', {
// 親クラス指定
superClass: 'CircleShape',
// コンストラクタ
init: function() {
// 親クラス初期化
this.superInit({
radius: BALL_RADIUS,
fill: 'silver',
});
// スピード
this.speed = 6;
},
});
/*
* メイン処理
*/
phina.main(function() {
// アプリケーションを生成
var app = GameApp({
title: 'GAMES',
});
// fps変更
app.fps = 60;
// 実行
app.run();
});
</script>
</body>
</html>