4 #define COLOR_BG 50 50 50 255
5 #define COLOR_FG 222 222 222 255
7 #define PAD_DISTANCE 20
9 #define BALL_SPEEDUP 0.1
18 public ballspeedx, ballspeedy;
19 public player_score, ai_score;
23 set_int(player_score, 0);
24 set_text(PART:"score1", "0");
25 set_text(PART:"score2", "0");
30 set_float(ballspeedx, 0.0);
31 set_float(ballspeedy, 0.0);
32 set_float(ballx, 100);
33 set_float(bally, 100);
37 set_float(ballspeedx, BALL_SPEED);
38 set_float(ballspeedy, BALL_SPEED * randf());
41 public player_wins() {
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);
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);
57 public game_loop(count) {
60 /* get field geometry */
62 get_geometry(PART:"bg", fx, fy, fw, fh);
64 /* get mouse coords */
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);
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);
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);
90 /* calc new ball position */
94 /* check walls collision */
100 else if (by + BALL_SIZE > fh)
103 by = fh - BALL_SIZE - 1;
106 /* check player pad collision */
108 (bx < PAD_DISTANCE + 10) && (bx > 0) &&
109 (by + BALL_SIZE > pady) && (by < pady + PAD_SIZE))
111 new Float:dy = by - pady - PAD_SIZE / 2;
113 speedx = -speedx + BALL_SPEEDUP;
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))
121 new Float:dy = by - pad2y - PAD_SIZE / 2;
123 speedx = -speedx - BALL_SPEEDUP;
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);
131 /* update global vars */
132 set_float(ballx, bx);
133 set_float(bally, by);
134 set_float(ballspeedx, speedx);
135 set_float(ballspeedy, speedy);
137 /* AI score a point */
138 if (bx < 0) ai_wins();
139 /* player score a point */
140 if (bx + BALL_SIZE > fw) player_wins();
142 /* show debug info (if debug enabled) */
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);
151 /* recall the loop in n seconds */
152 timer(1.0 / FPS, "game_loop", count);
158 description { state: "default" 0.0;
164 description { state: "default" 0.0;
169 part { name: "score1";
171 description { state: "default" 0.0;
173 rel2.relative: 0.5 0.5;
183 part { name: "score2";
185 description { state: "default" 0.0;
187 rel1.relative: 0.5 0.0;
199 description { state: "default" 0.0;
204 rel1.offset: PAD_DISTANCE 0;
209 description { state: "default" 0.0;
214 rel2.offset: -PAD_DISTANCE 0;
219 description { state: "default" 0.0;
221 max: BALL_SIZE BALL_SIZE;
224 rel1.offset: 100 100;
230 description { state: "default" 0.0;
231 color: 255 255 255 200;
242 /* on load: reset the game and start the game loop */
248 timer(0.1 , "game_loop", 0);
251 /* mouse left click: start the game, if not yet started */
253 signal: "mouse,down,1";
256 if (get_float(ballspeedx) == 0.0)
260 /* mouse right click: restart the game*/
262 signal: "mouse,down,3";