import http.server
import socketserver
import tempfile
import webbrowser
# HTMLとJavaScriptのコード
html_content = """
<!DOCTYPE html>
<html>
<head>
<title>シューティングゲーム</title>
<style>
canvas {
background: #eee;
display: block;
margin: auto;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="480" height="320"></canvas>
<script>
var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
// 自機の設定
var playerSize = 20; // 自機のサイズ
var playerX = (canvas.width - playerSize) / 2; // 自機のX座標(初期位置は中央)
var playerY = canvas.height - playerSize - 10; // 自機のY座標(画面下部に配置)
// 弾の設定
var bulletRadius = 5; // 弾の半径
var bullets = []; // 弾のリスト
var bulletSpeed = 5; // 弾の速度
// 敵の設定
var enemySize = 30; // 敵のサイズ
var enemies = []; // 敵のリスト
var enemySpeed = 2; // 敵の速度
var enemySpawnInterval = 2000; // 敵の生成間隔(ミリ秒)
var lastEnemySpawnTime = Date.now(); // 最後に敵を生成した時間
// 射撃角度と状態
var shootingAngle = 0; // 弾の射撃角度(初期値は0)
var isShooting = false; // 射撃中かどうかのフラグ
// ランダムな色を生成する関数
function randomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
// 自機を描画する関数
function drawPlayer() {
ctx.beginPath();
// 三角形の自機を描画
ctx.moveTo(playerX + playerSize / 2, playerY); // 三角形の頂点
ctx.lineTo(playerX + playerSize, playerY + playerSize); // 三角形の右下
ctx.lineTo(playerX, playerY + playerSize); // 三角形の左下
ctx.closePath(); // 三角形を閉じる
ctx.fillStyle = randomColor(); // ランダムな色で塗りつぶし
ctx.fill();
ctx.strokeStyle = '#000000'; // 黒い線で縁取り
ctx.stroke();
}
// 弾を描画する関数
function drawBullet(bullet) {
ctx.beginPath();
ctx.arc(bullet.x, bullet.y, bulletRadius, 0, Math.PI * 2); // 弾を円形に描画
ctx.fillStyle = randomColor(); // ランダムな色で塗りつぶし
ctx.fill();
ctx.strokeStyle = '#000000'; // 黒い線で縁取り
ctx.stroke();
}
// 敵を描画する関数
function drawEnemy(enemy) {
ctx.beginPath();
ctx.rect(enemy.x, enemy.y, enemySize, enemySize); // 敵を矩形に描画
ctx.fillStyle = randomColor(); // ランダムな色で塗りつぶし
ctx.fill();
ctx.strokeStyle = '#000000'; // 黒い線で縁取り
ctx.stroke();
}
// ゲームの描画と更新を行う関数
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // 画面をクリア
drawPlayer(); // 自機の描画
// 弾と敵を描画
bullets.forEach(bullet => drawBullet(bullet));
enemies.forEach(enemy => drawEnemy(enemy));
// 弾の移動処理
bullets.forEach((bullet, index) => {
bullet.x += Math.cos(bullet.angle) * bulletSpeed; // 弾のX座標を更新
bullet.y += Math.sin(bullet.angle) * bulletSpeed; // 弾のY座標を更新
// 弾が画面外に出た場合は削除
if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
bullets.splice(index, 1);
}
});
// 敵の移動処理
enemies.forEach((enemy, index) => {
enemy.y += enemySpeed; // 敵のY座標を更新
if (enemy.y > canvas.height) {
enemies.splice(index, 1); // 敵が画面下に出た場合は削除
}
});
// 弾と敵の衝突判定
bullets.forEach((bullet, bIndex) => {
enemies.forEach((enemy, eIndex) => {
if (bullet.x > enemy.x && bullet.x < enemy.x + enemySize &&
bullet.y > enemy.y && bullet.y < enemy.y + enemySize) {
bullets.splice(bIndex, 1); // 衝突した弾を削除
enemies.splice(eIndex, 1); // 衝突した敵を削除
}
});
});
// 敵の生成処理
if (Date.now() - lastEnemySpawnTime > enemySpawnInterval) {
var enemyX = Math.random() * (canvas.width - enemySize); // 敵のX座標をランダムに決定
enemies.push({ x: enemyX, y: 0 }); // 新しい敵を生成
lastEnemySpawnTime = Date.now(); // 最後の敵生成時間を更新
}
// 射撃中なら弾を生成
if (isShooting) {
bullets.push({
x: playerX + playerSize / 2, // 自機の中心から弾を発射
y: playerY,
angle: shootingAngle // 現在の射撃角度を設定
});
}
// 次のフレームをリクエスト
requestAnimationFrame(draw);
}
// キーが押されたときの処理
document.addEventListener("keydown", function(event) {
if (event.code === "ArrowLeft") {
shootingAngle -= 0.05; // 左カーソルキーで射撃角度を減少
} else if (event.code === "ArrowRight") {
shootingAngle += 0.05; // 右カーソルキーで射撃角度を増加
} else if (event.code === "Space") {
isShooting = true; // スペースキーが押されたときに射撃開始
}
});
// キーが離されたときの処理
document.addEventListener("keyup", function(event) {
if (event.code === "Space") {
isShooting = false; // スペースキーが離されたときに射撃停止
}
});
// ゲームの描画を開始
draw();
</script>
</body>
</html>
"""
# 一時的なファイルにHTMLコンテンツを書き込む
with tempfile.NamedTemporaryFile(delete=False, suffix=".html") as temp_html:
temp_html.write(html_content.encode("utf-8"))
temp_html.flush()
# ブラウザでファイルを開く
webbrowser.open(f"file://{temp_html.name}")
# HTTPサーバーを作成してHTMLを提供する
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Serving at port {PORT}")
httpd.serve_forever()