Skip to content

Instantly share code, notes, and snippets.

@ryogrid
Created May 4, 2025 06:08
Show Gist options
  • Save ryogrid/a68441b6b5879fbca872aeb816d16af7 to your computer and use it in GitHub Desktop.
Save ryogrid/a68441b6b5879fbca872aeb816d16af7 to your computer and use it in GitHub Desktop.
ブロック崩しゲームもどき by Qwen3 8B 3bit量子化 アンド コンテキスト長くした版
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>ブロック崩しゲーム</title>
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
background-color: #f2f2f2;
display: block;
}
</style>
</head>
<body>
<canvas id="game" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
// ゲームオブジェクト
let paddle = {
x: 375,
y: 575,
width: 100,
height: 10,
dx: 0
};
let ball = {
x: 400,
y: 300,
radius: 10,
dx: 3,
dy: -2
};
// ブロックの配置
const rows = 5;
const cols = 10;
const blockWidth = 70;
const blockHeight = 20;
const blockPaddingX = 10; // 横方向のマージン
const blockPaddingY = 10; // 垂直方向のマージン
let blocks = [];
// ブロック初期化関数
function initBlocks() {
blocks.length = 0; // 現在のブロックをクリア
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
blocks.push({
x: col * (blockWidth + blockPaddingX) + blockPaddingX,
y: row * (blockHeight + blockPaddingY) + blockPaddingY,
width: blockWidth,
height: blockHeight
});
}
}
}
initBlocks(); // 初期化
// ゲーム状態
let gameOver = false;
// ペイメント操作の管理
let leftPressed = false;
let rightPressed = false;
// キーイベントリスナー
document.addEventListener('keydown', function (e) {
if (e.key === 'ArrowLeft') {
leftPressed = true;
} else if (e.key === 'ArrowRight') {
rightPressed = true;
} else if (e.key === ' ' && gameOver) { // ゲームオーバー時はスペースでリセット
resetGame();
}
});
document.addEventListener('keyup', function (e) {
if (e.key === 'ArrowLeft') {
leftPressed = false;
} else if (e.key === 'ArrowRight') {
rightPressed = false;
}
});
// ゲームリセット関数
function resetGame() {
ball.x = 400;
ball.y = 300;
ball.dx = 3;
ball.dy = -2;
paddle.x = 375;
initBlocks();
gameOver = false;
}
// 描画処理
function draw() {
if (gameOver) {
ctx.fillStyle = 'black';
ctx.font = '30px Arial';
ctx.fillText('Game Over', canvas.width / 2 - 80, canvas.height / 2);
return;
}
// パネルクリア
ctx.clearRect(0, 0, canvas.width, canvas.height);
// ブロック描画(赤)
ctx.fillStyle = '#f44336';
blocks.forEach(block => {
ctx.fillRect(block.x, block.y, block.width, block.height);
});
// パドル描画(青)
ctx.fillStyle = '#2196f3';
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
// ボール描画(黄)
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = '#ffeb3b';
ctx.fill();
// パドル移動
if (leftPressed) {
paddle.x -= 5;
} else if (rightPressed) {
paddle.x += 5;
}
// パドル範囲制限
if (paddle.x < 0) paddle.x = 0;
if (paddle.x > canvas.width - paddle.width) paddle.x = canvas.width - paddle.width;
// ボール移動
ball.x += ball.dx;
ball.y += ball.dy;
// 壁との衝突処理
if (
ball.x + ball.radius > canvas.width ||
ball.x - ball.radius < 0
) {
ball.dx = -ball.dx;
}
if (ball.y - ball.radius < 0) {
ball.dy = -ball.dy;
}
// パドルとの衝突処理
if (
ball.y + ball.radius > canvas.height - paddle.height &&
ball.x > paddle.x &&
ball.x < paddle.x + paddle.width
) {
ball.dy = -ball.dy;
}
// ブロックとの衝突処理
for (let i = blocks.length - 1; i >= 0; i--) {
const block = blocks[i];
if (
ball.x + ball.radius > block.x &&
ball.x - ball.radius < block.x + block.width &&
ball.y + ball.radius > block.y &&
ball.y - ball.radius < block.y + block.height
) {
// ブロックの削除とボール方向の反転
ball.dy = -ball.dy;
blocks.splice(i, 1);
break; // 同一フレームで複数ブロックを処理しない
}
}
// ゲームオーバー判定
if (ball.y + ball.radius > canvas.height) {
gameOver = true;
}
requestAnimationFrame(draw);
}
// ゲームループ起動
draw();
</script>
</body>
</html>
@ryogrid
Copy link
Author

ryogrid commented May 4, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment