// VazPac Delux a game by PhilVaz // Full Screen DirectDraw game (converted from GDI version) // Oct 18, 2003 // Oct 01, 2004 -- JOYSTICK SUPPORT ADDED // Mar 20, 2005 -- converted to DirectDraw // INCLUDES /////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN #include // include all the windows headers #include // include useful macros #include // for DirectSound #include // for rand functions #include #include #include // include DirectDraw #include "ddutil.h" // for DDLoadBitmap #include // include DirectSound #include "dsutil.h" // for LoadSoundBuffer() #include "VazPac.h" // sounds and bitmap resources // DEFINES //////////////////////////////////////////////// // defines for windows #define WINDOW_CLASS_NAME "WINCLASS1" #define WINDOW_WIDTH 800 // size of game window #define WINDOW_HEIGHT 600 #define WINDOW_BPP 16 // resolution #define GAME_SPEED 30 // speed of game (increase to go slower) #define GAME_STATE_DEMO_INIT 0 // demo initialization state #define GAME_STATE_DEMO_RUN 1 // demo running state #define GAME_STATE_GAME_INIT 2 // game initialization state #define GAME_STATE_GAME_RUN 3 // game running state #define GAME_STATE_GAME_RESET 4 // game reset state (new level) #define GAME_STATE_GAME_PAUSE 5 // game pause state (no movement) #define GAME_STATE_INTM_INIT 6 // intermission init #define GAME_STATE_INTM_RUN 7 // intermission running #define VAZ_SPEED 3 // Vaz character 3 pixels per move constant #define BULLET_SPEED 6 // for ghostbuster gun #define MAZE_WIDTH 25 // Maze horizontal width 25 blocks #define MAZE_HEIGHT 19 // Maze vertical height 19 blocks #define BLOCK_SIZE 30 // Maze block size = 30 pixels each block #define XTOP_LEFT 25 // Top Left X pixel position for Maze #define YTOP_LEFT 0 // Top Left Y pixel position for Maze #define XSCREEN_LIMIT 745 // limit for objects on X #define YSCREEN_LIMIT 540 // limit for objects on Y #define MAX_GHOSTS 9 // 3 = level 1,2 -- 6 = level 3,4,5 -- 9 = level 6+ #define MAX_POWER 10 // max number of power pills #define MAX_FOOD 10 // max number of food items #define MAX_SCORES 20 // max number of displayed scores #define MAX_BULLETS 5 // max bullets for ghostbuster gun #define MAX_PARTICLES 250 // max number of particles for explosions etc #define SCORE_PELLET 5 #define SCORE_POWER 25 #define SCORE_FOOD 100 // times level # #define SCORE_GHOST 100 // doubles each ghost chomped, 200, 400, 800, 1600, etc #define SCORE_EXTRA 10000 // score for extra Vaz #define LEVEL_PAUSE 150 // pause between levels, show Level #, Ready!, Go! #define GHOST_PAUSE 4 // pause for feet positions #define BULLET_PAUSE 10 // pause time between bullets #define BULLET_DURATION 90 // how long bullet lasts #define GUN_DURATION 1000 #define VAZ_NORMAL 0 #define VAZ_DYING 1 #define DIFFICULTY_EASY 0 // ghost speed = 2 demonic speed = 3 #define DIFFICULTY_HARD 1 // ghost speed = 3 demonic speed = 4 #define CHASE_NORMAL 0 // ghost chasing vaz #define CHASE_AWAY 1 // ghost running away #define CHASE_DEMONIC 2 // ghost demonic chasing #define CHASE_EYES 3 // ghost eyes only back to jail #define GHOST_BLUE 0 // bmp positions 0,1,2,3, 4,5,6,7 #define GHOST_GREEN 8 // bmp positions 8,9,10,11, 12,13,14,15 #define GHOST_RED 16 // bmp positions 16,17,18,19, 20,21,22,23 #define GHOST_SCARED 24 // bmp positions 24,25,26,27, 28,29,30,31 white/yellow #define GHOST_DEMONIC 32 // bmp positions 32,33,34,35, 36,37,38,39 dark red #define GHOST_EYES 40 // bmp positions 40,41,42,43 eyes only #define DIRECTION_RIGHT 0 #define DIRECTION_DOWN 1 #define DIRECTION_LEFT 2 #define DIRECTION_UP 3 #define DIRECTION_NONE 99 #define VAZ_RIGHT 0 // bmp positions #define VAZ_DOWN 6 #define VAZ_LEFT 12 #define VAZ_UP 18 #define MAZE_BLUE 0 #define MAZE_GREEN 10 #define MAZE_RED 20 #define MAZE_BLANK 0 #define MAZE_PELLET 1 #define MAZE_POWER 2 #define MAZE_BL 3 // curve bottom-left #define MAZE_BR 4 // curve bottom-right #define MAZE_TL 5 // curve top-left #define MAZE_TR 6 // curve top-right #define MAZE_HZ 7 // straight horizontal #define MAZE_VT 8 // straight vertical #define MAZE_LT 9 // left end #define MAZE_RT 10 // right end #define MAZE_UP 11 // up end #define MAZE_DN 12 // down end // MACROS ///////////////////////////////////////////////// #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) // GLOBALS //////////////////////////////////////////////// HWND game_window = NULL; // global game window handle HINSTANCE game_instance = NULL; // global game instance handle // DirectDraw variables LPDIRECTDRAW game_draw_main = NULL; // dd main object LPDIRECTDRAWSURFACE game_draw_surface = NULL; // dd primary surface LPDIRECTDRAWSURFACE game_draw_back = NULL; // dd back surface DDSURFACEDESC game_draw_desc; // dd surface description DDSCAPS game_draw_caps; // dd surface capabilities DDBLTFX back_fill; // to clear back buffer to black LPDIRECTSOUND game_sound_main = NULL; // global direct sound object LPDIRECTSOUNDBUFFER game_sound_death1 = NULL; // sound death 1 LPDIRECTSOUNDBUFFER game_sound_death2 = NULL; // sound death 2 LPDIRECTSOUNDBUFFER game_sound_eat1 = NULL; // sound normal food eat LPDIRECTSOUNDBUFFER game_sound_eat2 = NULL; // sound eat 2 LPDIRECTSOUNDBUFFER game_sound_eat3 = NULL; // sound eat 3 LPDIRECTSOUNDBUFFER game_sound_eat4 = NULL; // sound eat 4 burp LPDIRECTSOUNDBUFFER game_sound_eat5 = NULL; // sound eat 5 burp LPDIRECTSOUNDBUFFER game_sound_eat6 = NULL; // sound eat 6 LPDIRECTSOUNDBUFFER game_sound_eat7 = NULL; // sound eat 7 hic LPDIRECTSOUNDBUFFER game_sound_eat8 = NULL; // sound eat 8 hic LPDIRECTSOUNDBUFFER game_sound_extra = NULL; // sound extra vaz LPDIRECTSOUNDBUFFER game_sound_fire = NULL; // sound fire bullet LPDIRECTSOUNDBUFFER game_sound_ghosteat = NULL; // sound ghost eaten LPDIRECTSOUNDBUFFER game_sound_ghosteyes = NULL; // sound ghost eyes to jail LPDIRECTSOUNDBUFFER game_sound_happy = NULL; // sound happy giggle LPDIRECTSOUNDBUFFER game_sound_hurl = NULL; // sound hurl garth LPDIRECTSOUNDBUFFER game_sound_interm1 = NULL; // sound interm 1 LPDIRECTSOUNDBUFFER game_sound_interm2 = NULL; // sound interm 2 LPDIRECTSOUNDBUFFER game_sound_interm3 = NULL; // sound interm 3 LPDIRECTSOUNDBUFFER game_sound_interm4 = NULL; // sound interm 4 LPDIRECTSOUNDBUFFER game_sound_munch = NULL; // sound normal munch LPDIRECTSOUNDBUFFER game_sound_open1 = NULL; // sound open song 1 LPDIRECTSOUNDBUFFER game_sound_open2 = NULL; // sound open song 2 LPDIRECTSOUNDBUFFER game_sound_power = NULL; // sound power pill LPDIRECTSOUNDBUFFER game_sound_siren1 = NULL; // sound siren 1 LPDIRECTSOUNDBUFFER game_sound_siren2 = NULL; // sound siren 2 LPDIRECTSOUNDBUFFER game_sound_siren3 = NULL; // sound siren 3 LPDIRECTSOUNDBUFFER game_sound_siren4 = NULL; // sound siren 4 LPDIRECTSOUNDBUFFER game_sound_siren5 = NULL; // sound siren 5 // global joystick variables bool joy_ok; // whether joystick found ok UINT joy_num; // number of joys JOYINFO joy_info; // joy init info UINT joy_ID; // joy ID JOYCAPS joy_caps; // joy capture info RECT joy_trip; // joy trip info DWORD joy_xcenter; // joy x axis center DWORD joy_ycenter; // joy y axis center // joy directions (1=true, 0=false) int joy_left, joy_right, joy_up, joy_down, joy_but1, joy_but2, joy_but3, joy_but4; // global game variables int game_state = GAME_STATE_DEMO_INIT; // start in demo state UINT game_speed = GAME_SPEED; char text[80]; // for display text output int game_score = 0; int chomp_score; // for remember ghost doubled 100,200,400,800, etc int extra_score; // target score for extra Vaz int game_level = 1; int game_difficulty = DIFFICULTY_EASY; int ghost_speed; // faster with DIFFICULTY_HARD int ghost_feet, ghost_delay; // for feet position int vaz_left = 0; int pellets_left; // total number of pellets counted from Maze int level_countdown = 0; // pause time between levels int bullet_countdown = 0; // pause time between bullets bool draw_ok; // for whether DirectDraw init ok bool sound_ok; // for whether DirectSound set okay bool anim_over; // for whether intermission animation over int maze_color; // current maze color int Maze[MAZE_HEIGHT][MAZE_WIDTH]; int Archive1[MAZE_HEIGHT][MAZE_WIDTH] = // MAZE 1 { { 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 8, 1, 9, 7, 7, 10, 1, 9, 7, 7, 10, 1, 12, 1, 9, 7, 7, 10, 1, 9, 7, 7, 10, 1, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 7, 7, 10, 1, 9, 6, 1, 9, 7, 7, 7, 10, 1, 5, 10, 1, 9, 7, 7, 10, 1, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 7, 7, 7, 6, 1, 8, 7, 10, 1, 12, 1, 9, 7, 8, 1, 5, 7, 7, 7, 10, 1, 8 }, { 8, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 0, 0, 0, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 8 }, { 3, 7, 7, 7, 10, 1, 8, 1, 12, 1, 5, 10, 0, 9, 6, 1, 12, 1, 8, 1, 9, 7, 7, 7, 4 }, { 0, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 0, 0, 0, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 0 }, { 5, 7, 7, 7, 10, 1, 8, 1, 11, 1, 3, 7, 7, 7, 4, 1, 11, 1, 8, 1, 9, 7, 7, 7, 6 }, { 8, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 0, 0, 0, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 7, 6, 1, 12, 1, 12, 1, 9, 7, 7, 7, 10, 1, 12, 1, 12, 1, 5, 7, 10, 1, 8 }, { 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8 }, { 8, 7, 10, 1, 12, 1, 9, 7, 10, 1, 11, 1, 8, 1, 11, 1, 9, 7, 10, 1, 12, 1, 9, 7, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 7, 7, 7, 7, 7, 10, 1, 12, 1, 12, 1, 12, 1, 9, 7, 7, 7, 7, 7, 10, 1, 8 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4 } }; int Archive2[MAZE_HEIGHT][MAZE_WIDTH] = // MAZE 2 { { 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6 }, { 8, 2, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 2, 8 }, { 8, 1, 9, 7, 7, 10, 1, 12, 1, 9, 7, 7, 7, 7, 7, 10, 1, 12, 1, 9, 7, 7, 10, 1, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 3, 7, 7, 10, 1, 11, 1, 9, 7, 7, 10, 1, 11, 1, 9, 7, 7, 10, 1, 11, 1, 9, 7, 7, 4 }, { 0, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 0 }, { 5, 7, 7, 10, 1, 3, 7, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 7, 4, 1, 9, 7, 7, 6 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 10, 1, 5, 7, 7, 10, 1, 5, 10, 0, 9, 6, 1, 9, 7, 7, 6, 1, 9, 10, 1, 8 }, { 8, 1, 1, 1, 1, 8, 1, 1, 1, 1, 8, 0, 0, 0, 8, 1, 1, 1, 1, 8, 1, 1, 1, 1, 8 }, { 3, 7, 7, 10, 1, 8, 1, 9, 6, 1, 3, 7, 7, 7, 4, 1, 5, 10, 1, 8, 1, 9, 7, 7, 4 }, { 0, 1, 1, 1, 1, 8, 1, 1, 8, 1, 1, 0, 0, 0, 1, 1, 8, 1, 1, 8, 1, 1, 1, 1, 0 }, { 5, 7, 7, 10, 1, 12, 1, 9, 7, 7, 10, 1, 11, 1, 9, 7, 7, 10, 1, 12, 1, 9, 7, 7, 6 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 5, 7, 10, 1, 5, 7, 10, 1, 9, 7, 7, 7, 10, 1, 9, 7, 6, 1, 9, 7, 6, 1, 8 }, { 8, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 8 }, { 8, 1, 12, 1, 9, 7, 4, 1, 9, 7, 7, 7, 7, 7, 7, 7, 10, 1, 3, 7, 10, 1, 12, 1, 8 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4 } }; int Archive3[MAZE_HEIGHT][MAZE_WIDTH] = // MAZE 3 { { 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 0, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 8, 1, 9, 7, 6, 1, 9, 7, 6, 1, 9, 4, 1, 3, 10, 1, 5, 7, 10, 1, 5, 7, 10, 1, 8 }, { 8, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 8 }, { 8, 1, 11, 1, 3, 7, 6, 1, 3, 7, 7, 10, 1, 9, 7, 7, 4, 1, 5, 7, 4, 1, 11, 1, 8 }, { 8, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 8 }, { 8, 1, 3, 7, 6, 1, 3, 7, 6, 1, 9, 10, 1, 9, 10, 1, 5, 7, 4, 1, 5, 7, 4, 1, 8 }, { 8, 1, 1, 1, 8, 1, 1, 1, 8, 2, 1, 0, 0, 0, 1, 2, 8, 1, 1, 1, 8, 1, 1, 1, 8 }, { 3, 7, 10, 1, 3, 7, 10, 1, 12, 1, 5, 10, 0, 9, 6, 1, 12, 1, 9, 7, 4, 1, 9, 7, 4 }, { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 0, 0, 0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, { 5, 7, 10, 1, 5, 7, 10, 1, 11, 1, 3, 7, 7, 7, 4, 1, 11, 1, 9, 7, 6, 1, 9, 7, 6 }, { 8, 1, 1, 1, 8, 1, 1, 1, 8, 2, 1, 0, 0, 0, 1, 2, 8, 1, 1, 1, 8, 1, 1, 1, 8 }, { 8, 1, 5, 7, 4, 1, 5, 7, 4, 1, 9, 10, 1, 9, 10, 1, 3, 7, 6, 1, 3, 7, 6, 1, 8 }, { 8, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 8 }, { 8, 1, 12, 1, 5, 7, 4, 1, 5, 7, 7, 10, 1, 9, 7, 7, 6, 1, 3, 7, 6, 1, 12, 1, 8 }, { 8, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 1, 1, 1, 8 }, { 8, 1, 9, 7, 4, 1, 9, 7, 4, 1, 9, 6, 1, 5, 10, 1, 3, 7, 10, 1, 3, 7, 10, 1, 8 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4 } }; int Archive4[MAZE_HEIGHT][MAZE_WIDTH] = // MAZE 4 { { 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 8, 1, 11, 1, 5, 7, 10, 1, 5, 7, 7, 7, 7, 7, 7, 7, 6, 1, 9, 7, 6, 1, 11, 1, 8 }, { 8, 1, 8, 1, 8, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 8, 1, 8, 1, 8 }, { 8, 1, 12, 1, 8, 1, 11, 1, 1, 1, 9, 10, 1, 9, 10, 1, 1, 1, 11, 1, 8, 1, 12, 1, 8 }, { 8, 1, 1, 1, 8, 1, 8, 1, 11, 1, 1, 1, 1, 1, 1, 1, 11, 1, 8, 1, 8, 1, 1, 1, 8 }, { 8, 1, 11, 1, 8, 1, 12, 1, 8, 1, 9, 7, 7, 7, 10, 1, 8, 1, 12, 1, 8, 1, 11, 1, 8 }, { 8, 1, 8, 1, 8, 1, 1, 1, 8, 1, 1, 0, 0, 0, 1, 1, 8, 1, 1, 1, 8, 1, 8, 1, 8 }, { 12, 1, 8, 1, 12, 1, 11, 1, 8, 1, 5, 10, 0, 9, 6, 1, 8, 1, 11, 1, 12, 1, 8, 1, 12 }, { 1, 1, 8, 1, 1, 1, 8, 1, 8, 2, 8, 0, 0, 0, 8, 2, 8, 1, 8, 1, 1, 1, 8, 1, 1 }, { 11, 1, 8, 1, 11, 1, 12, 1, 8, 1, 3, 7, 7, 7, 4, 1, 8, 1, 12, 1, 11, 1, 8, 1, 11 }, { 8, 1, 8, 1, 8, 1, 1, 1, 8, 1, 1, 0, 0, 0, 1, 1, 8, 1, 1, 1, 8, 1, 8, 1, 8 }, { 8, 1, 12, 1, 8, 1, 11, 1, 8, 1, 9, 7, 7, 7, 10, 1, 8, 1, 11, 1, 8, 1, 12, 1, 8 }, { 8, 1, 1, 1, 8, 1, 8, 1, 12, 1, 1, 1, 1, 1, 1, 1, 12, 1, 8, 1, 8, 1, 1, 1, 8 }, { 8, 1, 11, 1, 8, 1, 12, 1, 1, 1, 9, 10, 1, 9, 10, 1, 1, 1, 12, 1, 8, 1, 11, 1, 8 }, { 8, 1, 8, 1, 8, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 8, 1, 8, 1, 8 }, { 8, 1, 12, 1, 3, 7, 10, 1, 3, 7, 7, 7, 7, 7, 7, 7, 4, 1, 9, 7, 4, 1, 12, 1, 8 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4 } }; int Archive5[MAZE_HEIGHT][MAZE_WIDTH] = // MAZE 5 { { 5, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 6 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 8, 1, 9, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 10, 1, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 12, 1, 9, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 10, 1, 12 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 11, 1, 9, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 10, 1, 11 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 11, 1, 11, 1, 11, 1, 11, 1, 5, 10, 0, 9, 6, 1, 11, 1, 11, 1, 11, 1, 11, 1, 8 }, { 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 0, 0, 0, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8 }, { 8, 1, 12, 1, 12, 1, 12, 1, 12, 1, 3, 7, 7, 7, 4, 1, 12, 1, 12, 1, 12, 1, 12, 1, 8 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 12, 1, 9, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 10, 1, 12 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 11, 1, 9, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 10, 1, 11 }, { 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8 }, { 8, 1, 9, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 10, 1, 8 }, { 8, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 8 }, { 3, 7, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 10, 1, 9, 7, 7, 7, 7, 7, 7, 4 } }; // for bitmap graphics LPDIRECTDRAWSURFACE hvazbmp[24]; LPDIRECTDRAWSURFACE hghostbmp[44]; // blue 0-7 green 8-15 red 16-23 scared 24-31 demonic 32-39 eyes 40-43 LPDIRECTDRAWSURFACE hmazebmp[30]; // 10 for blue, 10 for green, 10 for red walls etc LPDIRECTDRAWSURFACE hfoodbmp[20]; LPDIRECTDRAWSURFACE hflashbmp[6]; // flash power positions LPDIRECTDRAWSURFACE hpelletbmp; LPDIRECTDRAWSURFACE hbulletbmp; RECT bmp_rect = {0, 0, BLOCK_SIZE, BLOCK_SIZE}; // bmp rect for blitting using block (tile) size RECT temp_rect; // temp rect for blitting at x,y // // particle direction X (sin) and Y (-cos) // float xdir[32] = {0.0f, 0.1951f, 0.3827f, 0.5556f, 0.7071f, 0.8315f, 0.9239f, 0.9808f, 1.0f, 0.9808f, 0.9239f, 0.8315f, 0.7071f, 0.5556f, 0.3827f, 0.1951f, 0.0f, -0.1951f, -0.3827f, -0.5556f, -0.7071f, -0.8315f, -0.9239f, -0.9808f, -1.0f, -0.9808f, -0.9239f, -0.8315f, -0.7071f, -0.5556f, -0.3827f, -0.1951f}; float ydir[32] = {-1.0f, -0.9808f, -0.9239f, -0.8315f, -0.7071f, -0.5556f, -0.3827f, -0.1951f, 0.0f, 0.1951f, 0.3827f, 0.5556f, 0.7071f, 0.8315f, 0.9239f, 0.9808f, 1.0f, 0.9808f, 0.9239f, 0.8315f, 0.7071f, 0.5556f, 0.3827f, 0.1951f, 0.0f, -0.1951f, -0.3827f, -0.5556f, -0.7071f, -0.8315f, -0.9239f, -0.9808f}; typedef struct { int state; // VAZ_NORMAL or DYING int x; // x y top-left int y; int xm; int ym; int tomove; // where Vaz wants to move int mouth; // mouth position 0 to 5 for bmp = dir + mouth int dir; // facing direction bool gun; // TRUE = has gun and can fire if VAZ_NORMAL, FALSE = no gun int count; // for dying positions and fire count } VAZ_STRUCT; VAZ_STRUCT Vaz; typedef struct { bool alive; // TRUE = exist, FALSE = not int color; // GHOST_BLUE, _GREEN, _RED -- note: must remember original color int chase; // CHASE_NORMAL, _AWAY, _DEMONIC, _EYES int x; // x y top-left int y; int xm; int ym; bool jailed; // TRUE = in jail, FALSE = normal chase int count; // for flashing during run away, for jail time during jail } GHOST_STRUCT; GHOST_STRUCT Ghosts[MAX_GHOSTS]; typedef struct { bool alive; // TRUE = exist, FALSE = not int x; // x y center int y; int count; // for size of flashing power pill 0 to 15 } POWER_STRUCT; POWER_STRUCT Power[MAX_POWER]; typedef struct { bool alive; // TRUE = exist, FALSE = not int x; // x y top-left int y; int xm; int ym; int count; // duration of bullet, start at BULLET_DURATION } BULLET_STRUCT; BULLET_STRUCT Bullets[MAX_BULLETS]; typedef struct { bool alive; // TRUE = exist, FALSE = not int type; // type of food 0 to 19 int x; // x y top-left int y; int xm; int ym; int count; // how long food lasts } FOOD_STRUCT; FOOD_STRUCT Food[MAX_FOOD]; typedef struct { bool alive; // TRUE = exist, FALSE = not int amount; // amount of score int x; // x y top-left int y; int count; // how long score lasts before fade out } SCORE_STRUCT; SCORE_STRUCT Scores[MAX_SCORES]; typedef struct { bool alive; // TRUE = exist, FALSE = not float x; // x y center float y; float xm; float ym; int duration; // duration of particle, keep on screen then fade out } PARTICLE_STRUCT; PARTICLE_STRUCT Particles[MAX_PARTICLES]; typedef unsigned short USHORT; // for pixel plotting // set up white pixel RGB 5.6.5 16-bit color value USHORT white_pixel = (USHORT)((255%32) + ((255%64) << 6) + ((255%32) << 11)); // FUNCTIONS ////////////////////////////////////////////// bool GameInit(); // game initialization, set up DirectDraw, go full screen etc void GameMain(); // game main loop and processing void GameQuit(); // game quit and clean up void DisplayScore(); // display text score/level bottom of screen void SetMaze(); void DrawMaze(); void SetVaz(); void MoveVaz(); void SetGhosts(); void MoveGhosts(); void InsertFood(); void MoveFood(); void InsertBullet(); void MoveBullets(); void InsertScore(int, int, int); // insert score at x,y with score amount void DrawScores(); void InsertParticles(int, int, int); // particle explosion at x,y of type t void MoveParticles(); bool SoundInit(); void SoundQuit(); bool JoyInit(); void JoyQuit(); void JoyStatus(); void SetInterm(); // set up intermission bool AnimInterm(); // return TRUE when done anim, otherwise FALSE void FlashPower(); void CheckCollisions(); // Check for all potential Collisions void ResetAll(); // Reset (clear) all ghosts, food, bullets, scores, particles int XMazeToXScreen(int); // convert a maze column to x pixel position int YMazeToYScreen(int); // convert a maze row to y pixel position int XScreenToXMaze(int); // convert x pixel to maze column int YScreenToYMaze(int); // convert y pixel to maze row bool CanMove(int, int); // check if valid move (not inside wall) // WINPROC //////////////////////////////////////////////// LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main message handler of the system HDC hdc; // handle to a device context PAINTSTRUCT ps; // used in WM_PAINT switch(msg) // what is the message { case WM_CREATE: { // do initialization stuff here return(0); // return success } break; case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); // validate the window EndPaint(hwnd, &ps); return(0); // return success } break; case WM_DESTROY: { PostQuitMessage(0); // kill the application, sends a WM_QUIT message return(0); // return success } break; default:break; } // end switch // process any default messages return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // WINMAIN //////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASSEX winclass; // this will hold the class we create HWND hwnd; // generic window handle MSG msg; // generic message // save the game instance handle game_instance = hinstance; // first fill in the window class structure // WHEN DONE ADD // LoadIcon(game_instance, MAKEINTRESOURCE(ICON_VAZGAMES)) winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WinProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(game_instance, IDI_APPLICATION); winclass.hIconSm = LoadIcon(game_instance, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; // register the window class if (!RegisterClassEx(&winclass)) return(0); // create the window if (!(hwnd = CreateWindowEx(NULL, // extended style WINDOW_CLASS_NAME, // class "VazPac", // title WS_POPUP | WS_VISIBLE, // use POPUP for full screen 0,0, // initial game window x,y WINDOW_WIDTH, // initial game width WINDOW_HEIGHT, // initial game height NULL, // handle to parent NULL, // handle to menu hinstance, // instance of this application NULL))) // extra creation parms return(0); // save the game window handle game_window = hwnd; draw_ok = GameInit(); // game initialization function called here if (!draw_ok) SendMessage(game_window, WM_CLOSE, 0, 0); // enter main event loop using PeekMessage() to retrieve messages while(TRUE) { // get initial tick count to keep game speed constant DWORD start_tick = GetTickCount(); // is there a message in queue, if so get it if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { // test if this is a quit if (msg.message == WM_QUIT) break; // translate any accelerator keys TranslateMessage(&msg); // send the message to WinProc DispatchMessage(&msg); } // end if // if not pause, erase the back buffer if (game_state != GAME_STATE_GAME_PAUSE) IDirectDrawSurface_Blt(game_draw_back,NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT, &back_fill); GameMain(); // game main processing function called here // copy/flip back buffer to front buffer IDirectDrawSurface_Flip(game_draw_surface,NULL,DDFLIP_WAIT); // check for key and send quit game if (KEYDOWN(VK_ESCAPE)) SendMessage (game_window, WM_CLOSE, 0, 0); // wait until we hit correct game speed frame rate while ((GetTickCount() - start_tick) < game_speed); } // end while GameQuit(); // game quit function and clean up before exit called here return(msg.wParam); // return to Windows } // end WinMain // BEGIN GAME CODE //////////////////////////////////////// /////////////////////////////////////////////////////////// // // GAME INITIALIZATION // /////////////////////////////////////////////////////////// bool GameInit() { int i; srand(GetTickCount()); // seed the random numbers ShowCursor(FALSE); // set up DirectDraw, temporary change to full screen mode // first create base IDirectDraw interface if (FAILED(DirectDrawCreate(NULL, &game_draw_main, NULL))) { MessageBox(game_window, "DirectDraw could not be initialized -- Create Error","DirectDraw Error",MB_OK); return FALSE; // error returned } // set cooperation to full screen if (FAILED(IDirectDraw_SetCooperativeLevel(game_draw_main, game_window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))) { MessageBox(game_window, "DirectDraw could not be initialized -- Cooperative Level Error","DirectDraw Error",MB_OK); return FALSE; // error returned } // set display mode to specific resolution if (FAILED(IDirectDraw_SetDisplayMode(game_draw_main, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP))) { MessageBox(game_window, "DirectDraw could not be initialized -- Screen Resolution Not Available","DirectDraw Error",MB_OK); return FALSE; // error returned } // create the primary surface with a back buffer ZeroMemory(&game_draw_desc, sizeof(game_draw_desc)); // clear out surface description game_draw_desc.dwSize = sizeof(game_draw_desc); game_draw_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; game_draw_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; game_draw_desc.dwBackBufferCount = 1; if (FAILED(IDirectDraw_CreateSurface(game_draw_main, &game_draw_desc, &game_draw_surface, NULL))) { MessageBox(game_window, "DirectDraw could not be initialized -- Primary Surface Error","DirectDraw Error",MB_OK); return FALSE; // error returned } // get the pointer to the back buffer game_draw_caps.dwCaps = DDSCAPS_BACKBUFFER; if (FAILED(IDirectDrawSurface_GetAttachedSurface(game_draw_surface, &game_draw_caps, &game_draw_back))) { MessageBox(game_window, "DirectDraw could not be initialized -- Back Surface Error","DirectDraw Error",MB_OK); return FALSE; // error returned } // load the BMP maze resources // BLUE WALL hmazebmp[0] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBH), 0,0); hmazebmp[1] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBV), 0,0); hmazebmp[2] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLB1), 0,0); hmazebmp[3] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLB2), 0,0); hmazebmp[4] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLB3), 0,0); hmazebmp[5] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLB4), 0,0); hmazebmp[6] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBL), 0,0); hmazebmp[7] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBR), 0,0); hmazebmp[8] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBU), 0,0); hmazebmp[9] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLBD), 0,0); // GREEN WALL hmazebmp[10] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGH), 0,0); hmazebmp[11] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGV), 0,0); hmazebmp[12] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLG1), 0,0); hmazebmp[13] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLG2), 0,0); hmazebmp[14] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLG3), 0,0); hmazebmp[15] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLG4), 0,0); hmazebmp[16] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGL), 0,0); hmazebmp[17] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGR), 0,0); hmazebmp[18] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGU), 0,0); hmazebmp[19] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLGD), 0,0); // RED WALL hmazebmp[20] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRH), 0,0); hmazebmp[21] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRV), 0,0); hmazebmp[22] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLR1), 0,0); hmazebmp[23] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLR2), 0,0); hmazebmp[24] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLR3), 0,0); hmazebmp[25] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLR4), 0,0); hmazebmp[26] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRL), 0,0); hmazebmp[27] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRR), 0,0); hmazebmp[28] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRU), 0,0); hmazebmp[29] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_WALLRD), 0,0); // VAZPAC POSITIONS hvazbmp[0] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC0), 0,0); hvazbmp[1] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC1), 0,0); hvazbmp[2] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC2), 0,0); hvazbmp[3] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC3), 0,0); hvazbmp[4] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC4), 0,0); hvazbmp[5] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC5), 0,0); hvazbmp[6] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC6), 0,0); hvazbmp[7] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC7), 0,0); hvazbmp[8] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC8), 0,0); hvazbmp[9] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC9), 0,0); hvazbmp[10] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC10),0,0); hvazbmp[11] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC11),0,0); hvazbmp[12] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC12),0,0); hvazbmp[13] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC13),0,0); hvazbmp[14] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC14),0,0); hvazbmp[15] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC15),0,0); hvazbmp[16] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC16),0,0); hvazbmp[17] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC17),0,0); hvazbmp[18] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC18),0,0); hvazbmp[19] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC19),0,0); hvazbmp[20] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC20),0,0); hvazbmp[21] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC21),0,0); hvazbmp[22] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC22),0,0); hvazbmp[23] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PAC23),0,0); for (i=0; i<24; i++) DDSetColorKey(hvazbmp[i], RGB(0,0,0)); // GHOST BMPs hghostbmp[0] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST00), 0,0); hghostbmp[1] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST01), 0,0); hghostbmp[2] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST02), 0,0); hghostbmp[3] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST03), 0,0); hghostbmp[4] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST04), 0,0); hghostbmp[5] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST05), 0,0); hghostbmp[6] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST06), 0,0); hghostbmp[7] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST07), 0,0); hghostbmp[8] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST08), 0,0); hghostbmp[9] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST09), 0,0); hghostbmp[10] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST10), 0,0); hghostbmp[11] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST11), 0,0); hghostbmp[12] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST12), 0,0); hghostbmp[13] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST13), 0,0); hghostbmp[14] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST14), 0,0); hghostbmp[15] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST15), 0,0); hghostbmp[16] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST16), 0,0); hghostbmp[17] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST17), 0,0); hghostbmp[18] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST18), 0,0); hghostbmp[19] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST19), 0,0); hghostbmp[20] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST20), 0,0); hghostbmp[21] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST21), 0,0); hghostbmp[22] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST22), 0,0); hghostbmp[23] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST23), 0,0); hghostbmp[24] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST24), 0,0); hghostbmp[25] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST25), 0,0); hghostbmp[26] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST26), 0,0); hghostbmp[27] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST27), 0,0); hghostbmp[28] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST28), 0,0); hghostbmp[29] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST29), 0,0); hghostbmp[30] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST30), 0,0); hghostbmp[31] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST31), 0,0); hghostbmp[32] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST32), 0,0); hghostbmp[33] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST33), 0,0); hghostbmp[34] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST34), 0,0); hghostbmp[35] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST35), 0,0); hghostbmp[36] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST36), 0,0); hghostbmp[37] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST37), 0,0); hghostbmp[38] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST38), 0,0); hghostbmp[39] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST39), 0,0); hghostbmp[40] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST40), 0,0); hghostbmp[41] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST41), 0,0); hghostbmp[42] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST42), 0,0); hghostbmp[43] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_GHOST43), 0,0); for (i=0; i<44; i++) DDSetColorKey(hghostbmp[i], RGB(0,0,0)); // FOOD BMPs hfoodbmp[0] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD00), 0,0); hfoodbmp[1] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD01), 0,0); hfoodbmp[2] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD02), 0,0); hfoodbmp[3] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD03), 0,0); hfoodbmp[4] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD04), 0,0); hfoodbmp[5] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD05), 0,0); hfoodbmp[6] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD06), 0,0); hfoodbmp[7] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD07), 0,0); hfoodbmp[8] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD08), 0,0); hfoodbmp[9] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD09), 0,0); hfoodbmp[10] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD10), 0,0); hfoodbmp[11] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD11), 0,0); hfoodbmp[12] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD12), 0,0); hfoodbmp[13] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD13), 0,0); hfoodbmp[14] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD14), 0,0); hfoodbmp[15] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD15), 0,0); hfoodbmp[16] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD16), 0,0); hfoodbmp[17] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD17), 0,0); hfoodbmp[18] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD18), 0,0); hfoodbmp[19] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FOOD19), 0,0); for (i=0; i<20; i++) DDSetColorKey(hfoodbmp[i], RGB(0,0,0)); hflashbmp[0] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH0), 0,0); hflashbmp[1] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH1), 0,0); hflashbmp[2] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH2), 0,0); hflashbmp[3] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH3), 0,0); hflashbmp[4] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH4), 0,0); hflashbmp[5] = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_FLASH5), 0,0); for (i=0; i<6; i++) DDSetColorKey(hflashbmp[i], RGB(0,0,0)); hpelletbmp = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_PELLET), 0,0); // added for DD DDSetColorKey(hpelletbmp, RGB(0,0,0)); hbulletbmp = DDLoadBitmap(game_draw_main, MAKEINTRESOURCE(BMP_BULLET), 0,0); // added for DD DDSetColorKey(hbulletbmp, RGB(0,0,0)); ZeroMemory(&back_fill,sizeof(back_fill)); // set up back fill for clear background back_fill.dwSize = sizeof(back_fill); back_fill.dwFillColor = RGB(0,0,0); // Initialize DirectSound sound_ok = SoundInit(); // Initialize Joystick joy_ok = JoyInit(); return TRUE; } // END OF GameInit /////////////////////////////////////////////////////////// // // GAME MAIN LOOP AND PROCESSING // /////////////////////////////////////////////////////////// void GameMain() { switch(game_state) { case GAME_STATE_DEMO_INIT: { SetMaze(); SetGhosts(); game_state = GAME_STATE_DEMO_RUN; } break; case GAME_STATE_DEMO_RUN: { DrawMaze(); MoveGhosts(); MoveFood(); MoveParticles(); FlashPower(); DrawScores(); DisplayScore(); // check for play opening song if (KEYDOWN(VK_SPACE) || KEYDOWN(49)) { game_level = 1; game_state = GAME_STATE_GAME_INIT; game_difficulty = DIFFICULTY_EASY; game_speed = GAME_SPEED; if (sound_ok) IDirectSoundBuffer_Play(game_sound_open1,0,0,NULL); } if (KEYDOWN(50)) { game_level = 1; game_state = GAME_STATE_GAME_INIT; game_difficulty = DIFFICULTY_HARD; game_speed = GAME_SPEED; if (sound_ok) IDirectSoundBuffer_Play(game_sound_interm4,0,0,NULL); } if (KEYDOWN(51)) { game_level = 1; game_state = GAME_STATE_GAME_INIT; game_difficulty = DIFFICULTY_HARD; game_speed = GAME_SPEED / 2; if (sound_ok) IDirectSoundBuffer_Play(game_sound_interm1,0,0,NULL); } if (KEYDOWN(52)) { game_level = 3; game_state = GAME_STATE_GAME_INIT; game_difficulty = DIFFICULTY_HARD; game_speed = GAME_SPEED / 2; if (sound_ok) IDirectSoundBuffer_Play(game_sound_interm3,0,0,NULL); } } break; case GAME_STATE_GAME_INIT: { // reset scores, level, vaz to initial values game_score = 0; vaz_left = 5; chomp_score = SCORE_GHOST; extra_score = SCORE_EXTRA; level_countdown = LEVEL_PAUSE; SetMaze(); SetVaz(); SetGhosts(); game_state = GAME_STATE_GAME_RUN; } break; case GAME_STATE_GAME_RUN: { DrawMaze(); FlashPower(); MoveParticles(); DrawScores(); MoveVaz(); MoveBullets(); if (game_state == GAME_STATE_GAME_RUN) // make sure not switched to reset { MoveGhosts(); MoveFood(); CheckCollisions(); } DisplayScore(); // if 'p' key pressed, set state to GAME_PAUSE if (KEYDOWN(80)) game_state = GAME_STATE_GAME_PAUSE; } break; case GAME_STATE_GAME_RESET: { if (pellets_left == 0) { game_level++; SetMaze(); // also check game_level > 6 && game_level 10, 15, 20, 25, etc mod 5 ? if (game_level == 3 || game_level == 6) game_state = GAME_STATE_INTM_INIT; } SetVaz(); SetGhosts(); level_countdown = LEVEL_PAUSE; if (game_state != GAME_STATE_INTM_INIT) game_state = GAME_STATE_GAME_RUN; //////////////////////////////////// // TURN OFF ANY LOOPING SOUNDS //////////////////////////////////// if (sound_ok) { IDirectSoundBuffer_Stop(game_sound_power); IDirectSoundBuffer_Stop(game_sound_ghosteyes); IDirectSoundBuffer_Stop(game_sound_siren1); IDirectSoundBuffer_Stop(game_sound_siren2); IDirectSoundBuffer_Stop(game_sound_siren3); IDirectSoundBuffer_Stop(game_sound_siren4); IDirectSoundBuffer_Stop(game_sound_siren5); } } break; case GAME_STATE_GAME_PAUSE: { // if key pressed resume game if (KEYDOWN(VK_SPACE)) game_state = GAME_STATE_GAME_RUN; } break; case GAME_STATE_INTM_INIT: { SetInterm(); game_state = GAME_STATE_INTM_RUN; } break; case GAME_STATE_INTM_RUN: { anim_over = AnimInterm(); if (anim_over) { if (sound_ok) { if (game_level == 3) IDirectSoundBuffer_Play(game_sound_open2,0,0,NULL); if (game_level == 6) IDirectSoundBuffer_Play(game_sound_open1,0,0,NULL); } game_state = GAME_STATE_GAME_RUN; } } break; } // end switch } // END OF GameMain /////////////////////////////////////////////////////////// // // GAME QUIT AND CLEAN UP // /////////////////////////////////////////////////////////// void GameQuit() { int i; SoundQuit(); // turn off DirectSound and release buffers JoyQuit(); // release Joystick // // RELEASE/DELETE ALL BITMAPS HERE // for (i=0; i<30; i++) { if (hmazebmp[i]) IDirectDrawSurface_Release(hmazebmp[i]); } for (i=0; i<24; i++) { if (hvazbmp[i]) IDirectDrawSurface_Release(hvazbmp[i]); } for (i=0; i<44; i++) { if (hghostbmp[i]) IDirectDrawSurface_Release(hghostbmp[i]); } for (i=0; i<20; i++) { if (hfoodbmp[i]) IDirectDrawSurface_Release(hfoodbmp[i]); } for (i=0; i<6; i++) { if (hflashbmp[i]) IDirectDrawSurface_Release(hflashbmp[i]); } if (hpelletbmp) IDirectDrawSurface_Release(hpelletbmp); if (hbulletbmp) IDirectDrawSurface_Release(hbulletbmp); // release/delete the primary and back dd surfaces if (game_draw_back) IDirectDrawSurface_Release(game_draw_back); if (game_draw_surface) IDirectDrawSurface_Release(game_draw_surface); // release/delete the IDirectDraw interface if (game_draw_main) { IDirectDraw_Release(game_draw_main); game_draw_main = NULL; } } // END OF GameQuit ///////////////////////////////////////////////////////// // // display text score/level/vaz bottom of screen // ///////////////////////////////////////////////////////// void DisplayScore() { int temp, temp2; HDC temp_dc; IDirectDrawSurface_GetDC(game_draw_back, &temp_dc); // get GDI device context SetTextColor(temp_dc, RGB(255,255,255)); // white text SetBkColor(temp_dc, RGB(0,0,0)); // black back sprintf(text,"SCORE = %d", game_score); TextOut(temp_dc, 80, 580, text, strlen(text)); sprintf(text,"LEVEL = %d", game_level); TextOut(temp_dc, 210, 580, text, strlen(text)); sprintf(text,"VAZ = %d", vaz_left); TextOut(temp_dc, 340, 580, text, strlen(text)); sprintf(text,"VazPac a game by PhilVaz (c) 2003"); TextOut(temp_dc, 470, 580, text, strlen(text)); if (game_state == GAME_STATE_DEMO_RUN) { sprintf(text,"VazPac Delux a game by PhilVaz (c) 2003"); TextOut(temp_dc, 270, 90, text, strlen(text)); sprintf(text,"www.bringyou.to/games"); TextOut(temp_dc, 310, 110, text, strlen(text)); sprintf(text,"Arrow Keys or JOYSTICK (if detected) = Move Vaz"); TextOut(temp_dc, 270, 140, text, strlen(text)); sprintf(text,"CTRL or JOY1 = Fire Ghostbuster Gun When Found"); TextOut(temp_dc, 270, 160, text, strlen(text)); temp = SCORE_PELLET; temp2 = SCORE_POWER; sprintf(text,"%d Points for Pellet, %d Points for Power Pill", temp, temp2); TextOut(temp_dc, 270, 190, text, strlen(text)); temp = SCORE_GHOST; sprintf(text,"%d Points for Ghost, Doubles Each Time", temp); TextOut(temp_dc, 270, 210, text, strlen(text)); temp = SCORE_EXTRA; sprintf(text,"Extra Vaz Every %d Points", temp); TextOut(temp_dc, 310, 230, text, strlen(text)); sprintf(text,"Eat the Pellets/Food, Avoid the Ghosts"); TextOut(temp_dc, 270, 330, text, strlen(text)); sprintf(text,"Eat Power Pill or Find the Gun to Blast Ghosts"); TextOut(temp_dc, 270, 350, text, strlen(text)); sprintf(text,"

