pong: make ball move
Stefan Schuermans

Stefan Schuermans commited on 2019-06-10 12:32:31
Showing 5 changed files, with 106 additions and 7 deletions.

... ...
@@ -3,6 +3,7 @@
3 3
    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4 4
    a blinkenarea.org project */
5 5
 
6
+#include <stdlib.h>
6 7
 #include <string>
7 8
 #include <vector>
8 9
 
... ...
@@ -16,6 +17,8 @@
16 17
 #include "Module.h"
17 18
 #include "OutStreamFile.h"
18 19
 #include "Pong.h"
20
+#include "Time.h"
21
+#include "TimeCallee.h"
19 22
 
20 23
 namespace Blinker {
21 24
 
... ...
@@ -28,7 +31,9 @@ namespace Blinker {
28 31
 Pong::Pong(const std::string &name, Mgrs &mgrs, const Directory &dirBase):
29 32
   Game(name, mgrs, dirBase),
30 33
   m_fileBallColor(dirBase.getFile("ballColor")),
31
-  m_ballColor()
34
+  m_fileLineColor(dirBase.getFile("lineColor")),
35
+  m_ballColor(), m_lineColor(),
36
+  m_ballPosX(-1), m_ballPosY(-1), m_ballDirX(0), m_ballDirY(0)
32 37
 {
33 38
   // FIXME: activate at begin for initial development only
34 39
   activate();
... ...
@@ -37,6 +42,8 @@ Pong::Pong(const std::string &name, Mgrs &mgrs, const Directory &dirBase):
37 42
 /// virtual destructor
38 43
 Pong::~Pong()
39 44
 {
45
+  // cancel time callback request
46
+  m_mgrs.m_callMgr.cancelTimeCall(this);
40 47
 }
41 48
 
42 49
 /// check for update of configuration (derived game), return true on update
... ...
@@ -45,7 +52,8 @@ bool Pong::updateConfigGame()
45 52
   bool ret = false;
46 53
 
47 54
   // color file was modified -> convert color, return true for update
48
-  if (colorUpdate(m_fileBallColor, m_ballColor)) {
55
+  if (colorUpdate(m_fileBallColor, m_ballColor) ||
56
+      colorUpdate(m_fileLineColor, m_lineColor)) {
49 57
     ret = true;
50 58
   }
51 59
 
... ...
@@ -59,20 +67,90 @@ void Pong::reinitialize()
59 67
 
60 68
   // convert colors
61 69
   color2data(m_fileBallColor, m_ballColor);
70
+  color2data(m_fileLineColor, m_lineColor);
71
+
72
+  // FIXME: start ball for development
73
+  startBall();
62 74
 }
63 75
 
64 76
 /// redraw current game image, expected to call sendFrame() at end
65 77
 void Pong::redraw()
66 78
 {
67
-  // set image buffer to background color
79
+  int y, x;
80
+
81
+  // draw background
68 82
   rectFill(0, m_height, 0, m_width, m_backgroundColor);
69 83
 
70
-  // FIXME: draw ball
71
-  pixel(m_height / 2, m_width / 2, m_ballColor);
84
+  // draw middle line: single line on odd width, two dashed lines at even width
85
+  for (y = 0; y < m_height; ++y) {
86
+    x = (m_width - (y & 1)) / 2;
87
+    pixel(y, x, m_lineColor);
88
+  }
89
+
90
+  // draw ball
91
+  pixel(m_ballPosY, m_ballPosX, m_ballColor);
72 92
 
73 93
   // send updated image buffer as frame
74 94
   sendFrame();
75 95
 }
76 96
 
97
+/// callback when requested time reached
98
+void Pong::timeCall()
99
+{
100
+  // bounce ball
101
+  if (m_ballPosY <= 0 && m_ballDirY < 0) {
102
+    m_ballDirY = 1;
103
+  }
104
+  if (m_ballPosY >= m_height - 1 && m_ballDirY > 0) {
105
+    m_ballDirY = -1;
106
+  }
107
+  if (m_ballPosX <= 0 && m_ballDirX < 0) {
108
+    m_ballDirX = 1;
109
+  }
110
+  if (m_ballPosX >= m_width - 1 && m_ballDirX > 0) {
111
+    m_ballDirX = -1;
112
+  }
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
122
+  Time stepTime;
123
+  stepTime.fromMs(100);
124
+  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
125
+}
126
+
127
+/// move ball out of the field and halt it
128
+void Pong::hideBall()
129
+{
130
+  m_ballPosX = -1;
131
+  m_ballPosY = -1;
132
+  m_ballDirX = 0;
133
+  m_ballDirY = 0;
134
+
135
+  // cancel time callback request
136
+  m_mgrs.m_callMgr.cancelTimeCall(this);
137
+}
138
+
139
+/// start ball
140
+void Pong::startBall()
141
+{
142
+  // ball starts horizontally at middle of field, vertically random
143
+  m_ballPosX = (m_width - (rand() & 1)) / 2;
144
+  m_ballPosY = rand() % m_height;
145
+  // random diagonal direction
146
+  m_ballDirX = (rand() & 1) * 2 - 1;
147
+  m_ballDirY = (rand() & 1) * 2 - 1;
148
+
149
+  // request first time call
150
+  Time stepTime;
151
+  stepTime.fromMs(100);
152
+  m_mgrs.m_callMgr.requestTimeCall(this, Time::now() + stepTime);
153
+}
154
+
77 155
 } // namespace Blinker
78 156
 
... ...
@@ -20,11 +20,13 @@
20 20
 #include "Mgrs.h"
21 21
 #include "Module.h"
22 22
 #include "OutStreamFile.h"
23
+#include "Time.h"
24
+#include "TimeCallee.h"
23 25
 
24 26
 namespace Blinker {
25 27
 
26 28
 /// pong game
27
-class Pong: public Game
29
+class Pong: public Game, public TimeCallee
28 30
 {
29 31
 public:
30 32
   /**
... ...
@@ -56,9 +58,24 @@ protected:
56 58
   /// redraw current game image, expected to call sendFrame() at end
57 59
   virtual void redraw();
58 60
 
61
+  /// callback when requested time reached
62
+  virtual void timeCall();
63
+
64
+  /// move ball out of the field and halt it
65
+  void hideBall();
66
+
67
+  /// start ball
68
+  void startBall();
69
+
59 70
 protected:
60 71
   ColorFile m_fileBallColor; ///< color file for ball color
72
+  ColorFile m_fileLineColor; ///< color file for center line
61 73
   ColorData m_ballColor;     ///< ball color
74
+  ColorData m_lineColor;     ///< center line color
75
+  int       m_ballPosX;      ///< ball position X
76
+  int       m_ballPosY;      ///< ball position Y
77
+  int       m_ballDirX;      ///< ball direction X
78
+  int       m_ballDirY;      ///< ball direction Y
62 79
 }; // class Canvas
63 80
 
64 81
 } // namespace Blinker
... ...
@@ -4,7 +4,9 @@
4 4
    a blinkenarea.org project */
5 5
 
6 6
 #include <iostream>
7
+#include <stdlib.h>
7 8
 #include <string>
9
+#include <time.h>
8 10
 
9 11
 #include "Canvas.h"
10 12
 #include "Directory.h"
... ...
@@ -95,6 +97,7 @@ int main(int argc, const char *argv[])
95 97
   }
96 98
   dirConfig = argv[1];
97 99
 
100
+  srand(time(NULL));
98 101
   PlatformInit pfInit;
99 102
 
100 103
   run(dirConfig);
101 104