VAZTEROIDS Game Design Notes (May 20, 2003) For WIN32 game, Visual C++ compiler, GDI graphics only (and DirectSound) ======================================================================= GAME STATES for Vazteroids GAME_STATE_DEMO_INIT = 0 GAME_STATE_DEMO_RUN = 1 GAME_STATE_GAME_INIT = 2 GAME_STATE_GAME_RUN = 3 GAME_STATE_GAME_RESET = 4 GAME_STATE_GAME_PAUSE = 5 ======================================================================= CONSTANTS for Vazteroids THRUST_SPEED .75 (speed up speed) THRUST_FRICTION .1 (slow down speed) MAX_SHIP_SPEED 20 BULLET_SPEED 12 MAX_ASTEROIDS 60 MAX_PARTICLES 2000 MAX_BULLETS 5 ======================================================================= GLOBAL VARS and initial values int game_state = DEMO_INIT; // initial game state int game_score = 0; // game score int game_level = 1; // game level (starts at 1) int rocks_hit = 0; // number of rocks hit int ships_left = 0; // number of ships left (5 at start of game) // (0 here since at Game Over ships = 0) ======================================================================= FUNCTIONS for Vazteroids GameInit() -- Game Initialization, go full screen GameMain() -- Game Main Loop and Processing GameQuit() -- Game Quit and Clean Up DisplayScore() -- Display Score bottom of screen SetRocks() -- set up new level of rocks Level 1 = 4 large, Level 2 = 6 large, Level 3 = 8 large MoveRocks() -- move all rocks once SetShip() -- set new ship (middle of screen/pointing up), set regen time MoveShip() -- move ship once, checks for regen time, check for rotate/thrust/fire RotateShip(i) -- rotates ship specified degrees MoveUFO() -- move existing UFO once, and randomly create one if not exist InsertRocks(x,y,t)-- after large or medium destroyed, insert 2 in place -- make sure they are set travelling away from bullet/ship -- x, y = approx point to insert on screen -- t=type, if t=2 insert two medium, if t=1 insert two small InsertBullet() -- insert one new bullet in array travelling at ship firing direction MoveBullets() -- move all existing bullets once SetUFOBullet() -- set new UFO bullet MoveUFOBullet() -- move UFO bullet once, and constantly fire InsertParticles() -- inserts particles in array (after explosion, thrust) MoveParticles() -- moves all existing particles (implement this last) CheckCollisions() -- Checks for ALL potential collisions ======================================================================= STRUCTS for Vazteroids ASTEROID ( array up to Rocks[MAX_ASTEROIDS] ) .alive (is alive TRUE/FALSE) .xcenter .ycenter (x/y center of rock) .xmove .ymove (x/y movement speed) .size (1=small, 2=med, 3=large) .shape (5 different shapes of asteroids) SHIP ( just one Ship ) .regen (time to wait until regeneration -- fade in -- of new ship) (when reaches 0 ship is fully bright and can be destroyed) (when > 0 ship waiting for regeneration, cannot be destroyed) .xcenter .ycenter (x/y center of ship) .xmove .ymove (x/y movement speed) .angle (rotation angle 32 positions, 0=up, 8=right, 16=down, 24=left) BULLET ( array up to Bullets[MAX_BULLETS] ) .alive (is alive TRUE/FALSE) .xcenter .ycenter (x/y center of bullet -- 3 pixels around) .xmove .ymove (x/y movement speed of bullet) .duration (starts at some value then decrement every frame) UFO ( just one ) .alive (is alive TRUE/FALSE, .size (2=large dumb, 1=small smart) .xcenter .ycenter (x/y center of UFO -- set ellipse shape) .xmove .ymove (x/y speed of UFO) .xbullet .ybullet (x/y bullet of UFO -- 5 pixels around) .xbmove .ybmove (x/y speed of UFO bullet) .duration (duration of UFO bullet, when done then fire again) PARTICLE ( pixels for explosions/thrust up to Particles[MAX_PARTICLES] ) .alive (is alive TRUE/FALSE) .xcenter .ycenter (x/y center of particle) .xmove .ymove (x/y speed of particle) .duration (duration of particle, keep on screen a little and fade out) NOTES: the bounding box for collision is computed from xcenter ycenter of objects duration is decreased each frame by 1 regen is decreased by 1 just before ship appears on screen at start of game or just after destroyed to leave some wait time ================================================================================== CHARACTERISTICS OF OBJECTS Rocks start out at 4 large on level 1, 6 large on level 2, 8 large on level >= 3. When large (green) hit, becomes 2 medium (blue). When medium (blue) hit, becomes 2 small (red). When small (red) hit, becomes dead (alive = FALSE). Large UFO can appear anytime on a level. When 20 or more rocks are hit small UFO can appear. Only one UFO at a time. UFO stays on screen until hit by ship, ship's bullet, or rock. UFO bounces off sides or randomly disappears if not hit. Ship rotates/moves according to key press (Left/Right Arrow = Rotate, CTRL = Fire, Shift/Up Arrow = Thrust). ======================================================================= MATH for Vazteroids // NOT NEEDED, PUT INITIAL VALUES INTO ARRAYS Convert Degrees to Radians formula (all floats) PI = 3.14159265 rads = degs * PI / 180.0 Look Up tables cos_table[32], sin_table[32] PSEUDO CODE TO CREATE LOOK UP TABLE degs = 0 for i = 0 to 31 rads = degs * PI / 180.0; cos_table[i] = cos(rads); sin_table[i] = sin(rads); degs = degs + 11.25 next Therefore 32 total angles ==> 0 = point up, 8 (90) = point right, 16 (180) = point down, 24 (270) = point left // AGAIN NOT NEEDED, JUST READ ROTATION POINTS FROM ARRAYS ROTATE FORMULA (for ship) newx = oldx * cos_table[angle] - oldy * sin_table[angle] newy = oldy * cos_table[angle] + oldx * sin_table[angle] // ALSO NOT NEEDED, SAVE THRUST AND BULLET DIRECTION VALUES INTO AN ARRAY THRUST BUTTON X/Y speed components when thrust held xmove += sin_table[angle] * THRUST_SPEED (or some slow constant) ymove += -cos_table[angle] * THRUST_SPEED (or some slow constant) if (xmove > MAX_SHIP_SPEED) xmove = MAX_SHIP_SPEED // MAX positive x speed if (xmove < - MAX_SHIP_SPEED) xmove = - MAX_SHIP_SPEED // MAX negative x speed if (ymove > MAX_SHIP_SPEED) ymove = MAX_SHIP_SPEED // MAX positive y speed if (ymove < - MAX_SHIP_SPEED) ymove = - MAX_SHIP_SPEED // MAX negative y speed BULLET DIRECTION (to insert new bullet) bullet.xcenter = ship.xcenter (x center of ship) bullet.ycenter = ship.ycenter (y center of ship) bullet.xmove = sin_table(ship.angle) * BULLET_SPEED (or fast constant) bullet.ymove = -cos_table(ship.angle) * BULLET_SPEED (or fast constant) works for 0 = up, 8 (90) = right, 16 (180) = down, 24 (270) = left ======================================================================= PSEUDO CODE for Vazteroids When DEMO_INIT SetRocks() // large rocks appear randomly at sides, level 1=4 rocks, 2=6, 3=8 Set state to DEMO_RUN When DEMO_RUN NOTE: No Sound in Demo MoveRocks() // move all existing rocks once MoveParticles() // move all existing particles once MoveUFO() // move UFO once MoveUFOBullet() // move UFO bullet once CheckCollisions() // check for all potential collisions (see below) DisplayScore() and when DEMO_RUN show text instructions Vazteroids a game by PhilVaz (c) 2003 Left/Right Arrow Keys = Rotate Ship CTRL = Fire, Shift or Up Arrow = Thrust 10 Points for Large Rock 25 Points for Medium Rock 50 Points for Small Rock 100 Points for Large UFO 500 Points for Small UFO Extra Ship at 5000 Points

