daf8809635ef5a9e199f9bf586f73937b8bc0856
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: add pads

Stefan Schuermans authored 5 years ago

111)   // bounce ball at sides
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

112)   if (m_ballPosY <= 0 && m_ballDirY < 0) {
113)     m_ballDirY = 1;
114)   }
115)   if (m_ballPosY >= m_height - 1 && m_ballDirY > 0) {
116)     m_ballDirY = -1;
117)   }
118)   if (m_ballPosX <= 0 && m_ballDirX < 0) {
119)     m_ballDirX = 1;
120)   }
121)   if (m_ballPosX >= m_width - 1 && m_ballDirX > 0) {
122)     m_ballDirX = -1;
123)   }
124) 
Stefan Schuermans pong: add pads

Stefan Schuermans authored 5 years ago

125)   // bounce ball at left player
126)   if (m_ballPosX == 1 && m_ballDirX < 0) {
127)     // top corner
128)     if (m_ballPosY == m_leftPosY - 1 && m_ballDirY > 0) {
129)       m_ballDirX = 1;
130)       m_ballDirY = -1;
131)     }
132)     // bottom corner
133)     else if (m_ballPosY == m_leftPosY + m_padSize && m_ballDirY < 0) {
134)       m_ballDirX = 1;
135)       m_ballDirY = 1;
136)     }
137)     // pad edge
138)     else if (m_ballPosY >= m_leftPosY &&
139)              m_ballPosY < m_leftPosY + m_padSize) {
140)       m_ballDirX = 1;
141)     }
142)   }
143) 
144)   // bounce ball at right player
145)   if (m_ballPosX == m_width - 2 && m_ballDirX > 0) {
146)     // top corner
147)     if (m_ballPosY == m_rightPosY - 1 && m_ballDirY > 0) {
148)       m_ballDirX = -1;
149)       m_ballDirY = -1;
150)     }
151)     // bottom corner
152)     else if (m_ballPosY == m_rightPosY + m_padSize && m_ballDirY < 0) {
153)       m_ballDirX = -1;
154)       m_ballDirY = 1;
155)     }
156)     // pad edge
157)     else if (m_ballPosY >= m_rightPosY &&
158)              m_ballPosY < m_rightPosY + m_padSize) {
159)       m_ballDirX = -1;
160)     }
161)   }
162) 
Stefan Schuermans pong: make ball move

Stefan Schuermans authored 5 years ago

163)   // move ball
164)   m_ballPosX += m_ballDirX;
165)   m_ballPosY += m_ballDirY;
166) 
167)   // draw and send frame
168)   redraw();
169) 
170)   // request next call
171)   Time stepTime;
172)   stepTime.fromMs(100);
173)   m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
174) }
175) 
176) /// move ball out of the field and halt it
177) void Pong::hideBall()
178) {
179)   m_ballPosX = -1;
180)   m_ballPosY = -1;
181)   m_ballDirX = 0;
182)   m_ballDirY = 0;
183) 
184)   // cancel time callback request
185)   m_mgrs.m_callMgr.cancelTimeCall(this);
186) }
187) 
188) /// start ball
189) void Pong::startBall()
190) {
191)   // ball starts horizontally at middle of field, vertically random
192)   m_ballPosX = (m_width - (rand() & 1)) / 2;
193)   m_ballPosY = rand() % m_height;
194)   // random diagonal direction
195)   m_ballDirX = (rand() & 1) * 2 - 1;
196)   m_ballDirY = (rand() & 1) * 2 - 1;
197) 
198)   // request first time call
199)   Time stepTime;
200)   stepTime.fromMs(100);
201)   m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
202) }
203)