<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>レトロRPG</title>
<style>
body {
background: black;
color: white;
text-align: center;
font-family: monospace;
}
canvas {
border: 2px solid white;
background: #202020;
image-rendering: pixelated;
}
#ui {
margin-top: 10px;
}
</style>
</head>
<body>
<h1>レトロ風RPG</h1>
<canvas id="game" width="160" height="160"></canvas>
<div id="ui">
<p id="status">HP: 10</p>
<p id="log"></p>
</div>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const statusEl = document.getElementById("status");
const logEl = document.getElementById("log");
const tileSize = 16;
const map = [
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
[1, 0, 1, 0, 1, 1, 0, 0, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[1, 1, 1, 1, 1, 0, 1, 1, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[0, 1, 1, 0, 0, 0, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 1, 1, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
];
const player = {
x: 0,
y: 0,
hp: 10,
color: "#ff0000"
};
const enemies = [
{ x: 4, y: 2, hp: 5, alive: true },
{ x: 8, y: 7, hp: 7, alive: true },
];
function drawMap() {
for (let y = 0; y < map.length; y++) {
for (let x = 0; x < map[0].length; x++) {
ctx.fillStyle = map[y][x] === 1 ? "#444" : "#88cc88";
ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
}
}
}
function drawPlayer() {
ctx.fillStyle = player.color;
ctx.fillRect(player.x * tileSize, player.y * tileSize, tileSize, tileSize);
}
function drawEnemies() {
ctx.fillStyle = "#ffcc00";
enemies.forEach(enemy => {
if (enemy.alive) {
ctx.fillRect(enemy.x * tileSize, enemy.y * tileSize, tileSize, tileSize);
}
});
}
function canMove(x, y) {
return map[y] && map[y][x] === 0;
}
function updateUI() {
statusEl.textContent = `HP: ${player.hp}`;
}
function showLog(text) {
logEl.textContent = text;
}
function battle(enemy) {
showLog("戦闘開始!");
const battleInterval = setInterval(() => {
// プレイヤーの攻撃
let playerDmg = Math.floor(Math.random() * 3) + 1;
enemy.hp -= playerDmg;
showLog(`あなたの攻撃! 敵に${playerDmg}ダメージ!`);
if (enemy.hp <= 0) {
showLog("敵を倒した!");
enemy.alive = false;
clearInterval(battleInterval);
gameLoop();
return;
}
// 敵の攻撃
let enemyDmg = Math.floor(Math.random() * 3) + 1;
player.hp -= enemyDmg;
updateUI();
showLog(`敵の反撃! あなたは${enemyDmg}ダメージを受けた!`);
if (player.hp <= 0) {
showLog("あなたは倒れた… GAME OVER");
clearInterval(battleInterval);
document.removeEventListener("keydown", handleKey);
}
}, 1000);
}
function checkEnemy(x, y) {
for (let enemy of enemies) {
if (enemy.x === x && enemy.y === y && enemy.alive) {
battle(enemy);
return true;
}
}
return false;
}
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawMap();
drawEnemies();
drawPlayer();
updateUI();
}
function handleKey(e) {
let nx = player.x;
let ny = player.y;
if (e.key === "ArrowUp") ny--;
if (e.key === "ArrowDown") ny++;
if (e.key === "ArrowLeft") nx--;
if (e.key === "ArrowRight") nx++;
if (canMove(nx, ny)) {
player.x = nx;
player.y = ny;
if (!checkEnemy(nx, ny)) {
showLog(""); // 戦闘中じゃないならログを消す
}
}
gameLoop();
}
document.addEventListener("keydown", handleKey);
gameLoop();
</script>
</body>
</html>