4 * Created on: Apr 9, 2012
10 #include "../app/Control.h"
18 using game::Collision;
20 using std::runtime_error;
21 using std::stringstream;
29 , scoreFont(TTF_OpenFont("data/font/Magra-Regular.ttf", 24))
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))
55 throw runtime_error("failed to load score font");
58 ball.SetPosition(Entity::Vector(400, 240));
59 ball.SetVelocity(Entity::Vector(190, 190));
60 ball.SetMaxVelocity(750.0f);
62 secondBall.SetPosition(Entity::Vector(300, 240));
63 secondBall.SetVelocity(Entity::Vector(-100, -100));
64 secondBall.SetMaxVelocity(600.0f);
66 thirdBall.SetPosition(Entity::Vector(250, 440));
67 thirdBall.SetVelocity(Entity::Vector(100, 100));
68 thirdBall.SetMaxVelocity(600.0f);
70 fourthBall.SetPosition(Entity::Vector(550, 250));
71 fourthBall.SetVelocity(Entity::Vector(100, 100));
72 fourthBall.SetMaxVelocity(600.0f);
74 fifthBall.SetPosition(Entity::Vector(340, 250));
75 fifthBall.SetVelocity(Entity::Vector(100, 100));
76 fifthBall.SetMaxVelocity(600.0f);
78 sixthBall.SetPosition(Entity::Vector(550, 350));
79 sixthBall.SetVelocity(Entity::Vector(100, 100));
80 sixthBall.SetMaxVelocity(600.0f);
82 leftPaddle.SetPosition(Entity::Vector(0, 200));
83 rightPaddle.SetPosition(Entity::Vector(790, 280));
85 leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
86 rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
88 leftPaddle.SetStatic();
89 rightPaddle.SetStatic();
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));
97 rightWall.SetStatic();
98 bottomWall.SetStatic();
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);
115 collisions.reserve(2 * entities.size());
118 Match::~Match(void) {
123 void Match::EnterState(Control *c, SDL_Surface *screen) {
127 void Match::ExitState(void) {
129 TTF_CloseFont(scoreFont);
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();
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();
160 void Match::UpdateWorld(float deltaT) {
161 UpdateEntities(deltaT);
162 CheckCollisions(deltaT);
163 HandleCollisions(deltaT);
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);
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()) {
179 while ((*i)->Overlaps(**j, normal)) {
182 } else if ((*j)->IsDynamic()) {
184 while ((*j)->Overlaps(**i, normal)) {
188 (*i)->Revert(deltaT);
189 (*j)->Revert(deltaT);
191 collisions.push_back(Collision(*i, *j, normal));
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();
205 if (!collisions.empty()) {
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);
220 void Match::RenderHUD(SDL_Surface *screen) {
228 void Match::RenderScore(SDL_Surface *screen) {
229 SDL_Rect dest = { 2, 2, 0, 0 };
230 SDL_BlitSurface(leftScoreText, 0, screen, &dest);
232 dest.x = screen->w - rightScoreText->w - 2;
233 SDL_BlitSurface(rightScoreText, 0, screen, &dest);
236 // dest.y = screen->h - topScoreText->h - 2;
237 // SDL_BlitSurface(topScoreText, 0, screen, &dest);
239 // dest.x = screen->w - bottomScoreText->w - 2;
240 // dest.y = screen->h - bottomScoreText->h - 2;
241 // SDL_BlitSurface(bottomScoreText, 0, screen, &dest);
243 // dest.x = screen->w/2 - totalScoreText->w/2;
245 // SDL_BlitSurface(totalScoreText, 0, screen, &dest);
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);
262 s << "right: " << rightWall.HitCount();
263 leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
266 s << "left: " << leftWall.HitCount();
267 rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
270 s << "top: " << topWall.HitCount();
271 topScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
274 s << "bottom: " << bottomWall.HitCount();
275 bottomScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
278 s << "total: " << rightWall.HitCount() + leftWall.HitCount() + topWall.HitCount() + bottomWall.HitCount();
279 totalScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);