doom.html
body { margin: 0; overflow: hidden; }
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
font-family: Arial, sans-serif;
background: rgba(0, 0, 0, 0.5);
padding: 10px;
}
let scene, camera, renderer, controls;
let enemies = [];
let bullets = [];
let player = { x: 0, y: 1.8, z: 0, speed: 0.1, health: 100 };
let keys = {};
// シーンを作成
scene = new THREE.Scene();
scene.background = new THREE.Color(0x202020);
// カメラ(FPS視点)
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(player.x, player.y, player.z);
// レンダラー
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 地面
const floor = new THREE.Mesh(
new THREE.PlaneGeometry(50, 50),
new THREE.MeshBasicMaterial({ color: 0x228B22, side: THREE.DoubleSide })
);
floor.rotation.x = -Math.PI / 2;
scene.add(floor);
// 敵(赤い立方体)
function spawnEnemy() {
const enemy = new THREE.Mesh(
new THREE.BoxGeometry(1, 2, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
enemy.position.set(Math.random() * 20 – 10, 1, Math.random() * 20 – 10);
scene.add(enemy);
enemies.push({ mesh: enemy, health: 3 });
}
for (let i = 0; i (keys[e.key] = true));
document.addEventListener(“keyup”, (e) => (keys[e.key] = false));
// マウス操作(FPS視点)
document.addEventListener(“click”, () => document.body.requestPointerLock());
document.addEventListener(“mousemove”, (e) => {
if (document.pointerLockElement) {
camera.rotation.y -= e.movementX * 0.002;
camera.rotation.x -= e.movementY * 0.002;
}
});
// 射撃(クリックで弾を発射)
document.addEventListener(“mousedown”, () => {
const bullet = {
mesh: new THREE.SphereGeometry(0.1, 8, 8),
velocity: new THREE.Vector3(
-Math.sin(camera.rotation.y) * 0.5,
0,
-Math.cos(camera.rotation.y) * 0.5
),
position: new THREE.Vector3(camera.position.x, 1.5, camera.position.z)
};
const bulletMesh = new THREE.Mesh(bullet.mesh, new THREE.MeshBasicMaterial({ color: 0xffff00 }));
bulletMesh.position.copy(bullet.position);
scene.add(bulletMesh);
bullets.push({ mesh: bulletMesh, velocity: bullet.velocity });
});
// ゲームループ
function update() {
// プレイヤー移動
if (keys[“w”]) {
camera.position.x -= Math.sin(camera.rotation.y) * player.speed;
camera.position.z -= Math.cos(camera.rotation.y) * player.speed;
}
if (keys[“s”]) {
camera.position.x += Math.sin(camera.rotation.y) * player.speed;
camera.position.z += Math.cos(camera.rotation.y) * player.speed;
}
if (keys[“a”]) {
camera.position.x -= Math.cos(camera.rotation.y) * player.speed;
camera.position.z += Math.sin(camera.rotation.y) * player.speed;
}
if (keys[“d”]) {
camera.position.x += Math.cos(camera.rotation.y) * player.speed;
camera.position.z -= Math.sin(camera.rotation.y) * player.speed;
}
// 弾の移動
bullets.forEach((bullet, index) => {
bullet.mesh.position.add(bullet.velocity);
if (bullet.mesh.position.length() > 50) {
scene.remove(bullet.mesh);
bullets.splice(index, 1);
}
});
// 敵AI(プレイヤーに向かってくる)
enemies.forEach((enemy, index) => {
const direction = new THREE.Vector3(
camera.position.x – enemy.mesh.position.x,
0,
camera.position.z – enemy.mesh.position.z
).normalize();
enemy.mesh.position.addScaledVector(direction, 0.02);
// 弾が敵に当たったらダメージ
bullets.forEach((bullet, bIndex) => {
if (bullet.mesh.position.distanceTo(enemy.mesh.position) < 1) {
enemy.health–;
scene.remove(bullet.mesh);
bullets.splice(bIndex, 1);
if (enemy.health <= 0) {
scene.remove(enemy.mesh);
enemies.splice(index, 1);
}
}
});
});
renderer.render(scene, camera);
requestAnimationFrame(update);
}
update();
body { margin: 0; overflow: hidden; font-family: Arial, sans-serif; }
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0, 0, 0, 0.5);
padding: 10px;
}
let scene, camera, renderer;
let enemies = [];
let bullets = [];
let items = [];
let player = { x: 0, y: 1.8, z: 0, speed: 0.1, health: 100, score: 0 };
let keys = {};
// シーン作成
scene = new THREE.Scene();
scene.background = new THREE.Color(0x202020);
// カメラ(FPS視点)
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(player.x, player.y, player.z);
// レンダラー
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 地面
const floor = new THREE.Mesh(
new THREE.PlaneGeometry(50, 50),
new THREE.MeshBasicMaterial({ color: 0x228B22, side: THREE.DoubleSide })
);
floor.rotation.x = -Math.PI / 2;
scene.add(floor);
// 迷路の壁を作成
const walls = [];
function createWall(x, z) {
const wall = new THREE.Mesh(
new THREE.BoxGeometry(2, 3, 2),
new THREE.MeshBasicMaterial({ color: 0x808080 })
);
wall.position.set(x, 1.5, z);
scene.add(wall);
walls.push(wall);
}
// 迷路の配置
for (let x = -20; x <= 20; x += 5) {
createWall(x, -10);
createWall(x, 10);
}
for (let z = -10; z <= 10; z += 5) {
createWall(-20, z);
createWall(20, z);
}
// 敵(攻撃するAI)
function spawnEnemy() {
const enemy = new THREE.Mesh(
new THREE.BoxGeometry(1, 2, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
enemy.position.set(Math.random() * 20 – 10, 1, Math.random() * 20 – 10);
scene.add(enemy);
enemies.push({ mesh: enemy, health: 3, speed: 0.02 });
}
for (let i = 0; i < 5; i++) spawnEnemy(); // 5体の敵を生成
// アイテム(回復アイテム)
function spawnItem() {
const item = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 8, 8),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
item.position.set(Math.random() * 20 – 10, 0.5, Math.random() * 20 – 10);
scene.add(item);
items.push(item);
}
for (let i = 0; i (keys[e.key] = true));
document.addEventListener(“keyup”, (e) => (keys[e.key] = false));
// マウス操作
document.addEventListener(“click”, () => document.body.requestPointerLock());
document.addEventListener(“mousemove”, (e) => {
if (document.pointerLockElement) {
camera.rotation.y -= e.movementX * 0.002;
camera.rotation.x -= e.movementY * 0.002;
}
});
// 射撃処理
document.addEventListener(“mousedown”, () => {
const bullet = {
mesh: new THREE.SphereGeometry(0.1, 8, 8),
velocity: new THREE.Vector3(
-Math.sin(camera.rotation.y) * 0.5,
0,
-Math.cos(camera.rotation.y) * 0.5
),
position: new THREE.Vector3(camera.position.x, 1.5, camera.position.z)
};
const bulletMesh = new THREE.Mesh(bullet.mesh, new THREE.MeshBasicMaterial({ color: 0xffff00 }));
bulletMesh.position.copy(bullet.position);
scene.add(bulletMesh);
bullets.push({ mesh: bulletMesh, velocity: bullet.velocity });
});
// アイテム取得処理(Eキー)
document.addEventListener(“keydown”, (e) => {
if (e.key === “e”) {
items.forEach((item, index) => {
if (camera.position.distanceTo(item.position) {
const direction = new THREE.Vector3(
camera.position.x – enemy.mesh.position.x,
0,
camera.position.z – enemy.mesh.position.z
).normalize();
enemy.mesh.position.addScaledVector(direction, enemy.speed);
// 弾が敵に当たったら倒れる
bullets.forEach((bullet, bIndex) => {
if (bullet.mesh.position.distanceTo(enemy.mesh.position) < 1) {
enemy.health–;
if (enemy.health <= 0) {
player.score += 10;
updateScore();
scene.remove(enemy.mesh);
enemies.splice(index, 1);
}
scene.remove(bullet.mesh);
bullets.splice(bIndex, 1);
}
});
});
renderer.render(scene, camera);
requestAnimationFrame(update);
}
update();