da21aee4e2fb260f4b152444e3bb6e5b88138c71
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

1) /* Blinker
2)    Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
3)    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4)    a blinkenarea.org project */
5) 
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

6) #include <stdlib.h>
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

7) #include <string>
8) #include <vector>
9) 
10) #include <BlinkenLib/BlinkenFrame.h>
11) 
12) #include "File.h"
13) #include "Format.h"
14) #include "FormatFile.h"
15) #include "Game.h"
16) #include "Mgrs.h"
17) #include "Module.h"
18) #include "OutStreamFile.h"
19) #include "Pong.h"
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

20) #include "Time.h"
21) #include "TimeCallee.h"
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

22) 
23) namespace Blinker {
24) 
25) /**
26)  * @brief constructor
27)  * @param[in] name module name
28)  * @param[in] mgrs managers
29)  * @param[in] dirBase base directory
30)  */
31) Pong::Pong(const std::string &name, Mgrs &mgrs, const Directory &dirBase):
32)   Game(name, mgrs, dirBase),
33)   m_fileBallColor(dirBase.getFile("ballColor")),
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

34)   m_fileLineColor(dirBase.getFile("lineColor")),
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

35)   m_filePadColor(dirBase.getFile("padColor")),
36)   m_ballColor(), m_lineColor(), m_padColor(),
37)   m_ballPosX(-1), m_ballPosY(-1), m_ballDirX(0), m_ballDirY(0),
38)   m_padSize(0), m_leftPosY(0), m_rightPosY(0)
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

39) {
40)   // FIXME: activate at begin for initial development only
41)   activate();
42) }
43) 
44) /// virtual destructor
45) Pong::~Pong()
46) {
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

47)   // cancel time callback request
48)   m_mgrs.m_callMgr.cancelTimeCall(this);
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

49) }
50) 
51) /// check for update of configuration (derived game), return true on update
52) bool Pong::updateConfigGame()
53) {
54)   bool ret = false;
55) 
56)   // color file was modified -> convert color, return true for update
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

57)   if (colorUpdate(m_fileBallColor, m_ballColor) ||
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

58)       colorUpdate(m_fileLineColor, m_lineColor) ||
59)       colorUpdate(m_filePadColor, m_padColor)) {
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

60)     ret = true;
61)   }
62) 
63)   return ret;
64) }
65) 
66) /// re-initialize game (e.g. due to config change)
67) void Pong::reinitialize()
68) {
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

69)   // compute parameters
70)   m_padSize = (m_height + 1) / 3;
71)   m_leftPosY = (m_height - m_padSize) / 2;
72)   m_rightPosY = (m_height - m_padSize) / 2;
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

73) 
74)   // convert colors
75)   color2data(m_fileBallColor, m_ballColor);
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

76)   color2data(m_fileLineColor, m_lineColor);
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

77)   color2data(m_filePadColor, m_padColor);
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

78) 
79)   // FIXME: start ball for development
80)   startBall();
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

81) }
82) 
83) /// redraw current game image, expected to call sendFrame() at end
84) void Pong::redraw()
85) {
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

86)   int y, x;
87) 
88)   // draw background
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

89)   rectFill(0, m_height, 0, m_width, m_backgroundColor);
90) 
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

91)   // draw middle line: single line on odd width, two dashed lines at even width
92)   for (y = 0; y < m_height; ++y) {
93)     x = (m_width - (y & 1)) / 2;
94)     pixel(y, x, m_lineColor);
95)   }
96) 
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

97)   // draw pads
98)   lineVert(m_leftPosY, m_leftPosY + m_padSize - 1, 0, m_padColor);
99)   lineVert(m_rightPosY, m_rightPosY + m_padSize - 1, m_width - 1, m_padColor);
100) 
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

101)   // draw ball
102)   pixel(m_ballPosY, m_ballPosX, m_ballColor);
Stefan Schuermans begin of Pong game

Stefan Schuermans authored 5 years ago

103) 
104)   // send updated image buffer as frame
105)   sendFrame();
106) }
107) 
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

