setup()
setup() runs once when the sketch starts. It initializes the entire game world—defining all rooms, placing the player and entities, configuring mobile input buttons, and setting the first game state. This single function establishes the foundation for everything the game does.
🔬 The rooms object defines the game world layout. What happens if you change mainRoom's width (w: 600) to w: 1000 or w: 300? How does the safe zone change?
rooms = {
mainRoom: { x: 0, y: 0, w: 600, h: 400, color: '#333333', floor: -1,
function setup() {
createCanvas(windowWidth, windowHeight);
noStroke();
textAlign(CENTER, CENTER);
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:
createCanvas(windowWidth, windowHeight);
Creates a full-screen canvas matching the device size; noStroke() removes outlines from all shapes; textAlign centers text
rooms = { mainRoom: { x: 0, y: 0, w: 600, h: 400, ... }, ... };
Defines the game world layout—each room is a rectangle with a position, size, background color, and floor number; stairs connect them
player = { x: rooms.mainRoom.x + 100, y: rooms.mainRoom.y + 100, w: 30, h: 30, vx: 0, vy: 0, isMoving: false, isRunning: false };
Places the player in the main room with zero velocity and stores dimensions for collision detection
joystick = { baseX: width * 0.2, ... }; runButton = { x: width * 0.8, ... };
Positions the joystick (left side) and run button (right side) relative to screen size for touch control
for (let i = 0; i < MAX_MONSTERS; i++) { spawnMonster(); } spawnCollectibles();
Populates the game world with monsters on lab floors and keys/scrap scattered across rooms
createCanvas(windowWidth, windowHeight);- Creates a canvas that fills the entire browser window; uses window dimensions for responsive design
noStroke();- Disables outlines on all shapes drawn afterward—shapes will have fill colors only
textAlign(CENTER, CENTER);- Centers all text both horizontally and vertically relative to the coordinates you give text()
rooms = { mainRoom: { x: 0, y: 0, w: 600, h: 400, color: '#333333', floor: -1, ... }, ... };- Creates an object where each room is keyed by name (e.g., 'mainRoom', 'floor0') with properties defining its position, size, appearance, and connectivity
player = { x: rooms.mainRoom.x + 100, y: rooms.mainRoom.y + 100, w: 30, h: 30, vx: 0, vy: 0, isMoving: false, isRunning: false };- Initializes the player object at coordinates 100 pixels into the main room with 30×30 dimensions, zero velocity, and false states for movement and running
joystick = { baseX: width * 0.2, baseY: height * 0.8, radius: 60, ... };- Creates a joystick object positioned at 20% from left and 80% from top of screen (bottom-left) with a 60-pixel interaction radius
for (let i = 0; i < MAX_MONSTERS; i++) { spawnMonster(); }- Spawns MAX_MONSTERS (default 5) monsters randomly on the lab floors (not in safe zones)
spawnCollectibles();- Places one key on each floor and 5 scrap pieces per floor for the player to collect
gameState = "loading"; loadingTimer = 0;- Sets the initial game state to 'loading' so the draw loop displays the loading screen for 3 seconds