Subversion Repositories battle

[/] [trunk/] [Battle/] [Gameplay.cpp] - Blame information for rev 161

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 77 bert
#include "SDL/SDL.h"
2 bert
 
3 bert
#include <vector>
4 bert
 
5 bert
#include "Main.h"
6 bert
#include "Level.h"
7 bert
#include "Player.h"
8 bert
#include "GameplayObject.h"
9 82 bert
#include "PauseMenu.h"
10 77 bert
 
11 bert
#include "Gameplay.h"
12 bert
 
13 84 bert
#ifndef WIN32
14 bert
#define sprintf_s snprintf
15 bert
#endif
16 bert
 
17 77 bert
int Gameplay::frame = 0;
18 78 bert
Gameplay * Gameplay::instance = 0;
19 77 bert
 
20 bert
Gameplay::Gameplay() {
21 78 bert
        instance = this;
22 bert
 
23 77 bert
        game_running = false;
24 bert
        players = new std::vector<Player*>();
25 136 bert
        npcs = new std::vector<NPC*>();
26 77 bert
        objects = new std::vector<GameplayObject*>();
27 78 bert
 
28 bert
        players_collide = true;
29 bert
        npcs_collide = true;
30 bert
        players_npcs_collide = true;
31 bert
 
32 77 bert
}
33 bert
 
34 bert
Gameplay::~Gameplay() {
35 78 bert
        instance = NULL;
36 77 bert
}
37 bert
 
