ロゴシュミグラム

ブロックの新しい種類を追加

ブロックの種類の追加

blockDictionary の末尾に新しい種類のブロックを追加していきます。

ハードブロック

2回ボールを当てないと壊れないハードブロックを作ります。

blocks.js

const blockDictionary = {
...
'hard': {
borderColor: 'black',
fillColor: 'blue',
hitPoints: 2,
effect () {
// 色を変更したあとcanvasに描く
this.borderColor = 'midnightblue';
this.fillColor = 'deepskyblue';
drawBlock(this);
}
},
};

特殊効果として1回当たったら色が変化するようにしています。

ダブルブロック

当たるとボールが2個に増えるダブルブロックを作ります。

blocks.js

const blockDictionary = {
...
'double': {
borderColor: 'chocolate',
fillColor: 'orange',
hitPoints: 1,
effect (ball) {
// 新しく生成するボールの進行角度
const degree=Math.random() * 100 + 220
createBall(ball.x, ball.y, degree);
},
},
};

新しく生成されたボールのx座標とy座標は当たったボールと同じにします。進行角度は220°~320°の範囲でランダムに決められます。

もし進行角度を0°~360°の範囲でランダムに決めたとすると、180°に近いボールを生成してしまうこともあります。これだとずっと横移動だけして下りてこないので、このようなボールは生成しないようにします。

壁ブロック

当たっても壊れない壁ブロックを作ります。

blocks.js

const blockDictionary = {
...
'wall': {
borderColor: 'lightgray',
fillColor: 'whitesmoke',
isUnbreakable: true,
},
};

isUnbreakable: true にすると壊れないブロックになります。

ブロックの初期配置を変更

一番最初のページにあるようなブロックの配置に変更します。

blocks.js

const initBlocks = () => {
blocks = [];
blocksCount = 0;
blocksCtx.fillStyle = backgroundColor;
blocksCtx.fillRect(0, 0, canvasWidth, canvasHeight);
for (let rowIndex = 0; rowIndex < blocksRowLength; rowIndex++) {
blocks.push([]);
for (let columnIndex = 0; columnIndex < blocksColumnLength; columnIndex++) {
// ブロックを置かないで通路を作る
if (
rowIndex >= 1 && rowIndex <= 6 && columnIndex >= 18 && columnIndex <= 48
|| rowIndex >= 6 && rowIndex <= 13 && columnIndex >= 18 && columnIndex <= 24
|| rowIndex > 1 && columnIndex >= 43 && columnIndex < 49
) {
blocks[rowIndex][columnIndex] = null;
// 通路の両脇にある壁ブロック
} else if (
rowIndex >= 0 && rowIndex <= 9 && columnIndex === 17
|| rowIndex >= 7 && rowIndex <= 9 && columnIndex === 25
|| rowIndex === 0 && columnIndex >= 18
|| rowIndex === 7 && columnIndex >= 25
|| rowIndex >= 1 && (columnIndex === 42 || columnIndex === 49)
) {
createBlock('wall', rowIndex, columnIndex);
// 通路の出口にあるノーマルブロック
} else if (
rowIndex >= 10 && rowIndex <= 14 && (columnIndex === 17 || columnIndex === 25)
|| rowIndex === 14 && columnIndex >= 17 && columnIndex <= 25
) {
createBlock('normal', rowIndex, columnIndex);
// 中央付近にあるダブルブロックのかたまり
} else if (rowIndex >= 10 && rowIndex <= 36 && columnIndex >= 4 && columnIndex <= 37) {
createBlock('double', rowIndex, columnIndex);
// それ以外はハードブロック
} else {
createBlock('hard', rowIndex, columnIndex);
}
}
}
updateBlocksCountLabel();
};

これで機能拡張は完了です。

自分だけのブロック崩しを作ろう

これまでのように blockDictionary に新しいブロックを追加して、 initBlocks で生成すれば、自由に新しい種類のブロックを作ることができます。

当たるとボールの移動スピードが変化するブロックや、当たると爆発して周りのブロックを壊すブロックなどあったら面白いと思います。

ぜひ自分だけのブロック崩しを作ってみてください。

変更後のソースコード

settings.js
bar.js
blocks.js
balls.js

const canvasWidth = 400;
const canvasHeight = 550;
const backgroundColor = '#333333';
const blocksAreaWidth = canvasWidth;
const blocksAreaHeight = 400;
const blocksColumnLength = 50;
const blocksRowLength = 50;
const blockWidth = blocksAreaWidth / blocksColumnLength;
const blockHeight = blocksAreaHeight / blocksRowLength;
const barColor = 'white';
const barWidth = 200;
const barHalfWidth = barWidth / 2;
const barHeight = 5;
const barPosition = canvasHeight - 60;
const ballColor = 'orange';
const ballRadius = 3;
const speed = 3;
let gameState = 'initial';
const blocksCanvas = document.getElementById('blocks-canvas');
blocksCanvas.width = canvasWidth;
blocksCanvas.height = canvasHeight;
const blocksCtx = blocksCanvas.getContext("2d");
const barBallsCanvas = document.getElementById('bar-balls-canvas');
barBallsCanvas.width = canvasWidth;
barBallsCanvas.height = canvasHeight;
const barBallsCtx = barBallsCanvas.getContext("2d");
const messageLabel = document.getElementById('message');
const blocksCountLabel = document.getElementById('blocks-count');