TKeyResponse CSpaceInvadersAppView::HandleKeyEventL(const TKeyEvent& aKeyEvent,
        TEventCode aType)
{
    TKeyResponse retVal = EKeyWasNotConsumed;

    if ( aKeyEvent.iCode == EKeyUpArrow )
    {
        MoveShipUp();
        retVal = EKeyWasConsumed;
    }
    else if ( aKeyEvent.iCode == EKeyRightArrow )
    {
        MoveShipRight();
        retVal = EKeyWasConsumed;
    }
    else if ( aKeyEvent.iCode == EKeyDownArrow )
    {
        MoveShipDown();
        retVal = EKeyWasConsumed;
    }
    else if ( aKeyEvent.iCode == EKeyLeftArrow )
    {
        MoveShipLeft();
        retVal = EKeyWasConsumed;
    }
    else if ( aKeyEvent.iCode == EKeyDevice1 )
    {
        GameOver();
        retVal = EKeyWasConsumed;
    }
    else if ( aKeyEvent.iCode == EKeyDevice3
              || aKeyEvent.iCode == EKeyEnter )
    {
        if ( ! iShip->HasFired() )
        {
            iShip->ShotFired();
        }

        retVal = EKeyWasConsumed;
    }

    return retVal;
}
Exemple #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;
}
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;
}
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)
{
	//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;
}