38 bert
void Gameplay::run() {
39 bert
        SDL_Event event;
40 bert
 
41 bert
        screen = Main::instance->screen;
42 bert
 
43 138 bert
        Main::autoreset = false;
44 bert
 
45 77 bert
        initialize();
46 bert
 
47 bert
        reset_game();
48 bert
 
49 bert
        game_running = true;
50 124 bert
        Main::instance->audio->stop_music();
51 bert
        music_playing = false;
52 114 bert
 
53 bert
        // Set the input defaults
54 bert
        for(unsigned int idx = 0; idx < players->size(); idx++) {
55 bert
                Player * p = players->at(idx);
56 bert
                p->input->unset_delay();
57 bert
        }
58 77 bert
 
59 bert
        while(Main::running && game_running) {
60 bert
                // Event handling
61 bert
                while(SDL_PollEvent(&event)) {
62 bert
                        Main::instance->handle_event(&event);
63 bert
 
64 bert
                        // Handle player input
65 bert
                        for(unsigned int idx = 0; idx < players->size(); idx++) {
66 bert
                                Player * p = players->at(idx);
67 114 bert
                                p->input->handle_event(&event);
68 77 bert
                        }
69 115 bert
 
70 bert
                        handle_pause_input(&event);
71 bert
 
72 77 bert
                }
73 bert
 
74 bert
                // Gameplay processing
75 78 bert
                on_pre_processing();
76 82 bert
                if(!countdown && !ended) {
77 77 bert
                        // Move and process players
78 bert
                        for(unsigned int idx = 0; idx < players->size(); idx++) {
79 bert
                                Player * p = players->at(idx);
80 78 bert
                                p->move(level);
81 bert
                                p->process();
82 77 bert
                        }
83 bert
 
84 bert
                        process_player_collission();
85 bert
 
86 bert
                        // Move and process NPCs
87 136 bert
                        for(unsigned int idx = 0; idx < npcs->size(); idx++) {
88 77 bert
                                NPC * npc = npcs->at(idx);
89 136 bert
                                npc->move(level);
90 77 bert
                                npc->process();
91 137 bert
 
92 bert
                                if(npc->done) {
93 bert
                                        npcs->erase(npcs->begin() + idx);
94 bert
                                        delete npc;
95 bert
                                }
96 136 bert
                        }
97 77 bert
 
98 bert
                        process_npc_collission();
99 bert
 
100 137 bert
                        process_player_npc_collission();
101 bert
 
102 77 bert
                        // Move and process objects
103 bert
                        for(unsigned int idx = 0; idx < objects->size(); idx++) {
104 bert
                                GameplayObject * obj = objects->at(idx);
105 78 bert
                                obj->move(level);
106 77 bert
                                obj->process();
107 78 bert
                                for(unsigned int i = 0; i < players->size(); i++) {
108 bert
                                        Player * p = players->at(i);
109 79 bert
                                        if(p->is_dead)
110 bert
                                                continue;
111 78 bert
                                        SDL_Rect * rect;
112 bert
                                        rect = p->get_rect();
113 bert
                                        if(is_intersecting(rect, obj->position)) {
114 bert
                                                obj->hit_player(p);
115 bert
                                        }
116 bert
                                        delete rect;
117 bert
                                }
118 140 bert
                                for(unsigned int i = 0; i < npcs->size(); i++) {
119 bert
                                        NPC * npc = npcs->at(i);
120 bert
                                        if(npc->is_dead)
121 bert
                                                continue;
122 bert
                                        SDL_Rect * rect;
123 bert
                                        rect = npc->get_rect();
124 bert
                                        if(is_intersecting(rect, obj->position)) {
125 bert
                                                obj->hit_npc(npc);
126 bert
                                        }
127 bert
                                        delete rect;
128 bert
                                }
129 77 bert
                                if(obj->done) {
130 bert
                                        objects->erase(objects->begin() + idx);
131 bert
                                        delete obj;
132 bert
                                }
133 bert
                        }
134 bert
                }
135 80 bert
                if(countdown) {
136 bert
                        process_countdown();
137 bert
                }
138 bert
 
139 78 bert
                on_post_processing();
140 77 bert
 
141 bert
                // Drawing
142 82 bert
                frame++;
143 77 bert
 
144 bert
                level->draw(screen);
145 bert
 
146 bert
                for(unsigned int idx = 0; idx < players->size(); idx++) {
147 bert
                        Player * p = players->at(idx);
148 107 bert
                        if(countdown)
149 bert
                                p->draw(screen, true);
150 bert
                        else
151 bert
                                p->draw(screen);
152 77 bert
                }
153 136 bert
                for(unsigned int idx = 0; idx < npcs->size(); idx++) {
154 77 bert
                        NPC * npc = npcs->at(idx);
155 bert
                        npc->draw(screen);
156 136 bert
                }
157 77 bert
 
158 bert
                for(unsigned int idx = 0; idx < objects->size(); idx++) {
159 bert
                        GameplayObject * obj = objects->at(idx);
160 bert
                        obj->draw(screen);
161 bert
                }
162 bert
 
163 80 bert
                draw_score();
164 78 bert
 
165 bert
                if(ended) {
166 bert
                        draw_game_ended();
167 77 bert
 
168 82 bert
                        if(frame - end_start > 120) {
169 78 bert
                                reset_game();
170 bert
                        }
171 bert
                }
172 bert
                if(countdown) {
173 80 bert
                        draw_countdown();
174 78 bert
                }
175 bert
 
176 77 bert
                Main::instance->flip();
177 bert
        }
178 bert
 
179 bert
        deinitialize();
180 138 bert
 
181 bert
        Main::autoreset = true;
182 77 bert
}
183 bert
 
184 80 bert
void Gameplay::handle_pause_input(SDL_Event * event) {
185 82 bert
        Player * player;
186 bert
        for(unsigned int i = 0; i < players->size(); i++) {
187 bert
                player = players->at(i);
188 bert
 
189 114 bert
                if(player->input->is_pressed(A_START)) {
190 bert
                        pause(player);
191 80 bert
                }
192 bert
        }
193 bert
}
194 bert
 
195 bert
void Gameplay::pause(Player * p) {
196 82 bert
        int ret;
197 bert
        ret = pause_menu->pause(p);
198 bert
        if(ret == 1) game_running = false;
199 80 bert
}
200 bert
 
201 77 bert
void Gameplay::set_level(Level * l) {
202 bert
        if(!game_running) {
203 bert
                level = l;
204 bert
        }
205 bert
}
206 bert
 
