void CSpaceInvadersAppUi::ChangeView(CCoeControl* aView)
{
	RemoveFromStack( iCurrentView );
	
	iCurrentView->MakeVisible(EFalse);
	iCurrentView = aView;
	iCurrentView->MakeVisible(ETrue);
	AddToStackL( iCurrentView );
	
	if ( aView == iAppView )
	{
		InitShip();
		iAppView->StartTimerL();
		iAudioPlayer->PlayMySampleL();
	}
	else if ( aView == iHighscoreView )
	{
		iHighscoreHolder->UpdatePoints();
	}
	
	iCurrentView->DrawNow();
}
Esempio n. 2
0
int main(void)
{
	// primitive variables
	bool done = false; // for game loop
	bool redraw = true;  // for redraw. 
	const int FPS = 60;  // Frames Per Second
	bool isGameOver = false; 
	// initialize
	// object variables
	SpaceShip ship, ship2;
	Bullet bullet[NUM_BULLETS]; 
	Bullet bullet2[NUM_BULLETS]; 
	// Initialize 
	ALLEGRO_DISPLAY *display = NULL; 
	ALLEGRO_EVENT_QUEUE *event_queue = NULL ;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL; 
	ALLEGRO_BITMAP *image1 = NULL , *image2 = NULL; 
	if(!al_init()) return -1; 
	display = al_create_display(WIDTH, HEIGHT); 
		if(!display) return -1; 

	// initializing primitives (for drawing ship) 
	al_init_primitives_addon(); 
	al_install_keyboard(); 
	al_init_font_addon();
	al_init_ttf_addon(); 
	al_init_image_addon(); 
	event_queue = al_create_event_queue(); 
	timer = al_create_timer(1.0/FPS); 
	// initialize objects
	srand(time(NULL)); // sees number generator with current time. 
						// as time changes, the random number changes too. 
	InitShip(ship); 
	InitShip2(ship2); 
	InitBullet(bullet, NUM_BULLETS); // array of bullets for ship
	InitBullet(bullet2, NUM_BULLETS); // array of bullets for ship2
	font18 = al_load_font("Arial.ttf", 18, 0); 
	image1 = al_load_bitmap("Ship1.bmp"); 
	image2 = al_load_bitmap("Ship2.bmp"); 
	// register keyboard. 
	al_register_event_source(event_queue, al_get_keyboard_event_source()); 
	al_register_event_source(event_queue, al_get_timer_event_source(timer)); 
	al_register_event_source(event_queue, al_get_display_event_source(display)); 
	// START TIMER
	al_start_timer(timer); 
	while(!done)
	{
		ALLEGRO_EVENT ev; 
		// wait for event to come in from queue. 
		al_wait_for_event(event_queue, &ev); 
		// only happens once every 60 seconds max. 
		if (ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true; 
			// update the position of the ship, depending if the keys are pressed. 
			if(keys[UP]) MoveShipUp(ship2);
			if(keys[DOWN]) MoveShipDown(ship2);
			if(keys[LEFT]) MoveShip2Left(ship2);
			if(keys[RIGHT]) MoveShip2Right(ship2);
			if(keys[W]) MoveShipUp(ship);
			if(keys[S]) MoveShipDown(ship);
			if(keys[A]) MoveShipLeft(ship);
			if(keys[D]) MoveShipRight(ship);

			if(!isGameOver)
			{
				UpdateBullet(bullet, NUM_BULLETS);  // update the position of the bullet
				UpdateBullet2(bullet2, NUM_BULLETS); 
				// test if all the objects collide after all the objects move. 
				CollideBullet(bullet, NUM_BULLETS, ship2, ship); 
				CollideBullet2(bullet2, NUM_BULLETS, ship, ship2); 
				if(ship.lives <= 0 || ship2.lives <=0) isGameOver = true; 
			}
		}
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) done = true; 
		else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true; 
				FireBullet2(bullet2, NUM_BULLETS, ship2); // break to fire one bullet only
				break; 
			case ALLEGRO_KEY_W:
				keys[W] = true;
				break;
			case ALLEGRO_KEY_A:
				keys[A] = true;
				break;
			case ALLEGRO_KEY_S:
				keys[S] = true;
				break;
			case ALLEGRO_KEY_D:
				keys[D] = true;
				break;
			case ALLEGRO_KEY_E:
				keys[E] = true; 
				FireBullet(bullet, NUM_BULLETS, ship); // break to fire one bullet only
				break; 
			}
		}

		else if(ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch(ev.keyboard.keycode)
			{
				case ALLEGRO_KEY_ESCAPE:
					done = true;
					break;
				case ALLEGRO_KEY_UP:
					keys[UP] = false;
					break;
				case ALLEGRO_KEY_DOWN:
					keys[DOWN] = false;
					break;
				case ALLEGRO_KEY_LEFT:
					keys[LEFT] = false;
					break;
				case ALLEGRO_KEY_RIGHT:
					keys[RIGHT] = false;
					break;
				case ALLEGRO_KEY_SPACE:
					keys[SPACE] = false; 
					break; 
				case ALLEGRO_KEY_W:
					keys[W] = false;
					break;
				case ALLEGRO_KEY_A:
					keys[A] = false;
					break;
				case ALLEGRO_KEY_S:
					keys[S] = false;
					break;
				case ALLEGRO_KEY_D:
					keys[D] = false;
					break;
				case ALLEGRO_KEY_E:
					keys[E] = false; 
					// break to fire one bullet only
					break; 
			}
		}

		// if redraw is true and no queue for event. 
		if ( redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false; 

			if (!isGameOver)
			{
				// draws the latest position of bullet and ship that has been updated. 
				DrawShip(ship, image1); // Draw ship
				DrawShip(ship2, image2); 
				DrawBullet(bullet, NUM_BULLETS); // draw bullets 
				DrawBullet(bullet2, NUM_BULLETS); 
				al_draw_textf(font18, al_map_rgb(255,0,255), 5, 5, 0, "Player 1 Lives left: %i \nScore: %i\n", ship.lives, ship.score); 
				al_draw_textf(font18, al_map_rgb(255,0,255), 50, 50, 0, "Player 2Lives left: %i \nScore: %i\n", ship2.lives, ship2.score);
			}
			else 
			{ al_draw_textf(font18, al_map_rgb(0,255,255), WIDTH/2, HEIGHT/2, ALLEGRO_ALIGN_CENTRE,
							"GAME OVER. P1 Final Score: %i\n P2 Final Score %i",ship.score, ship2.score); 

			}
			al_flip_display(); 
			al_clear_to_color(al_map_rgb(0, 0, 0)); 
		}
	}
	al_destroy_display(display); 
	return 0;
}
Esempio n. 3
0
/****************************************************************************
 * ClientWndProc                                                            *
 *  - Typical PM client window procedure.  (see below)                      *
 *  - Standard client window I/O                                            *
 ****************************************************************************/
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
	   RECTL  rcl;
	   SWP	  swp;
	   HPS	  hpsPaint;

    static HPS	  hps;                      /* Permanent HPS                */
    static INT    cx, cy;		    /* Client window dimensions     */
    static BOOL   bSlowUpdateNow = FALSE;   /* Update toggle for asteroids  *
                                             *   and enemy which are slow.  */
    static POINTL ptlCenter;		    /* Center of client window      */

    switch (msg) {
      /* Recieved from WinCreateStdWindow */
      case WM_CREATE:
	/* Get permanent PS for entire window */
	hps = WinGetPS(hwnd);

	/* Load private Asteroid fonts from ASTEROID.DLL */
	if (GpiLoadFonts(hab, "ASTEROID") != GPI_OK) {
            WinReleasePS(hps);
	    WinAlarm(HWND_DESKTOP, WA_WARNING);
	    WinMessageBox(HWND_DESKTOP,NULLHANDLE,
		"Please put ASTEROID.DLL in a directory in your LIBPATH.",
		"Error reading ASTEROID.DLL",
		0,MB_ICONHAND|MB_OK|MB_APPLMODAL);
	    WinPostMsg(hwnd,WM_QUIT,(MPARAM) 0L,(MPARAM) 0L);
	    return (MRESULT) TRUE;
	    }

        /* Register/create logical fonts for use */
	InitFonts(hps);

	/* Display About dialoge box */
	WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutDlgProc, NULLHANDLE,
		  IDD_ABOUT, NULL);

	return 0;

      /* Recieved during attract mode when user starts game */
      case WM_STARTGAME:
        /* Determine the number of players */
	cPlayers = (INT)LONGFROMMP(mp1);

        /* Initialize each player */
	for (Player=0;Player<cPlayers;Player++) {
	    Level[Player] = 1;
	    Ships[Player] = prfProfile.iSHIPS;
	    DeletePhotons();
	    InitAsteroids();
	    InitEnemy();
	    }

        /* Start with player 1 */
	Player = 0;
	iGameMode = GAME_MODE_NEXT;
	iGameModeCnt = GAME_PAUSE_TIME-1;

	/* Hide the pointer if mouse controls are enabled */
	ShowMouse(FALSE);
        
        /* Paint everything */
	WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID);

	return 0;

      /* Recieved at startup and at the completion of a game */
      case WM_INITGAME:
        /* Make mouse visible if we hid it before */
        ShowMouse(TRUE);
        
	/* Fix menu to reflect attract mode */
	EnableMenuItem(hwndMenu, IDM_START, TRUE);
	EnableMenuItem(hwndMenu, IDM_STOP, FALSE);

	/* Initialize player and enemy data structures */
	cPlayers = 0;
	Level[0] = 1;
	for (Player=0;Player<2;Player++) {
	    Score[Player] = 0L;
	    Ships[Player] = 0;
	    DeletePhotons();
	    }
	Player = 0;

	/* Initialize asteroids (and enemy) for attract mode */
	InitAsteroids();
	InitEnemy();

        /* Depending on whether ASTEROID was just started or a game just  *
         *   completed display the "High Score" or "Press 1 or 2" screen. */
	if (SHORT1FROMMP(mp1) == 0) {
	    iGameMode = GAME_MODE_INIT1;
	    iGameModeCnt = GAME_INIT_TIME;
	    }
	else {
	    iGameMode = GAME_MODE_INIT2;
	    iGameModeCnt = GAME_INIT_TIME;
	    }

        /* Paint everything */
	WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID);
	return 0;

      /* Usually recieved from the system, sometime forced by the program to *
       *   ensure the screen is not corrupt.                                 */
      case WM_PAINT:
	/* Clear entire window to insure no "droppings" */
	WinQueryWindowRect(hwnd,&rcl);
        WinFillRect(hps, &rcl, CLR_BLACK);
	WinInvalidateRect(hwnd, &rcl, FALSE);

	/* Get the update region and paint it black */
	hpsPaint = WinBeginPaint(hwnd, (HPS)NULL, &rcl);
	WinFillRect(hpsPaint, &rcl, CLR_BLACK);
	WinEndPaint(hpsPaint);

        /* Only in normal play mode should we draw the ship */
	if ((iGameMode == GAME_MODE_PLAY) &&
	    (iShipMode[Player] != EXPLOSION) &&
	    (iShipMode[Player] != HYPERSPACE))
	    DrawShip(hps, cx, cy, DRAW_INIT);
	else if ((iGameMode == GAME_MODE_PLAY) &&
		 (iShipMode[Player] == EXPLOSION))
	    ExplodeShip(hps, cx, cy);

        /* Draw the enemy if it is on the screen */
	if (iEnemyMode[Player] != NONE)
	    if (iEnemyMode[Player] != EXPLOSION)
		DrawEnemy(hps, cx, cy,DRAW_INIT);
	    else
		ExplodeEnemy(hps, cx, cy);

        /* Draw photons and asteroids in all modes but the "Enter your *
         *   initials" mode, otherwise draw that screen.               */
	if (iGameMode != GAME_MODE_HIGH) {
	    DrawPhotons(hps, cx, cy, DRAW_INIT);
	    DrawAsteroids(hps, cx, cy, DRAW_INIT);
	    }
	else
	    DrawHighScore(hps, cx, cy, DRAW_INIT);

        /* Always draw the score */
	DrawScore(hps, cx, cy, DRAW_INIT);

	return 0;

      /* Left mouse button down.  This simulates the move/track function *
       *   in the system menu.                                           */
      case WM_BUTTON1DOWN:
        if (prfProfile.bMOUSECONTROL &&
            iGameMode != GAME_MODE_INIT1 &&
            iGameMode != GAME_MODE_INIT2 &&
            !TogglePause(CHECK)) {
	    UPDATE_FIRE(iShipMode[Player], TRUE);
            return (MRESULT)TRUE;
        }
	return WinSendMsg(hwndFrame, WM_TRACKFRAME,
			 (MPARAM) (SHORT1FROMMP(mp2) | TF_MOVE), MPVOID);

      case WM_BUTTON1UP:
        if (prfProfile.bMOUSECONTROL) {
	    UPDATE_FIRE(iShipMode[Player], FALSE);
            return (MRESULT)TRUE;
        }
        return 0;
        
      /* Left mouse button double clicked.  Toggle frame control display. */
      case WM_BUTTON1DBLCLK:
        if (!prfProfile.bMOUSECONTROL ||
            iGameMode == GAME_MODE_INIT1 ||
            iGameMode == GAME_MODE_INIT2 ||
            TogglePause(CHECK)) {
            if (prfProfile.bCONTROLS = !prfProfile.bCONTROLS)
	    	ShowFrameControls();
            else
	    	HideFrameControls();
        }
	return 0;

      case WM_BUTTON2DOWN:
        if (prfProfile.bMOUSECONTROL) {
	    UPDATE_SHIELD(iShipMode[Player], iShipShieldCnt[Player]);
            return (MRESULT)TRUE;
        }
        return 0;
        
      case WM_BUTTON2CLICK:
        if (prfProfile.bMOUSECONTROL) {
            UPDATE_HYPERSPACE(iShipMode[Player], iShipModeCnt[Player]);
            return (MRESULT)TRUE;
        }
        return 0;
        
      /* Right mouse button double clicked.  Display the about dialog box. */
      case WM_BUTTON2DBLCLK:
        if (!prfProfile.bMOUSECONTROL ||
            iGameMode == GAME_MODE_INIT1 ||
            iGameMode == GAME_MODE_INIT2 ||
            TogglePause(CHECK)) {
            WinDlgBox(HWND_DESKTOP, hwndClient, (PFNWP)AboutDlgProc,
            	      NULLHANDLE, IDD_ABOUT, NULL);
        }
	return 0;

      /* User typed a key.  Most of this is self explanatory. */
      case WM_CHAR:
	ProcessChar((CHAR) (CHARMSG(&msg)->vkey-1),
		    CHARMSG(&msg)->fs & KC_VIRTUALKEY,
		    (CHAR) (CHARMSG(&msg)->chr),
		    (BOOL) !(CHARMSG(&msg)->fs & KC_KEYUP));
	return 0;

      /* User entered a command via the menu bar. */
      case WM_COMMAND:
	DoCommand(hwnd, msg, mp1, mp2);
	return 0;

      /* Suspend/un-suspend game depending on focus */
      case WM_SETFOCUS:
	if ((BOOL) SHORT1FROMMP(mp2))
	    TogglePause(SUSPEND_OFF);
	else if (!prfProfile.bBACKGRND)
	    TogglePause(SUSPEND_ON);
	return 0;

      /* Keep track of the client window size.  Profile information is not *
       *   updated here because there are better places (i.e. at exit)     */
      case WM_SIZE:
	cx = (INT)SHORT1FROMMP(mp2);
	cy = (INT)SHORT2FROMMP(mp2);

      /* Keep track of client window position.  Also updates profile info. */
      case WM_MOVE:
	WinQueryWindowPos(hwndFrame,&swp);
	if (!(swp.fl & SWP_MAXIMIZE) && !(swp.fl & SWP_MINIMIZE)) {
	    prfProfile.x  = swp.x;prfProfile.y   = swp.y;
	    prfProfile.cx = swp.cx;prfProfile.cy = swp.cy;
	    }

	if (swp.fl & SWP_MINIMIZE)
	    if (!prfProfile.bBACKGRND) {
		/* Set icon */
		WinSendMsg(hwndFrame, WM_SETICON,
		    (MPARAM) WinLoadPointer(HWND_DESKTOP, NULLHANDLE,
					    ID_RESOURCE), MPVOID);

		TogglePause(SUSPEND_ON);
		}
	    else
		WinSendMsg(hwndFrame, WM_SETICON, MPVOID, MPVOID);
	else
	    TogglePause(SUSPEND_OFF);

	ptlCenter.x = swp.cx / 2;
        ptlCenter.y = swp.cy / 2;
        WinMapWindowPoints(hwndClient, HWND_DESKTOP, &ptlCenter, 1L);

	return 0;

      /* Recieved approximately 31 times a second.  This is the longest and *
       *   ugliest of the messages, partly because there are so many cases  *
       *   to keep track of, partly because it must be highly optimized.    */
      case WM_TIMER:
        if (prfProfile.bMOUSECONTROL &&
            iGameMode != GAME_MODE_INIT1 &&
            iGameMode != GAME_MODE_INIT2) {                   POINTL ptl;
            static BOOL   bUp, bLeft, bRight;

            WinQueryPointerPos(HWND_DESKTOP, &ptl);
            if (bUp || (ptl.y - ptlCenter.y > 0))
	       	UPDATE_THRUST(iShipMode[Player],
            		      bUp = (ptl.y - ptlCenter.y > 0));
            if (bLeft || (ptlCenter.x - ptl.x > 0))
                UPDATE_LEFT(iShipMode[Player],
                	    bLeft = (ptlCenter.x - ptl.x > 0));
            if (bRight || (ptlCenter.x - ptl.x < 0))
                UPDATE_RIGHT(iShipMode[Player],
                 	     bRight = (ptlCenter.x - ptl.x < 0));
            WinSetPointerPos(HWND_DESKTOP, ptlCenter.x, ptlCenter.y);
        }
        
        /* Determine the current game mode */
	switch (iGameMode) {

          /* Either initialization/attract mode screen. */
	  case GAME_MODE_INIT1: case GAME_MODE_INIT2:
            /* Switch screens when count expires */
	    if (--iGameModeCnt == 0) {
		if (iGameMode == GAME_MODE_INIT1)
		    iGameMode = GAME_MODE_INIT2;
		else
		    iGameMode = GAME_MODE_INIT1;
		iGameModeCnt = GAME_INIT_TIME;

                /* Score must be redrawn because the attract mode screens *
                 *   draw the score differently.                          */
		DrawScore(hps, cx, cy, DRAW_REINIT);
		}

            /* Update photons, asteroids, enemy, and score */
	    UpdatePhotons(hps, cx, cy);
	    if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		UpdateAsteroids(hps, cx, cy);
		UpdateEnemy(hps, cx, cy);
		DrawScore(hps, cx, cy, DRAW_REFRESH);
		}
	    break;

          /* Completion of one player's turn or new game */
	  case GAME_MODE_NEXT:
            /* Initially, erase and redraw everything for new player */
	    if (iGameModeCnt-- == GAME_PAUSE_TIME) {
		if ((cPlayers == MAXPLAYERS) &&
                    (Ships[(Player+1) % MAXPLAYERS])) {
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);
		    DrawPhotons(hps, cx, cy, DRAW_ERASE);
		    Player = (Player+1) % MAXPLAYERS;
		    }
		DrawScore(hps, cx, cy, DRAW_REINIT);
		DrawAsteroids(hps, cx, cy, DRAW_INIT);
		}
            /* During countdown update score and asteroids */
	    else if (iGameModeCnt > 0) {
		if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		    UpdateAsteroids(hps, cx, cy);
		    }
		}
            /* At end of countdown start the player */
	    else {
		InitShip();
		InitEnemy();
		iGameMode = GAME_MODE_PLAY;
		DrawScore(hps, cx, cy, DRAW_REINIT);
		}
	    break;

          /* Normal play mode */
	  case GAME_MODE_PLAY:
            /* Update ship, photons, asteroids, enemy, and score */
	    UpdateShip(hps, cx, cy);
	    UpdatePhotons(hps, cx, cy);
	    if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		UpdateAsteroids(hps, cx, cy);
		UpdateEnemy(hps, cx, cy);
                /* Erase old and draw new scores if there is a change*/
		if (bChangeScore) {
		    bChangeScore = FALSE;
		    DrawScore(hps, cx, cy, DRAW_REINIT);
		    }
                /* Else just refresh the score */
		else
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		}
	    break;

          /* Game over mode.  This is the longest and ugliest case because  *
           *   conditions are highly dependent on the number of players,    *
           *   multiplayer game status, and the number and order of high    *
           *   scores.                                                      */
	  case GAME_MODE_OVER:
            /* Initially, just update the score and number of ships */
	    if (iGameModeCnt-- == GAME_PAUSE_TIME)
		DrawScore(hps, cx, cy, DRAW_REINIT);

            /* During countdown refresh the score and update the asteroids */
	    else if (iGameModeCnt > 0) {
		if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		    UpdateAsteroids(hps, cx, cy);
		    }
		}

            /* At the end of the countdown, if there are any other players, *
             *   continue with them.                                        */
	    else {
                /* Countinue on with any remaining players. */
		if ((cPlayers == MAXPLAYERS) &&
                    (Ships[(Player+1) % MAXPLAYERS])) {
                    /* Erase all of the old asteroids. */
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);

                    /* Setup everything for the next player */
		    Player = (Player+1) % MAXPLAYERS;
		    InitShip();
		    InitEnemy();
		    iGameMode = GAME_MODE_PLAY;
		    DrawAsteroids(hps, cx, cy, DRAW_INIT);
		    DrawScore(hps, cx, cy, DRAW_REINIT);
		    }

                /* Check for new high scores and update table as necessary. */
		else {
                    /* Erase all of the old asteroids. */
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);


                /* The following if/else block is admittedly a kludge, it is *
                 *   simple and it does work, however.  Ideally it should    *
                 *   sort the high scores and update the high score table in *
                 *   descending order.                                       */

                    /* If player 1 scored higher than player 2 then check *
                     *   player 1 first for a high score.                 */
       		    if (Score[0] > Score[1])
			for (Player=0;Player<cPlayers;Player++)
                            /* If the player's score is > than the lowest, *
                             *   update the high score table.              */
			    if (Score[Player] > prfProfile.lSCORES[9]) {
				UpdateHighScores();
				iGameMode = GAME_MODE_HIGH;
				}
                            /* Otherwise, make sure he is not asked for his *
                             *   initials.                                  */
			    else
				Score[Player] = 0;

                    /* Otherwise, check player 2 first */
		    else
			for (Player=cPlayers;Player>=0;Player--)
                            /* If the player's score is > than the lowest, *
                             *   update the high score table.              */
			    if (Score[Player] > prfProfile.lSCORES[9]) {
				UpdateHighScores();
				iGameMode = GAME_MODE_HIGH;
				}
                            /* Otherwise, make sure he is not asked for his *
                             *   initials.                                  */
			    else
				Score[Player] = 0L;

                    /* If there was no high score, go into attract mode */
		    if (iGameMode != GAME_MODE_HIGH)
			WinSendMsg(hwnd,WM_INITGAME,MPFROMSHORT(1),(MPARAM) 0L);
                    /* Else, check for player 1's initials first then 2's   *
                     * This is not faithful, in the arcade game the player  *
                     *   with the higher score always goes first.           */
		    else {
			if (Score[0] > 0L)
			    Player = 0;
			else
			    Player = 1;
			DrawScore(hps, cx, cy, DRAW_REINIT);
			DrawHighScore(hps, cx, cy, DRAW_INIT);
			}
		    }
		}
	    break;

          /* Mode which prompts players to enter their initials */
	  case GAME_MODE_HIGH:
            /* If the player's position is > 0 then refresh the screen */
	    if (Score[Player] > 0L)
		DrawHighScore(hps, cx, cy, DRAW_REFRESH);
            /* Else, the current player is done go to the next */
	    else if ((cPlayers == MAXPLAYERS) && (Player == 0) &&
		     (Score[1] > 0L)) {
		Player++;
		DrawHighScore(hps, cx, cy, DRAW_REINIT);
		}
            /* If there are no more high scores then go into attract mode */
	    else
		WinSendMsg(hwnd, WM_INITGAME, MPFROMSHORT(1), MPVOID);
	    break;
	  }
	return 0;

      /* Used by help manager */
      case HM_QUERY_KEYS_HELP:
	 return((MRESULT)IDH_CLIENTKEYS);

      /* Recieved always from the system or in the case of an initialization*
       *   error.  Both messages will normally save the profile information.*
       * Ideally the profile section should be moved to a subroutine and the*
       *   the following should be broken into two distinct cases.	    */
      case WM_SAVEAPPLICATION:
      case WM_DESTROY:
	/* If the fonts were not found bApplicationOk will be false, in     *
	 *   that case the window profile information should not be updated.*/
	if (TRUE) {
	    /* Copy window position and size info into profile structure */
	    WinQueryWindowPos(hwndFrame, &swp);
	    if (swp.fl & SWP_MAXIMIZE)
		prfProfile.ulMINMAX = SWP_MAXIMIZE;
	    else if (swp.fl & SWP_MINIMIZE)
		prfProfile.ulMINMAX = SWP_MINIMIZE;
	    else {
		prfProfile.ulMINMAX = 0;
		prfProfile.x  = swp.x;prfProfile.y   = swp.y;
		prfProfile.cx = swp.cx;prfProfile.cy = swp.cy;
		}

	    /* Write profile information */
	    PrfWriteProfileData(HINI_USERPROFILE, szClientClass, "Data",
		&prfProfile, sizeof(PROFILEREC));
	    }

        /* If the application is terminating release the fonts and the hps. */
        if (msg == WM_DESTROY) {
	    /* Make sure mouse is visible if we hid it before */
            ShowMouse(TRUE);
            
	    /* Release font identifiers and DLL resource module */
	    GpiSetCharSet(hps, LCID_DEFAULT);
	    GpiDeleteSetId(hps, LCID_LARGE);
	    GpiDeleteSetId(hps, LCID_SMALL);
	    GpiUnloadFonts(hab, "ASTEROID");

	    /* Release the "permanent" presentation space */
	    WinReleasePS(hps);
            }
	return 0;

      }
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
Esempio n. 4
0
int main(void){
	//allegro variables
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_BITMAP *bg = NULL;
	ALLEGRO_TIMER *timer;

	//program init
	if(!al_init())										//initialize Allegro
		return -1;

	display = al_create_display(WIDTH, HEIGHT);			//create our display object

	if(!display)										//test display object
		return -1;

	//==============================================
	//ADDON INSTALL
	//==============================================
	al_install_keyboard();
	al_init_image_addon();
	al_init_font_addon();
	al_init_ttf_addon();
	al_init_primitives_addon();

    // FONT DEL PROGRAMA.
	ALLEGRO_FONT *font = al_load_ttf_font("Sarpanch-SemiBold.ttf",30,0 );

    // VARIABLES DEL JUEGO ========================
    bg = al_load_bitmap("img/sp1.jpg");

    SpaceShip nave_jugador;
    Enemy enemies1[10];
    Enemy enemies2[10];
    Enemy enemies3[10];
    Enemy enemies4[10];
    Enemy jefe1[10];
    Bullet bullets[5];


    char vidas_char[2];


    // INICIALIZAR OBJETOS====================
    InitShip(nave_jugador);
    InitBullet(bullets, NUM_BULLETS);
    InitEnemies(enemies1,ENM1,10,0,220,WIDTH/2);
    InitEnemies(enemies2,ENM2,8,50,180,WIDTH/2+100);
    InitEnemies(enemies3,ENM3,6,100,140,WIDTH);
    InitEnemies(enemies4,ENM4,4,150,100,(WIDTH/2)+100);
    InitEnemies(jefe1,JEFE,2,200,60);
    //DrawEnemies(enemies,NUM_ENEMIES);

	//==============================================
	//TIMER INIT AND STARTUP
	//==============================================
	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / 60);

	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_keyboard_event_source());

	al_start_timer(timer);

    //AnimacionEntrada(enemies,NUM_ENEMIES);
    printf("ya");
    int animacion=1;
    int movimientos=0;
	while(!done){

		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);

        // INFORMACION DEL JUEGO Y BG
        // DrawWindowStatus();
		al_draw_bitmap(bg, 0, 0, 0);
        al_draw_bitmap(nave_jugador.image, 5,440,0);
        al_draw_text(font, al_map_rgb(255,255,255), 40,430, 0, "X");
        sprintf(vidas_char,"%d",vidas);
        al_draw_text(font, al_map_rgb(255,255,255), 60,430, 0, vidas_char);
        al_draw_text(font, al_map_rgb(255,255,255), WIDTH/2 - 30, 0,ALLEGRO_ALIGN_CENTRE, "Score");
        char vartext[10];
        sprintf(vartext,"%d",score);
        al_draw_text(font, al_map_rgb(255,255,255), WIDTH/2 + 40, 0, 0, vartext);


		//==============================================
		//INPUT
		//==============================================
        if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN){
			switch(ev.keyboard.keycode){
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				FireBullet(bullets, NUM_BULLETS, nave_jugador);
				break;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_UP)
        {
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}


		//==============================================
		//GAME UPDATE
		//==============================================
		else if(ev.type == ALLEGRO_EVENT_TIMER){
			render = true;

			if(keys[LEFT])
				MoveShipLeft(nave_jugador);
			else if(keys[RIGHT])
				MoveShipRight(nave_jugador);

            UpdateBullet(bullets, NUM_BULLETS);

            CollideBullet(bullets,NUM_BULLETS,enemies1,NUM_ENEMIES);
            CollideBullet(bullets,NUM_BULLETS,enemies2,8);
            CollideBullet(bullets,NUM_BULLETS,enemies3,6);
            CollideBullet(bullets,NUM_BULLETS,enemies4,4);
            CollideBullet(bullets,NUM_BULLETS,jefe1,2);
		}

		//==============================================
		//RENDER
		//==============================================
		if(render && al_is_event_queue_empty(event_queue))
		{
			if (animacion==1){
                printf("si primero");
                movEnemies(enemies1,10,1);
                movEnemies(enemies2, 8,1);
                movEnemies(enemies3,6,1);
                movEnemies(enemies4,4,1);
                movEnemies(jefe1,2,1);
                animacion=0;
                movimientos=1;
			}


			render = false;

            // Dibujar nave
			al_draw_bitmap(nave_jugador.image, nave_jugador.x - nave_jugador.w / 2, nave_jugador.y - nave_jugador.h / 2, 0);
			// Dibujar Balas
			DrawBullet(bullets, NUM_BULLETS);

            // Dibuja los enemigos.
            DrawEnemies(enemies1,10);
            DrawEnemies(enemies2,8);
            DrawEnemies(enemies3,6);
            DrawEnemies(enemies4,4);
            DrawEnemies(jefe1,2);

			al_flip_display();
			al_clear_to_color(al_map_rgb(0,0,0));
			if (movimientos){
                movimientos=0;
                movEnemies(enemies1,10,2);
                movEnemies(enemies2,8,3);
			}
		}

	}


    for (int i =0;i<10;i++)

    al_destroy_bitmap(enemies1[i].image);

	al_destroy_event_queue(event_queue);
	al_destroy_timer(timer);
	al_destroy_display(display);						//destroy our display object

	return 0;
}
int main(void)
{
	//primitive variable
	bool done = false;
	bool redraw = true;
	const int FPS = 60;
	bool isGameOver = false;

	//object variables
	SpaceShip ship;
	Bullet bullets[NUM_BULLETS];
	Comet comets[NUM_COMETS];

	//Allegro variables
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL;

	//Initialization Functions
	if(!al_init())										//initialize Allegro
		return -1;

	display = al_create_display(WIDTH, HEIGHT);			//create our display object

	if(!display)										//test display object
		return -1;

	al_init_primitives_addon();
	al_install_keyboard();
	al_init_font_addon();
	al_init_ttf_addon();

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);

	srand(time(NULL));
	InitShip(ship);
	InitBullet(bullets, NUM_BULLETS);
	InitComet(comets, NUM_COMETS);
	
	font18 = al_load_font("arial.ttf", 18, 0);

	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_display_event_source(display));

	al_start_timer(timer);
	while(!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);

		if(ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			if(keys[UP])
				MoveShipUp(ship);
			if(keys[DOWN])
				MoveShipDown(ship);
			if(keys[LEFT])
				MoveShipLeft(ship);
			if(keys[RIGHT])
				MoveShipRight(ship);

			if(!isGameOver)
			{
				UpdateBullet(bullets, NUM_BULLETS);
				StartComet(comets, NUM_COMETS);
				UpdateComet(comets, NUM_COMETS);
				CollideBullet(bullets, NUM_BULLETS, comets, NUM_COMETS, ship);
				CollideComet(comets, NUM_COMETS, ship);

				if(ship.lives <= 0)
					isGameOver = true;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				FireBullet(bullets, NUM_BULLETS, ship);
				break;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}

		if(redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false; 

			if(!isGameOver)
			{
				DrawShip(ship);
				DrawBullet(bullets, NUM_BULLETS);
				DrawComet(comets, NUM_COMETS);

				al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Player has %i lives left. Player has destroyed %i objects", ship.lives, ship.score);
			}
			else
			{
				al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH / 2, HEIGHT / 2, ALLEGRO_ALIGN_CENTRE, "Game Over. Final Score: %i", ship.score);
			}
		
			al_flip_display();
			al_clear_to_color(al_map_rgb(0,0,0));
		}
	}

	al_destroy_event_queue(event_queue);
	al_destroy_timer(timer);
	al_destroy_font(font18);
	al_destroy_display(display);						//destroy our display object

	return 0;
}
int main(void)
{
	// don't forget to put allegro-5.0.10-monolith-md-debug.lib
	//primitive variable
	bool done = false;
	bool redraw = true;
	const int FPS = 60;
	bool isGameOver = false;

	//object variables
	spaceShip ship;
	Bullet bullets[NUM_BULLETS];
	Comet comets[NUM_COMETS];
	Explosion explosions[NUM_EXPLOSIONS];

	//Allegro variables
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL;
	ALLEGRO_BITMAP *shipImage;
	ALLEGRO_BITMAP *cometImage;
	ALLEGRO_BITMAP *expImage;
	ALLEGRO_SAMPLE * sample = NULL;
	ALLEGRO_SAMPLE * sample2 = NULL;
	ALLEGRO_SAMPLE * sample3 = NULL;
	ALLEGRO_SAMPLE_INSTANCE * instance1 = NULL;
	ALLEGRO_SAMPLE_INSTANCE * instance2 = NULL;
	ALLEGRO_SAMPLE_INSTANCE * instance3 = NULL;

	//Initialization Functions
	if(!al_init())										//initialize Allegro
		return -1;

	display = al_create_display(WIDTH, HEIGHT);			//create our display object

	if(!display)										//test display object
		return -1;

	al_init_primitives_addon();
	al_install_keyboard();
	al_init_font_addon();
	al_init_ttf_addon();
	al_init_image_addon();
	al_install_audio(); // always initialize audio before the codecs
	al_init_acodec_addon();
	
	al_reserve_samples(10); // reserves numbers of samples/ channels or voices

	sample = al_load_sample("chirp.ogg");
	sample2 = al_load_sample("static.ogg");
	sample3 = al_load_sample("JSS - Our Song.ogg");

	instance1 = al_create_sample_instance(sample);
	instance2 = al_create_sample_instance(sample2);
	instance3 = al_create_sample_instance(sample3);	

	al_set_sample_instance_playmode(instance3, ALLEGRO_PLAYMODE_LOOP);

	al_attach_sample_instance_to_mixer(instance1, al_get_default_mixer());
    al_attach_sample_instance_to_mixer(instance2, al_get_default_mixer());
	al_attach_sample_instance_to_mixer(instance3, al_get_default_mixer());

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);

	cometImage = al_load_bitmap("asteroid-1-96.png");
	//above does not need convert_mask_to_alpha because it is tranparent background in sprite sheet
	shipImage = al_load_bitmap("Spaceship_by_arboris.png");
	al_convert_mask_to_alpha(shipImage,al_map_rgb(255,0,255));

	expImage = al_load_bitmap("explosion_3_40_128.png");

	srand(time(NULL));
	InitShip(ship, shipImage);
	InitBullet(bullets, NUM_BULLETS);
	InitComet(comets, NUM_COMETS, cometImage);
	InitExplosions(explosions, NUM_EXPLOSIONS, expImage);

	font18 = al_load_font("arial.ttf", 18, 0);

	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_display_event_source(display));

	al_play_sample_instance(instance3);

	al_start_timer(timer);
	while(!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);

		if(ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			int soundX = ship.x;
			int soundY = ship.y;
			
			if(keys[UP])
				MoveShipUp(ship);
			else if(keys[DOWN])
				MoveShipDown(ship);
			else
				ResetShipAnimation(ship,1);
			if(keys[LEFT])
				MoveShipLeft(ship);
			else if(keys[RIGHT])
				MoveShipRight(ship);
			else
				ResetShipAnimation(ship, 2);
			
			if(soundX != ship.x || soundY != ship.y){
				//al_play_sample(sample, 1,0,1, ALLEGRO_PLAYMODE_ONCE, NULL);
				al_play_sample_instance(instance1);
			}
			if (ship.x -10 < 0 || ship.x + 10 > WIDTH || ship.y - 10 < 0 || ship.y + 10 > HEIGHT){
				al_play_sample_instance(instance2);
			}

			if(!isGameOver)
			{
				UpdateExplosions(explosions, NUM_EXPLOSIONS);
				UpdateBullet(bullets, NUM_BULLETS);
				StartComet(comets, NUM_COMETS);
				UpdateComet(comets, NUM_COMETS);
				CollideBullet(bullets, NUM_BULLETS, comets, NUM_COMETS, ship, explosions, NUM_EXPLOSIONS);
				CollideComet(comets, NUM_COMETS, ship, explosions, NUM_BULLETS);

				if(ship.lives <= 0)
					isGameOver = true;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				FireBullet(bullets, NUM_BULLETS, ship);
				break;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch(ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}

		if(redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false; 

			if(!isGameOver)
			{
				DrawShip(ship);
				if(al_get_sample_instance_playing(instance1)){
					al_draw_text(font18, al_map_rgb(255,255,255),5,30,0, "Instance 1 is playing");
				}
				if(al_get_sample_instance_playing(instance2)){
					al_draw_text(font18, al_map_rgb(255,255,255),WIDTH - 5,30,ALLEGRO_ALIGN_RIGHT, "Instance 2 is playing");
				}
				if(al_get_sample_instance_playing(instance3)){
					al_draw_textf(font18, al_map_rgb(255,255,255),5,HEIGHT - 30,0, "Instance 3 is playing: %.1f %%", al_get_sample_instance_position(instance3) / (float)al_get_sample_instance_length(instance3) * 100);
				}

				DrawBullet(bullets, NUM_BULLETS);
				DrawComet(comets, NUM_COMETS);
				DrawExplosions(explosions, NUM_EXPLOSIONS);

				al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Player has %i lives left. Player has destroyed %i objects", ship.lives, ship.score);
			}
			else
			{
				al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH / 2, HEIGHT / 2, ALLEGRO_ALIGN_CENTRE, "Game Over. Final Score: %i", ship.score);
			}
		
			al_flip_display();
			al_clear_to_color(al_map_rgb(0,0,0));
		}
	}

	al_destroy_sample_instance(instance1);
	al_destroy_sample_instance(instance2);
	al_destroy_sample_instance(instance3);
	al_destroy_sample(sample);
	al_destroy_sample(sample2);
	al_destroy_sample(sample3);
	al_destroy_bitmap(expImage);
	al_destroy_bitmap(shipImage);
	al_destroy_bitmap(cometImage);
	al_destroy_event_queue(event_queue);
	al_destroy_timer(timer);
	al_destroy_font(font18);
	al_destroy_display(display);						//destroy our display object

	return 0;
}
Esempio n. 7
0
int main(void)
{
	//primitive variable
	const int FPS = 60;
	bool done = false;
	bool redraw = true;
	bool isGameOver = false;

	//object variables
	struct SpaceShip ship;
	struct Bullet bullets[NUM_BULLETS];
	struct Comet comets[NUM_COMETS];

	//Allegro variables
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_BITMAP *shipImage;
	ALLEGRO_BITMAP *cometImage;
	ALLEGRO_BITMAP *bulletImage;

	ALLEGRO_FONT *font = NULL;
	ALLEGRO_PATH *font_path;

	//Initialization Functions
	if (!al_init())										//initialize Allegro
		return -1;

	display = al_create_display(WIDTH, HEIGHT);		//create our display object

	if (!display)										//test display object
		return -1;

	// inicio inicializacao fontes
	al_init_image_addon();

	font_path = get_resources_path();
	al_set_path_filename(font_path, "a4_font.tga");

	al_init_font_addon();
	al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
	font = al_load_bitmap_font(al_path_cstr(font_path, '/'));
	if (!font)
	{
		return 1;
	}

	al_destroy_path(font_path);
	// termino inicializacao fontes

	al_init_primitives_addon();
	al_install_keyboard();
	al_init_image_addon();

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);

	shipImage = al_load_bitmap("spaceship_by_arboris.png");
	al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));

	bulletImage = al_load_bitmap("bullets_by_arboris.png");
	al_convert_mask_to_alpha(bulletImage, al_map_rgb(255, 0, 255));

	cometImage = al_load_bitmap("asteroid-1-96.png");

	srand(time(NULL ));

	//Game Init
	ship = InitShip(shipImage);

	// init bullets
	int i = 0;
	while (i < NUM_BULLETS)
	{
		bullets[i].ID = BULLET;
		bullets[i].speed = 10;
		bullets[i].live = false;

		bullets[i].maxFrame = 143;
		bullets[i].curFrame = 0;
		bullets[i].frameCount = 0;
		bullets[i].frameDelay = 2;
		bullets[i].frameWidth = 20;
		bullets[i].frameHeight = 10;
		bullets[i].animationColumns = 1;

		bullets[i].animationRow = 1;

		bullets[i].image = bulletImage;

		i++;
	}

	// init comets
	i = 0;
	while (i < NUM_COMETS)
	{
		comets[i].ID = ENEMY;
		comets[i].live = false;
		comets[i].speed = 5;
		comets[i].boundx = 35;
		comets[i].boundy = 35;

		comets[i].maxFrame = 143;
		comets[i].curFrame = 0;
		comets[i].frameCount = 0;
		comets[i].frameDelay = 2;
		comets[i].frameWidth = 96;
		comets[i].frameHeight = 96;
		comets[i].animationColumns = 21;

		if (rand() % 2)
			comets[i].animationDirection = 1;
		else
			comets[i].animationDirection = -1;

		comets[i].image = cometImage;

		i++;
	}

	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_display_event_source(display));
	al_register_event_source(event_queue, al_get_timer_event_source(timer));

	al_start_timer(timer);

	while (!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);

		if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if (ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			if (keys[UP])
				ship = MoveShipUp(ship);
			else if (keys[DOWN])
				ship = MoveShipDown(ship);
			else
				ship = ResetShipAnimation(ship, 1);

			if (keys[LEFT])
				ship = MoveShipLeft(ship);
			else if (keys[RIGHT])
				ship = MoveShipRight(ship);
			else
				ship = ResetShipAnimation(ship, 2);

			if (!isGameOver)
			{
				//UpdateBullet
				int i = 0;
				while (i < NUM_BULLETS)
				{
					if (bullets[i].live)
					{
						bullets[i].x += bullets[i].speed;
						if (bullets[i].x > WIDTH)
							bullets[i].live = false;
					}

					i++;
				}

				// start comet
				i = 0;
				while (i < NUM_COMETS)
				{
					if (!comets[i].live)
					{
						if (rand() % 500 == 0)
						{
							comets[i].live = true;
							comets[i].x = WIDTH;
							comets[i].y = 30 + rand() % (HEIGHT - 60);

							break;
						}
					}

					i++;
				}

				// UpdateComet(Comet comets[], int size)
				i = 0;
				while (i < NUM_COMETS)
				{
					if (comets[i].live)
					{
						if (++comets[i].frameCount >= comets[i].frameDelay)
						{
							comets[i].curFrame += comets[i].animationDirection;
							if (comets[i].curFrame >= comets[i].maxFrame)
								comets[i].curFrame = 0;
							else if (comets[i].curFrame <= 0)
								comets[i].curFrame = comets[i].maxFrame - 1;

							comets[i].frameCount = 0;
						}

						comets[i].x -= comets[i].speed;
					}

					i++;
				}

				// collide bullet
				i = 0;
				while (i < NUM_BULLETS)
				{
					if (bullets[i].live)
					{
						int j = 0;
						while (j < NUM_COMETS)
						{
							if (comets[j].live)
							{
								if (bullets[i].x
										> (comets[j].x - comets[j].boundx)
										&& bullets[i].x
												< (comets[j].x
														+ comets[j].boundx)
										&& bullets[i].y
												> (comets[j].y
														- comets[j].boundy)
										&& bullets[i].y
												< (comets[j].y
														+ comets[j].boundy))
								{
									bullets[i].live = false;
									comets[j].live = false;

									ship.score++;
								}
							}

							j++;
						}
					}

					i++;
				}

				// collide comet
				i = 0;
				while (i < NUM_COMETS)
				{
					if (comets[i].live)
					{
						if (comets[i].x - comets[i].boundx
								< ship.x + ship.boundx
								&& comets[i].x + comets[i].boundx
										> ship.x - ship.boundx
								&& comets[i].y - comets[i].boundy
										< ship.y + ship.boundy
								&& comets[i].y + comets[i].boundy
										> ship.y - ship.boundy)
						{
							ship.lives--;
							comets[i].live = false;
						}
						else if (comets[i].x < 0)
						{
							comets[i].live = false;
							ship.lives--;
						}
					}

					i++;
				}

				if (ship.lives <= 0)
					isGameOver = true;
			}
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;

				//FireBullet
				int i = 0;
				while (i < NUM_BULLETS)
				{
					if (!bullets[i].live)
					{
						bullets[i].x = ship.x + 17;
						bullets[i].y = ship.y;
						bullets[i].live = true;
						break;
					}

					i++;
				}

				break;
			}
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}

		if (redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false;

			if (!isGameOver)
			{
				DrawShip(ship);
				DrawBullet(bullets, NUM_BULLETS);
				DrawComet(comets, NUM_COMETS);
				al_draw_textf(font, al_map_rgb(255, 0, 255), 5, 5, 0,
						"Player has %i lives left. Player has destroyed %i objects",
						ship.lives, ship.score);
			}
			else
			{
				al_draw_textf(font, al_map_rgb(0, 255, 255), WIDTH / 2,
						HEIGHT / 2, ALLEGRO_ALIGN_CENTRE,
						"Game Over. Final Score: %i", ship.score);
			}

			al_flip_display();
			al_clear_to_color(al_map_rgb(0, 0, 0));
		}
	}

	al_destroy_bitmap(bulletImage);
	al_destroy_bitmap(cometImage);
	al_destroy_bitmap(shipImage);
	al_destroy_event_queue(event_queue);
	al_destroy_timer(timer);
	al_destroy_font(font);
	al_destroy_display(display);					//destroy our display object

	return 0;
}