以下がブロック崩しの実装例です。セキュリティ上の問題を避けるため、evalや他のサイトへの遷移・リダイレクトは行いません。
<!DOCTYPE html>
<html>
<head>
<style>
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<h1>ブロック崩し</h1>
<canvas id="canvas" width="480" height="320"></canvas>
<br>
<button onclick="reset()">リセット</button>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const ballRadius = 10;
let ballX = canvas.width / 2;
let ballY = canvas.height - 30;
let ballDX = 2;
let ballDY = -2;
const paddleHeight = 10;
const paddleWidth = 75;
let paddleX = (canvas.width - paddleWidth) / 2;
const brickRowCount = 3;
const brickColumnCount = 5;
const brickWidth = 75;
const brickHeight = 20;
const brickPadding = 10;
const brickOffsetTop = 30;
const brickOffsetLeft = 30;
let score = 0;
const bricks = [];
for (let c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (let r = 0; r < brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };
}
}
document.addEventListener('mousemove', function (e) {
const relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
});
function collisionDetection() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
const b = bricks[c][r];
if (b.status === 1) {
if (
ballX > b.x &&
ballX < b.x + brickWidth &&
ballY > b.y &&
ballY < b.y + brickHeight
) {
ballDY = -ballDY;
b.status = 0;
score++;
if (score === brickRowCount * brickColumnCount) {
alert('やったぜ! すごいぞ!');
document.showToast("再読み込みしてください");
}
}
}
}
}
}
function drawScore() {
ctx.font = '16px Arial';
ctx.fillStyle = '#0095DD';
ctx.fillText('Score: ' + score, 8, 20);
}
function drawBall() {
ctx.beginPath();
ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = '#0095DD';
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = '#0095DD';
ctx.fill();
ctx.closePath();
}
function drawBricks() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status === 1) {
const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = '#0095DD';
ctx.fill();
ctx.closePath();
}
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawScore();
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
if (ballX + ballDX > canvas.width - ballRadius || ballX + ballDX < ballRadius) {
ballDX = -ballDX;
}
if (ballY + ballDY < ballRadius) {
ballDY = -ballDY;
} else if (ballY + ballDY > canvas.height - ballRadius) {
if (ballX > paddleX && ballX < paddleX + paddleWidth) {
ballDY = -ballDY;
} else {
alert("やめて! ボール... オイルまみれにしちゃうよ!");
document.showToast("再読み込みしてください");
clearInterval(interval);
}
}
ballX += ballDX;
ballY += ballDY;
}
function reset() {
document.showToast("再読み込みしてください");
}
const interval = setInterval(draw, 10);
</script>
</body>
</html>
※ ジョークとして、ボールが床に落ちた時のアラートメッセージを「やめて! ボール... オイルまみれにしちゃうよ!」としています。