Add browser-based Doom clone with raycasting engine
Built a complete FPS game playable in the browser using vanilla JS and HTML5 Canvas. Features a raycasting renderer with 8 textured wall types, 3 weapons (pistol, shotgun, plasma gun), 3 enemy types with AI (imp, demon, baron), 3 levels of increasing difficulty, HUD with minimap, pickups, doors, explosive barrels, and procedural audio. Includes GitHub Actions workflow for GitHub Pages deployment. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+177
@@ -0,0 +1,177 @@
|
||||
// Level definitions
|
||||
// Map: 2D array where numbers correspond to wall types (0 = empty)
|
||||
// Entities: array of {type, x, y} for enemies and pickups
|
||||
|
||||
const Levels = [
|
||||
// LEVEL 1: Military Base - Introduction level
|
||||
{
|
||||
name: "Military Base",
|
||||
map: [
|
||||
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
|
||||
[1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,2,2,0,0,0,1,1,0,0,0,3,3,0,0,0,1],
|
||||
[1,0,0,0,2,2,0,0,0,1,1,0,0,0,3,3,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,1,1,1,1,5,1,1,0,0,0,0,1,1,5,1,1,1,1,1],
|
||||
[1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1],
|
||||
[1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
|
||||
[1,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,1],
|
||||
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
|
||||
],
|
||||
playerStart: { x: 2.5, y: 2.5, angle: 0 },
|
||||
entities: [
|
||||
// Enemies
|
||||
{ type: ENTITY_ENEMY_IMP, x: 15.5, y: 2.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 5.5, y: 11.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 14.5, y: 11.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 10.5, y: 14.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 10.5, y: 17.5 },
|
||||
// Pickups
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 8.5, y: 1.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 1.5, y: 8.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 18.5, y: 8.5 },
|
||||
{ type: ENTITY_PICKUP_SHOTGUN, x: 10.5, y: 7.5 },
|
||||
{ type: ENTITY_PICKUP_ARMOR, x: 1.5, y: 11.5 },
|
||||
// Decorations
|
||||
{ type: ENTITY_LAMP, x: 5.5, y: 7.5 },
|
||||
{ type: ENTITY_LAMP, x: 14.5, y: 7.5 },
|
||||
{ type: ENTITY_BARREL, x: 17.5, y: 12.5 },
|
||||
{ type: ENTITY_BARREL, x: 2.5, y: 17.5 },
|
||||
]
|
||||
},
|
||||
|
||||
// LEVEL 2: Research Lab - Medium difficulty
|
||||
{
|
||||
name: "Research Lab",
|
||||
map: [
|
||||
[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],
|
||||
[4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,3,3,3,3,0,0,0,4,0,0,0,0,4],
|
||||
[4,4,5,4,4,4,0,0,0,3,0,0,3,0,0,0,4,4,5,4,4,4],
|
||||
[4,0,0,0,0,0,0,0,0,3,0,0,3,0,0,0,0,0,0,0,0,4],
|
||||
[4,0,0,0,0,0,0,0,0,5,0,0,5,0,0,0,0,0,0,0,0,4],
|
||||
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4],
|
||||
[4,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,4],
|
||||
[4,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,4],
|
||||
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4],
|
||||
[4,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,4],
|
||||
[4,4,4,5,4,4,0,0,0,4,0,0,4,0,0,0,4,4,5,4,4,4],
|
||||
[4,0,0,0,0,4,0,0,0,5,0,0,5,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,4,0,0,4,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,4,0,0,4,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4],
|
||||
[4,0,0,0,0,4,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,4],
|
||||
[4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4],
|
||||
],
|
||||
playerStart: { x: 2.5, y: 2.5, angle: Math.PI / 4 },
|
||||
entities: [
|
||||
// Enemies
|
||||
{ type: ENTITY_ENEMY_IMP, x: 10.5, y: 1.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 19.5, y: 2.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 2.5, y: 7.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 19.5, y: 7.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 10.5, y: 8.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 5.5, y: 11.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 16.5, y: 11.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 2.5, y: 15.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 19.5, y: 15.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 10.5, y: 16.5 },
|
||||
// Pickups
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 19.5, y: 1.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 1.5, y: 6.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 20.5, y: 6.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 1.5, y: 18.5 },
|
||||
{ type: ENTITY_PICKUP_PLASMA, x: 10.5, y: 10.5 },
|
||||
{ type: ENTITY_PICKUP_ARMOR, x: 20.5, y: 18.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 10.5, y: 14.5 },
|
||||
// Decorations
|
||||
{ type: ENTITY_LAMP, x: 6.5, y: 8.5 },
|
||||
{ type: ENTITY_LAMP, x: 15.5, y: 8.5 },
|
||||
{ type: ENTITY_BARREL, x: 7.5, y: 1.5 },
|
||||
{ type: ENTITY_BARREL, x: 14.5, y: 1.5 },
|
||||
{ type: ENTITY_BARREL, x: 7.5, y: 18.5 },
|
||||
{ type: ENTITY_BARREL, x: 14.5, y: 18.5 },
|
||||
]
|
||||
},
|
||||
|
||||
// LEVEL 3: Hell - Hard difficulty
|
||||
{
|
||||
name: "Gates of Hell",
|
||||
map: [
|
||||
[8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8],
|
||||
[8,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,8,0,0,0,7,7,7,7,0,0,0,8,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,8,0,0,0,7,0,0,7,0,0,0,8,0,0,0,0,0,8],
|
||||
[8,8,8,5,8,8,8,0,0,0,5,0,0,5,0,0,0,8,8,8,5,8,8,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,7,0,0,7,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,7,7,7,7,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,8,8,8,0,0,0,0,0,0,0,0,0,8,8,8,0,0,0,0,8],
|
||||
[8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,8],
|
||||
[8,0,0,0,8,0,0,0,0,8,0,0,0,0,8,0,0,0,8,0,0,0,0,8],
|
||||
[8,0,0,0,8,0,0,0,0,8,0,0,0,0,8,0,0,0,8,0,0,0,0,8],
|
||||
[8,0,0,0,8,0,0,0,0,8,0,0,0,0,8,0,0,0,8,0,0,0,0,8],
|
||||
[8,0,0,0,8,8,5,8,8,8,0,0,0,0,8,8,5,8,8,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,8,8,8,8,8,8,8,8,0,0,0,0,0,0,8,8,8,8,8,8,8,8,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,8],
|
||||
[8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8],
|
||||
],
|
||||
playerStart: { x: 2.5, y: 2.5, angle: 0 },
|
||||
entities: [
|
||||
// Many enemies
|
||||
{ type: ENTITY_ENEMY_IMP, x: 21.5, y: 2.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 10.5, y: 2.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 14.5, y: 2.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 2.5, y: 7.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 21.5, y: 7.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 4.5, y: 10.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 19.5, y: 10.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 12.5, y: 9.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 6.5, y: 13.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 17.5, y: 13.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 12.5, y: 15.5 },
|
||||
{ type: ENTITY_ENEMY_BARON, x: 12.5, y: 21.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 2.5, y: 18.5 },
|
||||
{ type: ENTITY_ENEMY_IMP, x: 21.5, y: 18.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 5.5, y: 21.5 },
|
||||
{ type: ENTITY_ENEMY_DEMON, x: 19.5, y: 21.5 },
|
||||
// Pickups
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 4.5, y: 1.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 21.5, y: 5.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 12.5, y: 17.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 1.5, y: 1.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 22.5, y: 1.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 1.5, y: 17.5 },
|
||||
{ type: ENTITY_PICKUP_AMMO, x: 22.5, y: 17.5 },
|
||||
{ type: ENTITY_PICKUP_ARMOR, x: 12.5, y: 5.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 8.5, y: 20.5 },
|
||||
{ type: ENTITY_PICKUP_HEALTH, x: 16.5, y: 20.5 },
|
||||
// Decorations
|
||||
{ type: ENTITY_LAMP, x: 9.5, y: 9.5 },
|
||||
{ type: ENTITY_LAMP, x: 14.5, y: 9.5 },
|
||||
{ type: ENTITY_BARREL, x: 8.5, y: 17.5 },
|
||||
{ type: ENTITY_BARREL, x: 16.5, y: 17.5 },
|
||||
{ type: ENTITY_BARREL, x: 3.5, y: 21.5 },
|
||||
{ type: ENTITY_BARREL, x: 20.5, y: 21.5 },
|
||||
]
|
||||
}
|
||||
];
|
||||
Reference in New Issue
Block a user