]> git.localhorst.tv Git - sdl-test7.git/blob - src/pong/Match.cpp
added some comments
[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", 24))
30 , leftScoreText(0)
31 , rightScoreText(0)
32 , topScoreText(0)
33 , bottomScoreText(0)
34 , totalScoreText(0)
35 , paddleSpeed(250)
36 , worldWidth(800)
37 , worldHeight(480)
38 , ball(10)
39 , secondBall(7)
40 , thirdBall(7)
41 , fourthBall(8)
42 , fifthBall(9)
43 , sixthBall(11)
44 , leftPaddle(Entity::Vector(10, 100))
45 , rightPaddle(Entity::Vector(10, 100))
46 , topWall(Entity::Vector(800, 20))
47 , bottomWall(Entity::Vector(800, 20))
48 , leftWall(Entity::Vector(10, 480))
49 , rightWall(Entity::Vector(10, 480))
50 , entities()
51 , collisions()
52 , updateScore(true) {
53
54         if (!scoreFont) {
55                 throw runtime_error("failed to load score font");
56         }
57
58         ball.SetPosition(Entity::Vector(400, 240));
59         ball.SetVelocity(Entity::Vector(190, 190));
60         ball.SetMaxVelocity(750.0f);
61
62         secondBall.SetPosition(Entity::Vector(300, 240));
63         secondBall.SetVelocity(Entity::Vector(-100, -100));
64         secondBall.SetMaxVelocity(600.0f);
65
66         thirdBall.SetPosition(Entity::Vector(250, 440));
67         thirdBall.SetVelocity(Entity::Vector(100, 100));
68         thirdBall.SetMaxVelocity(600.0f);
69
70         fourthBall.SetPosition(Entity::Vector(550, 250));
71         fourthBall.SetVelocity(Entity::Vector(100, 100));
72         fourthBall.SetMaxVelocity(600.0f);
73
74         fifthBall.SetPosition(Entity::Vector(340, 250));
75         fifthBall.SetVelocity(Entity::Vector(100, 100));
76         fifthBall.SetMaxVelocity(600.0f);
77
78         sixthBall.SetPosition(Entity::Vector(550, 350));
79         sixthBall.SetVelocity(Entity::Vector(100, 100));
80         sixthBall.SetMaxVelocity(600.0f);
81
82         leftPaddle.SetPosition(Entity::Vector(0, 200));
83         rightPaddle.SetPosition(Entity::Vector(790, 280));
84
85         leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
86         rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
87
88         leftPaddle.SetStatic();
89         rightPaddle.SetStatic();
90
91         topWall.SetPosition(Entity::Vector(0, -20));
92         rightWall.SetPosition(Entity::Vector(800, 0));
93         bottomWall.SetPosition(Entity::Vector(0, 480));
94         leftWall.SetPosition(Entity::Vector(-10, 0));
95
96         topWall.SetStatic();
97         rightWall.SetStatic();
98         bottomWall.SetStatic();
99         leftWall.SetStatic();
100
101         entities.reserve(12);
102         entities.push_back(&ball);
103         entities.push_back(&secondBall);
104         entities.push_back(&thirdBall);
105 //      entities.push_back(&fourthBall);
106 //      entities.push_back(&fifthBall);
107 //      entities.push_back(&sixthBall);
108         entities.push_back(&leftPaddle);
109         entities.push_back(&rightPaddle);
110         entities.push_back(&topWall);
111         entities.push_back(&bottomWall);
112         entities.push_back(&leftWall);
113         entities.push_back(&rightWall);
114
115         collisions.reserve(2 * entities.size());
116 }
117
118 Match::~Match(void) {
119
120 }
121
122
123 void Match::EnterState(Control *c, SDL_Surface *screen) {
124         ctrl = c;
125 }
126
127 void Match::ExitState(void) {
128         if (scoreFont) {
129                 TTF_CloseFont(scoreFont);
130                 scoreFont = 0;
131         }
132 }
133
134 void Match::HandleEvent(const SDL_Event &e) {
135         if (e.type == SDL_KEYDOWN) {
136                 if (e.key.keysym.sym == SDLK_w) {
137                         leftPaddle.StartMovingUp();
138                 } else if (e.key.keysym.sym == SDLK_s) {
139                         leftPaddle.StartMovingDown();
140                 } else if (e.key.keysym.sym == SDLK_UP) {
141                         rightPaddle.StartMovingUp();
142                 } else if (e.key.keysym.sym == SDLK_DOWN) {
143                         rightPaddle.StartMovingDown();
144                 }
145         } else if (e.type == SDL_KEYUP) {
146                 if (e.key.keysym.sym == SDLK_w) {
147                         leftPaddle.StopMovingUp();
148                 } else if (e.key.keysym.sym == SDLK_s) {
149                         leftPaddle.StopMovingDown();
150                 } else if (e.key.keysym.sym == SDLK_UP) {
151                         rightPaddle.StopMovingUp();
152                 } else if (e.key.keysym.sym == SDLK_DOWN) {
153                         rightPaddle.StopMovingDown();
154                 } else if (e.key.keysym.sym == SDLK_q) {
155                         if (ctrl) ctrl->Quit();
156                 }
157         }
158 }
159
160 void Match::UpdateWorld(float deltaT) {
161         UpdateEntities(deltaT);
162         CheckCollisions(deltaT);
163         HandleCollisions(deltaT);
164 }
165
166 void Match::UpdateEntities(float deltaT) {
167         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
168                 (*i)->Update(deltaT);
169         }
170 }
171
172 void Match::CheckCollisions(float deltaT) {
173         Entity::Vector normal;
174         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
175                 for (vector<Entity *>::const_iterator j(i + 1); j != end; ++j) {
176                         if ((*i)->Overlaps(**j, normal)) {
177                                 if ((*i)->IsDynamic()) {
178                                         (*i)->Move(normal);
179                                         while ((*i)->Overlaps(**j, normal)) {
180                                                 (*i)->Move(normal);
181                                         }
182                                 } else if ((*j)->IsDynamic()) {
183                                         (*j)->Move(normal);
184                                         while ((*j)->Overlaps(**i, normal)) {
185                                                 (*j)->Move(normal);
186                                         }
187                                 } else {
188                                         (*i)->Revert(deltaT);
189                                         (*j)->Revert(deltaT);
190                                 }
191                                 collisions.push_back(Collision(*i, *j, normal));
192                         }
193                 }
194         }
195 }
196
197 void Match::HandleCollisions(float deltaT) {
198         for (vector<Collision>::const_iterator i(collisions.begin()), end(collisions.end()); i != end; ++i) {
199                 i->left->Collide(*(i->right), i->normal);
200                 i->right->Collide(*(i->left), -(i->normal));
201                 i->left->PostCollide();
202                 i->right->PostCollide();
203
204         }
205         if (!collisions.empty()) {
206                 updateScore = true;
207         }
208         collisions.clear();
209 }
210
211
212 void Match::Render(SDL_Surface *screen) {
213         SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
214         for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
215                 (*i)->Render(screen);
216         }
217         RenderHUD(screen);
218 }
219
220 void Match::RenderHUD(SDL_Surface *screen) {
221         if (updateScore) {
222                 UpdateScore(screen);
223                 updateScore = false;
224         }
225         RenderScore(screen);
226 }
227
228 void Match::RenderScore(SDL_Surface *screen) {
229         SDL_Rect dest = { 2, 2, 0, 0 };
230         SDL_BlitSurface(leftScoreText, 0, screen, &dest);
231
232         dest.x = screen->w - rightScoreText->w - 2;
233         SDL_BlitSurface(rightScoreText, 0, screen, &dest);
234
235 //      dest.x = 2;
236 //      dest.y = screen->h - topScoreText->h - 2;
237 //      SDL_BlitSurface(topScoreText, 0, screen, &dest);
238 //
239 //      dest.x = screen->w - bottomScoreText->w - 2;
240 //      dest.y = screen->h - bottomScoreText->h - 2;
241 //      SDL_BlitSurface(bottomScoreText, 0, screen, &dest);
242 //
243 //      dest.x = screen->w/2 - totalScoreText->w/2;
244 //      dest.y = 2;
245 //      SDL_BlitSurface(totalScoreText, 0, screen, &dest);
246 }
247
248 void Match::UpdateScore(SDL_Surface *screen) {
249         if (!scoreFont) return;
250         if (leftScoreText) SDL_FreeSurface(leftScoreText);
251         if (rightScoreText) SDL_FreeSurface(rightScoreText);
252         if (topScoreText) SDL_FreeSurface(topScoreText);
253         if (bottomScoreText) SDL_FreeSurface(bottomScoreText);
254         if (totalScoreText) SDL_FreeSurface(totalScoreText);
255
256         SDL_Color color;
257         color.r = 0xFF;
258         color.g = 0xFF;
259         color.b = 0xFF;
260
261         stringstream s;
262         s << "right: " << rightWall.HitCount();
263         leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
264
265         s.str("");
266         s << "left: " << leftWall.HitCount();
267         rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
268
269         s.str("");
270         s << "top: " << topWall.HitCount();
271         topScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
272
273         s.str("");
274         s << "bottom: " << bottomWall.HitCount();
275         bottomScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
276
277         s.str("");
278         s << "total: " << rightWall.HitCount() + leftWall.HitCount() + topWall.HitCount() + bottomWall.HitCount();
279         totalScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
280 }
281
282 }