108) /// callback when requested time reached
109) void Pong::timeCall()
110) {
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

111)   // bounce ball
112)   bounceBall();
113) 
114)   // move ball
115)   m_ballPosX += m_ballDirX;
116)   m_ballPosY += m_ballDirY;
117) 
118)   // draw and send frame
119)   redraw();
120) 
121)   // request next call if needed
122)   planTimeCall();
123) }
124) 
125) /// bounce ball
126) void Pong::bounceBall()
127) {
128)   bounceBallSide();
129)   bounceBallLeft();
130)   bounceBallRight();
131) }
132) 
133) /// bounce ball at sides
134) void Pong::bounceBallSide()
135) {
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

136)   if (m_ballPosY <= 0 && m_ballDirY < 0) {
137)     m_ballDirY = 1;
138)   }
139)   if (m_ballPosY >= m_height - 1 && m_ballDirY > 0) {
140)     m_ballDirY = -1;
141)   }
142)   if (m_ballPosX <= 0 && m_ballDirX < 0) {
143)     m_ballDirX = 1;
144)   }
145)   if (m_ballPosX >= m_width - 1 && m_ballDirX > 0) {
146)     m_ballDirX = -1;
147)   }
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

148) }
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

149) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

150) /// bounce ball at left pad
151) void Pong::bounceBallLeft()
152) {
153)   if (m_ballPosX != 1 || m_ballDirX >= 0) {
154)     return;
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

155)   }
156) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

157)   // top corner
158)   if (m_ballPosY == m_leftPosY - 1 && m_ballDirY > 0) {
159)     m_ballDirX = 1;
160)     m_ballDirY = -1;
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

161)   }
162) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

163)   // bottom corner
164)   else if (m_ballPosY == m_leftPosY + m_padSize && m_ballDirY < 0) {
165)     m_ballDirX = 1;
166)     m_ballDirY = 1;
167)   }
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

168) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

169)   // pad edge
170)   else if (m_ballPosY >= m_leftPosY &&
171)            m_ballPosY < m_leftPosY + m_padSize) {
172)     m_ballDirX = 1;
173)   }
174) }
175) 
176) /// bounce ball at right pad
177) void Pong::bounceBallRight()
178) {
179)   if (m_ballPosX != m_width - 2 || m_ballDirX <= 0) {
180)     return;
181)   }
182) 
183)   // top corner
184)   if (m_ballPosY == m_rightPosY - 1 && m_ballDirY > 0) {
185)     m_ballDirX = -1;
186)     m_ballDirY = -1;
187)   }
188) 
189)   // bottom corner
190)   else if (m_ballPosY == m_rightPosY + m_padSize && m_ballDirY < 0) {
191)     m_ballDirX = -1;
192)     m_ballDirY = 1;
193)   }
194) 
195)   // pad edge
196)   else if (m_ballPosY >= m_rightPosY &&
197)            m_ballPosY < m_rightPosY + m_padSize) {
198)     m_ballDirX = -1;
199)   }
200) }
201) 
202) /// request next time call - or cancel request if not needed
203) void Pong::planTimeCall()
204) {
205)   if (m_ballPosX < 0 ||  m_ballPosY < 0) {
206)     m_mgrs.m_callMgr.cancelTimeCall(this);
207)     return;
208)   }
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

209) 
210)   Time stepTime;
211)   stepTime.fromMs(100);
212)   m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
213) }
214) 
215) /// move ball out of the field and halt it
216) void Pong::hideBall()
217) {
218)   m_ballPosX = -1;
219)   m_ballPosY = -1;
220)   m_ballDirX = 0;
221)   m_ballDirY = 0;
222) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

223)   // update time call request
224)   planTimeCall();
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

225) }
226) 
227) /// start ball
228) void Pong::startBall()
229) {
230)   // ball starts horizontally at middle of field, vertically random
231)   m_ballPosX = (m_width - (rand() & 1)) / 2;
232)   m_ballPosY = rand() % m_height;
233)   // random diagonal direction
234)   m_ballDirX = (rand() & 1) * 2 - 1;
235)   m_ballDirY = (rand() & 1) * 2 - 1;
236) 
Stefan Schuermans pong: split large time func...

Stefan Schuermans authored 5 years ago

237)   // request first time call if needed
238)   planTimeCall();
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

239) }
240)