Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 238 additions & 0 deletions games/Dex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/*
@title: dexter_nightshift
@description: Dexter must grab the knife and kill the victim before Doakes catches him! Includes hazards and multiple maps.
@author: Kings-Indian
@tags: ['stealth', 'puzzle', 'multiplayer']
@addedOn: 2025-08-19
Instructions:
Player 1 (Dexter): Use WASD to move. Grab the knife (k) and then reach the victim (t).
Player 2 (Doakes): Use IJKL to move. Catch Dexter (d) before he kills the victim.
Walls (w) block movement. Hazards (h) instantly kill Dexter if he steps on them.
If Dexter wins a map, the game automatically advances to the next one.
*/
const dexter = "d";
const target = "t";
const doakes = "c";
const knife = "k";
const wall = "w";
const hazard = "h";
// Sprites
setLegend(
[ dexter, bitmap`
................
................
......000000....
......003003....
...0..000000....
...00.003003....
...00.003003....
...00.003333....
...00..0........
..0000.0........
...00..0........
...00000000.....
.......0........
......000.......
......0.0.......
......0.0.......` ],
[ target, bitmap`
................
................
................
................
................
....000000......
....033330......
..00000000......
....606066......
....606066......
....66660.......
........0.......
.....0000.......
.....0000.......
.....0000.......
.......00.......` ],
[ doakes, bitmap`
................
................
................
................
................
......5555......
......5555......
......CCCC......
......0660......
......6336......
.......66.......
.....655556.....
.....6.55.6.....
.....6.55.6.....
.......55.......
.......55.......` ],
[ knife, bitmap`
.......33.......
......3333......
.....333233.....
.....033223.....
.....023023.....
.....020020.....
.....020220.....
.....020020.....
.....022020.....
.....020020.....
....00000000....
...0000000000...
.......CC.......
.......CC.......
.......CC.......
.......96.......` ],
[ wall, bitmap`
0000000000000000
0000000000000000
0000L00000000000
0000L00000000000
00000000000L0000
0000000000000000
000000000000L000
00000L0000000000
0000000LL0000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
000LL00000L00000
0000000000000000
0000000000000000` ],
[ hazard, bitmap`
................
................
................
................
......6666......
.....688886.....
.....688886.....
......6666......
......6666......
.....688886.....
.....688886.....
......6666......
................
................
................
................` ]
);
// Levels
const levels = [
map`
wwwwwwwwwwwwwwww
wd.....k.......w
w..wwwwwww.....w
w..............w
w.....c........w
w..........t...w
w..............w
wwwwwwwwwwwwwwww`,
map`
wwwwwwwwwwwwwwww
wd....w...k....w
w.w..h.w.......w
w.w............w
w....c....h....w
w....h......t..w
w..............w
wwwwwwwwwwwwwwww`,
map`
wwwwwwwwwwwwwwww
w..d...........w
w....wwwwwww...w
w..k....h......w
w..............w
w.....c........w
w..........t...w
wwwwwwwwwwwwwwww`
];
let level = 0;
setMap(levels[level]);
// Solids
setSolids([ wall ]);
// State
let dexterHasKnife = false;
let gameOver = false;
// Dexter’s movement (WASD)
onInput("w", () => moveCharacter(dexter, 0, -1));
onInput("s", () => moveCharacter(dexter, 0, 1));
onInput("a", () => moveCharacter(dexter, -1, 0));
onInput("d", () => moveCharacter(dexter, 1, 0));
// Doakes’ movement (IJKL)
onInput("i", () => moveCharacter(doakes, 0, -1));
onInput("k", () => moveCharacter(doakes, 0, 1));
onInput("j", () => moveCharacter(doakes, -1, 0));
onInput("l", () => moveCharacter(doakes, 1, 0));
// Movement helper
function moveCharacter(type, dx, dy) {
if (gameOver) return;
const sprite = getFirst(type);
const nextX = sprite.x + dx;
const nextY = sprite.y + dy;
if (!tileHasType(nextX, nextY, wall)) {
sprite.x = nextX;
sprite.y = nextY;
}
}
// Check tile contents
const tileHasType = (x, y, type) => getTile(x, y).some(s => s.type === type);
// Full screen message
function fullScreenMessage(text, colorCode) {
clearText();
for (let y = 0; y < 8; y++) {
addText(text, { y, color: colorCode });
}
}
// Load next level or end
function nextLevel() {
level++;
if (level < levels.length) {
setMap(levels[level]);
dexterHasKnife = false;
gameOver = false;
clearText();
} else {
fullScreenMessage("GAME COMPLETE!", color`9`);
gameOver = true;
}
}
// After each move
afterInput(() => {
if (gameOver) return;
const d = getFirst(dexter);
const c = getFirst(doakes);
if (!d || !c) return;
// Dexter interactions
const tile = getTile(d.x, d.y);
tile.forEach(obj => {
if (obj.type === knife) {
obj.remove();
dexterHasKnife = true;
addText("Dexter armed!", { y: 0, color: color`3` });
}
if (obj.type === target) {
if (dexterHasKnife) {
obj.remove();
fullScreenMessage("DEXTER WINS!", color`9`);
gameOver = true;
setTimeout(nextLevel, 1000);
} else {
addText("Need a weapon!", { y: 1, color: color`6` });
}
}
if (obj.type === hazard) {
fullScreenMessage("DEXTER DIED!", color`6`);
gameOver = true;
}
});
// Doakes catches Dexter
if (d.x === c.x && d.y === c.y) {
fullScreenMessage("DOAKES WINS!", color`2`);
gameOver = true;
}
});
Binary file added games/img/Dex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.