key pauses the game during play"); TextOut(temp_dc, 270, 380, text, strlen(text)); sprintf(text,"press or 1=easy, 2=hard, 3=harder, 4=hardest to start game"); TextOut(temp_dc, 210, 400, text, strlen(text)); } // end of if IDirectDrawSurface_ReleaseDC(game_draw_back, temp_dc); // release temp device context } // END OF DisplayScore ///////////////////////////////////////////////////////// // // set the current maze based on level # // ///////////////////////////////////////////////////////// void SetMaze() { int r,c; // row and column of maze int m; // maze character symbol int t; // maze type int num_power = 0; // clear number of power pills pellets_left = 0; // clear pellets_left for new count ResetAll(); // // test for game_level here and pick color and type of maze // if (game_level == 1) { maze_color = MAZE_BLUE; t = 1; } if (game_level == 2) { maze_color = MAZE_BLUE; t = 1; } if (game_level == 3) { maze_color = MAZE_GREEN; t = 2; } if (game_level == 4) { maze_color = MAZE_BLUE; t = 1; } if (game_level == 5) { maze_color = MAZE_GREEN; t = 2; } if (game_level == 6) { maze_color = MAZE_RED; t = 3; } if (game_level == 7) { maze_color = MAZE_GREEN; t = 4; } if (game_level == 8) { maze_color = MAZE_BLUE; t = 5; } if (game_level == 9) { maze_color = MAZE_RED; t = 1; } if (game_level > 9 || game_speed < 30) { t = rand()%3; if (t == 0) maze_color = MAZE_BLUE; if (t == 1) maze_color = MAZE_GREEN; if (t == 2) maze_color = MAZE_RED; t = rand()%5 + 1; // random maze color and type if level > 9 or very hard } for (r = 0; r < MAZE_HEIGHT; r++) // do the row { for (c = 0; c < MAZE_WIDTH; c++) // do the column { if (t == 1) m = Archive1[r][c]; // get maze tile from maze Archive if (t == 2) m = Archive2[r][c]; // of type t if (t == 3) m = Archive3[r][c]; // and row r, col c if (t == 4) m = Archive4[r][c]; if (t == 5) m = Archive5[r][c]; // check if found a pellet if (m == MAZE_PELLET) pellets_left++; // check if found a Power Pill, add to list if (m == MAZE_POWER) { Power[num_power].alive = TRUE; Power[num_power].x = XMazeToXScreen(c) + 15; Power[num_power].y = YMazeToYScreen(r) + 15; Power[num_power].count = 5; num_power++; pellets_left++; } Maze[r][c] = m; // save archive into current maze } // end for column (WIDTH) } // end for row (HEIGHT) } // END OF SetMaze ///////////////////////////////////////////////////////// // // draw/refresh the current maze // ///////////////////////////////////////////////////////// void DrawMaze() { int r,c; // row and column of maze int m; // maze character symbol int b; // maze bmp index int x; // start x pixel pos int y = YTOP_LEFT - BLOCK_SIZE; // start y pixel pos for (r = 0; r < MAZE_HEIGHT; r++) // do the row { y += BLOCK_SIZE; x = XTOP_LEFT - BLOCK_SIZE; for (c = 0; c < MAZE_WIDTH; c++) // do the column { x += BLOCK_SIZE; b = 99; // if 99 then no bmp to display m = Maze[r][c]; // get the maze symbol if (m == MAZE_PELLET) // draw dot (pellet) to back buffer { SetRect(&temp_rect, x, y, x + BLOCK_SIZE, y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hpelletbmp, &bmp_rect, DDBLT_WAIT, NULL); } // if part of wall, translate symbol to bmp value if (m == MAZE_HZ) b = 0; if (m == MAZE_VT) b = 1; if (m == MAZE_TL) b = 2; if (m == MAZE_TR) b = 3; if (m == MAZE_BL) b = 4; if (m == MAZE_BR) b = 5; if (m == MAZE_LT) b = 6; if (m == MAZE_RT) b = 7; if (m == MAZE_UP) b = 8; if (m == MAZE_DN) b = 9; if (b != 99) { SetRect(&temp_rect, x, y, x + BLOCK_SIZE, y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hmazebmp[maze_color + b], &bmp_rect, DDBLT_WAIT, NULL); } } // end of for COLUMN (WIDTH) } // end of for ROW (HEIGHT) } // END OF DrawMaze ///////////////////////////////////////////////////////// // // set the vaz character middle of screen pointing right // ///////////////////////////////////////////////////////// void SetVaz() { Vaz.dir = VAZ_RIGHT; // point right Vaz.mouth = 3; // open mouth Vaz.x = XMazeToXScreen(12); // start at col 12 Vaz.y = YMazeToYScreen(11); // start at row 11 Vaz.xm = 0; Vaz.ym = 0; Vaz.tomove = DIRECTION_NONE; Vaz.state = VAZ_NORMAL; Vaz.gun = FALSE; Vaz.count = 0; } // END OF SetVaz ///////////////////////////////////////////////////////// // // move/update the vaz character once // ///////////////////////////////////////////////////////// void MoveVaz() { int x,y; // temp new x y int xc,yc; // check x y int c; // temp count HDC temp_dc; // check for level countdown = pause time between levels if (level_countdown > 0) { level_countdown--; IDirectDrawSurface_GetDC(game_draw_back, &temp_dc); // get temp GDI device context if (level_countdown > 40) { SetTextColor(temp_dc, RGB(255,255,0)); // yellow text SetBkColor(temp_dc, RGB(0,0,0)); // black back sprintf(text,"READY!"); TextOut(temp_dc, 370, 220, text, strlen(text)); } // end if else { SetTextColor(temp_dc, RGB(255,255,0)); // yellow text SetBkColor(temp_dc, RGB(0,0,0)); // black back sprintf(text,"GO!"); TextOut(temp_dc, 380, 220, text, strlen(text)); if (level_countdown == 1 && sound_ok) // set initial siren sound { if (pellets_left > 175) IDirectSoundBuffer_Play(game_sound_siren1,0,0,DSBPLAY_LOOPING); if (pellets_left < 176 && pellets_left > 125) IDirectSoundBuffer_Play(game_sound_siren2,0,0,DSBPLAY_LOOPING); if (pellets_left < 126 && pellets_left > 75) IDirectSoundBuffer_Play(game_sound_siren3,0,0,DSBPLAY_LOOPING); if (pellets_left < 76 && pellets_left > 25) IDirectSoundBuffer_Play(game_sound_siren4,0,0,DSBPLAY_LOOPING); if (pellets_left < 26) IDirectSoundBuffer_Play(game_sound_siren5,0,0,DSBPLAY_LOOPING); } // end if set siren sound } // end else IDirectDrawSurface_ReleaseDC(game_draw_back, temp_dc); } // end if else { if (Vaz.state == VAZ_DYING) { Vaz.count--; c = Vaz.count; // rotate quickly, then explode (insert particles) if (c == 0) { vaz_left--; if (vaz_left == 0) game_state = GAME_STATE_DEMO_INIT; else game_state = GAME_STATE_GAME_RESET; Vaz.state = VAZ_NORMAL; return; } if (c == 93) { if (sound_ok) { if (game_level < 3 || game_level > 5) IDirectSoundBuffer_Play(game_sound_death1,0,0,NULL); else IDirectSoundBuffer_Play(game_sound_death2,0,0,NULL); } } if (c > 0 && c < 40) return; if (c == 40) InsertParticles(Vaz.x + 15, Vaz.y + 15, 4); if ((c > 95 && c < 101) || (c > 75 && c < 81) || (c > 55 && c < 61)) Vaz.dir = VAZ_RIGHT; if ((c > 90 && c < 96) || (c > 70 && c < 76) || (c > 50 && c < 56)) Vaz.dir = VAZ_DOWN; if ((c > 85 && c < 91) || (c > 65 && c < 71) || (c > 45 && c < 51)) Vaz.dir = VAZ_LEFT; if ((c > 80 && c < 86) || (c > 60 && c < 66) || (c > 40 && c < 46)) Vaz.dir = VAZ_UP; // draw bmp and return Vaz.mouth = 3; SetRect(&temp_rect, Vaz.x, Vaz.y, Vaz.x + BLOCK_SIZE, Vaz.y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hvazbmp[Vaz.dir + Vaz.mouth], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); return; } // end if VAZ_DYING // state is VAZ_NORMAL x = Vaz.x; y = Vaz.y; // save current Vaz x y position xc = Vaz.x; yc = Vaz.y; // check on x y for new direction // allow movement with arrow keys if (joy_ok) JoyStatus(); if ((KEYDOWN(VK_RIGHT) || joy_right) && Vaz.xm != VAZ_SPEED) Vaz.tomove = DIRECTION_RIGHT; if ((KEYDOWN(VK_LEFT) || joy_left) && Vaz.xm != -VAZ_SPEED) Vaz.tomove = DIRECTION_LEFT; if ((KEYDOWN(VK_DOWN) || joy_down) && Vaz.ym != VAZ_SPEED) Vaz.tomove = DIRECTION_DOWN; if ((KEYDOWN(VK_UP) || joy_up) && Vaz.ym != -VAZ_SPEED) Vaz.tomove = DIRECTION_UP; if (Vaz.gun) { if (KEYDOWN(VK_CONTROL) || joy_but1) InsertBullet(); Vaz.count--; if (Vaz.count == 0) Vaz.gun = FALSE; } // wants to move right, check if possible yet if (Vaz.tomove == DIRECTION_RIGHT) { xc += VAZ_SPEED; if (xc > XSCREEN_LIMIT) xc = XTOP_LEFT; if (CanMove(xc,yc)) { Vaz.dir = VAZ_RIGHT; Vaz.xm = VAZ_SPEED; Vaz.ym = 0; Vaz.tomove = DIRECTION_NONE; } } // end if right // wants to move left, check if possible yet if (Vaz.tomove == DIRECTION_LEFT) { xc -= VAZ_SPEED; if (xc < XTOP_LEFT) xc = XSCREEN_LIMIT; if (CanMove(xc,yc)) { Vaz.dir = VAZ_LEFT; Vaz.xm = -VAZ_SPEED; Vaz.ym = 0; Vaz.tomove = DIRECTION_NONE; } } // end if left // wants to move down, check if possible yet if (Vaz.tomove == DIRECTION_DOWN) { yc += VAZ_SPEED; if (yc > YSCREEN_LIMIT) yc = YTOP_LEFT; if (CanMove(xc,yc)) { Vaz.dir = VAZ_DOWN; Vaz.xm = 0; Vaz.ym = VAZ_SPEED; Vaz.tomove = DIRECTION_NONE; } } // end if down // wants to move up, check if possible yet if (Vaz.tomove == DIRECTION_UP) { yc -= VAZ_SPEED; if (yc < YTOP_LEFT) yc = YSCREEN_LIMIT; if (CanMove(xc,yc)) { Vaz.dir = VAZ_UP; Vaz.xm = 0; Vaz.ym = -VAZ_SPEED; Vaz.tomove = DIRECTION_NONE; } } // end if up // move Vaz in current or new direction x += Vaz.xm; y += Vaz.ym; if (x > XSCREEN_LIMIT) x = XTOP_LEFT; else if (x < XTOP_LEFT) x = XSCREEN_LIMIT; if (y > YSCREEN_LIMIT) y = YTOP_LEFT; else if (y < YTOP_LEFT) y = YSCREEN_LIMIT; if (CanMove(x,y)) { Vaz.x = x; Vaz.y = y; } // move the mouth Vaz.mouth++; if (Vaz.mouth > 5) Vaz.mouth = 0; } // end of long else // display BMP to back buffer SetRect(&temp_rect, Vaz.x, Vaz.y, Vaz.x + BLOCK_SIZE, Vaz.y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hvazbmp[Vaz.dir + Vaz.mouth], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); // display red circle for gun if (Vaz.gun) { c = Vaz.count; if (c > 80 || (c > 60 && c < 70) || (c > 40 && c < 50) || (c > 20 && c < 30) || (c > 0 && c < 10)) { IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hbulletbmp, &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); } } // end if gun } // END OF MoveVaz ////////////////////////////////////////////// // // set the ghosts (in jail) based on level # // ////////////////////////////////////////////// void SetGhosts() { int num_ghost; int i, c; ghost_feet = 0; ghost_delay = GHOST_PAUSE; num_ghost = 3; ghost_speed = 2; if (game_difficulty == DIFFICULTY_HARD) ghost_speed = 3; if (game_level > 2) num_ghost = 6; if (game_level > 5) num_ghost = 9; for (i = 0; i < num_ghost; i++) { Ghosts[i].alive = TRUE; if (i == 0) c = GHOST_BLUE; if (i == 1) c = GHOST_GREEN; if (i == 2) c = GHOST_RED; if (i == 3) c = GHOST_BLUE; if (i == 4) c = GHOST_GREEN; if (i == 5) c = GHOST_RED; if (i == 6) c = GHOST_BLUE; if (i == 7) c = GHOST_GREEN; if (i == 8) c = GHOST_RED; Ghosts[i].color = c; Ghosts[i].chase = CHASE_NORMAL; Ghosts[i].x = XMazeToXScreen(rand()%3 + 11); Ghosts[i].y = YMazeToYScreen(9); Ghosts[i].xm = ghost_speed; Ghosts[i].ym = 0; Ghosts[i].jailed = TRUE; Ghosts[i].count = (rand()%300)+10; } // end for } // END OF SetGhosts ////////////////////////////////////////////////////////////// // // move/update all the ghosts once // ////////////////////////////////////////////////////////////// void MoveGhosts() { int i; int x,y; // current x y int c,d; // color and direction int g; // ghost speed int xL,yL,xR,yR,xU,yU,xD,yD; // movement check left, right, up, down bool canL, canR, canU, canD; bool sound_power = FALSE; int r, r0; // rand for choose direction int vx, vy, jx, jy; // vaz x y and jail x y // check if level_countdown > 0, if so wait if (level_countdown > 0 || Vaz.state == VAZ_DYING) return; vx = Vaz.x; vy = Vaz.y; // save vaz position jx = XMazeToXScreen(12); jy = YMazeToYScreen(7); // save jail target for (i = 0; i < MAX_GHOSTS; i++) { if (!Ghosts[i].alive) continue; // for whether to sound power wav if (Ghosts[i].chase == CHASE_AWAY) sound_power = TRUE; x = Ghosts[i].x; y = Ghosts[i].y; g = ghost_speed; if (Ghosts[i].jailed) // check if jailed { Ghosts[i].count--; if (Ghosts[i].count == 0) // release from jail { Ghosts[i].jailed = FALSE; Ghosts[i].x = XMazeToXScreen(12); Ghosts[i].xm = 0; Ghosts[i].ym = -g; Ghosts[i].y += Ghosts[i].ym; } else // "bounce" back and forth { x += Ghosts[i].xm; if (CanMove(x,y)) Ghosts[i].x = x; // check if move okay, not into wall else Ghosts[i].xm = -Ghosts[i].xm; // reverse direction if against wall } // end else } // end if jailed else // not in jail { if (Ghosts[i].chase == CHASE_DEMONIC) { g = 3; if (game_difficulty == DIFFICULTY_HARD) g = 6; } // demonic is faster if (Ghosts[i].chase == CHASE_EYES) g = 10; // eyes is fastest if (Ghosts[i].chase == CHASE_AWAY) { g = 1; if (game_difficulty == DIFFICULTY_HARD) g = 2; } // slower run away xR = x + g; yR = y; // check x y right if (xR > XSCREEN_LIMIT) xR = XTOP_LEFT; // wrap around x canR = CanMove(xR,yR); xD = x; yD = y + g; // check x y down if (yD > YSCREEN_LIMIT) yD = YTOP_LEFT; // wrap around y canD = CanMove(xD,yD); // prevent going back to jail if (XScreenToXMaze(xD) == 12 && YScreenToYMaze(yD) == 8) canD = FALSE; xL = x - g; yL = y; // check x y left if (xL < XTOP_LEFT) xL = XSCREEN_LIMIT; // wrap around x canL = CanMove(xL,yL); xU = x; yU = y - g; // check x y up if (yU < YTOP_LEFT) yU = YSCREEN_LIMIT; // wrap around y canU = CanMove(xU,yU); // // GHOST A.I. // r = (rand()%10)+1; // rand for chase r0 = 1; // chance to not chase if (Ghosts[i].color == GHOST_GREEN) r0 = 2; if (Ghosts[i].color == GHOST_BLUE) r0 = 3; if (Ghosts[i].chase == CHASE_DEMONIC) r0 = 0; if (canL && canR && canU && canD) { if (Ghosts[i].chase == CHASE_AWAY) { // away from vaz r = rand()%2; // either left/right or up/down if (r == 0) // chase left or right { if (x < vx) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } else // chase up or down { if (y < vy) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_AWAY else if (r0 < r && Ghosts[i].chase == CHASE_EYES) { // toward jail r = rand()%2; // either left/right or up/down if (r == 0) // chase left or right { if (jx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } else // chase up or down { if (jy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_EYES else if (r0 < r && game_state == GAME_STATE_GAME_RUN) // CHASE_NORMAL/DEMONIC { // toward vaz r = rand()%2; // either left/right or up/down if (r == 0 && vx != x) // chase left or right { if (vx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } else // chase up or down { if (vy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end toward vaz else { // pick one of four directions r = rand()%4; if (r == 0) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } if (r == 1) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } if (r == 2) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } if (r == 3) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } else if (canL && canR && canU) { if (Ghosts[i].chase == CHASE_AWAY) { // away from vaz r = rand()%2; // either up or left/right if (r == 0 && y < vy) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { if (x < vx) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end if CHASE_AWAY else if (r0 < r && Ghosts[i].chase == CHASE_EYES) { // toward jail r = rand()%2; // either up or left/right if (r == 0 && jy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { if (jx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end if CHASE_EYES else if (r0 < r && game_state == GAME_STATE_GAME_RUN) // CHASE_NORMAL/DEMONIC { // toward vaz r = rand()%2; // either up or left/right if (r == 0 && vy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { if (vx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end toward vaz else { // pick one of three directions r = rand()%3; if (r == 0) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } if (r == 1) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } if (r == 2) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } } } else if (canL && canR && canD) { if (Ghosts[i].chase == CHASE_AWAY) { // away from vaz r = rand()%2; // either down or left/right if (r == 0 && vy < y) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } else { if (x < vx) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end if CHASE_AWAY else if (r0 < r && Ghosts[i].chase == CHASE_EYES) { // toward jail r = rand()%2; // either down or left/right if (r == 0 && y < jy) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } else { if (jx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end if CHASE_EYES else if (r0 < r && game_state == GAME_STATE_GAME_RUN) // CHASE_NORMAL/DEMONIC { // toward vaz r = rand()%2; // either down or left/right if (r == 0 && y < vy) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } else { if (vx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } // end toward vaz else { // pick one of three directions r = rand()%3; if (r == 0) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } if (r == 1) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } if (r == 2) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } else if (canU && canD && canL) { if (Ghosts[i].chase == CHASE_AWAY) { // away from vaz r = rand()%2; // either left or up/down if (r == 0 && x < vx) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { if (y < vy) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_AWAY else if (r0 < r && Ghosts[i].chase == CHASE_EYES) { // toward jail r = rand()%2; // either left or up/down if (r == 0 && jx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { if (jy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_EYES else if (r0 < r && game_state == GAME_STATE_GAME_RUN) // CHASE_NORMAL/DEMONIC { // toward vaz r = rand()%2; // either left or up/down if (r == 0 && vx < x) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { if (vy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end toward vaz else { // pick one of three directions r = rand()%3; if (r == 0) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } if (r == 1) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } if (r == 2) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } } } else if (canU && canD && canR) { if (Ghosts[i].chase == CHASE_AWAY) { // away from vaz r = rand()%2; // either right or up/down if (r == 0 && vx < x) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else { if (y < vy) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_AWAY else if (r0 < r && Ghosts[i].chase == CHASE_EYES) { // toward jail r = rand()%2; // either right or up/down if (r == 0 && x < jx) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else { if (jy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end if CHASE_EYES else if (r0 < r && game_state == GAME_STATE_GAME_RUN) // CHASE_NORMAL/DEMONIC { // toward vaz r = rand()%2; // either right or up/down if (r == 0 && x < vx) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else { if (vy < y) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } } // end toward vaz else { // pick one of three directions r = rand()%3; if (r == 0) { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } if (r == 1) { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } if (r == 2) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } } } else if (canL && canR) // continue left or right { if (Ghosts[i].xm > 0) { Ghosts[i].x = xR; } if (Ghosts[i].xm < 0) { Ghosts[i].x = xL; } } else if (canU && canD) // continue up or down { if (Ghosts[i].ym > 0) { Ghosts[i].y = yD; } if (Ghosts[i].ym < 0) { Ghosts[i].y = yU; } } else if (canL && canU) // go left or up { if (Ghosts[i].ym > 0) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } } else if (canR && canU) // go right or up { if (Ghosts[i].ym > 0) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } } else if (canL && canD) // go left or down { if (Ghosts[i].ym < 0) { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } else if (canR && canD) // go right or down { if (Ghosts[i].ym < 0) { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } } else if (canL) // go left { Ghosts[i].x = xL; Ghosts[i].xm = -g; Ghosts[i].ym = 0; } else if (canR) // go right { Ghosts[i].x = xR; Ghosts[i].xm = g; Ghosts[i].ym = 0; } else if (canU) // go up { Ghosts[i].y = yU; Ghosts[i].xm = 0; Ghosts[i].ym = -g; } else if (canD) // go down { Ghosts[i].y = yD; Ghosts[i].xm = 0; Ghosts[i].ym = g; } // insert random demonic if level > 2 if (game_level > 2) { r0 = 10000 - (game_level * 1000); if (r0 < 1000) r0 = 1000; r = rand()%r0; if (r < 2 && Ghosts[i].chase == CHASE_NORMAL) { Ghosts[i].chase = CHASE_DEMONIC; Ghosts[i].count = (rand()%500)+100; // adjust ghost pixel position // required so ghost doesn't get "stuck" Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(Ghosts[i].x)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(Ghosts[i].y)); InsertParticles(Ghosts[i].x + 15, Ghosts[i].y + 15, 2); if (sound_ok && game_state == GAME_STATE_GAME_RUN) IDirectSoundBuffer_Play(game_sound_happy,0,0,NULL); } } } // end of else not in jail c = Ghosts[i].color; if (Ghosts[i].chase == CHASE_AWAY) { // "blink" the ghost when near end if ((Ghosts[i].count > 60) || (Ghosts[i].count > 40 && Ghosts[i].count < 50) || (Ghosts[i].count > 20 && Ghosts[i].count < 30) || (Ghosts[i].count > 0 && Ghosts[i].count < 10)) c = GHOST_SCARED; // check time count to change back Ghosts[i].count--; if (Ghosts[i].count == 0) { Ghosts[i].chase = CHASE_NORMAL; // adjust ghost pixel position // required so ghost doesn't get "stuck" Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(Ghosts[i].x)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(Ghosts[i].y)); InsertParticles(Ghosts[i].x + 15, Ghosts[i].y + 15, 1); } } if (Ghosts[i].chase == CHASE_DEMONIC) { c = GHOST_DEMONIC; // check time count to change back Ghosts[i].count--; if (Ghosts[i].count == 0) { Ghosts[i].chase = CHASE_NORMAL; // adjust ghost pixel position // required so ghost doesn't get "stuck" Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(Ghosts[i].x)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(Ghosts[i].y)); InsertParticles(Ghosts[i].x + 15, Ghosts[i].y + 15, 2); } } if (Ghosts[i].chase == CHASE_EYES) { c = GHOST_EYES; // check if reached jail target to change back if (XScreenToXMaze(Ghosts[i].x) == 12 && YScreenToYMaze(Ghosts[i].y) == 7) { Ghosts[i].chase = CHASE_NORMAL; Ghosts[i].x = XMazeToXScreen(12); Ghosts[i].y = YMazeToYScreen(9); Ghosts[i].xm = ghost_speed; Ghosts[i].ym = 0; Ghosts[i].jailed = TRUE; Ghosts[i].count = (rand()%300)+10; if (sound_ok) IDirectSoundBuffer_Stop(game_sound_ghosteyes); } } if (Ghosts[i].xm > 0) d = DIRECTION_RIGHT; if (Ghosts[i].ym > 0) d = DIRECTION_DOWN; if (Ghosts[i].xm < 0) d = DIRECTION_LEFT; if (Ghosts[i].ym < 0) d = DIRECTION_UP; SetRect(&temp_rect, Ghosts[i].x, Ghosts[i].y, Ghosts[i].x + BLOCK_SIZE, Ghosts[i].y + BLOCK_SIZE); if (Ghosts[i].chase == CHASE_EYES) IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hghostbmp[c + d], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); else IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hghostbmp[c + d + ghost_feet], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); } // end of for loop // stop power pill repeat sound if no ghosts are CHASE_AWAY if (!sound_power && sound_ok) IDirectSoundBuffer_Stop(game_sound_power); // switch the feet ghost_delay--; if (ghost_delay == 0) { ghost_feet += 4; if (ghost_feet > 4) ghost_feet = 0; ghost_delay = GHOST_PAUSE; } } // END OF MoveGhosts ///////////////////////////////////////////////////////// // // insert a new food item or gun based on level # // ///////////////////////////////////////////////////////// void InsertFood() { int i; int r; for (i = 0; i < MAX_FOOD; i++) { if (!Food[i].alive) // insert new food item here { Food[i].alive = TRUE; Food[i].x = XMazeToXScreen(12); Food[i].y = YMazeToYScreen(11); Food[i].count = (rand()%2000)+1000; Food[i].ym = 0; r = rand()%2; if (r == 0) Food[i].xm = 1; if (r == 1) Food[i].xm = -1; Food[i].type = rand()%6; if (game_level > 2 && game_level < 6) { r = rand()%3; // 1 in 3 chance for gun if (r == 0) Food[i].type = 11; else Food[i].type = rand()%12; } if (game_level > 5) { r = rand()%4; // 2 in 4 chance for gun if (r == 0) Food[i].type = 11; else if (r == 1) Food[i].type = 12; else Food[i].type = rand()%20; } InsertParticles(Food[i].x + 15, Food[i].y + 15, 3); return; } // end if } // end for } // END OF InsertFood ///////////////////////////////////////////////////////// // // move/update all existing food once // ///////////////////////////////////////////////////////// void MoveFood() { int i; int r, r0; int x,y; int g = 1; int xL, yL, xR, yR, xU, yU, xD, yD; bool canL, canR, canU, canD; if (level_countdown > 0 || Vaz.state == VAZ_DYING) return; if (game_difficulty == DIFFICULTY_HARD) g = 2; // check to insert new random food item r0 = 10000 - (game_level * 1000); if (r0 < 1000) r0 = 1000; r = rand()%r0; if (r < 4) InsertFood(); for (i = 0; i < MAX_FOOD; i++) { if (!Food[i].alive) continue; x = Food[i].x; y = Food[i].y; xR = x + g; yR = y; // check x y right if (xR > XSCREEN_LIMIT) xR = XTOP_LEFT; // wrap around x canR = CanMove(xR,yR); xD = x; yD = y + g; // check x y down if (yD > YSCREEN_LIMIT) yD = YTOP_LEFT; // wrap around y canD = CanMove(xD,yD); // prevent going to jail if (XScreenToXMaze(xD) == 12 && YScreenToYMaze(yD) == 8) canD = FALSE; xL = x - g; yL = y; // check x y left if (xL < XTOP_LEFT) xL = XSCREEN_LIMIT; // wrap around x canL = CanMove(xL,yL); xU = x; yU = y - g; // check x y up if (yU < YTOP_LEFT) yU = YSCREEN_LIMIT; // wrap around y canU = CanMove(xU,yU); // check for all possible moves and make random move if (canL && canR && canU && canD) { // pick one of four directions r = rand()%4; if (r == 0) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } if (r == 1) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } if (r == 2) { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } if (r == 3) { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } } else if (canL && canR && canU) { // pick one of three directions r = rand()%3; if (r == 0) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } if (r == 1) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } if (r == 2) { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } } else if (canL && canR && canD) { // pick one of three directions r = rand()%3; if (r == 0) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } if (r == 1) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } if (r == 2) { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } } else if (canU && canD && canL) { // pick one of three directions r = rand()%3; if (r == 0) { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } if (r == 1) { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } if (r == 2) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } } else if (canU && canD && canR) { // pick one of three directions r = rand()%3; if (r == 0) { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } if (r == 1) { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } if (r == 2) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } } else if (canL && canR) // continue left or right { if (Food[i].xm > 0) { Food[i].x = xR; } if (Food[i].xm < 0) { Food[i].x = xL; } } else if (canU && canD) // continue up or down { if (Food[i].ym > 0) { Food[i].y = yD; } if (Food[i].ym < 0) { Food[i].y = yU; } } else if (canL && canU) // go left or up { if (Food[i].ym > 0) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } else { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } } else if (canR && canU) // go right or up { if (Food[i].ym > 0) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } else { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } } else if (canL && canD) // go left or down { if (Food[i].ym < 0) { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } else { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } } else if (canR && canD) // go right or down { if (Food[i].ym < 0) { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } else { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } } else if (canL) // go left { Food[i].x = xL; Food[i].xm = -g; Food[i].ym = 0; } else if (canR) // go right { Food[i].x = xR; Food[i].xm = g; Food[i].ym = 0; } else if (canU) // go up { Food[i].y = yU; Food[i].xm = 0; Food[i].ym = -g; } else if (canD) // go down { Food[i].y = yD; Food[i].xm = 0; Food[i].ym = g; } SetRect(&temp_rect, Food[i].x, Food[i].y, Food[i].x + BLOCK_SIZE, Food[i].y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hfoodbmp[Food[i].type], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); Food[i].count--; if (Food[i].count == 0) { Food[i].alive = FALSE; InsertParticles(Food[i].x + 15, Food[i].y + 15, 3); } } // end for } // END OF MoveFood /////////////////////////////////////////////////////////// // // insert one bullet // /////////////////////////////////////////////////////////// void InsertBullet() { int i; // check for pause time between bullets if (bullet_countdown > 0) return; for (i = 0; i < MAX_BULLETS; i++) { if (!Bullets[i].alive) // insert new bullet here { Bullets[i].alive = TRUE; Bullets[i].x = Vaz.x; Bullets[i].y = Vaz.y; Bullets[i].count = BULLET_DURATION; if (Vaz.dir == VAZ_RIGHT) { Bullets[i].xm = BULLET_SPEED; Bullets[i].ym = 0; } if (Vaz.dir == VAZ_LEFT) { Bullets[i].xm = -BULLET_SPEED; Bullets[i].ym = 0; } if (Vaz.dir == VAZ_DOWN) { Bullets[i].xm = 0; Bullets[i].ym = BULLET_SPEED; } if (Vaz.dir == VAZ_UP) { Bullets[i].xm = 0; Bullets[i].ym = -BULLET_SPEED; } bullet_countdown = BULLET_PAUSE; if (sound_ok) IDirectSoundBuffer_Play(game_sound_fire,0,0,NULL); return; } // end if not alive } // end for } // END OF InsertBullet ///////////////////////////////////////////////////////// // // move/update all existing bullets once // ///////////////////////////////////////////////////////// void MoveBullets() { int i; int x,y; for (i = 0; i < MAX_BULLETS; i++) { if (Bullets[i].alive) { x = Bullets[i].x + Bullets[i].xm; y = Bullets[i].y + Bullets[i].ym; if (x > XSCREEN_LIMIT) x = XTOP_LEFT; // wrap around x else if (x < XTOP_LEFT) x = XSCREEN_LIMIT; if (y > YSCREEN_LIMIT) y = YTOP_LEFT; // wrap around y else if (y < YTOP_LEFT) y = YSCREEN_LIMIT; if (CanMove(x,y)) // check if bullet hit any wall { // not hit wall, draw in new position SetRect(&temp_rect, x, y, x + BLOCK_SIZE, y + BLOCK_SIZE); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hbulletbmp, &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); // save new bullet position Bullets[i].x = x; Bullets[i].y = y; Bullets[i].count--; if (Bullets[i].count == 0) Bullets[i].alive = FALSE; } else // yes hit wall, do small explosion { InsertParticles(x+15, y+15, 1); Bullets[i].alive = FALSE; } } // end if alive } // end for if (bullet_countdown > 0) bullet_countdown--; } // END OF MoveBullets ///////////////////////////////////////////////////////// // // insert an extra score at x,y of amount a // ///////////////////////////////////////////////////////// void InsertScore(int x, int y, int a) { int i; for (i = 0; i < MAX_SCORES; i++) { if (!Scores[i].alive) { Scores[i].alive = TRUE; Scores[i].amount = a; Scores[i].x = x; Scores[i].y = y; Scores[i].count = 100; return; } } // end for } // END OF InsertScore ///////////////////////////////////////////////////////// // // draw/refresh each existing score once // ///////////////////////////////////////////////////////// void DrawScores() { int i; HDC temp_dc; for (i = 0; i < MAX_SCORES; i++) { if (Scores[i].alive) { IDirectDrawSurface_GetDC(game_draw_back, &temp_dc); // get temp GDI device context SetTextColor(temp_dc, RGB(255,255,255)); // white color SetBkColor(temp_dc, RGB(0,0,0)); // black back sprintf(text,"%d", Scores[i].amount); // print the amount TextOut(temp_dc, Scores[i].x, Scores[i].y, text, strlen(text)); IDirectDrawSurface_ReleaseDC(game_draw_back, temp_dc); // release temp device context // display for a short time Scores[i].count--; if (Scores[i].count == 0) Scores[i].alive = FALSE; } } // end for } // END OF DrawScores //////////////////////////////////////////////////////////////// // // Insert Particles for explosion at point x,y of type t // (if t = 1 then small, 2 = larger explosion, 3 = largest, etc) // //////////////////////////////////////////////////////////////// void InsertParticles(int x, int y, int t) { int i, p, a, d, inserted; float xc, yc, v; xc = (float)x; yc = (float)y; p = t * 20; // get how many particles to insert inserted = 0; // reset how many inserted to zero for (i = 0; i < MAX_PARTICLES; i++) { if (!Particles[i].alive) // particle space is free -- insert here { Particles[i].alive = TRUE; Particles[i].x = xc; Particles[i].y = yc; a = rand()%32; // get random angle 0 to 31 v = (float)(rand()%5 + 2); // get random velocity d = (rand()%8 + 5) * t; // get random duration Particles[i].xm = xdir[a] * v; Particles[i].ym = ydir[a] * v; Particles[i].duration = d; inserted++; if (inserted == p) return; } // end of if particle free } // end of for particles } // END OF InsertParticles ///////////////////////////////////////////////////////// // // move all existing particles once // ///////////////////////////////////////////////////////// void MoveParticles() { int i, xi, yi; float x, y; // lock the primary surface IDirectDrawSurface_Lock(game_draw_back, NULL, &game_draw_desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); // get the pitch and set up video memory int pitch16 = (int)(game_draw_desc.lPitch >> 1); USHORT *video_memory = (USHORT *)game_draw_desc.lpSurface; for (i = 0; i < MAX_PARTICLES; i++) { if (Particles[i].alive) { x = Particles[i].x; y = Particles[i].y; // save particle x y x += Particles[i].xm; y += Particles[i].ym; // move particle if (x < 3) x = WINDOW_WIDTH - 3; else if (x > (WINDOW_WIDTH - 3)) x = 3; if (y < 3) y = WINDOW_HEIGHT - 3; else if (y > (WINDOW_HEIGHT - 3)) y = 3; Particles[i].x = x; Particles[i].y = y; xi = (int)x; yi = (int)y; // plot a white pixel at video memory point xi, yi video_memory[xi + yi * pitch16] = white_pixel; Particles[i].duration--; // check if duration over if (Particles[i].duration == 0) Particles[i].alive = FALSE; } // end of if } // end of for // unlock the primary surface IDirectDrawSurface_Unlock(game_draw_back, NULL); } // END OF MoveParticles /////////////////////////////////////////////////////// // // Initialize DirectSound and individual sound buffers // /////////////////////////////////////////////////////// bool SoundInit() { if (DirectSoundCreate(NULL, &game_sound_main, NULL) != DS_OK) { MessageBox(game_window, "Sound could not be initialized -- Direct Sound Create Error","Sound Error",MB_OK); return FALSE; } // // Direct Sound object succeeded so set coop level // if (IDirectSound_SetCooperativeLevel(game_sound_main, game_window, DSSCL_PRIORITY) != DS_OK) { MessageBox(game_window, "Sound could not be initialized -- Cooperative Level Error","Sound Error",MB_OK); return FALSE; } // // Cooperative Level succeeded so set up // secondary buffers and load wave file sound resources // game_sound_death1 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_DEATH1)); game_sound_death2 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_DEATH2)); game_sound_eat1 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT1)); game_sound_eat2 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT2)); game_sound_eat3 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT3)); game_sound_eat4 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT4)); game_sound_eat5 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT5)); game_sound_eat6 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT6)); game_sound_eat7 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT7)); game_sound_eat8 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EAT8)); game_sound_extra = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_EXTRA)); game_sound_fire = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_FIRE)); game_sound_ghosteat = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_GHOSTEAT)); game_sound_ghosteyes = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_GHOSTEYES)); game_sound_happy = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_HAPPY)); game_sound_hurl = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_HURL)); game_sound_interm1 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_INTERM1)); game_sound_interm2 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_INTERM2)); game_sound_interm3 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_INTERM3)); game_sound_interm4 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_INTERM4)); game_sound_munch = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_MUNCH)); game_sound_open1 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_OPEN1)); game_sound_open2 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_OPEN2)); game_sound_power = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_POWER)); game_sound_siren1 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_SIREN1)); game_sound_siren2 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_SIREN2)); game_sound_siren3 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_SIREN3)); game_sound_siren4 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_SIREN4)); game_sound_siren5 = DSLoadSoundBuffer(game_sound_main, MAKEINTRESOURCE(SOUND_SIREN5)); // return TRUE since main DirectSound initialized ok return TRUE; } // END OF SoundInit ////////////////////////////////////////////////////// // // Stop all sounds and close DirectSound and buffers // ///////////////////////////////////////////////////// void SoundQuit() { // if sound was set okay, release DirectSound objects if (game_sound_main) { // FIRST RELEASE SECONDARY BUFFERS IDirectSound_Release(game_sound_death1); IDirectSound_Release(game_sound_death2); IDirectSound_Release(game_sound_eat1); IDirectSound_Release(game_sound_eat2); IDirectSound_Release(game_sound_eat3); IDirectSound_Release(game_sound_eat4); IDirectSound_Release(game_sound_eat5); IDirectSound_Release(game_sound_eat6); IDirectSound_Release(game_sound_eat7); IDirectSound_Release(game_sound_eat8); IDirectSound_Release(game_sound_extra); IDirectSound_Release(game_sound_fire); IDirectSound_Release(game_sound_ghosteat); IDirectSound_Release(game_sound_ghosteyes); IDirectSound_Release(game_sound_happy); IDirectSound_Release(game_sound_hurl); IDirectSound_Release(game_sound_interm1); IDirectSound_Release(game_sound_interm2); IDirectSound_Release(game_sound_interm3); IDirectSound_Release(game_sound_interm4); IDirectSound_Release(game_sound_munch); IDirectSound_Release(game_sound_open1); IDirectSound_Release(game_sound_open2); IDirectSound_Release(game_sound_power); IDirectSound_Release(game_sound_siren1); IDirectSound_Release(game_sound_siren2); IDirectSound_Release(game_sound_siren3); IDirectSound_Release(game_sound_siren4); IDirectSound_Release(game_sound_siren5); // THEN RELEASE MAIN DIRECT SOUND OBJECT IDirectSound_Release(game_sound_main); } } // END OF SoundQuit /////////////////////////////////////////// // // set up intermission animation // /////////////////////////////////////////// void SetInterm() { } // END OF SetInterm ////////////////////////////////////////////// // // update intermission animation // ////////////////////////////////////////////// bool AnimInterm() { return TRUE; } // END OF AnimInterm ////////////////////////////////////////////// // // flash/update all the power pills once // ////////////////////////////////////////////// void FlashPower() { int i; int c; int x,y; for (i = 0; i < MAX_POWER; i++) { if (Power[i].alive) { c = Power[i].count; x = Power[i].x; y = Power[i].y; SetRect(&temp_rect, x - 15, y - 15, x + 15, y + 15); IDirectDrawSurface_Blt(game_draw_back, &temp_rect, hflashbmp[c], &bmp_rect, DDBLT_WAIT | DDBLT_KEYSRC, NULL); c--; if (c < 0) c = 5; // reset power pellet count Power[i].count = c; } // end if } // end for } // END OF FlashPower ////////////////////////////////////////////// // // Check ALL potential collisions // ////////////////////////////////////////////// void CheckCollisions() { int i,j; // for loops int c,r; // col and row check int cp,rp; // used to find power pill at x y int x,y; // screen pixel position for Vaz int x0,y0; // screen for food and ghosts int xb,yb; // screen for bullet int t,m,a; // time count, maze symbol, score amount if (level_countdown > 0 || Vaz.state == VAZ_DYING) return; x = Vaz.x + 15; y = Vaz.y + 15; // save Vaz x,y center c = XScreenToXMaze(x); r = YScreenToYMaze(y); // get Vaz col and row m = Maze[r][c]; // get the maze symbol if (m == MAZE_PELLET) // check Vaz to pellets { pellets_left--; game_score += SCORE_PELLET; Maze[r][c] = MAZE_BLANK; // clear pellet from maze // PLAY MUNCH SOUND HERE AND DETERMINE SIREN if (sound_ok) { IDirectSoundBuffer_Play(game_sound_munch,0,0,NULL); if (pellets_left < 176 && pellets_left > 125) { IDirectSoundBuffer_Stop(game_sound_siren1); IDirectSoundBuffer_Play(game_sound_siren2,0,0,DSBPLAY_LOOPING); } if (pellets_left < 126 && pellets_left > 75) { IDirectSoundBuffer_Stop(game_sound_siren2); IDirectSoundBuffer_Play(game_sound_siren3,0,0,DSBPLAY_LOOPING); } if (pellets_left < 76 && pellets_left > 25) { IDirectSoundBuffer_Stop(game_sound_siren3); IDirectSoundBuffer_Play(game_sound_siren4,0,0,DSBPLAY_LOOPING); } if (pellets_left < 26) { IDirectSoundBuffer_Stop(game_sound_siren4); IDirectSoundBuffer_Play(game_sound_siren5,0,0,DSBPLAY_LOOPING); } } // end if sound_ok } // end if MAZE_PELLET if (m == MAZE_POWER) // check Vaz to power pills { pellets_left--; game_score += SCORE_POWER; chomp_score = SCORE_GHOST; Maze[r][c] = MAZE_BLANK; // clear power pill from maze // also find and clear power pill from array for (i = 0; i < MAX_POWER; i++) { if (Power[i].alive) { cp = XScreenToXMaze(Power[i].x); rp = YScreenToYMaze(Power[i].y); if (cp == c && rp == r) Power[i].alive = FALSE; } } // end for // change all ghosts not in jail to CHASE_AWAY (running scared) for (i = 0; i < MAX_GHOSTS; i++) { if (Ghosts[i].alive && Ghosts[i].chase != CHASE_EYES && !Ghosts[i].jailed) { Ghosts[i].chase = CHASE_AWAY; t = 650 - (game_level * 50); if (t < 200) t = 200; Ghosts[i].count = t; // adjust ghost pixel position // required so ghost doesn't get "stuck" Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(Ghosts[i].x)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(Ghosts[i].y)); InsertParticles(Ghosts[i].x + 15, Ghosts[i].y + 15, 1); } } // end for // PLAY EAT POWER PILL REPEAT SOUND if (sound_ok) IDirectSoundBuffer_Play(game_sound_power,0,0,DSBPLAY_LOOPING); } // end if MAZE_POWER if (pellets_left == 0) game_state = GAME_STATE_GAME_RESET; // CHECK ALL FOOD TO VAZ for (i = 0; i < MAX_FOOD; i++) { if (Food[i].alive) { x0 = Food[i].x; y0 = Food[i].y; if (x > x0 && x < x0+30 && y > y0 && y < y0+30) { // Vaz touches food or gun item Food[i].alive = FALSE; // remove food t = Food[i].type; // get the food type if (t < 6) a = SCORE_FOOD; // fruits if (t > 5 && t < 11) a = SCORE_FOOD * 3; // veggies if (t > 10 && t < 13) // guns { a = SCORE_FOOD * 5; Vaz.gun = TRUE; Vaz.count = GUN_DURATION; bullet_countdown = 0; } if (t > 12 && t < 18) a = SCORE_FOOD * 7; // flowers/bugs if (t > 17) a = SCORE_FOOD * 10; // deserts InsertScore(x0+8, y0+10, a); game_score += a; // PLAY FOOD/GOT GUN SOUND OR RANDOM EAT SOUND if (sound_ok) { if (game_level < 3) IDirectSoundBuffer_Play(game_sound_eat1,0,0,NULL); else { r = rand()%20; if (r < 12) IDirectSoundBuffer_Play(game_sound_eat1,0,0,NULL); if (r == 12) IDirectSoundBuffer_Play(game_sound_eat2,0,0,NULL); if (r == 13) IDirectSoundBuffer_Play(game_sound_eat3,0,0,NULL); if (r == 14) IDirectSoundBuffer_Play(game_sound_eat4,0,0,NULL); if (r == 15) IDirectSoundBuffer_Play(game_sound_eat5,0,0,NULL); if (r == 16) IDirectSoundBuffer_Play(game_sound_eat6,0,0,NULL); if (r == 17) IDirectSoundBuffer_Play(game_sound_eat7,0,0,NULL); if (r == 18) IDirectSoundBuffer_Play(game_sound_eat8,0,0,NULL); if (r == 19) IDirectSoundBuffer_Play(game_sound_hurl,0,0,NULL); } } // end if sound_ok } // end if food collision } // end if food alive } // end for food /////////////////////////////////////////////////////// // // CHECK ALL BULLETS TO GHOSTS AND ALL GHOSTS TO VAZ // /////////////////////////////////////////////////////// for (i = 0; i < MAX_GHOSTS; i++) { if (Ghosts[i].alive && !Ghosts[i].jailed) { x0 = Ghosts[i].x; y0 = Ghosts[i].y; for (j = 0; j < MAX_BULLETS; j++) { if (Bullets[j].alive && Ghosts[i].chase != CHASE_EYES) { // save bullet position and compare with current ghost xb = Bullets[j].x + 15; yb = Bullets[j].y + 15; if (xb > x0 && xb < x0+30 && yb > y0 && yb < y0+30) { // bullet hit a ghost! Bullets[j].alive = FALSE; // clear bullet Ghosts[i].chase = CHASE_EYES; // change ghost chase status // add and display score, add particle explosion game_score += SCORE_GHOST; InsertScore(x0+8, y0+10, SCORE_GHOST); InsertParticles(x0+15, y0+15, 2); // adjust ghost position so ghost doesn't get stuck Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(x0)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(y0)); } // end if bullet hit ghost } // end if bullet alive } // end for bullets /////////////////////////////////////////////////// // // CHECK GHOST TO VAZ POSITION, EITHER EAT OR DIE // /////////////////////////////////////////////////// if (x > x0 && x < x0+30 && y > y0 && y < y0+30) { if (Ghosts[i].chase == CHASE_NORMAL || Ghosts[i].chase == CHASE_DEMONIC) { // Vaz dead! Vaz.state = VAZ_DYING; Vaz.count = 100; if (sound_ok) // STOP ANY LOOPING SOUNDS { IDirectSoundBuffer_Stop(game_sound_power); IDirectSoundBuffer_Stop(game_sound_ghosteyes); IDirectSoundBuffer_Stop(game_sound_siren1); IDirectSoundBuffer_Stop(game_sound_siren2); IDirectSoundBuffer_Stop(game_sound_siren3); IDirectSoundBuffer_Stop(game_sound_siren4); IDirectSoundBuffer_Stop(game_sound_siren5); } } if (Ghosts[i].chase == CHASE_AWAY) { // Vaz eat ghost! game_score += chomp_score; InsertScore(x0+8, y0+10, chomp_score); chomp_score *= 2; Ghosts[i].chase = CHASE_EYES; // adjust ghost position so ghost doesn't get stuck Ghosts[i].x = XMazeToXScreen(XScreenToXMaze(x0)); Ghosts[i].y = YMazeToYScreen(YScreenToYMaze(y0)); if (sound_ok) // play ghost eat once and ghost eyes repeating { IDirectSoundBuffer_Play(game_sound_ghosteat,0,0,NULL); IDirectSoundBuffer_Play(game_sound_ghosteyes,0,0,DSBPLAY_LOOPING); } } } // end if ghost collide with Vaz } // end if ghost alive } // end for ghosts // after all collisions see if game_score reached extra_score for extra Vaz if (game_score >= extra_score) { vaz_left++; extra_score += SCORE_EXTRA; if (sound_ok) IDirectSoundBuffer_Play(game_sound_extra,0,0,NULL); } } // END OF CheckCollisions ///////////////////////////////////////////////////////////////////////// // // Reset (initialize/clear) all ghosts, food, bullets, scores, particles // ///////////////////////////////////////////////////////////////////////// void ResetAll() { int i; for (i = 0; i < MAX_GHOSTS; i++) Ghosts[i].alive = FALSE; for (i = 0; i < MAX_FOOD; i++) Food[i].alive = FALSE; for (i = 0; i < MAX_BULLETS; i++) Bullets[i].alive = FALSE; for (i = 0; i < MAX_SCORES; i++) Scores[i].alive = FALSE; for (i = 0; i < MAX_PARTICLES; i++) Particles[i].alive = FALSE; for (i = 0; i < MAX_POWER; i++) Power[i].alive = FALSE; } // END OF ResetAll // convert maze column to X pixel position int XMazeToXScreen(int c) { return (c * BLOCK_SIZE) + XTOP_LEFT; } // convert maze row to Y pixel position int YMazeToYScreen(int r) { return (r * BLOCK_SIZE) + YTOP_LEFT; } // convert X pixel position to maze column int XScreenToXMaze(int x) { return (x - XTOP_LEFT) / BLOCK_SIZE; } // convert Y pixel position to maze row int YScreenToYMaze(int y) { return (y - YTOP_LEFT) / BLOCK_SIZE; } // // check if valid move at x,y (not inside wall) // bool CanMove(int x, int y) { int c1,r1,c2,r2,c3,r3,c4,r4; // maze object row and column corners c1 = XScreenToXMaze(x); r1 = YScreenToYMaze(y); c2 = XScreenToXMaze(x + BLOCK_SIZE - 1); r2 = YScreenToYMaze(y); c3 = XScreenToXMaze(x); r3 = YScreenToYMaze(y + BLOCK_SIZE - 1); c4 = XScreenToXMaze(x + BLOCK_SIZE - 1); r4 = YScreenToYMaze(y + BLOCK_SIZE - 1); if ((Maze[r1][c1] > 2) || (Maze[r2][c2] > 2) || (Maze[r3][c3] > 2) || (Maze[r4][c4] > 2)) return FALSE; // collision with wall, do not allow else return TRUE; // no collision, proceed } // END OF CanMove // JOYSTICK SUPPORT ADDED 10/1/2004 bool JoyInit() { // clear joystick status joy_left = 0; joy_right = 0; joy_up = 0; joy_down = 0; joy_but1 = 0; joy_but2 = 0; joy_but3 = 0; joy_but4 = 0; // make sure joystick driver is present if ((joy_num = joyGetNumDevs()) == 0) return FALSE; // make sure the joystick is attached if (joyGetPos(JOYSTICKID1, &joy_info) != JOYERR_UNPLUGGED) joy_ID = JOYSTICKID1; else return FALSE; // calculate the trip values joyGetDevCaps(joy_ID, &joy_caps, sizeof(JOYCAPS)); joy_xcenter = ((DWORD)joy_caps.wXmin + joy_caps.wXmax) / 2; joy_ycenter = ((DWORD)joy_caps.wYmin + joy_caps.wYmax) / 2; joy_trip.left = (joy_caps.wXmin + (WORD)joy_xcenter) / 2; joy_trip.right = (joy_caps.wXmax + (WORD)joy_xcenter) / 2; joy_trip.top = (joy_caps.wYmin + (WORD)joy_ycenter) / 2; joy_trip.bottom = (joy_caps.wYmax + (WORD)joy_ycenter) / 2; // capture the joystick joySetCapture(game_window, joy_ID, NULL, TRUE); return TRUE; } void JoyQuit() { // release joystick if (joy_ok) joyReleaseCapture(joy_ID); } void JoyStatus() { if (joy_ok && joyGetPos(joy_ID, &joy_info) == JOYERR_NOERROR) { // if we have no errors check the joystick position // check horizontal movement joy_left = 0; joy_right = 0; if (joy_info.wXpos < (WORD)joy_trip.left) joy_left = 1; else if (joy_info.wXpos > (WORD)joy_trip.right) joy_right = 1; // check vertical movement joy_up = 0; joy_down = 0; if (joy_info.wYpos < (WORD)joy_trip.top) joy_up = 1; else if (joy_info.wYpos > (WORD)joy_trip.bottom) joy_down = 1; // check four buttons joy_but1 = 0; joy_but2 = 0; joy_but3 = 0; joy_but4 = 0; if (joy_info.wButtons & JOY_BUTTON1) joy_but1 = 1; if (joy_info.wButtons & JOY_BUTTON2) joy_but2 = 1; if (joy_info.wButtons & JOY_BUTTON3) joy_but3 = 1; if (joy_info.wButtons & JOY_BUTTON4) joy_but4 = 1; } // end of if joy_ok AND NOERROR } // END GAME CODE ///////////////////////////////////////////////////////////////