]> git.localhorst.tv Git - sdl-test7.git/blob - src/pong/Match.cpp
made the game a bit more interesting :)
[sdl-test7.git] / src / pong / Match.cpp
1 /*
2  * Match.cpp
3  *
4  *  Created on: Apr 9, 2012
5  *      Author: holy
6  */
7
8 #include "Match.h"
9
10 #include "../app/Control.h"
11
12 #include <sstream>
13 #include <stdexcept>
14 #include <utility>
15 #include <SDL/SDL.h>
16
17 using app::Control;
18 using game::Collision;
19 using game::Entity;
20 using std::runtime_error;
21 using std::stringstream;
22 using std::vector;
23
24
25 namespace pong {
26
27 Match::Match(void)
28 : ctrl(0)
29 , scoreFont(TTF_OpenFont("data/font/Magra-Regular.ttf", 30))
30 , leftScoreText(0)
31 , rightScoreText(0)
32 , paddleSpeed(250)
33 , worldWidth(800)
34 , worldHeight(480)
35 , ball(10)
36 , secondBall(7)
37 , thirdBall(7)
38 , leftPaddle(Entity::Vector(10, 100))
39 , rightPaddle(Entity::Vector(10, 100))
40 , topWall(Entity::Vector(800, 20))
41 , bottomWall(Entity::Vector(800, 20))
42 , leftWall(Entity::Vector(10, 480))
43 , rightWall(Entity::Vector(10, 480))
44 , entities()
45 , collisions()
46 , updateScore(true) {
47
48         if (!scoreFont) {
49                 throw runtime_error("failed to load score font");
50         }
51
52         ball.SetPosition(Entity::Vector(400, 240));
53         ball.SetVelocity(Entity::Vector(190, 190));
54         ball.SetMaxVelocity(750.0f);
55
56         secondBall.SetPosition(Entity::Vector(300, 240));
57         secondBall.SetVelocity(Entity::Vector(-100, -100));
58         secondBall.SetMaxVelocity(600.0f);
59
60         thirdBall.SetPosition(Entity::Vector(250, 440));
61         thirdBall.SetVelocity(Entity::Vector(100, 100));
62         thirdBall.SetMaxVelocity(600.0f);
63
64         leftPaddle.SetPosition(Entity::Vector(0, 200));
65         rightPaddle.SetPosition(Entity::Vector(790, 280));
66
67         leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
68         rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
69
70         leftPaddle.SetStatic();
71         rightPaddle.SetStatic();
72
73         topWall.SetPosition(Entity::Vector(0, -20));
74         rightWall.SetPosition(Entity::Vector(800, 0));
75         bottomWall.SetPosition(Entity::Vector(0, 480));
76         leftWall.SetPosition(Entity::Vector(-10, 0));
77
78         topWall.SetStatic();
79         rightWall.SetStatic();
80         bottomWall.SetStatic();
81         leftWall.SetStatic();
82
83         entities.reserve(9);
84         entities.push_back(&ball);
85         entities.push_back(&secondBall);
86         entities.push_back(&thirdBall);
87         entities.push_back(&leftPaddle);
88         entities.push_back(&rightPaddle);
89         entities.push_back(&topWall);
90         entities.push_back(&bottomWall);
91         entities.push_back(&leftWall);
92         entities.push_back(&rightWall);
93
94         collisions.reserve(2 * entities.size());
95 }
96
97 Match::~Match(void) {
98
99 }
100
101
102 void Match::EnterState(Control *c, SDL_Surface *screen) {
103         ctrl = c;
104 }
105
106 void Match::ExitState(void) {
107         if (scoreFont) {
108                 TTF_CloseFont(scoreFont);
109                 scoreFont = 0;
110         }
111 }
112
113 void Match::HandleEvent(const SDL_Event &e) {
114         if (e.type == SDL_KEYDOWN) {
115                 if (e.key.keysym.sym == SDLK_w) {
116                         leftPaddle.StartMovingUp();
117                 } else if (e.key.keysym.sym == SDLK_s) {
118                         leftPaddle.StartMovingDown();
119                 } else if (e.key.keysym.sym == SDLK_UP) {
120                         rightPaddle.StartMovingUp();
121                 } else if (e.key.keysym.sym == SDLK_DOWN) {
122                         rightPaddle.StartMovingDown();
123                 }
124         } else if (e.type == SDL_KEYUP) {
125                 if (e.key.keysym.sym == SDLK_w) {
126                         leftPaddle.StopMovingUp();
127                 } else if (e.key.keysym.sym == SDLK_s) {
128                         leftPaddle.StopMovingDown();
129                 } else if (e.key.keysym.sym == SDLK_UP) {
130                         rightPaddle.StopMovingUp();
131                 } else if (e.key.keysym.sym == SDLK_DOWN) {
132                         rightPaddle.StopMovingDown();
133                 } else if (e.key.keysym.sym == SDLK_q) {
134                         if (ctrl) ctrl->Quit();
135                 }
136         }
137 }
138
139 void Match::UpdateWorld(float deltaT) {
140         UpdateEntities(deltaT);
141         CheckCollisions(deltaT);
142         HandleCollisions(deltaT);
143 }
144
145 void Match::UpdateEntities(float deltaT) {
146         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
147                 (*i)->Update(deltaT);
148         }
149 }
150
151 void Match::CheckCollisions(float deltaT) {
152         Entity::Vector normal;
153         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
154                 for (vector<Entity *>::const_iterator j(i + 1); j != end; ++j) {
155                         if ((*i)->Overlaps(**j, normal)) {
156                                 if ((*i)->IsDynamic()) {
157                                         (*i)->Move(normal);
158                                         while ((*i)->Overlaps(**j, normal)) {
159                                                 (*i)->Move(normal);
160                                         }
161                                 } else if ((*j)->IsDynamic()) {
162                                         (*j)->Move(normal);
163                                         while ((*j)->Overlaps(**i, normal)) {
164                                                 (*j)->Move(normal);
165                                         }
166                                 } else {
167                                         (*i)->Revert(deltaT);
168                                         (*j)->Revert(deltaT);
169                                 }
170                                 collisions.push_back(Collision(*i, *j, normal));
171                         }
172                 }
173         }
174 }
175
176 void Match::HandleCollisions(float deltaT) {
177         for (vector<Collision>::const_iterator i(collisions.begin()), end(collisions.end()); i != end; ++i) {
178                 i->left->Collide(*(i->right), i->normal);
179                 i->right->Collide(*(i->left), -(i->normal));
180                 i->left->PostCollide();
181                 i->right->PostCollide();
182
183         }
184         if (!collisions.empty()) {
185                 updateScore = true;
186         }
187         collisions.clear();
188 }
189
190
191 void Match::Render(SDL_Surface *screen) {
192         SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
193         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
194                 (*i)->Render(screen);
195         }
196         RenderHUD(screen);
197 }
198
199 void Match::RenderHUD(SDL_Surface *screen) {
200         if (updateScore) {
201                 UpdateScore(screen);
202                 updateScore = false;
203         }
204         RenderScore(screen);
205 }
206
207 void Match::RenderScore(SDL_Surface *screen) {
208         SDL_Rect dest = { 2, 2, 0, 0 };
209         SDL_BlitSurface(leftScoreText, 0, screen, &dest);
210
211         dest.x = screen->w - rightScoreText->w - 2;
212         SDL_BlitSurface(rightScoreText, 0, screen, &dest);
213 }
214
215 void Match::UpdateScore(SDL_Surface *screen) {
216         if (!scoreFont) return;
217         if (leftScoreText) SDL_FreeSurface(leftScoreText);
218         if (rightScoreText) SDL_FreeSurface(rightScoreText);
219
220         SDL_Color color;
221         color.r = 0xFF;
222         color.g = 0xFF;
223         color.b = 0xFF;
224
225         stringstream s;
226         s << rightWall.HitCount();
227         leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
228
229         s.str("");
230         s << leftWall.HitCount();
231         rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
232 }
233
234 }