\hypertarget{embryo_pong_8edc-example}{\section{embryo\+\_\+pong.\+edc}
}
Super-\/simple Pong implementation in pure embryo.


\begin{DoxyCodeInclude}
1 
2 #define DEBUG\_ENABLE 0
3 #define FPS 30
4 #define COLOR\_BG 50 50 50 255
5 #define COLOR\_FG 222 222 222 255
6 #define PAD\_SIZE 60
7 #define PAD\_DISTANCE 20
8 #define BALL\_SPEED 5.0
9 #define BALL\_SPEEDUP 0.1
10 #define BALL\_SIZE 10
11 
12 
13 collections \{
14    group \{ name: "main";
15       min: 500 300;
16       script \{
17          public ballx, bally;
18          public ballspeedx, ballspeedy;
19          public player\_score, ai\_score;
20 
21          public game\_reset() \{
22             set\_int(ai\_score, 0);
23             set\_int(player\_score, 0);
24             set\_text(PART:"score1", "0");
25             set\_text(PART:"score2", "0");
26             game\_init();
27          \}
28          
29          public game\_init() \{
30             set\_float(ballspeedx, 0.0);
31             set\_float(ballspeedy, 0.0);
32             set\_float(ballx, 100);
33             set\_float(bally, 100);
34          \}
35          
36          public start\_game() \{
37             set\_float(ballspeedx, BALL\_SPEED);
38             set\_float(ballspeedy, BALL\_SPEED * randf());
39          \}
40 
41          public player\_wins() \{
42             new buf[16]
43             set\_int(player\_score, get\_int(player\_score) + 1);
44             snprintf(buf, sizeof(buf), "%d", get\_int(player\_score));
45             set\_text(PART:"score1", buf);
46             game\_init();
47          \}
48 
49          public ai\_wins() \{
50             new buf[16]
51             set\_int(ai\_score, get\_int(ai\_score) + 1);
52             snprintf(buf, sizeof(buf), "%d", get\_int(ai\_score));
53             set\_text(PART:"score2", buf);
54             game\_init();
55          \}
56 
57          public game\_loop(count) \{
58             count++;
59 
60             /* get field geometry */
61             new fx, fy, fw, fh;
62             get\_geometry(PART:"bg", fx, fy, fw, fh);
63 
64             /* get mouse coords */
65             new mx, my;
66             get\_mouse(mx, my);
67 
68             /* get the ball info */
69             new Float:bx = get\_float(ballx);
70             new Float:by = get\_float(bally);
71             new Float:speedx = get\_float(ballspeedx);
72             new Float:speedy = get\_float(ballspeedy);
73 
74             /* move the player pad */
75             new pady = my - PAD\_SIZE / 2;
76             if (pady < 0) pady = 0;
77             else if (pady + PAD\_SIZE > fh) pady = fh - PAD\_SIZE;
78             custom\_state(PART:"pad1", "default", 0.0);
79             set\_state\_val(PART:"pad1", STATE\_REL1\_OFFSET, 20, pady);
80             set\_state(PART:"pad1", "custom", 0.0);
81 
82             /* move the AI pad */
83             new pad2y = round(by) - PAD\_SIZE / 2 - BALL\_SIZE / 2;
84             if (pad2y < 0) pad2y = 0;
85             else if (pad2y + PAD\_SIZE > fh) pad2y = fh - PAD\_SIZE;
86             custom\_state(PART:"pad2", "default", 0.0);
87             set\_state\_val(PART:"pad2", STATE\_REL1\_OFFSET, 20, pad2y);
88             set\_state(PART:"pad2", "custom", 0.0);
89          
90             /* calc new ball position */
91             bx += speedx;
92             by += speedy;
93 
94             /* check walls collision */
95             if (by < 0)
96             \{
97                speedy = -speedy;
98                by = 0;
99             \}
100             else if (by + BALL\_SIZE > fh)
101             \{
102                speedy = -speedy;
103                by = fh - BALL\_SIZE - 1;
104             \}
105 
106             /* check player pad collision */
107             if ((speedx < 0) &&
108                 (bx < PAD\_DISTANCE + 10) && (bx > 0) &&
109                 (by + BALL\_SIZE > pady) && (by < pady + PAD\_SIZE))
110             \{
111                new Float:dy = by - pady - PAD\_SIZE / 2;
112                speedy += dy / 10;
113                speedx = -speedx + BALL\_SPEEDUP;
114             \}
115 
116             /* check AI pad collision */
117             else if ((bx + BALL\_SIZE > fw - PAD\_DISTANCE - 10) &&
118                      (bx + BALL\_SIZE < fw) &&
119                      (by + BALL\_SIZE > pad2y) && (by < pad2y + PAD\_SIZE))
120             \{
121                new Float:dy = by - pad2y - PAD\_SIZE / 2;
122                speedy += dy / 10;
123                speedx = -speedx - BALL\_SPEEDUP;
124             \}
125             
126             /* apply the new ball position */
127             custom\_state(PART:"ball", "default", 0.0);
128             set\_state\_val(PART:"ball", STATE\_REL1\_OFFSET, round(bx), round(by));
129             set\_state(PART:"ball", "custom", 0.0);
130 
131             /* update global vars */
132             set\_float(ballx, bx);
133             set\_float(bally, by);
134             set\_float(ballspeedx, speedx);
135             set\_float(ballspeedy, speedy);
136 
137             /* AI score a point */
138             if (bx < 0) ai\_wins();
139             /* player score a point */
140             if (bx + BALL\_SIZE > fw) player\_wins();
141 
142             /* show debug info (if debug enabled) */
143 #if DEBUG\_ENABLE
144             new \_buf[128];
145             snprintf(\_buf, sizeof(\_buf),
146                      "loop:%d  [speed %f  %f] [mouse: %d %d] [ball: %f %f]",
147                      count, speedx, speedy, mx, my, bx, by);
148             set\_text(PART:"dbg", \_buf);
149 #endif
150 
151             /* recall the loop in n seconds */
152             timer(1.0 / FPS, "game\_loop", count);
153          \}
154       \}
155       parts \{
156          part \{ name: "bg";
157             type: RECT;
158             description \{ state: "default" 0.0;
159                color: COLOR\_BG;
160             \}
161          \}
162          part \{ name: "net";
163             type: RECT;
164             description \{ state: "default" 0.0;
165                color: COLOR\_FG;
166                max: 10 9999;
167             \}
168          \}
169          part \{ name: "score1";
170             type: TEXT;
171             description \{ state: "default" 0.0;
172                color: COLOR\_FG;
173                rel2.relative: 0.5 0.5;
174                rel2.offset: -20 0;
175                text \{
176                   text: "0";
177                   font: "Sans";
178                   size: 50;
179                   align: 1.0 0.0;
180                \} 
181             \}
182          \}
183          part \{ name: "score2";
184             type: TEXT;
185             description \{ state: "default" 0.0;
186                color: COLOR\_FG;
187                rel1.relative: 0.5 0.0;
188                rel1.offset: 20 0;
189                text \{
190                   text: "0";
191                   font: "Sans";
192                   size: 50;
193                   align: 0.0 0.0;
194                \} 
195             \}
196          \}
197          part \{ name: "pad1";
198             type: RECT;
199             description \{ state: "default" 0.0;
200                color: COLOR\_FG;
201                max: 10 PAD\_SIZE;
202                fixed: 1 1;
203                align: 0.0 0.0;
204                rel1.offset: PAD\_DISTANCE 0;
205             \}
206          \}
207          part \{ name: "pad2";
208             type: RECT;
209             description \{ state: "default" 0.0;
210                color: COLOR\_FG;
211                max: 10 PAD\_SIZE;
212                fixed: 1 1;
213                align: 1.0 0.0;
214                rel2.offset: -PAD\_DISTANCE 0;
215             \}
216          \}
217          part \{ name: "ball";
218             type: RECT;
219             description \{ state: "default" 0.0;
220                color: COLOR\_FG;
221                max: BALL\_SIZE BALL\_SIZE;
222                fixed: 1 1;
223                align: 0.0 0.0;
224                rel1.offset: 100 100;
225             \}
226          \}
227          #if DEBUG\_ENABLE
228          part \{ name: "dbg";
229             type: TEXT;
230             description \{ state: "default" 0.0;
231                color: 255 255 255 200;
232                text \{
233                   font: "Sans";
234                   size: 12;
235                   align: 1.0 1.0;
236                \}
237             \}
238          \}
239          #endif
240       \}
241       programs \{
242          /* on load: reset the game and start the game loop */
243          program \{
244             signal: "load";
245             source: "";
246             script \{
247                game\_reset();
248                timer(0.1 , "game\_loop", 0);
249             \}
250          \}
251          /* mouse left click: start the game, if not yet started */
252          program \{
253             signal: "mouse,down,1";
254             source: "bg";
255             script \{
256                if (get\_float(ballspeedx) == 0.0)
257                   start\_game();
258             \}
259          \}
260          /* mouse right click: restart the game*/
261          program \{
262             signal: "mouse,down,3";
263             source: "bg";
264             script \{
265                game\_reset();
266             \}
267          \}
268       \}
269    \}
270 \}
\end{DoxyCodeInclude}
 