key pauses the game Press to begin game Wait for key IF pressed, set state to GAME_INIT Otherwise, leave state at DEMO_RUN When GAME_INIT score = 0, level = 1, ships = 5, rocks_hit = 0 SetShip() // center of screen, pointing up, set regen time so ship fades in SetRocks() // large random Set state to GAME_RUN When GAME_RUN MoveShip() // move once -- if regen > 0 then ship still fading in // if regen = 0 then we are on the screen // check for input rotate/thrust/fire MoveBullets() // move all ship bullets once MoveRocks() // move all rocks once MoveParticles() // move all existing particles once MoveUFO() // move UFO once MoveUFOBullet() // move UFO bullet once CheckCollisions() // check for ALL potential collisions DETAILS FOR COLLISION DETECTION Bullets to Rocks --> InsertParticles() for explosion if small rock hit then destroy rock if ALL rocks hit then state = GAME_RESET if large or med rock hit insert 2 with InsertRocks(x,y,t) UFO Bullet to Rocks --> InsertParticles() for explosion if small rock hit then destroy rock if ALL rocks hit then state = GAME_RESET if large or med rock hit insert 2 with InsertRocks(x,y,t) Rocks to Ship --> InsertParticles() for explosion destroy Ship if small rock hit then destroy rock if ALL rocks hit then state = GAME_RESET if large or med rock hit insert 2 with InsertRocks(x,y,t) subtract one from ships_left if ships_left = 0 then state = DEMO_RUN if ships_left > 0 then SetShip() (set regen time) Bullets to UFO --> InsertParticles() for explosion destroy UFO UFO to Ship --> InsertParticles() for explosion destroy UFO and Ship subtract one from ships_left if ships_left = 0 then state = DEMO_RUN if ships_left > 0 then SetShip() (set regen time) UFO Bullet to Ship --> InsertParticles() for explosion destroy Ship substract one from ships_left if ships_left = 0 then state = DEMO_RUN if ships_left > 0 then SetShip() (set regen time) DisplayScore() // will only display bottom score/level/ships IF "p" key pressed, set state to GAME_PAUSE Otherwise, leave state at GAME_RUN When GAME_RESET add one to level SetRocks() // use timer to delay new rocks appearing Set state to GAME_RUN When GAME_PAUSE Stop all movement (by not updating) Wait for key to resume If key pressed, set state to GAME_RUN Otherwise, leave state at GAME_PAUSE ======================================================================== VAZTEROIDS screen diagram TOTAL SCREEN_WIDTH = 800 TOTAL SCREEN_HEIGHT = 600 space around the screen = 25 therefore GAME_WIDTH = 750 (if x < 25 or x > 775 then move object to other side of screen) GAME_HEIGHT = 550 (if y < 25 or y > 575 then move object to other side of screen) SCORE = XXX LEVEL = XX SHIPS = X Vazteroids a game by PhilVaz (c) 2003 ======================================================================================= END OF DESIGN NOTES