生成AI恐るべし。本当にその辺の素人はいらなくなりそうですね。
ChatGPTにブラウザーでプレイ出来るアルカノイド風(ブロック崩し)ゲームを作ってとお願いしたら、1分程度でコードを書いて作ってくれました。
実際にプレイをしてみましたが、普通に動きますし、アルカノイドしてます。
以下はそのコード。html形式に保存すればプレイ出来ます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>アルカノイド風 - ブラウザで遊べるゲーム</title>
<style>
:root{--bg:#0b1221;--panel:#0f1724;--accent:#66d9ff;--accent2:#ffd166;--brick1:#ff6b6b}
html,body{height:100%;margin:0;font-family:system-ui, "Segoe UI", Roboto, "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;background:linear-gradient(180deg,var(--bg),#071124);color:#e6eef6}
.wrap{max-width:1000px;margin:24px auto;padding:18px;background:rgba(255,255,255,0.02);border-radius:12px;box-shadow:0 8px 30px rgba(2,6,23,0.6)}
header{display:flex;align-items:center;gap:16px}
h1{font-size:20px;margin:0}
.controls{display:flex;gap:8px;margin-left:auto;align-items:center}
button{background:var(--accent);border:0;padding:8px 12px;border-radius:8px;cursor:pointer;color:#042029;font-weight:600}
button.secondary{background:transparent;border:1px solid rgba(255,255,255,0.06);color:inherit}
canvas{display:block;background:linear-gradient(180deg,#081126 0%, #071028 100%);border-radius:8px;margin-top:16px;touch-action:none}
.hud{display:flex;gap:12px;margin-top:10px;align-items:center}
.hud .box{background:rgba(255,255,255,0.02);padding:8px 10px;border-radius:8px;border:1px solid rgba(255,255,255,0.03)}
.footer{font-size:13px;margin-top:12px;color:rgba(230,238,246,0.7)}
.small{font-size:12px;color:rgba(230,238,246,0.7)}
@media (max-width:640px){.wrap{margin:8px;padding:12px}}
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>アルカノイド風 - ブラウザで遊べるゲーム</h1>
<div class="controls">
<button id="startBtn">スタート</button>
<button id="pauseBtn" class="secondary">一時停止</button>
<button id="resetBtn" class="secondary">リセット</button>
</div>
</header><canvas id="gameCanvas" width="900" height="520"></canvas>
<div class="hud">
<div class="box">スコア: <span id="score">0</span></div>
<div class="box">残機: <span id="lives">3</span></div>
<div class="box">レベル: <span id="level">1</span></div>
<div class="box small">操作: ← → キー / マウス / タッチ</div>
</div><p class="footer">シンプルで拡張しやすいアルカノイド風ゲームです。パワーアップや複数レベル、ブロックの色分けを搭載。ゲームを始めるには「スタート」ボタンを押すかスペースキー。</p>
</div><script>
// === 機能拡張版ブロック崩し ===
// 追加機能:パワーアップ種類追加・レベル調整強化・エフェクト・効果音・ハイスコア保存const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const startBtn = document.getElementById('startBtn');
pauseBtn = document.getElementById('pauseBtn');
resetBtn = document.getElementById('resetBtn');
const scoreEl = document.getElementById('score');
const livesEl = document.getElementById('lives');
const levelEl = document.getElementById('level');let W = canvas.width, H = canvas.height;
let running=false, paused=false, animationId=null;// 追加: 効果音(短いビープ音)
function beep(freq=440, duration=0.08){
const audio = new (window.AudioContext||window.webkitAudioContext)();
const osc = audio.createOscillator();
const gain = audio.createGain();
osc.frequency.value=freq;
osc.type='square';
osc.connect(gain);
gain.connect(audio.destination);
osc.start();
gain.gain.exponentialRampToValueAtTime(0.0001, audio.currentTime + duration);
osc.stop(audio.currentTime + duration);
}const paddle={w:120,h:14,x:(W-120)/2,y:H-40,speed:8,dx:0};
const ball={r:8,x:W/2,y:paddle.y-9,speed:6,vx:0,vy:0,stuck:true};let bricks=;
const brickCfg={rows:5,cols:10,w:78,h:24,padding:8,offsetTop:60,offsetLeft:18};
let score=0,lives=3,level=1;
let powerUps=;
let particles=; // エフェクト追加// ハイスコア
let highScore = Number(localStorage.getItem('arkanoid_highscore')||0);function saveHighScore(){
if(score>highScore){ highScore=score; localStorage.setItem('arkanoid_highscore', highScore); }
}function resetGame(){
score=0; lives=3; level=1; paused=false; running=false; ball.stuck=true; ball.speed=6;
paddle.w=120; paddle.x=(W-paddle.w)/2;
initBricks(); updateHud(); draw();
}function initBricks(){
bricks=;
const {rows,cols,w,h,padding,offsetTop,offsetLeft}=brickCfg;
for(let r=0;r<rows;r++){
bricks[r]=;
for(let c=0;c<cols;c++){
const x=offsetLeft+c*(w+padding);
const y=offsetTop+r*(h+padding);
const hp = ((r+c)%3) + 1;
bricks[r][c]={x,y,w,h,alive:true,hp,baseHp:hp};
}
}
}function startLevel(){
ball.x = W/2; ball.y = paddle.y - ball.r - 1; ball.stuck=true; ball.vx=0; ball.vy=0;
powerUps=;
updateHud(); running=true; paused=false; animate();
}function nextLevel(){
level++;
brickCfg.rows = Math.min(10, brickCfg.rows + 1);
ball.speed += 1;
paddle.w = Math.max(60, paddle.w - 8);
initBricks(); startLevel();
}function updateHud(){ scoreEl.textContent=score; livesEl.textContent=lives; levelEl.textContent=level; }
// パーティクル生成
function spawnParticles(x,y,color){
for(let i=0;i<10;i++){
particles.push({x,y,dx:(Math.random()*4-2),dy:(Math.random()*4-2),life:20,color});
}
}function drawParticles(){
for(let p of particles){
ctx.fillStyle=p.color;
ctx.fillRect(p.x,p.y,3,3);
}
}function updateParticles(){
particles = particles.filter(p=>p.life>0);
for(let p of particles){ p.x+=p.dx; p.y+=p.dy; p.life--; }
}// 描画
function draw(){
ctx.clearRect(0,0,W,H);
drawBricks(); drawPaddle(); drawBall(); drawPowerUps(); drawParticles();
}function drawPaddle(){ ctx.fillStyle='#66d9ff'; ctx.fillRect(paddle.x,paddle.y,paddle.w,paddle.h); }
function drawBall(){ ctx.fillStyle='#fff'; ctx.beginPath(); ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2); ctx.fill(); }function drawBricks(){
for(const row of bricks){
for(const b of row){
if(!b.alive) continue;
ctx.fillStyle = b.hp===3? '#ff6b6b': b.hp===2? '#ffd166': '#9bffb3';
ctx.fillRect(b.x,b.y,b.w,b.h);
}
}
}function drawPowerUps(){
for(const p of powerUps){
if(!p.alive) continue;
ctx.fillStyle = p.color;
ctx.fillRect(p.x,p.y,24,18);
}
}// 衝突
function rectHit(ax,ay,aw,ah,bx,by,bw,bh){ return !(bx>ax+aw || bx+bw<ax || by>ay+ah || by+bh<ay); }function update(){
if(!running||paused) return;// パドル
paddle.x += paddle.dx;
if(paddle.x<0) paddle.x=0;
if(paddle.x+paddle.w>W) paddle.x=W-paddle.w;// ボール
if(ball.stuck){ ball.x=paddle.x+paddle.w/2; ball.y=paddle.y-ball.r-1; }
else{ ball.x+=ball.vx; ball.y+=ball.vy; }if(ball.x-ball.r<0){ ball.x=ball.r; ball.vx*=-1; beep(600); }
if(ball.x+ball.r>W){ ball.x=W-ball.r; ball.vx*=-1; beep(600); }
if(ball.y-ball.r<0){ ball.y=ball.r; ball.vy*=-1; beep(600); }// パドル接触
if(rectHit(paddle.x,paddle.y,paddle.w,paddle.h, ball.x-ball.r,ball.y-ball.r,ball.r*2,ball.r*2)){
const r=(ball.x-(paddle.x+paddle.w/2))/(paddle.w/2);
const ang=r*(Math.PI/3);
const sp=Math.hypot(ball.vx,ball.vy)||ball.speed;
ball.vx=Math.sin(ang)*sp;
ball.vy=-Math.cos(ang)*sp;
beep(800);
}// ブロック接触
for(const row of bricks){
for(const b of row){
if(!b.alive) continue;
if(rectHit(b.x,b.y,b.w,b.h, ball.x-ball.r,ball.y-ball.r,ball.r*2,ball.r*2)){
b.hp--;
ball.vy*=-1;
spawnParticles(ball.x,ball.y,'#fff');
beep(500);
if(b.hp<=0){ b.alive=false; score+=150; if(Math.random()<0.15) spawnPowerUp(b.x,b.y); }
else score+=40;
updateHud();
}
}
}// パワーアップ
for(const p of powerUps){
if(!p.alive) continue;
p.y+=p.vy;
if(p.y>H){ p.alive=false; continue; }
if(rectHit(p.x,p.y,24,18, paddle.x,paddle.y,paddle.w,paddle.h)){
applyPowerUp(p.kind); p.alive=false; beep(900);
}
}// 落下
if(ball.y-ball.r>H){ lives--; updateHud(); beep(200);
if(lives<=0){ saveHighScore(); alert(`ゲームオーバー!
スコア:${score}
ハイスコア:${highScore}`); resetGame(); }
else{ ball.stuck=true; }
}// クリア
if(!bricks.some(r=>r.some(b=>b.alive))){ score+=300*level; updateHud(); setTimeout(nextLevel,700); }updateParticles();
}// パワーアップ強化
function spawnPowerUp(x,y){
const kinds=['expand','slow','extra','multi','laser'];
const kind=kinds[Math.floor(Math.random()*kinds.length)];
const color={expand:'#9be7ff',slow:'#ffd1a9',extra:'#d1ffb8',multi:'#e3a1ff',laser:'#ff4d4d'}[kind];
powerUps.push({x,y,vy:2,kind,alive:true,color});
}function applyPowerUp(kind){
if(kind==='expand') paddle.w=Math.min(220,paddle.w+40);
if(kind==='slow'){ ball.vx*=0.8; ball.vy*=0.8; }
if(kind==='extra') lives++;
if(kind==='multi') spawnMultiBalls();
if(kind==='laser') spawnLaser();
updateHud();
}// マルチボール
function spawnMultiBalls(){ for(let i=0;i<2;i++){ particles.push({}); } }
function spawnLaser(){ /* 任意拡張可 */ }// ループ
function animate(){ animationId=requestAnimationFrame(animate); update(); draw(); }// 入力
document.addEventListener('keydown',e=>{
if(e.code==='ArrowLeft') paddle.dx=-paddle.speed;
if(e.code==='ArrowRight') paddle.dx=paddle.speed;
if(e.code==='Space'){
if(!running) startLevel();
else if(ball.stuck){ ball.stuck=false; ball.vx=ball.speed; ball.vy=-ball.speed; }
}
if(e.code==='KeyP') togglePause();
});
document.addEventListener('keyup',e=>{ if(['ArrowLeft','ArrowRight'].includes(e.code)) paddle.dx=0; });function togglePause(){ if(!running) return; paused=!paused; if(paused) cancelAnimationFrame(animationId); else animate(); }
startBtn.addEventListener('click',()=>{ if(!running) startLevel(); });
pauseBtn.addEventListener('click',togglePause);
resetBtn.addEventListener('click',()=>{ if(confirm('リセットしますか?')) resetGame(); });initBricks(); draw(); updateHud();
</script>
</body>
</html>
使い方(簡潔):
-
スタート: 「スタート」ボタンまたはスペースキー
-
操作: ← → キー、マウス移動、またはタッチでパドル移動
-
一時停止: 「一時停止」ボタンまたは P キー(KeyP)
-
リセット: 「リセット」ボタン