Spaces:
Running
Running
// Define variables | |
var scene, camera, renderer, controls, clock; | |
var geometry, material, mesh; | |
var raycaster, mouse; | |
var enemies = []; | |
var towers = []; | |
var projectiles = []; | |
// Initialize game | |
init(); | |
animate(); | |
function init() { | |
// Create scene | |
scene = new THREE.Scene(); | |
// Create camera | |
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
camera.position.set(0, 10, 20); | |
// Create renderer | |
renderer = new THREE.WebGLRenderer(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
document.body.appendChild(renderer.domElement); | |
// Add controls | |
controls = new THREE.OrbitControls(camera, renderer.domElement); | |
// Add clock | |
clock = new THREE.Clock(); | |
// Create ground | |
geometry = new THREE.PlaneGeometry(100, 100); | |
material = new THREE.MeshBasicMaterial({color: 0x00ff00, side: THREE.DoubleSide}); | |
mesh = new THREE.Mesh(geometry, material); | |
mesh.rotateX(-Math.PI / 2); | |
scene.add(mesh); | |
// Add towers | |
addTower(5, 0, 5); | |
addTower(-5, 0, -5); | |
// Add enemies | |
addEnemy(0, 0, -10); | |
addEnemy(0, 0, -20); | |
// Add raycaster and mouse | |
raycaster = new THREE.Raycaster(); | |
mouse = new THREE.Vector2(); | |
// Add event listeners | |
window.addEventListener('resize', onWindowResize, false); | |
window.addEventListener('click', onClick, false); | |
} | |
function animate() { | |
requestAnimationFrame(animate); | |
// Move enemies | |
for (var i = 0; i < enemies.length; i++) { | |
var enemy = enemies[i]; | |
enemy.position.z += 0.1; | |
// Check if enemy is at end of path | |
if (enemy.position.z > 10) { | |
scene.remove(enemy); | |
enemies.splice(i, 1); | |
} | |
} | |
// Check for tower range and shoot | |
for (var i = 0; i < towers.length; i++) { | |
var tower = towers[i]; | |
var towerPosition = tower.position.clone(); | |
towerPosition.y = 0.5; | |
// Find nearest enemy | |
var nearestEnemy = null; | |
var nearestDistance = Infinity; | |
for (var j = 0; j < enemies.length; j++) { | |
var enemy = enemies[j]; | |
var distance = enemy.position.distanceTo(towerPosition); | |
if (distance < nearestDistance) { | |
nearestEnemy = enemy; | |
nearestDistance = distance; | |
} | |
} | |
// Shoot projectile | |
if (nearestEnemy && nearestDistance <= 5) { | |
var projectile = new THREE.Mesh(new THREE.SphereGeometry(0.1, 8, 8), new THREE.MeshBasicMaterial({color: 0xff0000})); | |
projectile.position.set(tower.position.x, tower.position.y + 0.5, tower.position.z); | |
projectiles.push(projectile); | |
scene.add(projectile); | |
// Remove enemy if hit | |
var index = enemies.indexOf(nearestEnemy); | |
if (index !== -1) { | |
scene.remove(nearestEnemy); | |
enemies.splice(index, 1); | |
} | |
} | |
} | |
// Move projectiles | |
for (var i = 0; i < projectiles.length; i++) { | |
var projectile = projectiles[i]; | |
projectile.position.z -= 0.5; | |
// Remove projectile if it hits enemy or end of path | |
for (var j = 0; j < enemies.length; j++) { | |
var enemy = enemies[j]; | |
if (projectile.position.distanceTo(enemy.position) <= 0.5) { | |
scene.remove(enemy); | |
enemies.splice(j, 1); | |
scene.remove(projectile); | |
projectiles.splice(i, 1); | |
break; | |
} | |
} | |
if (projectile.position.z < -10) { | |
scene.remove(projectile); | |
projectiles.splice(i, 1); | |
} | |
} | |
// Render scene | |
renderer.render(scene, camera); | |
// Update controls | |
controls.update(); | |
// Update clock | |
var delta = clock.getDelta(); | |
} | |
function addTower(x, y, z) { | |
var tower = new THREE.Mesh(new THREE.BoxGeometry(1, 2, 1), new THREE.MeshBasicMaterial({color: 0xff0000})); | |
tower.position.set(x, y + 1, z); | |
towers.push(tower); | |
scene.add(tower); | |
} | |
function addEnemy(x, y, z) { | |
var enemy = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({color: 0x0000ff})); | |
enemy.position.set(x, y + 0.5, z); | |
enemies.push(enemy); | |
scene.add(enemy); | |
} | |
function onWindowResize() { | |
camera.aspect = window.innerWidth / window.innerHeight; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
function onClick(event) { | |
// Calculate mouse position | |
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
// Cast ray from camera | |
raycaster.setFromCamera(mouse, camera); | |
// Check for tower placement | |
var intersects = raycaster.intersectObjects([mesh]); | |
if (intersects.length > 0) { | |
var point = intersects[0].point; | |
addTower(point.x, point.y, point.z); | |
} | |
} |