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", 30))
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))
49 throw runtime_error("failed to load score font");
52 ball.SetPosition(Entity::Vector(400, 240));
53 ball.SetVelocity(Entity::Vector(190, 190));
54 ball.SetMaxVelocity(750.0f);
56 secondBall.SetPosition(Entity::Vector(300, 240));
57 secondBall.SetVelocity(Entity::Vector(-100, -100));
58 secondBall.SetMaxVelocity(600.0f);
60 thirdBall.SetPosition(Entity::Vector(250, 440));
61 thirdBall.SetVelocity(Entity::Vector(100, 100));
62 thirdBall.SetMaxVelocity(600.0f);
64 leftPaddle.SetPosition(Entity::Vector(0, 200));
65 rightPaddle.SetPosition(Entity::Vector(790, 280));
67 leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
68 rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
70 leftPaddle.SetStatic();
71 rightPaddle.SetStatic();
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));
79 rightWall.SetStatic();
80 bottomWall.SetStatic();
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);
94 collisions.reserve(2 * entities.size());
102 void Match::EnterState(Control *c, SDL_Surface *screen) {
106 void Match::ExitState(void) {
108 TTF_CloseFont(scoreFont);
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();
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();
139 void Match::UpdateWorld(float deltaT) {
140 UpdateEntities(deltaT);
141 CheckCollisions(deltaT);
142 HandleCollisions(deltaT);
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);
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()) {
158 while ((*i)->Overlaps(**j, normal)) {
161 } else if ((*j)->IsDynamic()) {
163 while ((*j)->Overlaps(**i, normal)) {
167 (*i)->Revert(deltaT);
168 (*j)->Revert(deltaT);
170 collisions.push_back(Collision(*i, *j, normal));
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();
184 if (!collisions.empty()) {
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);
199 void Match::RenderHUD(SDL_Surface *screen) {
207 void Match::RenderScore(SDL_Surface *screen) {
208 SDL_Rect dest = { 2, 2, 0, 0 };
209 SDL_BlitSurface(leftScoreText, 0, screen, &dest);
211 dest.x = screen->w - rightScoreText->w - 2;
212 SDL_BlitSurface(rightScoreText, 0, screen, &dest);
215 void Match::UpdateScore(SDL_Surface *screen) {
216 if (!scoreFont) return;
217 if (leftScoreText) SDL_FreeSurface(leftScoreText);
218 if (rightScoreText) SDL_FreeSurface(rightScoreText);
226 s << rightWall.HitCount();
227 leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
230 s << leftWall.HitCount();
231 rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);