Skip to content

Commit 39f2e18

Browse files
authored
[Sprig App] Paddle Wars (#3280)
* Sprig App - Paddle Wars * Update Paddle-Wars.js * Update Paddle-Wars.js * Update Paddle-Wars.js
1 parent 752a108 commit 39f2e18

File tree

2 files changed

+200
-0
lines changed

2 files changed

+200
-0
lines changed

games/Paddle-Wars.js

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/*
2+
@title: Paddle Wars
3+
@description: Paddle Wars is a fast-paced 2-player arcade game where players use paddles to hit a bouncing ball. Player 1 controls with W/S and Player 2 with I/K. Score by passing the ball past the opponent—first to 6 wins. Featuring dynamic ball movement, grid background, score display, and looping music, it’s a simple and competitive head-to-head challenge.
4+
@author: R09Aditya
5+
@tags: [arcade, pong, multiplayer, classic, sports, competitive, retro, 2player, ball-game, skill, fast-paced, pixel, challenge]
6+
@addedOn: 2025-08-25
7+
*/
8+
const paddle = "p";
9+
const ball = "b";
10+
const darkBackground = "d";
11+
12+
setLegend(
13+
[ paddle, bitmap`
14+
......0000......
15+
......0000......
16+
......0000......
17+
......0000......
18+
......0000......
19+
......0000......
20+
......0000......
21+
......0000......
22+
......0000......
23+
......0000......
24+
......0000......
25+
......0000......
26+
......0000......
27+
......0000......
28+
......0000......
29+
......0000......`],
30+
[ ball, bitmap`
31+
................
32+
................
33+
................
34+
.....00000......
35+
....0000000.....
36+
...000000000....
37+
...0000000000...
38+
..00000000000...
39+
..0000000000....
40+
...000000000....
41+
....0000000.....
42+
.....00000......
43+
................
44+
................
45+
................
46+
................`],
47+
[ darkBackground, bitmap`
48+
1111111111111111
49+
1111111111111111
50+
1111111111111111
51+
1111111111111111
52+
1111111111111111
53+
1111111111111111
54+
1111111111111111
55+
1111111111111111
56+
1111111111111111
57+
1111111111111111
58+
1111111111111111
59+
1111111111111111
60+
1111111111111111
61+
1111111111111111
62+
1111111111111111
63+
1111111111111111`]
64+
);
65+
66+
const level = map`
67+
................
68+
................
69+
................
70+
................
71+
................
72+
................
73+
................
74+
p..............p
75+
................
76+
................
77+
................
78+
................
79+
................
80+
................
81+
................`;
82+
83+
setMap(level);
84+
setBackground(darkBackground);
85+
setSolids([paddle]);
86+
87+
let ballX = 7.5;
88+
let ballY = 7.5;
89+
let horizontalSpeed = 0.2;
90+
let verticalSpeed = 0.1;
91+
let ballVelX = Math.random() < 0.5 ? -horizontalSpeed : horizontalSpeed;
92+
let ballVelY = (Math.random() - 0.5) * 2 * verticalSpeed;
93+
94+
let player1Score = 0;
95+
let player2Score = 0;
96+
const maxScore = 6;
97+
let gameOver = false;
98+
99+
100+
onInput("w", () => {
101+
const paddle1 = getFirst(paddle);
102+
if (!gameOver && paddle1.y > 0) paddle1.y -= 1;
103+
});
104+
onInput("s", () => {
105+
const paddle1 = getFirst(paddle);
106+
if (!gameOver && paddle1.y < 13) paddle1.y += 1;
107+
});
108+
109+
onInput("i", () => {
110+
const paddle2 = getAll(paddle).find(p => p.x === 15);
111+
if (!gameOver && paddle2 && paddle2.y > 0) paddle2.y -= 1;
112+
});
113+
onInput("k", () => {
114+
const paddle2 = getAll(paddle).find(p => p.x === 15);
115+
if (!gameOver && paddle2 && paddle2.y < 13) paddle2.y += 1;
116+
});
117+
118+
function updateScoreboard() {
119+
clearText();
120+
addText(`${player1Score} - ${player2Score}`, { y: 1, color: color`2` });
121+
}
122+
123+
function endGame(winner) {
124+
gameOver = true;
125+
clearText();
126+
addText(`${winner} WINS!`, { y: 3, color: color`3` });
127+
}
128+
129+
function update() {
130+
if (gameOver) return;
131+
132+
clearTile(Math.floor(ballX), Math.floor(ballY));
133+
134+
ballX += ballVelX;
135+
ballY += ballVelY;
136+
137+
if (ballY < 0) {
138+
ballY = 0;
139+
ballVelY = Math.abs(ballVelY);
140+
} else if (ballY > 13) {
141+
ballY = 13;
142+
ballVelY = -Math.abs(ballVelY);
143+
}
144+
145+
const leftPaddle = getFirst(paddle);
146+
const rightPaddle = getAll(paddle).find(p => p.x === 15);
147+
148+
if (ballX <= 1 && ballY >= leftPaddle.y && ballY <= leftPaddle.y + 2) {
149+
ballVelX = Math.abs(ballVelX);
150+
ballVelY = (Math.random() - 0.5) * 2 * verticalSpeed;
151+
ballX = 1;
152+
}
153+
154+
if (rightPaddle && ballX >= 14 && ballY >= rightPaddle.y && ballY <= rightPaddle.y + 2) {
155+
ballVelX = -Math.abs(ballVelX);
156+
ballVelY = (Math.random() - 0.5) * 2 * verticalSpeed;
157+
ballX = 14;
158+
}
159+
160+
if (ballX < 0) {
161+
player2Score += 1;
162+
updateScoreboard();
163+
if (player2Score >= maxScore) return endGame("Player 2");
164+
resetBall();
165+
} else if (ballX > 15) {
166+
player1Score += 1;
167+
updateScoreboard();
168+
if (player1Score >= maxScore) return endGame("Player 1");
169+
resetBall();
170+
} else {
171+
addSprite(Math.floor(ballX), Math.floor(ballY), ball);
172+
}
173+
174+
setTimeout(update, 50);
175+
}
176+
177+
function resetBall() {
178+
ballX = 7.5;
179+
ballY = 7.5;
180+
ballVelX = Math.random() < 0.5 ? -horizontalSpeed : horizontalSpeed;
181+
ballVelY = (Math.random() - 0.5) * 2 * verticalSpeed;
182+
addSprite(Math.floor(ballX), Math.floor(ballY), ball);
183+
}
184+
185+
addSprite(Math.floor(ballX), Math.floor(ballY), ball);
186+
updateScoreboard();
187+
update();
188+
189+
const soundtrack = tune`
190+
150: c4^150, e4^150, g4^150, c5^150,
191+
150: g4^150, e4^150, c4^150, d4^150,
192+
150: f4^150, a4^150, f4^150, d4^150,
193+
150: e4^150, g4^150, b4^150, c5^150,
194+
150: c5^150, b4^150, g4^150, e4^150,
195+
150: d4^150, f4^150, a4^150, g4^150,
196+
200: c4^200, d4^200, e4^200, f4^200,
197+
300: g4^300
198+
`;
199+
200+
playTune(soundtrack, Infinity);

games/img/Paddle-Wars.png

1.47 KB
Loading

0 commit comments

Comments
 (0)