きも版

<!DOCTYPE html>

<html lang="ja">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>ハイクオリティブロック崩しゲーム</title>

<style>

body { font-family: Arial, sans-serif; text-align: center; }

canvas { background: #eee; display: block; margin: 0 auto; }

#score { font-size: 20px; margin: 20px; }

</style>

</head>

<body>

<h1>ハイクオリティブロック崩しゲーム</h1>

<canvas id="gameCanvas" width="480" height="320"></canvas>

<div id="score">スコア: 0</div>

<button onclick="startGame()">再スタート</button>


<audio id="hitSound" src="https://www.soundjay.com/button/sounds/button-4.mp3"></audio>

<audio id="winSound" src="https://www.soundjay.com/button/sounds/button-16.mp3"></audio>

<audio id="loseSound" src="https://www.soundjay.com/button/sounds/button-8.mp3"></audio>

<audio id="bgMusic" loop src="https://www.soundjay.com/button/sounds/button-1.mp3"></audio>


<script>

const canvas = document.getElementById("gameCanvas");

const ctx = canvas.getContext("2d");

const hitSound = document.getElementById("hitSound");

const winSound = document.getElementById("winSound");

const loseSound = document.getElementById("loseSound");

const bgMusic = document.getElementById("bgMusic");


let ballRadius = 10;

let x = canvas.width / 2;

let y = canvas.height - 30;

let dx = 2;

let dy = -2;

let paddleHeight = 10;

let paddleWidth = 75;

let paddleX;

let rightPressed = false;

let leftPressed = false;

let brickRowCount = 5;

let brickColumnCount = 3;

let brickWidth = 75;

let brickHeight = 20;

let brickPadding = 10;

let brickOffsetTop = 30;

let brickOffsetLeft = 30;

let score = 0;

let level = 1;

let bricks = [];

let powerUps = [];


// パワーアップの効果時間(フレーム数)

const powerUpDuration = 600; // 10秒(60fpsの場合)


// ブロックの初期化

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, points: Math.floor(Math.random() * 3) + 1 };

}

}


function startGame() {

document.getElementById("score").innerText = "スコア: 0";

score = 0;

level = 1;

x = canvas.width / 2;

y = canvas.height - 30;

dx = 2;

dy = -2;


paddleX = (canvas.width - paddleWidth) / 2;


bgMusic.play();

document.addEventListener("mousemove", mouseMoveHandler);

draw();

}


function drawBall() {

ctx.beginPath();

ctx.arc(x, y, 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++) {

const b = bricks[c][r];

if (b.status === 1) {

const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;

const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;

b.x = brickX;

b.y = brickY;

ctx.beginPath();

ctx.rect(brickX, brickY, brickWidth, brickHeight);

ctx.fillStyle = "#0095DD";

ctx.fill();

ctx.closePath();

}

}

}

}


function drawPowerUps() {

powerUps.forEach((powerUp, index) => {

ctx.beginPath();

ctx.arc(powerUp.x, powerUp.y, 5, 0, Math.PI * 2);

ctx.fillStyle = "#FF0000"; // パワーアップの色

ctx.fill();

ctx.closePath();

powerUp.y += 2; // パワーアップが下に落ちる


// 一定時間経過で削除

powerUp.lifetime--;

if (powerUp.lifetime <= 0) {

powerUps.splice(index, 1); // 時間切れで削除

}

});

}


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 (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {

dy = -dy;

b.status = 0; // ブロックを消す

score += b.points;

hitSound.play();

document.getElementById("score").innerText = "スコア: " + score;


// パワーアップの生成

if (Math.random() < 0.01) { // 1%の確率でパワーアップを生成

powerUps.push({ x: b.x + brickWidth / 2, y: b.y, lifetime: powerUpDuration }); // 効果時間を設定

}


if (score >= level * 10) {

level++;

brickRowCount++;

if (brickRowCount > 10) brickRowCount = 5; // 最大行数を制限

resetBricks();

}

}

}

}

}


// パワーアップの衝突判定

powerUps.forEach((powerUp, index) => {

if (powerUp.x > paddleX && powerUp.x < paddleX + paddleWidth && powerUp.y + 5 > canvas.height - paddleHeight) {

paddleWidth += 20; // パドルを大きくする

powerUps.splice(index, 1); // パワーアップを消す

setTimeout(() => {

paddleWidth -= 20; // 効果時間終了後にパドルを元に戻す

}, powerUpDuration);

}

});

}


function resetBricks() {

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, points: Math.floor(Math.random() * 3) + 1 };

}

}

}


function draw() {

ctx.clearRect(0, 0, canvas.width, canvas.height);

drawBricks();

drawBall();

drawPaddle();

drawPowerUps();

collisionDetection();


if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {

dx = -dx;

}

if (y + dy < ballRadius) {

dy = -dy;

} else if (y + dy > canvas.height - ballRadius) {

if (x > paddleX && x < paddleX + paddleWidth) {

dy = -dy;

} else {

loseSound.play();

alert("ゲームオーバー");

document.location.reload();

}

}


x += dx;

y += dy;


requestAnimationFrame(draw);

}


function mouseMoveHandler(e) {

const relativeX = e.clientX - canvas.getBoundingClientRect().left;

if (relativeX > 0 && relativeX < canvas.width) {

paddleX = relativeX - paddleWidth / 2;

}

}


window.onload = startGame;

</script>

</body>

</html>

  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る