207 bert
void Gameplay::add_player(Player * p) {
208 bert
        if(!game_running) {
209 bert
                players->push_back(p);
210 bert
        }
211 bert
}
212 bert
 
213 136 bert
void Gameplay::add_npc(NPC * npc) {
214 161 bert
        npcs->push_back(npc);
215 136 bert
}
216 bert
 
217 104 bert
void Gameplay::bounce_up_players_and_npcs(SDL_Rect * rect, SDL_Rect * source) {
218 78 bert
        Player * p;
219 bert
        for(unsigned int i = 0; i < players->size(); i++) {
220 bert
                p = players->at(i);
221 bert
                if(is_intersecting(rect, p->position))
222 104 bert
                        p->bounce_up(source);
223 78 bert
        }
224 bert
 
225 bert
        NPC * npc;
226 bert
        for(unsigned int i = 0; i < npcs->size(); i++) {
227 bert
                npc = npcs->at(i);
228 bert
                if(is_intersecting(rect, npc->position))
229 136 bert
                        npc->bounce_up(source);
230 bert
        }
231 78 bert
}
232 bert
 
233 bert
void Gameplay::add_object(GameplayObject * obj) {
234 bert
        objects->push_back(obj);
235 bert
}
236 bert
 
237 77 bert
void Gameplay::reset_game() {
238 bert
        frame = 0;
239 bert
 
240 82 bert
        //paused = false;
241 77 bert
        ended = false;
242 80 bert
        countdown = true;
243 78 bert
 
244 107 bert
        countdown_sec_left = 5;
245 82 bert
        countdown_start = frame;
246 104 bert
        strcpy(countdown_pre_text, "GET READY");
247 77 bert
 
248 bert
        level->reset();
249 78 bert
 
250 bert
        // Clear gameplay objects
251 bert
        GameplayObject * obj;
252 bert
        for(unsigned int i = 0; i < objects->size(); i++) {
253 bert
                obj = objects->at(i);
254 bert
                delete obj;
255 bert
        }
256 bert
        objects->clear();
257 77 bert
 
258 78 bert
        on_game_reset();
259 77 bert
 
260 124 bert
        //Main::audio->stop_music();
261 83 bert
262 bert
        srand(SDL_GetTicks());
263 78 bert
}
264 77 bert
 
265 bert
void Gameplay::initialize() {
266 82 bert
        pause_menu = new PauseMenu(screen);
267 84 bert
        pause_menu->add_option((char*)"RESUME\0");
268 bert
        pause_menu->add_option((char*)"QUIT\0");
269 77 bert
}
270 bert
 
271 bert
void Gameplay::deinitialize() {
272 78 bert
        // Stop the music
273 bert
        if(!countdown)
274 bert
                Main::audio->stop_music();
275 bert
 
276 136 bert
        // Clear players (we don't delete the players, because they are not created in this class)
277 78 bert
        players->clear();
278 bert
        delete players;
279 bert
 
280 136 bert
        // Clear NPC's
281 147 bert
        NPC * npc;
282 bert
        for(unsigned int i = 0; i < npcs->size(); i++) {
283 bert
                npc = npcs->at(i);
284 bert
                delete npc;
285 bert
        }
286 136 bert
        npcs->clear();
287 bert
        delete npcs;
288 bert
 
289 78 bert
        // Clear gameplay objects
290 bert
        GameplayObject * obj;
291 bert
        for(unsigned int i = 0; i < objects->size(); i++) {
292 bert
                obj = objects->at(i);
293 bert
                delete obj;
294 bert
        }
295 bert
        objects->clear();
296 bert
        delete objects;
297 bert
 
298 82 bert
        // Unload pause menu
299 bert
        delete pause_menu;
300 77 bert
}
301 78 bert
 
