🎮
game PROJECT
STELLAR ASSAULT
Three.js based 3D space shooter game. Various enemy units, combo system, wave progression, real-time radar included.
Three.js WebGL 3D Rendering
Spaceship/Enemy/Missile 3D Modeling
Particle Explosion Effects
Combo System
Wave Progression
Real-time Radar
Boss Units
📦 Starter Code Snippets
HTML Structure
Three.js Canvas Basic Structure
<!DOCTYPE html>
<html>
<head>
<title>3D Space Shooter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</head>
<body>
<div id="gameContainer">
<canvas id="gameCanvas"></canvas>
<div id="ui">
<div id="score">SCORE: 0</div>
<div id="health">HP: 100</div>
</div>
</div>
</body>
</html>
Scene Setup
Three.js Scene, Camera, Renderer Initialization
// Three.js Scene Setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000011);
scene.fog = new THREE.Fog(0x000011, 100, 500);
// Camera
const camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000
);
camera.position.set(0, 30, 50);
camera.lookAt(0, 0, 0);
// Renderer
const renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("gameCanvas"),
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
Player Ship
Create Player Spaceship
// Create Player Ship
function createPlayerShip() {
const group = new THREE.Group();
// Body
const bodyGeom = new THREE.ConeGeometry(2, 8, 6);
const bodyMat = new THREE.MeshPhongMaterial({
color: 0x00ff88,
emissive: 0x003322
});
const body = new THREE.Mesh(bodyGeom, bodyMat);
body.rotation.x = Math.PI / 2;
group.add(body);
// Wings
const wingGeom = new THREE.BoxGeometry(8, 0.3, 2);
const wingMat = new THREE.MeshPhongMaterial({ color: 0x0088ff });
const wings = new THREE.Mesh(wingGeom, wingMat);
wings.position.z = 2;
group.add(wings);
// Engine Glow
const glowGeom = new THREE.SphereGeometry(1);
const glowMat = new THREE.MeshBasicMaterial({ color: 0xff4400 });
const glow = new THREE.Mesh(glowGeom, glowMat);
glow.position.z = 4;
group.add(glow);
return group;
}
const playerShip = createPlayerShip();
scene.add(playerShip);
Enemy System
Enemy Unit Creation & Management
// Enemy Types
const ENEMY_TYPES = {
FIGHTER: { hp: 30, speed: 0.5, score: 100, color: 0xff0044 },
CRUISER: { hp: 100, speed: 0.3, score: 300, color: 0xff8800 },
BOSS: { hp: 500, speed: 0.2, score: 1000, color: 0xff00ff }
};
// Enemy Pool (Object Pooling)
const enemyPool = [];
const activeEnemies = [];
function getEnemy(type) {
let enemy = enemyPool.find(e => !e.active && e.type === type);
if (!enemy) {
enemy = createEnemy(type);
enemyPool.push(enemy);
}
enemy.active = true;
enemy.hp = ENEMY_TYPES[type].hp;
return enemy;
}
function createEnemy(type) {
const config = ENEMY_TYPES[type];
const geom = type === "BOSS"
? new THREE.DodecahedronGeometry(6)
: new THREE.OctahedronGeometry(type === "CRUISER" ? 4 : 2);
const mat = new THREE.MeshPhongMaterial({
color: config.color,
emissive: config.color,
emissiveIntensity: 0.3
});
const mesh = new THREE.Mesh(geom, mat);
mesh.type = type;
mesh.active = false;
return mesh;
}
Missile System
Missile Firing & Collision Detection
// Missile Pool
const missilePool = [];
const activeMissiles = [];
function fireMissile(position, direction) {
let missile = missilePool.find(m => !m.active);
if (!missile) {
const geom = new THREE.CylinderGeometry(0.2, 0.2, 3);
const mat = new THREE.MeshBasicMaterial({ color: 0x00ffff });
missile = new THREE.Mesh(geom, mat);
missile.rotation.x = Math.PI / 2;
missilePool.push(missile);
scene.add(missile);
}
missile.position.copy(position);
missile.direction = direction.normalize();
missile.speed = 3;
missile.active = true;
missile.visible = true;
activeMissiles.push(missile);
playSound("laser");
}
function updateMissiles() {
for (let i = activeMissiles.length - 1; i >= 0; i--) {
const missile = activeMissiles[i];
missile.position.add(
missile.direction.clone().multiplyScalar(missile.speed)
);
// Check collision with enemies
for (const enemy of activeEnemies) {
if (missile.position.distanceTo(enemy.position) < 3) {
enemy.hp -= 25;
recycleMissile(missile, i);
if (enemy.hp <= 0) destroyEnemy(enemy);
break;
}
}
// Remove if out of bounds
if (missile.position.length() > 200) {
recycleMissile(missile, i);
}
}
}
Game Loop
Main Game Loop
// Game State
const game = {
running: false,
score: 0,
wave: 1,
combo: 0
};
// Main Game Loop
function gameLoop() {
if (!game.running) return;
requestAnimationFrame(gameLoop);
// Update player
updatePlayerMovement();
// Update enemies
updateEnemies();
// Update missiles
updateMissiles();
// Update particles
updateParticles();
// Check wave completion
if (activeEnemies.length === 0) {
startNextWave();
}
// Render
renderer.render(scene, camera);
}
function startGame() {
game.running = true;
game.score = 0;
game.wave = 1;
spawnWave(1);
gameLoop();
}
function gameOver() {
game.running = false;
submitScore(game.score, game.wave);
showGameOverScreen();
}
💰 Monetization Roadmap
Phase 1
Basic Monetization
- AdSense banner ads integration
- 5-second video ads before game start
- Rewarded ads for respawn
- Expected revenue: $50-200/month (10K DAU)
Phase 2
In-App Purchase
- Skin shop (ships, missile effects)
- Premium currency system (Crystals)
- Booster item sales
- VIP Pass (ad-free + bonuses)
- Expected revenue: $500-2000/month
Phase 3
Social & Competitive
- Friend invite system (referral rewards)
- Guild/Clan system
- Weekly tournaments
- Season rankings & rewards
- PvP battle mode
- Expected revenue: $2000-10000/month
Phase 4
Platform Expansion
- Mobile App (React Native / Capacitor)
- Steam release ($4.99)
- NFT skin marketplace
- Sponsorship & brand collaborations
- Expected revenue: $10000+/month