ブロックを表示する
ボールとパドルができたので、次はブロックです。
とりあえず1列だけ表示してみます。
次のプログラムをボール処理の下に追加します。
<script>
// ブロック
function initBlock() {
for( let i=0; i<8; i++ ){
Crafty.e("Block, 2D, Canvas, Color")
.color('#00ff00')
.attr({x:1+i*50, y:50, w:48, h:30});
}
}
initBlock();
</script>
実行すると次のようになります。
ところで何気なく関数initBlockを作りました。
関数にしなくても良かったのですが、ブロックの処理をまとめたかったのでこうしました。
さて次は、ブロックに色を付けて4列にしてみます。
<script>
// ブロック
function initBlock() {
const col = ["red","orange","green","blue"];
for( let j=0; j<4; j++){
for( let i=0; i<8; i++ ){
Crafty.e("Block, 2D, Canvas, Color")
.color(col[j])
.attr({x:1+i*50, y:50+j*30, w:48, h:25});
}
}
}
initBlock();
</script>
実行してみましょう。
もうすっかりブロック崩しになりましたね。
.attr({x:1+i50, y:50+j30, w:48, h:25});
座標y も計算するようになりました。
計算の意味が分からないときは、数値を変えてテストするといいです。
例えばy:50+j*40で実行すれば30が何の数なのか分かります。
ブロックの高さをh:30からh:25にしています。
これで見た目のバランスが良くなりました。
.color(col[j])
配列を使って色を指定しています。
(配列の説明はあとで)
これまではcolor(’#00ff00’)のように色コードを使っていましたが
color(“orange”)という感じで英語でもOKです。
ただ対応しているのはメジャーな色だけです。
配列とconst
配列とは簡単にいうと、複数の変数を1つの名前で管理できるものです。
ただ、変数にはない機能があります。
詳しく知りたい人はjavascript 配列などで検索してみましょう。
次のように console.log を3行追加して実行してみます。
<script>
function initBlock() {
const col = ["red","orange","green","blue"];
console.log(col);
console.log("col[0]="+col[0]);
console.log("col[2]="+col[2]);
for( let j=0; j<4; j++){
for( let i=0; i<8; i++ ){
Crafty.e("Block, 2D, Canvas, Color")
.color(col[j])
.attr({x:1+i*50, y:50+j*30, w:48, h:25});
}
}
}
</script>
コンソールを見てみると次のように表示されます。
配列 col の中に4つの色が入っていることが分かります。
配列 col は次の行で作られました。
const col = [“red”,“orange”,“green”,“blue”];
配列の内容を参照するには角かっこに数値を入れます。
col[0]とすれば先頭(red)を参照できます。
col[2]とすれば3番目(green)の参照です。
角かっこの中の数は0から始まることに注意してください。
ざっくりと説明しましたが、これは基礎の基礎です。
また別のときに説明したいと思います。
const についてちょっと説明します。
const col = [“red”,“orange”,“green”,“blue”];
これは配列の宣言でしたね。
実は次のように宣言することも可能です。
let col = [“red”,“orange”,“green”,“blue”];
let はこれまでも使ってきました。
この2つの違いは const の場合は変更不可。
let の場合は変更可能ということです。
const は配列専用という訳ではありません。
let で変数を作っていたように const でも作れます。
例えば
const ENEMY_MAX = 50;
というように宣言をして
プログラム中で ENEMY_MAX を使えば処理内容が分かり易くなります。
ブロックとの当たり判定
作業の前に、先ほど追加した console.log を消しましょう。
ボールとブロックの当たり判定を入れます。
判定はボールで行います。
<script>
// ボール
Crafty.e("Ball, 2D, Canvas, Color, Collision")
.color('#eeeeee')
.attr({x:100, y:200, w:10, h:10,
dX:Crafty.math.randomInt(2,5), dY:5 })
.onHit('Paddle', function () { // パドルに当たったらy軸の方向転換
this.dY *= -1;
})
.onHit('Block', function (hitDatas) { // ブロックに当たったら
this.dY *= -1;
console.log("block len="+hitDatas.length);
// 複数のブロックに当たったときを考慮して全部調べる
for( let i=0,l=hitDatas.length; i<l; i++ ){
hitDatas[i].obj.destroy();
}
})
.bind('EnterFrame', function () {
if (this.x <= 0 || this.x >= 390){ // 画面の左右に当たれば跳ね返る
this.dX *= -1;
}
if (this.y < 10) { // 上の壁
this.dY *= -1;
}
if (this.y > 380) { // 下の壁
this.dY *= -1;
}
this.x += this.dX;
this.y += this.dY;
});
</script>
追加したところを見てみましょう。
当たり判定とボールの処理は Paddle のときと同じです。
this.dY *= -1;でボールの向きを変えています。
注目ポイントは hitDatas.length で複数のブロックと同時に当たったかを調べている点です。
そして、当たったブロックは次の行で消しています。
hitDatas[i].obj.destroy();
実行してみましょう。
うーん、ブロック崩しっぽい(笑)
ちゃんとブロックを消しています。
console.log(“block len="+hitDatas.length);
これで当たったブロックの数を表示しています。
コンソールで確認してみましょう。
ほとんど1つずつ当たっていますね。
ときどき2つ同時に当たることもあるようです。
ブロックの再配置
すべてのブロックを消したとき、再びブロックを表示します。
ブロックの数をカウントするための変数blockcntを作りました。
これが0のとき再配置します。
<script>
let blockcnt = 0;
// ボール
Crafty.e("Ball, 2D, Canvas, Color, Collision")
.color('#eeeeee')
.attr({x:100, y:200, w:10, h:10,
dX:Crafty.math.randomInt(2,5), dY:5 })
.onHit('Paddle', function () { // パドルに当たったらy軸の方向転換
this.dY *= -1;
if( blockcnt == 0 ){
initBlock(); // ブロックの再配置
}
})
.onHit('Block', function (hitDatas) { // ブロックに当たったら
this.dY *= -1;
console.log("block len="+hitDatas.length);
// 複数のブロックに当たったときを考慮して全部調べる
for( let i=0,l=hitDatas.length; i<l; i++ ){
hitDatas[i].obj.destroy();
blockcnt--;
}
})
.bind('EnterFrame', function () {
if (this.x <= 0 || this.x >= 390){ // 画面の左右に当たれば跳ね返る
this.dX *= -1;
}
if (this.y < 10) { // 上の壁
this.dY *= -1;
}
if (this.y > 380) { // 下の壁
this.dY *= -1;
}
this.x += this.dX;
this.y += this.dY;
});
// ブロック
function initBlock() {
const col = ["red","orange","green","blue"];
for( let j=0; j<4; j++){
for( let i=0; i<8; i++ ){
Crafty.e("Block, 2D, Canvas, Color")
.color(col[j])
.attr({x:1+i*50, y:50+j*30, w:48, h:25});
blockcnt++;
}
}
}
</script>
変更点を見てみましょう。4つあります。
処理は単純です。
変数blockcntでブロックの存在を確認します。
ブロックを表示するとき数を加え、消すときに引いていきます。
ボールがパドルに当たったときブロックが無ければ再配置します。
なぜこのタイミングかというと、ボールとブロックが一番離れた状態だからです。
ブロックがすべて消えたタイミングで再配置すると、連続してブロックを消す可能性があります。