302 bert
void Gameplay::draw_countdown() {
303 80 bert
        char text[5];
304 bert
        SDL_Surface * surf;
305 78 bert
 
306 107 bert
        if(countdown_sec_left > 3) {
307 105 bert
                surf = Main::text->render_text_medium(countdown_pre_text);
308 104 bert
        } else {
309 bert
                sprintf_s(text, 5, "%d", countdown_sec_left);
310 bert
                surf = Main::text->render_text_large(text);
311 bert
        }
312 80 bert
 
313 bert
        SDL_Rect rect;
314 bert
        rect.x = (screen->w - surf->w) / 2;
315 bert
        rect.y = (screen->h - surf->h) / 2;
316 bert
 
317 bert
        SDL_BlitSurface(surf, NULL, screen, &rect);
318 bert
        SDL_FreeSurface(surf);
319 78 bert
}
320 bert
 
321 bert
void Gameplay::draw_pause_screen() {
322 bert
 
323 bert
}
324 bert
 
325 bert
void Gameplay::draw_score() {
326 bert
 
327 bert
}
328 bert
 
329 bert
void Gameplay::draw_game_ended() {
330 bert
 
331 bert
}
332 bert
 
333 bert
bool Gameplay::is_intersecting(SDL_Rect * one, SDL_Rect * two) {
334 bert
        bool intersect;
335 bert
        int l1, r1, t1, b1;
336 bert
        int l2, r2, t2, b2;
337 bert
 
338 bert
        l1 = one->x;
339 bert
        r1 = one->x + one->w;
340 bert
        t1 = one->y;
341 bert
        b1 = one->y + one->h;
342 bert
 
343 bert
        l2 = two->x;
344 bert
        r2 = two->x + two->w;
345 bert
        t2 = two->y;
346 bert
        b2 = two->y + two->h;
347 bert
 
348 bert
        // Normal collision
349 bert
        intersect = true;
350 104 bert
        if(l1 >= r2) intersect = false;
351 bert
        if(r1 <= l2) intersect = false;
352 bert
        if(t1 >= b2) intersect = false;
353 bert
        if(b1 <= t2) intersect = false;
354 78 bert
        if(intersect) return true;
355 bert
 
356 bert
        // Collisions that go through the sides
357 bert
        if(r1 >= WINDOW_WIDTH && r2 < WINDOW_WIDTH) {
358 bert
                l1 -= WINDOW_WIDTH;
359 bert
                r1 -= WINDOW_WIDTH;
360 bert
                intersect = true;
361 bert
                if(l1 > r2) intersect = false;
362 bert
                if(r1 < l2) intersect = false;
363 bert
                if(t1 > b2) intersect = false;
364 bert
                if(b1 < t2) intersect = false;
365 bert
        }
366 bert
        else if(r2 >= WINDOW_WIDTH && r1 < WINDOW_WIDTH) {
367 bert
                l2 -= WINDOW_WIDTH;
368 bert
                r2 -= WINDOW_WIDTH;
369 bert
                intersect = true;
370 bert
                if(l1 > r2) intersect = false;
371 bert
                if(r1 < l2) intersect = false;
372 bert
                if(t1 > b2) intersect = false;
373 bert
                if(b1 < t2) intersect = false;
374 bert
        }
375 bert
 
376 bert
        return intersect;
377 bert
}
378 bert
 
379 bert
 
380 bert
void Gameplay::process_player_collission() {
381 bert
        if(!players_collide)
382 bert
                return;
383 bert
 
384 bert
        Player * p1, * p2;
385 bert
        SDL_Rect * r1, * r2;
386 bert
 
387 bert
        for(unsigned int i1 = 0; i1 < players->size(); i1++) {
388 bert
                p1 = players->at(i1);
389 79 bert
 
390 bert
                if(p1->is_dead) continue;
391 bert
 
392 78 bert
                for(unsigned int i2 = (i1 + 1); i2 < players->size(); i2++) {
393 bert
                        p2 = players->at(i2);
394 79 bert
 
395 bert
                        if(p2->is_dead) continue;
396 bert
 
397 78 bert
                        r1 = p1->get_rect();
398 bert
                        r2 = p2->get_rect();
399 bert
 
400 bert
                        if(is_intersecting(r1, r2)) {
401 126 bert
                                Main::audio->play(SND_BOUNCE, (p1->position->x + p2->position->x) / 2);
402 78 bert
 
403 86 bert
                                p1->bounce(p2);
404 bert
                                p2->bounce(p1);
405 bert
 
406 bert
                                p1->momentumx = p1->newmomentumx;
407 bert
                                p2->momentumx = p2->newmomentumx;
408 78 bert
                        }
409 bert
 
410 bert
                        delete r1;
411 bert
                        delete r2;
412 bert
                }
413 bert
        }
414 bert
}
415 bert
 
