/** * Render Cycle * * Clear the screen and render all the ships */ void Application::Render() { hge_->Gfx_BeginScene(); hge_->Gfx_Clear(0); // Background if (background) { background->Render(0, 0); } // Base if (base) { base->Render(S_SCREEN_WIDTH * 0.5f, S_SCREEN_HEIGHT * 0.5f); } ShipList::iterator itr; for (itr = ships_.begin(); itr != ships_.end(); itr++) { (*itr)->Render(); } // Lab 13 Task 6 : Render the missile if (mymissile) { mymissile->Render(); } // Lab 13 Task 12 : Render network missiles MissileList::iterator itr2; for (itr2 = missiles_.begin(); itr2 != missiles_.end(); itr2++) { (*itr2)->Render(); } // Render enemies for (vector<Enemy*>::iterator it = enemyList.begin(); it != enemyList.end(); ++it) { Enemy* e = *it; if (e->GetActive()) { e->Render(); } } // Render projectile for (vector<Projectile*>::iterator it = projectileList.begin(); it != projectileList.end(); ++it) { Projectile* p = *it; if (p->GetActive()) { p->Render(); } } // Render boom for (vector<Boom*>::iterator it = boomList.begin(); it != boomList.end(); ++it) { Boom* b = *it; if (b->isActive()) { b->Render(); } } // Render explosion for (vector<Explosion*>::iterator it = explosionList.begin(); it != explosionList.end(); ++it) { Explosion* e = *it; if (e->isActive()) { e->Render(); } } // Base hp if (f_base_hp) { f_base_hp->Render(S_SCREEN_WIDTH * 0.5f, S_SCREEN_HEIGHT * 0.1f, HGETEXT_CENTER, std::to_string(base_hp).c_str()); } // Score if (p1_score) { string score = "Your score: " + std::to_string(ships_.at(0)->GetScore()); p1_score->Render(S_SCREEN_WIDTH * 0.25f, S_SCREEN_HEIGHT * 0.1f, HGETEXT_CENTER, score.c_str()); } if (p2_score && ships_.size() > 1) { string score = "Other score: " + std::to_string(ships_.at(1)->GetScore()); p1_score->Render(S_SCREEN_WIDTH * 0.75f, S_SCREEN_HEIGHT * 0.1f, HGETEXT_CENTER, score.c_str()); } // Chat if (chatMode || chatShowTimer > 0.f) { const float MSG_INTERVAL = 30.f; if (chatList.size() > 0) { int index = 0; for (vector<string>::iterator it = chatList.begin(); it != chatList.end(); ++it, ++index) { string msg = *it; chatMsg->Render(0, S_SCREEN_HEIGHT - (MSG_INTERVAL * (chatList.size() + 1 - index)), HGETEXT_LEFT, msg.c_str()); } } chatMsg->Render(0, S_SCREEN_HEIGHT - MSG_INTERVAL, HGETEXT_LEFT, typingMsg.c_str()); } hge_->Gfx_EndScene(); }
int main(void) { initialize(); int nva = al_get_num_video_adapters(); assert(nva); ALLEGRO_MONITOR_INFO aminfo; al_get_monitor_info(0, &aminfo); screen_w = aminfo.x2 - aminfo.x1 + 1; screen_h = aminfo.y2 - aminfo.y1 + 1; ALLEGRO_DISPLAY *display = al_create_display(screen_w, screen_h); ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue(); ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 120.0); al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true); if (!display) { printf("Failed to create display!\n"); exit(EXIT_FAILURE); } al_register_event_source(evqueue, al_get_keyboard_event_source()); al_register_event_source(evqueue, al_get_mouse_event_source()); al_register_event_source(evqueue, al_get_display_event_source(display)); al_register_event_source(evqueue, al_get_timer_event_source(fps_timer)); al_start_timer(fps_timer); //////////////////////////////////////////////////////////////////////////////////////////////// // Local Variables //////////////////////////////////////////////////////////////////////////////////////////////// //#ifdef DEBUG float fps = 0, delta_time = 0, current_time = 0, last_time = al_get_time(); //#endif //DEBUG bool render = true, executing = true; unsigned int spawn_counter = 0; Assets* assets = new Assets(); Stage stage = Menu; Stats stats; Button *play = new Button("Play", assets->fnt_menu, screen_w / 2, 300, [&stage, &stats]() -> void { stage = Game; stats.start_time = al_get_time(); }), *leaderboard = new Button("Leaderboard", assets->fnt_menu, screen_w / 2, 400, [&stage]() -> void { stage = Leaderboard; }), *options = new Button("Options", assets->fnt_menu, screen_w / 2, 500, [&stage]() -> void { stage = Options; }), *quit = new Button("Quit", assets->fnt_menu, screen_w / 2, 600, [&executing]() -> void { executing = false; }); b2Vec2 gravity(0.0f, 0.0f); b2World world(gravity); Projectile *player = new Projectile(assets->png_player, &world, screen_w / 2, screen_h - 200); std::vector<Projectile*> Meteors; //////////////////////////////////////////////////////////////////////////////////////////////// // Game Loop //////////////////////////////////////////////////////////////////////////////////////////////// while (executing) { ALLEGRO_EVENT event; al_wait_for_event(evqueue, &event); //#ifdef DEBUG current_time = al_get_time(); delta_time = current_time - last_time; fps = 1/(delta_time); last_time = current_time; //#endif //DEBUG world.Step(delta_time, 8, 3); switch (event.type) { // HANDLE ALLEGRO EVENTS case ALLEGRO_EVENT_TIMER: render = true; if (stage == Game) spawn_counter++; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: executing = false; break; case ALLEGRO_EVENT_KEY_DOWN: executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE; switch(event.keyboard.keycode) { case ALLEGRO_KEY_A: case ALLEGRO_KEY_LEFT: if (stage == Game) player->Velocity.x = -5; break; case ALLEGRO_KEY_D: case ALLEGRO_KEY_RIGHT: if (stage == Game) player->Velocity.x = 5; break; } break; case ALLEGRO_EVENT_KEY_UP: if (stage == Game) { player->Velocity.x = 0; player->Velocity.y = 0; } break; default: break; } switch (stage) { // UPDATE case Menu: play->Update(&event); leaderboard->Update(&event); options->Update(&event); quit->Update(&event); break; case Game: if (player->m_body->GetPosition().x < 1) player->m_body->SetTransform(b2Vec2(screen_w - 2, player->m_body->GetPosition().y), 0); if (player->m_body->GetPosition().x > screen_w - 1) player->m_body->SetTransform(b2Vec2(2, player->m_body->GetPosition().y), 0); if (spawn_counter > 75) { spawn_counter = 0; ALLEGRO_BITMAP *meteor_png; switch (rand() % 4) { // Size case 0: switch (rand() % 4) { // Selection case 0: meteor_png = rand() % 2 ? assets->png_meteor_brown_big1 : assets->png_meteor_grey_big1; break; case 1: meteor_png = rand() % 2 ? assets->png_meteor_brown_big2 : assets->png_meteor_grey_big2; break; case 2: meteor_png = rand() % 2 ? assets->png_meteor_brown_big3 : assets->png_meteor_grey_big3; break; case 3: meteor_png = rand() % 2 ? assets->png_meteor_brown_big4 : assets->png_meteor_grey_big4; break; default: break; } break; case 1: switch (rand() % 2) { // Selection case 0: meteor_png = rand() % 2 ? assets->png_meteor_brown_med1 : assets->png_meteor_grey_med1; break; case 1: meteor_png = rand() % 2 ? assets->png_meteor_brown_med2 : assets->png_meteor_grey_med2; break; default: break; } break; case 2: switch (rand() % 2) { // Selection case 0: meteor_png = rand() % 2 ? assets->png_meteor_brown_small1 : assets->png_meteor_grey_small1; break; case 1: meteor_png = rand() % 2 ? assets->png_meteor_brown_small2 : assets->png_meteor_grey_small2; break; default: break; } break; case 3: switch (rand() % 2) { // Selection case 0: meteor_png = rand() % 2 ? assets->png_meteor_brown_tiny1 : assets->png_meteor_grey_tiny1; break; case 1: meteor_png = rand() % 2 ? assets->png_meteor_brown_tiny2 : assets->png_meteor_grey_tiny2; break; default: break; } break; default: break; } auto it = Meteors.end(); Projectile *meteor = new Projectile(meteor_png, &world, rand() % screen_w, -75); meteor->Velocity = b2Vec2(-5 + (rand() % 10), rand() % 15); Meteors.insert(it, meteor); } for (std::vector<Projectile*>::iterator it = Meteors.begin(); it != Meteors.end(); ++it) { if (((*it)->m_body->GetPosition().x >= screen_w + 500 || (*it)->m_body->GetPosition().x <= -500) || ((*it)->m_body->GetPosition().y >= screen_h + 500 || (*it)->m_body->GetPosition().y <= -500) || (((*it)->m_body->GetTransform().p.x == 0.0) && (*it)->m_body->GetTransform().p.y == 0.0)) { delete *it; Meteors.erase(it); } } player->Update(&event); for (auto& x : Meteors) { x->Update(&event); } break; case Leaderboard: break; case Options: break; case End: break; default: break; } if (render && al_is_event_queue_empty(evqueue)) { render = false; al_clear_to_color(al_map_rgb(0, 0, 0)); al_set_target_bitmap(al_get_backbuffer(display)); for (float x = 0; x < screen_w; x += al_get_bitmap_width(assets->png_background)) { for (float y = 0; y < screen_h; y += al_get_bitmap_height(assets->png_background)) { al_draw_bitmap(assets->png_background, x, y, 0); } } #ifdef DEBUG //al_draw_textf(assets->fnt_menu, al_map_rgb(255, 0, 255), 10, 5, ALLEGRO_ALIGN_LEFT, "Debug"); //al_draw_textf(assets->fnt_menu, al_map_rgb(255, 0, 255), 10, 35, ALLEGRO_ALIGN_LEFT, "FPS: %i", (int)fps); //al_draw_textf(assets->fnt_menu, al_map_rgb(255, 0, 255), 10, 65, ALLEGRO_ALIGN_LEFT, "Meteor Count: %i", Meteors.size()); #endif // DEBUG switch (stage) { // RENDER default: break; case Menu: al_draw_text(assets->fnt_title, al_map_rgb(255, 255, 255), screen_w/2, 100, ALLEGRO_ALIGN_CENTRE, "SPACE SHOOTER III"); play->Render(); leaderboard->Render(); options->Render(); quit->Render(); break; case Game: player->Render(); for (auto& x : Meteors) { x->Render(); } break; case Leaderboard: break; case Options: break; case End: break; } al_flip_display(); } render = false; } //////////////////////////////////////////////////////////////////////////////////////////////// // Deinitialization //////////////////////////////////////////////////////////////////////////////////////////////// delete player; al_unregister_event_source(evqueue, al_get_keyboard_event_source()); al_unregister_event_source(evqueue, al_get_mouse_event_source()); al_unregister_event_source(evqueue, al_get_display_event_source(display)); al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer)); al_destroy_display(display); al_destroy_event_queue(evqueue); al_destroy_timer(fps_timer); delete assets; shutdown(); return EXIT_SUCCESS; }
void BattleStage::Render() { BattlePlayer* ply; al_draw_bitmap( backgroundImage, 0, 0, 0 ); for( std::list<Pickup*>::const_iterator i = GamePickups.begin(); i != GamePickups.end(); i++ ) { Pickup* p = (*i); p->Render(); } for( std::list<Projectile*>::const_reverse_iterator i = GameObjects.rbegin(); i != GameObjects.rend(); i++ ) { Projectile* p = (*i); p->Render(); } LeftPlayer->Render(); RightPlayer->Render(); // Boundaries of playing area al_draw_line( MAIN_POS_X - MAIN_BORDER, MAIN_POS_Y - MAIN_BORDER/ 2.0f, MAIN_POS_X + MAIN_WIDTH + MAIN_BORDER, MAIN_POS_Y - MAIN_BORDER/ 2.0f, al_map_rgb( 255, 255, 255 ), MAIN_BORDER ); al_draw_line( MAIN_POS_X + MAIN_WIDTH + MAIN_BORDER / 2.0f, MAIN_POS_Y, MAIN_POS_X + MAIN_WIDTH + MAIN_BORDER / 2.0f, MAIN_POS_Y + MAIN_HEIGHT, al_map_rgb( 255, 255, 255 ), MAIN_BORDER ); al_draw_line( MAIN_POS_X - MAIN_BORDER, MAIN_POS_Y + MAIN_HEIGHT + MAIN_BORDER/ 2.0f, MAIN_POS_X + MAIN_WIDTH + MAIN_BORDER, MAIN_POS_Y + MAIN_HEIGHT + MAIN_BORDER/ 2.0f, al_map_rgb( 255, 255, 255 ), MAIN_BORDER ); al_draw_line( MAIN_POS_X - MAIN_BORDER/ 2.0f, MAIN_POS_Y, MAIN_POS_X - MAIN_BORDER/ 2.0f, MAIN_POS_Y + MAIN_HEIGHT, al_map_rgb( 255, 255, 255 ), MAIN_BORDER ); ply = (BattlePlayer*)LeftPlayer; // Left player inventory al_draw_text( labelFont, al_map_rgb( 255, 255, 255 ), INVENTORY_LEFT_X_POS + INVENTORY_ITEM_SIZE / 2.0f, INVENTORY_LEFT_Y_POS - LABEL_FONT_SIZE * 1.2f, ALLEGRO_ALIGN_CENTRE, "items" ); inventoryIcons->DrawSprite( ply->Inventory[0], INVENTORY_LEFT_X_POS, INVENTORY_LEFT_Y_POS, 1.0f, 1.0f, 0 ); inventoryIcons->DrawSprite( ply->Inventory[1], INVENTORY_LEFT_X_POS, INVENTORY_LEFT_Y_POS + INVENTORY_ITEM_SIZE + INVENTORY_LEFT_Y_SPACING, 1.0f, 1.0f, 0 ); inventoryIcons->DrawSprite( ply->Inventory[2], INVENTORY_LEFT_X_POS, INVENTORY_LEFT_Y_POS + (INVENTORY_ITEM_SIZE + INVENTORY_LEFT_Y_SPACING) * 2, 1.0f, 1.0f, 0 ); // Left player health al_draw_text( labelFont, al_map_rgb( 255, 255, 255 ), HEALTH_LEFT_X_POS + HEALTH_LEFT_WIDTH / 2.0f, HEALTH_LEFT_Y_POS - HEALTH_LEFT_BORDER - LABEL_FONT_SIZE * 1.2f, ALLEGRO_ALIGN_CENTRE, "health" ); al_draw_filled_rectangle( HEALTH_LEFT_X_POS - HEALTH_LEFT_BORDER, HEALTH_LEFT_Y_POS - HEALTH_LEFT_BORDER, HEALTH_LEFT_X_POS + HEALTH_LEFT_WIDTH + HEALTH_LEFT_BORDER, HEALTH_LEFT_Y_POS + HEALTH_LEFT_HEIGHT + HEALTH_LEFT_BORDER, al_map_rgb( 255, 255, 255 ) ); al_draw_filled_rectangle( HEALTH_LEFT_X_POS, HEALTH_LEFT_Y_POS + (1.0f - (ply->Health / (float)ply->MaxHealth)) * HEALTH_LEFT_HEIGHT, HEALTH_LEFT_X_POS + HEALTH_LEFT_WIDTH, HEALTH_LEFT_Y_POS + HEALTH_LEFT_HEIGHT, al_map_rgb( 168, 0, 0 ) ); ply = (BattlePlayer*)RightPlayer; // Right player inventory al_draw_text( labelFont, al_map_rgb( 255, 255, 255 ), INVENTORY_RIGHT_X_POS + INVENTORY_ITEM_SIZE / 2.0f, INVENTORY_RIGHT_Y_POS - LABEL_FONT_SIZE * 1.2f, ALLEGRO_ALIGN_CENTRE, "items" ); inventoryIcons->DrawSprite( ply->Inventory[0], INVENTORY_RIGHT_X_POS, INVENTORY_RIGHT_Y_POS, 1.0f, 1.0f, 0 ); inventoryIcons->DrawSprite( ply->Inventory[1], INVENTORY_RIGHT_X_POS, INVENTORY_RIGHT_Y_POS + INVENTORY_ITEM_SIZE + INVENTORY_RIGHT_Y_SPACING, 1.0f, 1.0f, 0 ); inventoryIcons->DrawSprite( ply->Inventory[2], INVENTORY_RIGHT_X_POS, INVENTORY_RIGHT_Y_POS + (INVENTORY_ITEM_SIZE + INVENTORY_RIGHT_Y_SPACING) * 2, 1.0f, 1.0f, 0 ); // Right player health al_draw_text( labelFont, al_map_rgb( 255, 255, 255 ), HEALTH_RIGHT_X_POS + HEALTH_RIGHT_WIDTH / 2.0f, HEALTH_RIGHT_Y_POS - HEALTH_RIGHT_BORDER- LABEL_FONT_SIZE * 1.2f, ALLEGRO_ALIGN_CENTRE, "health" ); al_draw_filled_rectangle( HEALTH_RIGHT_X_POS - HEALTH_RIGHT_BORDER, HEALTH_RIGHT_Y_POS - HEALTH_RIGHT_BORDER, HEALTH_RIGHT_X_POS + HEALTH_RIGHT_WIDTH + HEALTH_RIGHT_BORDER, HEALTH_RIGHT_Y_POS + HEALTH_RIGHT_HEIGHT + HEALTH_RIGHT_BORDER, al_map_rgb( 255, 255, 255 ) ); al_draw_filled_rectangle( HEALTH_RIGHT_X_POS, HEALTH_RIGHT_Y_POS + (1.0f - (ply->Health / (float)ply->MaxHealth)) * HEALTH_RIGHT_HEIGHT, HEALTH_RIGHT_X_POS + HEALTH_RIGHT_WIDTH, HEALTH_RIGHT_Y_POS + HEALTH_RIGHT_HEIGHT, al_map_rgb( 168, 0, 0 ) ); }