Skip to content

Commit fcb40ef

Browse files
Add files via upload
1 parent accce9e commit fcb40ef

File tree

1 file changed

+309
-0
lines changed

1 file changed

+309
-0
lines changed

games/MaxMove.js

Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
/*
2+
@title: max_move
3+
@tags: ['beginner']
4+
@addedOn: 2025-11-06
5+
@author: nick extra levels by: sam, minghao
6+
7+
Check the tutorial in the bottom right, the run button is in the top right.
8+
Make sure to remix this tutorial if you want to save your progress!
9+
*/
10+
11+
function wait(time) {
12+
let startTime_ = performance.now();
13+
while (performance.now() - startTime_ < time) {}
14+
}
15+
16+
// define the sprites in our game
17+
const player = "p";
18+
const box = "b";
19+
const goal = "g";
20+
const wall = "w";
21+
22+
// create sound
23+
const melody = tune`
24+
500: D5~500,
25+
15500`
26+
27+
// assign bitmap art to each sprite
28+
setLegend(
29+
[ player, bitmap`
30+
................
31+
................
32+
................
33+
.......0........
34+
.....00.000.....
35+
....0.....00....
36+
....0.0.0..0....
37+
....0......0....
38+
....0......0....
39+
....00....0.....
40+
......00000.....
41+
......0...0.....
42+
....000...000...
43+
................
44+
................
45+
................`],
46+
[ box, bitmap`
47+
................
48+
................
49+
................
50+
...88888888888..
51+
...8....8....8..
52+
...8....8....8..
53+
...8....8....8..
54+
...8....8....8..
55+
...88888888888..
56+
...8....8....8..
57+
...8....8....8..
58+
...8....8....8..
59+
...8....8....8..
60+
...88888888888..
61+
................
62+
................`],
63+
[ goal, bitmap`
64+
................
65+
................
66+
................
67+
....444444......
68+
...44....44.....
69+
...4......4.....
70+
...4.......4....
71+
...4.......4....
72+
...4.......4....
73+
...44......4....
74+
....4......4....
75+
....44....44....
76+
.....444444.....
77+
................
78+
................
79+
................`],
80+
[ wall, bitmap`
81+
0000000000000000
82+
0000000000000000
83+
0000000000000000
84+
0000000000000000
85+
0000000000000000
86+
0000000000000000
87+
0000000000000000
88+
0000000000000000
89+
0000000000000000
90+
0000000000000000
91+
0000000000000000
92+
0000000000000000
93+
0000000000000000
94+
0000000000000000
95+
0000000000000000
96+
0000000000000000`]
97+
);
98+
99+
// create game levels
100+
let level = 0; // this tracks the level we are on
101+
const levels = [
102+
map`
103+
w...g
104+
.....
105+
.....
106+
p..w.`,
107+
map`
108+
p..
109+
.b.
110+
..g`,
111+
map`
112+
p.wg
113+
.b..
114+
....
115+
..w.`,
116+
map`
117+
pb..
118+
...b
119+
....
120+
.bbg`,
121+
map`
122+
...
123+
.p.
124+
...`,
125+
map`
126+
ppw.
127+
..wg
128+
....
129+
...g`,
130+
map`
131+
pp.w.
132+
...g.
133+
.b.w.
134+
..bg.`,
135+
map`
136+
pp...
137+
..wg.
138+
.b.w.
139+
..bg.`,
140+
map`
141+
....p.
142+
p...w.
143+
w.bb..
144+
..b...
145+
g.gwb.
146+
......`
147+
];
148+
149+
// set the map displayed to the current level
150+
const currentLevel = levels[level];
151+
setMap(currentLevel);
152+
153+
setSolids([ player, box, wall ]); // other sprites cannot go inside of these sprites
154+
155+
// allow certain sprites to push certain other sprites
156+
setPushables({
157+
[player]: [box],
158+
[box]: [box]
159+
});
160+
161+
function onGoal(playerSprite) {
162+
let sprites = getTile(playerSprite.x, playerSprite.y);
163+
let result = false;
164+
for (let i = 0; i < sprites.length; i++) {
165+
if (sprites[i].type === "g") {
166+
result = true;
167+
break;
168+
}
169+
}
170+
return result;
171+
}
172+
173+
174+
function getPlayerSprite() {
175+
let finalSprite;
176+
let found = false;
177+
getAll(player).forEach((playerSprite) => {
178+
if (found) return;
179+
let valid = true;
180+
getTile(playerSprite.x, playerSprite.y).forEach((sprite) => {
181+
if (sprite.type == goal) valid = false;
182+
});
183+
if (valid) {
184+
finalSprite = playerSprite;
185+
}
186+
});
187+
return finalSprite;
188+
}
189+
190+
var isMoving = false;
191+
192+
// inputs for player movement control
193+
onInput("w", () => {
194+
if (isMoving) return;
195+
else isMoving = true;
196+
let playerSprite = getPlayerSprite();
197+
let lastY = playerSprite.y + 1;
198+
function move() {
199+
if (!(lastY != playerSprite.y && playerSprite.y > 0 && !onGoal(playerSprite))) {
200+
isMoving = false;
201+
setTimeout(afterMove, 1);
202+
return;
203+
}
204+
lastY = playerSprite.y;
205+
playerSprite.y -= 1;
206+
playTune(melody);
207+
setTimeout(move, 20);
208+
}
209+
move();
210+
});
211+
212+
onInput("s", () => {
213+
if (isMoving) return;
214+
else isMoving = true;
215+
let playerSprite = getPlayerSprite();
216+
let lastY = playerSprite.y - 1;
217+
function move() {
218+
if (!(lastY != playerSprite.y && playerSprite.y < height() - 1 && !onGoal(playerSprite))) {
219+
isMoving = false;
220+
setTimeout(afterMove, 1);
221+
return;
222+
}
223+
lastY = playerSprite.y;
224+
playerSprite.y += 1; // positive y is downwards
225+
playTune(melody);
226+
setTimeout(move, 20);
227+
}
228+
move();
229+
});
230+
231+
onInput("a", () => {
232+
if (isMoving) return;
233+
else isMoving = true;
234+
let playerSprite = getPlayerSprite();
235+
let lastX = playerSprite.x + 1;
236+
function move() {
237+
if (!(lastX != playerSprite.x && playerSprite.x > 0 && !onGoal(playerSprite))) {
238+
isMoving = false;
239+
setTimeout(afterMove, 1);
240+
return;
241+
}
242+
lastX = playerSprite.x;
243+
playerSprite.x -= 1;
244+
playTune(melody);
245+
setTimeout(move, 20);
246+
}
247+
move();
248+
});
249+
250+
onInput("d", () => {
251+
if (isMoving) return;
252+
else isMoving = true;
253+
let playerSprite = getPlayerSprite();
254+
let lastX = playerSprite.x - 1;
255+
function move() {
256+
if (!(lastX != playerSprite.x && playerSprite.x < width() - 1 && !onGoal(playerSprite))) {
257+
isMoving = false;
258+
setTimeout(afterMove, 1);
259+
return;
260+
}
261+
lastX = playerSprite.x;
262+
playerSprite.x += 1;
263+
playTune(melody);
264+
setTimeout(move, 20);
265+
}
266+
move();
267+
});
268+
269+
// input to reset level
270+
onInput("j", () => {
271+
const currentLevel = levels[level]; // get the original map of the level
272+
273+
// make sure the level exists before we load it
274+
if (currentLevel !== undefined) {
275+
clearText("");
276+
setMap(currentLevel);
277+
}
278+
});
279+
280+
// this gets run after every move
281+
function afterMove() {
282+
clearText();
283+
284+
// count the number of tiles with goals
285+
const targetNumber = tilesWith(goal).length;
286+
287+
// count the number of tiles with goals and players
288+
const numberCovered = tilesWith(goal, player).length;
289+
290+
// if the number of goals is the same as the number of goals covered
291+
// all goals are covered and we can go to the next level
292+
if (numberCovered === targetNumber) {
293+
// increase the current level number
294+
level = level + 1;
295+
296+
const currentLevel = levels[level];
297+
298+
// make sure the level exists and if so set the map
299+
// otherwise, we have finished the last level, there is no level
300+
// after the last level
301+
if (currentLevel !== undefined) {
302+
setMap(currentLevel);
303+
} else {
304+
addText("you win!", { y: 4, color: color`3` });
305+
}
306+
}
307+
}
308+
309+
addText("WASD, j to restart", { y: 4, color: color`3` });

0 commit comments

Comments
 (0)