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))
37 , leftPaddle(Entity::Vector(10, 100))
38 , rightPaddle(Entity::Vector(10, 100))
39 , topWall(Entity::Vector(800, 10))
40 , bottomWall(Entity::Vector(800, 10))
41 , leftWall(Entity::Vector(10, 480))
42 , rightWall(Entity::Vector(10, 480))
48 throw runtime_error("failed to load score font");
51 ball.SetPosition(Entity::Vector(400, 240));
52 ball.SetVelocity(Entity::Vector(180, 180));
53 ball.SetMaxVelocity(500.0f);
55 secondBall.SetPosition(Entity::Vector(300, 240));
56 secondBall.SetVelocity(Entity::Vector(-20, -20));
57 secondBall.SetMaxVelocity(600.0f);
59 leftPaddle.SetPosition(Entity::Vector(0, 200));
60 rightPaddle.SetPosition(Entity::Vector(790, 280));
62 leftPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
63 rightPaddle.SetMovementSpeed(Entity::Vector(0, paddleSpeed));
65 leftPaddle.SetStatic();
66 rightPaddle.SetStatic();
68 topWall.SetPosition(Entity::Vector(0, -10));
69 rightWall.SetPosition(Entity::Vector(800, 0));
70 bottomWall.SetPosition(Entity::Vector(0, 480));
71 leftWall.SetPosition(Entity::Vector(-10, 0));
74 rightWall.SetStatic();
75 bottomWall.SetStatic();
79 entities.push_back(&ball);
80 entities.push_back(&secondBall);
81 entities.push_back(&leftPaddle);
82 entities.push_back(&rightPaddle);
83 entities.push_back(&topWall);
84 entities.push_back(&bottomWall);
85 entities.push_back(&leftWall);
86 entities.push_back(&rightWall);
88 collisions.reserve(2 * entities.size());
96 void Match::EnterState(Control *c, SDL_Surface *screen) {
100 void Match::ExitState(void) {
102 TTF_CloseFont(scoreFont);
107 void Match::HandleEvent(const SDL_Event &e) {
108 if (e.type == SDL_KEYDOWN) {
109 if (e.key.keysym.sym == SDLK_w) {
110 leftPaddle.StartMovingUp();
111 } else if (e.key.keysym.sym == SDLK_s) {
112 leftPaddle.StartMovingDown();
113 } else if (e.key.keysym.sym == SDLK_UP) {
114 rightPaddle.StartMovingUp();
115 } else if (e.key.keysym.sym == SDLK_DOWN) {
116 rightPaddle.StartMovingDown();
118 } else if (e.type == SDL_KEYUP) {
119 if (e.key.keysym.sym == SDLK_w) {
120 leftPaddle.StopMovingUp();
121 } else if (e.key.keysym.sym == SDLK_s) {
122 leftPaddle.StopMovingDown();
123 } else if (e.key.keysym.sym == SDLK_UP) {
124 rightPaddle.StopMovingUp();
125 } else if (e.key.keysym.sym == SDLK_DOWN) {
126 rightPaddle.StopMovingDown();
127 } else if (e.key.keysym.sym == SDLK_q) {
128 if (ctrl) ctrl->Quit();
133 void Match::UpdateWorld(float deltaT) {
134 UpdateEntities(deltaT);
135 CheckCollisions(deltaT);
136 HandleCollisions(deltaT);
139 void Match::UpdateEntities(float deltaT) {
140 for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
141 (*i)->Update(deltaT);
145 void Match::CheckCollisions(float deltaT) {
146 Entity::Vector normal;
147 for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
148 for (vector<Entity *>::const_iterator j(i + 1); j != end; ++j) {
149 if ((*i)->Overlaps(**j, normal)) {
150 if ((*i)->IsDynamic()) {
152 while ((*i)->Overlaps(**j, normal)) {
155 } else if ((*j)->IsDynamic()) {
157 while ((*j)->Overlaps(**i, normal)) {
161 (*i)->Revert(deltaT);
162 (*j)->Revert(deltaT);
164 collisions.push_back(Collision(*i, *j, normal));
170 void Match::HandleCollisions(float deltaT) {
171 for (vector<Collision>::const_iterator i(collisions.begin()), end(collisions.end()); i != end; ++i) {
172 i->left->Collide(*(i->right), i->normal);
173 i->right->Collide(*(i->left), -(i->normal));
174 i->left->PostCollide();
175 i->right->PostCollide();
178 if (!collisions.empty()) {
185 void Match::Render(SDL_Surface *screen) {
186 SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
187 for (vector<Entity *>::const_iterator i(entities.begin()), end(entities.end()); i != end; ++i) {
188 (*i)->Render(screen);
193 void Match::RenderHUD(SDL_Surface *screen) {
201 void Match::RenderScore(SDL_Surface *screen) {
202 SDL_Rect dest = { 2, 2, 0, 0 };
203 SDL_BlitSurface(leftScoreText, 0, screen, &dest);
205 dest.x = screen->w - rightScoreText->w - 2;
206 SDL_BlitSurface(rightScoreText, 0, screen, &dest);
209 void Match::UpdateScore(SDL_Surface *screen) {
210 if (!scoreFont) return;
211 if (leftScoreText) SDL_FreeSurface(leftScoreText);
212 if (rightScoreText) SDL_FreeSurface(rightScoreText);
220 s << rightWall.HitCount();
221 leftScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);
224 s << leftWall.HitCount();
225 rightScoreText = TTF_RenderUTF8_Blended(scoreFont, s.str().c_str(), color);