setup()
setup() runs once when the sketch starts. It initializes the entire game world: canvas, rooms, the player, all monsters, all collectibles, all UI buttons, and audio oscillators. Everything you see and interact with is defined here. Understanding setup() is key to understanding the game's structure.
function setup() {
createCanvas(windowWidth, windowHeight);
noStroke();
textAlign(CENTER, CENTER);
// Define rooms (x, y, width, height) relative to the entire game world
rooms = {
mainRoom: { x: 0, y: 0, w: 600, h: 400, color: '#333333', floor: -1,
scrapMachine: { x: 500, y: 150, w: 80, h: 100 },
lockers: [
{ x: 100, y: 300, w: 40, h: 60 },
{ x: 150, y: 300, w: 40, h: 60 },
{ x: 200, y: 300, w: 40, h: 60 }
]
},
monsterRoom: { x: 600, y: 0, w: 400, h: 400, color: '#222222', floor: -1 },
floor0: { x: 0, y: 400, w: 800, h: 600, color: '#554444', floor: 0 },
floor1: { x: 800, y: 400, w: 800, h: 600, color: '#445544', floor: 1 },
floor2: { x: 1600, y: 400, w: 800, h: 600, color: '#665555', floor: 2 },
floor3: { x: 2400, y: 400, w: 800, h: 600, color: '#556655', floor: 3 },
floor4: { x: 3200, y: 400, w: 800, h: 600, color: '#776666', floor: 4 }
};
player = {
x: rooms.mainRoom.x + 100,
y: rooms.mainRoom.y + 100,
w: 30,
h: 30,
vx: 0,
vy: 0,
isMoving: false,
isRunning: false
};
boombox.x = rooms.mainRoom.x + rooms.mainRoom.w / 2;
boombox.y = rooms.mainRoom.y + rooms.mainRoom.h / 2;
boombox.w = 80;
boombox.h = 60;
itemsForSale = [
{ name: "Speed Boost", cost: 10, type: "speedBoost", effect: () => { player.isRunning = true; }, description: "Run faster for a limited time." },
{ name: "Health Pack", cost: 5, type: "healthPack", description: "Restores health (not implemented yet)." }
];
staircases = [
{ x: rooms.mainRoom.x + 200, y: rooms.mainRoom.y + rooms.mainRoom.h - 50, w: 200, h: 50, targetRoom: "floor0", targetPlayerX: rooms.floor0.x + 300, targetPlayerY: rooms.floor0.y + 50 },
{ x: rooms.floor0.x + 300, y: rooms.floor0.y, w: 200, h: 50, targetRoom: "mainRoom", targetPlayerX: rooms.mainRoom.x + 300, targetPlayerY: rooms.mainRoom.y + rooms.mainRoom.h - player.h },
{ x: rooms.mainRoom.x + rooms.mainRoom.w - 50, y: rooms.mainRoom.y + 150, w: 50, h: 100, targetRoom: "monsterRoom", targetPlayerX: rooms.monsterRoom.x + 50, targetPlayerY: rooms.monsterRoom.y + 200 },
{ x: rooms.monsterRoom.x, y: rooms.monsterRoom.y + 150, w: 50, h: 100, targetRoom: "mainRoom", targetPlayerX: rooms.mainRoom.x + rooms.mainRoom.w - 50, targetPlayerY: rooms.mainRoom.y + 200 },
{ x: rooms.floor0.x + rooms.floor0.w - 50, y: rooms.floor0.y + 200, w: 50, h: 200, targetRoom: "floor1", targetPlayerX: rooms.floor1.x + 50, targetPlayerY: rooms.floor1.y + 300 },
{ x: rooms.floor1.x, y: rooms.floor1.y + 200, w: 50, h: 200, targetRoom: "floor0", targetPlayerX: rooms.floor0.x + rooms.floor0.w - 50, targetPlayerY: rooms.floor0.y + 300 },
{ x: rooms.floor1.x + rooms.floor1.w - 50, y: rooms.floor1.y + 200, w: 50, h: 200, targetRoom: "floor2", targetPlayerX: rooms.floor2.x + 50, targetPlayerY: rooms.floor2.y + 300 },
{ x: rooms.floor2.x, y: rooms.floor2.y + 200, w: 50, h: 200, targetRoom: "floor1", targetPlayerX: rooms.floor1.x + rooms.floor1.w - 50, targetPlayerY: rooms.floor1.y + 300 },
{ x: rooms.floor2.x + rooms.floor2.w - 50, y: rooms.floor2.y + 200, w: 50, h: 200, targetRoom: "floor3", targetPlayerX: rooms.floor3.x + 50, targetPlayerY: rooms.floor3.y + 300 },
{ x: rooms.floor3.x, y: rooms.floor3.y + 200, w: 50, h: 200, targetRoom: "floor2", targetPlayerX: rooms.floor2.x + rooms.floor2.w - 50, targetPlayerY: rooms.floor2.y + 300 },
{ x: rooms.floor3.x + rooms.floor3.w - 50, y: rooms.floor3.y + 200, w: 50, h: 200, targetRoom: "floor4", targetPlayerX: rooms.floor4.x + 50, targetPlayerY: rooms.floor4.y + 300 },
{ x: rooms.floor4.x, y: rooms.floor4.y + 200, w: 50, h: 200, targetRoom: "floor3", targetPlayerX: rooms.floor3.x + rooms.floor3.w - 50, targetPlayerY: rooms.floor0.y + 300 },
];
joystick = {
baseX: width * 0.2,
baseY: height * 0.8,
radius: 60,
knobX: width * 0.2,
knobY: height * 0.8,
active: false,
touchId: -1,
maxX: width * 0.4
};
runButton = {
x: width * 0.8,
y: height * 0.8,
w: 80,
h: 80,
active: false,
touchId: -1
};
modButton = {
x: width * 0.9,
y: height * 0.1,
w: 80,
h: 40,
active: false,
touchId: -1
};
scrapMachineButton = {
x: width / 2,
y: height - 50,
w: 200,
h: 60,
active: false,
touchId: -1,
visible: false
};
lockerButton = {
x: width / 2,
y: height - 50,
w: 200,
h: 60,
active: false,
touchId: -1,
visible: false
};
for (let i = 0; i < MAX_MONSTERS; i++) {
spawnMonster();
}
spawnCollectibles();
if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {
// Permission will be requested in touchStarted()
} else {
window.addEventListener('deviceorientation', handleDeviceOrientation);
deviceOrientationGranted = true;
}
gameState = "loading";
loadingTimer = 0;
}
Line-by-line explanation (9 lines)
🔧 Subcomponents:
rooms = { mainRoom: {...}, floor0: {...}, floor1: {...}, ... };
Defines the 2D positions and sizes of all five facility floors, the safe main room, and the monster gallery room - these are the game world boundaries
player = { x: rooms.mainRoom.x + 100, y: rooms.mainRoom.y + 100, w: 30, h: 30, vx: 0, vy: 0, isMoving: false, isRunning: false };
Creates the player object with position, size, velocity, and state flags that will be updated every frame
staircases = [ { x: rooms.mainRoom.x + 200, y: ..., targetRoom: "floor0", ... }, ... ];
Defines rectangular zones that teleport the player between rooms when touched - each staircase knows its target room and player spawn position
joystick = {...}; runButton = {...}; modButton = {...};
Creates button objects that track position, size, and which touch ID is controlling them for multi-touch support
createCanvas(windowWidth, windowHeight);- Creates a full-screen canvas that fills the entire browser window, making the game responsive to screen size
noStroke(); textAlign(CENTER, CENTER);- Disables outlines on shapes and centers all text - keeps the visual style clean and consistent
rooms = { mainRoom: { x: 0, y: 0, w: 600, h: 400, ... }, floor0: { x: 0, y: 400, ... } };- Maps out the entire game world by defining bounding boxes for each room - mainRoom starts at (0,0), floors are laid out horizontally below it at y=400
player = { x: rooms.mainRoom.x + 100, y: rooms.mainRoom.y + 100, w: 30, h: 30, vx: 0, vy: 0, isMoving: false, isRunning: false };- Creates the player character with initial position (100 pixels into mainRoom), fixed 30×30 size, zero velocity, and state tracking for movement and running
staircases = [ { x: rooms.mainRoom.x + 200, y: rooms.mainRoom.y + rooms.mainRoom.h - 50, w: 200, h: 50, targetRoom: "floor0", targetPlayerX: rooms.floor0.x + 300, targetPlayerY: rooms.floor0.y + 50 }, ... ];- Creates a list of invisible zones that trigger room transitions - each staircase has an entrance position and exit position in the target room
joystick = { baseX: width * 0.2, baseY: height * 0.8, radius: 60, knobX: width * 0.2, knobY: height * 0.8, active: false, touchId: -1, maxX: width * 0.4 };- Creates the virtual joystick positioned at the bottom-left 20% of screen, with a 60-pixel radius - tracking which touch controls it enables multi-touch on mobile
for (let i = 0; i < MAX_MONSTERS; i++) { spawnMonster(); }- Loops MAX_MONSTERS times (5) calling spawnMonster to populate the facility with enemies scattered across the floor rooms
spawnCollectibles();- Populates the floors with keys (one per floor) and scrap pieces (5 per floor) that the player can collect
gameState = "loading"; loadingTimer = 0;- Sets the game to display a loading screen for 3 seconds before transitioning to the start screen