416 136 bert
void Gameplay::process_npc_collission() {
417 bert
        if(!npcs_collide)
418 bert
                return;
419 bert
 
420 bert
        NPC * c1, * c2;
421 bert
        SDL_Rect * r1, * r2;
422 bert
 
423 bert
        for(unsigned int i1 = 0; i1 < npcs->size(); i1++) {
424 bert
                c1 = npcs->at(i1);
425 bert
 
426 bert
                if(c1->is_dead) continue;
427 bert
 
428 bert
                for(unsigned int i2 = (i1 + 1); i2 < npcs->size(); i2++) {
429 bert
                        c2 = npcs->at(i2);
430 bert
 
431 bert
                        if(c2->is_dead) continue;
432 bert
 
433 bert
                        r1 = c1->get_rect();
434 bert
                        r2 = c2->get_rect();
435 bert
 
436 bert
                        if(is_intersecting(r1, r2)) {
437 bert
                                c1->bounce(c2);
438 bert
                                c2->bounce(c1);
439 bert
 
440 137 bert
                                c1->momentumx = c1->newmomentumx;
441 bert
                                c2->momentumx = c2->newmomentumx;
442 136 bert
                        }
443 bert
 
444 bert
                        delete r1;
445 bert
                        delete r2;
446 bert
                }
447 bert
        }
448 bert
}
449 bert
 
450 bert
 
451 137 bert
void Gameplay::process_player_npc_collission() {
452 bert
        Player * player;
453 bert
        NPC * npc;
454 bert
        SDL_Rect * r_player, * r_npc;
455 bert
 
456 bert
        for(unsigned int i1 = 0; i1 < players->size(); i1++) {
457 bert
                player = players->at(i1);
458 bert
 
459 bert
                if(player->is_dead) continue;
460 bert
 
461 bert
                for(unsigned int i2 = 0; i2 < npcs->size(); i2++) {
462 bert
                        npc = npcs->at(i2);
463 bert
 
464 bert
                        if(npc->is_dead) continue;
465 bert
 
466 bert
                        r_player = player->get_rect();
467 bert
                        r_npc = npc->get_rect();
468 bert
 
469 bert
                        if(is_intersecting(r_player, r_npc)) {
470 bert
                                npc->bounce(player);
471 bert
 
472 bert
                                player->momentumx = player->newmomentumx;
473 bert
                                npc->momentumx = npc->newmomentumx;
474 bert
                        }
475 bert
 
476 bert
                        delete r_player;
477 bert
                        delete r_npc;
478 bert
                }
479 bert
        }
480 bert
}
481 bert
 
482 80 bert
void Gameplay::process_countdown() {
483 82 bert
        if(frame - countdown_start >= 60) {
484 80 bert
                if(countdown_sec_left == 1) {
485 bert
                        countdown = false;
486 bert
                        Main::audio->play(SND_GO);
487 124 bert
                        if(!music_playing) {
488 152 bert
                                Main::audio->play_music(level->music);
489 124 bert
                                music_playing = true;
490 bert
                        }
491 80 bert
                        return;
492 bert
                }
493 bert
                countdown_sec_left--;
494 82 bert
                countdown_start = frame;
495 80 bert
 
496 107 bert
                if(countdown_sec_left <= 3)
497 bert
                        Main::audio->play(SND_COUNTDOWN);
498 80 bert
        }
499 bert
}