diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index b3fc702375..032e98b10f 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -4,6 +4,10 @@ on: pull_request: types: [opened, reopened, edited, synchronize] +env: + PUBLIC_MAX_LOOP_TIME_MS: 1500 + PUBLIC_MAX_ITERATIONS: 2000 + jobs: build: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index f3b0646c3a..f2eebb3d7b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ yarn-error.log .env dist/ games/metadata.json -public/*.json \ No newline at end of file +public/*.json +firmware/spade/firmware.elf +firmware/spade/firmware.uf2 \ No newline at end of file diff --git a/games/2Ptag.js b/games/2Ptag.js new file mode 100644 index 0000000000..1e7a7fa234 --- /dev/null +++ b/games/2Ptag.js @@ -0,0 +1,195 @@ +/* +@title: 2Ptag +@author: Shadow8928 +@tags: [] +@addedOn: 2025-01-03 +*/ +var end = 0 +const player = "p" +const player1 = "q" +const pl1_win = tune` +16000` +const pl2_win = tune` +16000` +const win = "w" +const win2 = "s" +var turn = 1; +setLegend( + [player, bitmap` +................ +................ +.......000...... +.......0.0...... +......0..0...... +......0...0.0... +....0003.30.0... +....0.0...000... +....0.05550..... +......0...0..... +.....0....0..... +.....0...0...... +......000....... +......0.0....... +.....00.00...... +................`], + [player1, bitmap` +................ +................ +.......000...... +.......0.0...... +......0..0...... +......0...0.0... +....0003.30.0... +....0.0...000... +....0.05550..... +......0...0..... +.....0....0..... +.....0...0...... +......000....... +......0.0....... +.....00.00...... +................`], + [win, bitmap` +................ +................ +................ +................ +.0.0.0.000.0...0 +.0.0.0.0.0.00..0 +.0.0.0.0.0.0.0.0 +.0.0.0.0.0.0..00 +.00000.000.0...0 +................ +.000.00......... +.0.0..0......... +.000..0......... +.0....0......... +.0....0......... +................`], + [win2, bitmap` +................ +................ +................ +................ +.0.0.0.000.0...0 +.0.0.0.0.0.00..0 +.0.0.0.0.0.0.0.0 +.0.0.0.0.0.0..00 +.00000.000.0...0 +................ +.000..000....... +.0.0....0....... +.000..000....... +.0....0.0....... +.0....00000..... +................`] + +) + +setSolids([]) + +let level = 0 +var levels = [ + map` +.....q +...... +...... +...... +p.....` +] + +setMap(levels[level]) + +setPushables({ + [player]: [] +}) +pl1 = getFirst(player) +pl2 = getFirst(player1) +onInput("s", () => { + if (turn == 1) { + pl1.y += 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + turn = 3 + playTune(pl1_win) + end = 1 + } + } +}) +onInput("w", () => { + if (turn == 1) { + getFirst(player).y -= 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + turn = 3 + playTune(pl1_win) + end = 1 + } + } +}) +onInput("a", () => { + if (turn == 1) { + getFirst(player).x -= 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + turn = 3 + playTune(pl1_win) + end = 1 + } + } +}) +onInput("d", () => { + if (turn == 1) { + getFirst(player).x += 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + turn = 3 + playTune(pl1_win) + end = 1 + } + } +}) + +onInput("k", () => { + if (turn == 1) { + getFirst(player1).y += 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + turn = 3 + playTune(pl2_win) + end = 2 + } + } +}) +onInput("i", () => { + if (turn == 1) { + getFirst(player1).y -= 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + playTune(pl2_win) + end = 2 + turn = 3 + } + } +}) +onInput("j", () => { + if (turn == 1) { + getFirst(player1).x -= 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + playTune(pl2_win) + end = 2 + turn = 3 + } + } +}) +onInput("l", () => { + if (turn == 1) { + getFirst(player1).x += 1 + if (pl1.x == pl2.x && pl1.y == pl2.y) { + playTune(pl2_win) + end = 2 + turn = 3 + } + } +}) +afterInput(() => { + if (end == 1) { + addText("Player 1 Wins!", { x: 5, y: 5, color: color`0` }) + } else if (end == 2) { + addText("Player 2 Wins!", { x: 5, y: 5, color: color`0` }) + } +}) diff --git a/games/Be_Younique.js b/games/Be_Younique.js new file mode 100644 index 0000000000..a947fb696e --- /dev/null +++ b/games/Be_Younique.js @@ -0,0 +1,575 @@ +/* +@title: Be Younique +@author: pixelianWarrior +@tags: [] +@addedOn: 2024-11-29 +*/ + +const player = "p" +const enemy = "e" +const immobileEnemy = "i" +const ammoPack = "a" +const ground = "g" +const wall = "w" +const playerWall = "q" +const bulletWall = "b" + +const upBullet = "u" +const downBullet = "d" +const leftBullet = "l" +const rightBullet = "r" + +const hit = tune` +258.62068965517244: B5-258.62068965517244, +8017.241379310346` +const die = tune` +234.375: B5^234.375, +234.375: E5/234.375, +234.375: A4/234.375, +234.375: C4/234.375, +6562.5` +const win = tune` +238.0952380952381: C4/238.0952380952381, +238.0952380952381: C5/238.0952380952381 + G4-238.0952380952381 + D4^238.0952380952381, +238.0952380952381: B5/238.0952380952381 + F5-238.0952380952381 + C5^238.0952380952381, +6904.761904761905` +const reload = tune` +135.13513513513513: C5/135.13513513513513 + A4^135.13513513513513, +135.13513513513513: D5^135.13513513513513 + G4/135.13513513513513, +4054.0540540540537` +const shoot = tune` +79.57559681697613: F5^79.57559681697613, +79.57559681697613: E5^79.57559681697613 + C5^79.57559681697613, +79.57559681697613: F5^79.57559681697613, +2307.6923076923076` + +let changing = false +let ammo = 8 + +clearText() +addText(ammo + "/8", { + x: 0, + y: 0, + color: color`6` +}) + +setLegend( + [player, bitmap` +.....000000..... +....082LL280.... +....0LLLLLL0.... +....0LLHHHL0.... +.....000000..... +0.....0000.....0 +00....0000....00 +..000000000000.. +......0000...... +......0000...... +......0000...... +.....000000..... +.....0....0..... +.....0....0..... +....00....00.... +..000......000..`], + [enemy, bitmap` +.....000000..... +....028LL280.... +....0LLLLLL0.... +....0LLHHLL0.... +.....000000..... +......3333...... +.....773377..... +....7.7337.7.... +....0.7337.0.... +....0.7777.0.... +....0.7777.0.... +......FFFF...... +......F..F...... +......F..F...... +......3..3...... +.....33..33.....`], + [immobileEnemy, bitmap` +.....000000..... +....082LL820.... +....0LLLLLL0.... +....0LLHHLL0.... +.....000000..... +......4444...... +.....HH44HH..... +....H.H44H.H.... +....0.H44H.0.... +....0.HHHH.0.... +....0.HHHH.0.... +......FFFF...... +......F..F...... +......F..F...... +......9..9...... +.....99..99.....`], + [ammoPack, bitmap` +................ +.......D........ +.......DD....... +........DD...... +.........DD..... +..........DD.... +......424..DD... +....664246F6DD.. +...DFFDDDDDDD... +...D66DDDDDDD... +...DFFDDDDDDD... +...D66DDDDDDD... +...DDDDDDDDDD... +...DDDDDDDDDD... +................ +................`], + [ground, bitmap` +1LLLLLL11LLLLLL1 +1LLLLLL11LLLLLL1 +1LLLLLL11LLLLLL1 +1111111111111111 +LLL11LLLLLL11LLL +LLL11LLLLLL11LLL +LLL11LLLLLL11LLL +1111111111111111 +1LLLLLL11LLLLLL1 +1LLLLLL11LLLLLL1 +1LLLLLL11LLLLLL1 +1111111111111111 +LLL11LLLLLL11LLL +LLL11LLLLLL11LLL +LLL11LLLLLL11LLL +1111111111111111`], + [wall, bitmap` +LLLLLLLLLLLLLLLL +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +L00000000000000L +LLLLLLLLLLLLLLLL`], + [playerWall, bitmap` +33HHHHHHHHHHHH33 +333..........333 +H333........333H +H.333......333.H +H..333....333..H +H...333..333...H +H....333333....H +H.....3HH3.....H +H.....3HH3.....H +H....333333....H +H...333..333...H +H..333....333..H +H.333......333.H +H333........333H +333..........333 +33HHHHHHHHHHHH33`], + [bulletWall, bitmap` +......8888...... +.......11....... +.......11....... +.......11....... +.......11....... +.......11....... +8.....8118.....8 +8111111881111118 +8111111881111118 +8.....8118.....8 +.......11....... +.......11....... +.......11....... +.......11....... +.......11....... +......8888......`], + [upBullet, bitmap` +................ +................ +................ +................ +................ +.......99....... +......9339...... +.....933339..... +.....933339..... +.....933339..... +.....933339..... +................ +................ +................ +................ +................`], + [downBullet, bitmap` +................ +................ +................ +................ +................ +.....933339..... +.....933339..... +.....933339..... +.....933339..... +......9339...... +.......99....... +................ +................ +................ +................ +................`], + [leftBullet, bitmap` +................ +................ +................ +................ +................ +.......9999..... +......93333..... +.....933333..... +.....933333..... +......93333..... +.......9999..... +................ +................ +................ +................ +................`], + [rightBullet, bitmap` +................ +................ +................ +................ +................ +.....9999....... +.....33339...... +.....333339..... +.....333339..... +.....33339...... +.....9999....... +................ +................ +................ +................ +................`] +) + +setSolids([player, enemy, immobileEnemy, wall, playerWall]) + +let level = 0 +const levels = [ + map` +a.......ea +e......... +.......... +.....p.... +.......... +.......... +.........e +ae.......a`, + map` +.....we... +.....we... +aeew.ww... +wwww.p.... +......wwww +...ww.weea +...ew..... +...ew.....`, + map` +a........p +qqqqqqqqq. +........q. +.e......q. +....ww..q. +....wwe.q. +....e...q. +e.......qa`, + map` +qqq..a.bbb +qiq....beb +qqq....bbb +.......... +.......... +bbbbqqbbbb +ee..qq.... +ie.aqq...p`, + map` +pb......be +bb.wqqw.bb +..w....w.. +..q.ii.q.. +..q.ii.q.. +..w....w.. +bb.wqqw.bb +eb......be` +] + +setMap(levels[level]) + +setBackground(ground) + +setPushables({ + [player]: [] +}) + +onInput("s", () => { + getFirst(player).y += 1 +}) + +onInput("w", () => { + getFirst(player).y -= 1 +}) + +onInput("d", () => { + getFirst(player).x += 1 +}) + +onInput("a", () => { + getFirst(player).x -= 1 +}) + +onInput("k", () => { + if (ammo > 0) { + playTune(shoot) + addSprite(getFirst(player).x, getFirst(player).y, downBullet) + getAll(downBullet)[getAll(downBullet).length - 1].isPlayer = true + ammo-- + } +}) + +onInput("i", () => { + if (ammo > 0) { + playTune(shoot) + addSprite(getFirst(player).x, getFirst(player).y, upBullet) + getAll(upBullet)[getAll(upBullet).length - 1].isPlayer = true + ammo-- + } +}) + +onInput("l", () => { + if (ammo > 0) { + playTune(shoot) + addSprite(getFirst(player).x, getFirst(player).y, rightBullet) + getAll(rightBullet)[getAll(rightBullet).length - 1].isPlayer = true + ammo-- + } +}) + +onInput("j", () => { + if (ammo > 0) { + playTune(shoot) + addSprite(getFirst(player).x, getFirst(player).y, leftBullet) + getAll(leftBullet)[getAll(leftBullet).length - 1].isPlayer = true + ammo-- + } +}) + +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min)) + min; +} + +afterInput(() => { + getAll(upBullet).forEach(bullet => { + if (bullet.y === 0) { + bullet.remove() + } else { + bullet.y -= 1 + } + const potentialEnemy = getTile(bullet.x, bullet.y) + if (potentialEnemy.some(sprite => sprite.type === player && !bullet.isPlayer)) { + clearTile(bullet.x, bullet.y) + playTune(die) + addText("GAME OVER", { + x: 6, + y: 4, + color: color`3` + }) + } else if ((potentialEnemy.some(sprite => sprite.type === enemy) || potentialEnemy.some(sprite => sprite.type === immobileEnemy)) && bullet.isPlayer) { + playTune(hit) + clearTile(bullet.x, bullet.y) + const action = getRandomInt(1, 3) + if(action == 1) { + addSprite(bullet.x,bullet.y,ammoPack) + } + } else if (potentialEnemy.some(sprite => sprite.type === wall) || potentialEnemy.some(sprite => sprite.type === bulletWall)) { + bullet.remove() + } + }) + + getAll(downBullet).forEach(bullet => { + if (bullet.y === height() - 1) { + bullet.remove() + } else { + bullet.y += 1 + } + const potentialEnemy = getTile(bullet.x, bullet.y) + if (potentialEnemy.some(sprite => sprite.type === player && !bullet.isPlayer)) { + clearTile(bullet.x, bullet.y) + playTune(die) + addText("GAME OVER", { + x: 6, + y: 4, + color: color`3` + }) + } else if ((potentialEnemy.some(sprite => sprite.type === enemy) || potentialEnemy.some(sprite => sprite.type === immobileEnemy)) && bullet.isPlayer) { + playTune(hit) + clearTile(bullet.x, bullet.y) + const action = getRandomInt(1, 3) + if(action == 1) { + addSprite(bullet.x,bullet.y,ammoPack) + } + } else if (potentialEnemy.some(sprite => sprite.type === wall) || potentialEnemy.some(sprite => sprite.type === bulletWall)) { + bullet.remove() + } + }) + + getAll(rightBullet).forEach(bullet => { + if (bullet.x === width() - 1) { + bullet.remove() + } else { + bullet.x += 1 + } + const potentialEnemy = getTile(bullet.x, bullet.y) + if (potentialEnemy.some(sprite => sprite.type === player && !bullet.isPlayer)) { + clearTile(bullet.x, bullet.y) + playTune(die) + addText("GAME OVER", { + x: 6, + y: 4, + color: color`3` + }) + } else if ((potentialEnemy.some(sprite => sprite.type === enemy) || potentialEnemy.some(sprite => sprite.type === immobileEnemy)) && bullet.isPlayer) { + playTune(hit) + clearTile(bullet.x, bullet.y) + const action = getRandomInt(1, 3) + if(action == 1) { + addSprite(bullet.x,bullet.y,ammoPack) + } + } else if (potentialEnemy.some(sprite => sprite.type === wall) || potentialEnemy.some(sprite => sprite.type === bulletWall)) { + bullet.remove() + } + }) + + getAll(leftBullet).forEach(bullet => { + if (bullet.x === 0) { + bullet.remove() + } else { + bullet.x -= 1 + } + const potentialEnemy = getTile(bullet.x, bullet.y) + if (potentialEnemy.some(sprite => sprite.type === player && !bullet.isPlayer)) { + clearTile(bullet.x, bullet.y) + playTune(die) + addText("GAME OVER", { + x: 6, + y: 4, + color: color`3` + }) + } else if ((potentialEnemy.some(sprite => sprite.type === enemy) || potentialEnemy.some(sprite => sprite.type === immobileEnemy)) && bullet.isPlayer) { + playTune(hit) + clearTile(bullet.x, bullet.y) + const action = getRandomInt(1, 3) + if(action == 1) { + addSprite(bullet.x,bullet.y,ammoPack) + } + + } else if (potentialEnemy.some(sprite => sprite.type === wall) || potentialEnemy.some(sprite => sprite.type === bulletWall)) { + bullet.remove() + } + }) + + getAll(enemy).forEach(en => { + const action = getRandomInt(1, 17); + switch (action) { + case 1: + en.x += 1 + break + case 2: + en.x -= 1 + break + case 3: + en.y -= 1 + break + case 4: + en.y += 1 + break + case 5: + addSprite(en.x, en.y, upBullet) + break + case 6: + addSprite(en.x, en.y, downBullet) + break + case 7: + addSprite(en.x, en.y, leftBullet) + break + case 8: + addSprite(en.x, en.y, rightBullet) + break + } + }) + + getAll(immobileEnemy).forEach(en => { + const action = getRandomInt(1, 7); + switch (action) { + case 1: + addSprite(en.x, en.y, upBullet) + break + case 2: + addSprite(en.x, en.y, downBullet) + break + case 3: + addSprite(en.x, en.y, leftBullet) + break + case 4: + addSprite(en.x, en.y, rightBullet) + break + } + }) + + const potentialEnemy = getTile(getFirst(player).x, getFirst(player).y) + if (potentialEnemy.some(sprite => sprite.type === ammoPack)) { + ammo = 8 + playTune(reload) + potentialEnemy.filter(sprite => sprite.type === ammoPack)[0].remove() + } + if (getFirst(enemy) === undefined && getFirst(immobileEnemy) === undefined && !changing) { + changing = true + playTune(win) + addText("YOU WIN", { + x: 7, + y: 4, + color: color`4` + }) + if (level < levels.length - 1) { + setTimeout(() => { + level++ + setMap(levels[level]) + clearText() + changing = false + ammo = 8 + addText(ammo + "/8", { + x: 0, + y: 0, + color: color`6` + }) + }, 2000) + } + } + if (!changing) { + clearText() + addText(ammo + "/8", { + x: 0, + y: 0, + color: color`6` + }) + } + + +}) diff --git a/games/ChocolateNimGame.js b/games/ChocolateNimGame.js new file mode 100644 index 0000000000..8a2200f177 --- /dev/null +++ b/games/ChocolateNimGame.js @@ -0,0 +1,201 @@ +/* +@title: ChocolateNimGame +@author: Sarah Akhtar +@tags: ['strategy', 'puzzle'] +@addedOn: 2024-12-10 +*/ + +/** + * Creates Entities + */ +const chocolate = "c" +const spoiled = "s" +setLegend( + [ chocolate, bitmap` +0000000000000000 +0CCCCCCCCCCCCCC0 +0C22C2CCCCCCCCC0 +0C2CCCCCCCCCCCC0 +0C2CCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0CCCCCCCCCCCCCC0 +0000000000000000`], + [ spoiled, bitmap` +5555555555555555 +5000000000000005 +505550LLLLLLLL05 +505550LLLLLLLL05 +5055500000000005 +5000007777705505 +50L0500000005505 +50L050550LL05505 +50L050550LL05505 +50L0500000005505 +500050LL0LL05505 +505050000LL05505 +500050550LL05505 +507050550LL05505 +5000000000000005 +5555555555555555`] +) +setSolids([]) + +/** + * Defining States + */ +let chocolateBar = [] +let spoiledRow = 0 +let spoiledCol = 0 +let isPlayerTurn = true + +/** + * Starting Game + */ +initializeGame(5, 5) + +/** + * Random State Generation + */ +function getRandomPosition(rows, cols) { + return { + row: Math.floor(Math.random() * rows), + col: Math.floor(Math.random() * cols) + } +} + +/** + * Creating Game + */ +function initializeGame(rows, cols) { + const { row: sr, col: sc } = getRandomPosition(rows, cols) + + chocolateBar = Array(rows).fill().map(() => Array(cols).fill(chocolate)) + spoiledRow = sr + spoiledCol = sc + chocolateBar[spoiledRow][spoiledCol] = spoiled + + isPlayerTurn = ((rows % 2 === 1 && cols % 2 === 1) || (rows % 2 === 0 && cols % 2 === 0)) + + updateMap() +} + +/** + * Updating Map from Key + */ +function updateMap() { + clearText() + const newMap = chocolateBar.map(row => row.join('')).join('\n') + setMap(newMap) + addText("Chocolate Nim Game", { + y: 2, + color: color`6`, + }) +} + +/** + * Input Command 'W' + */ +onInput("w", () => { + if (isPlayerTurn) eatChocolate('u') +}) + +/** + * Input Command 'S' + */ +onInput("s", () => { + if (isPlayerTurn) eatChocolate('d') +}) + +/** + * Input Command 'A' + */ +onInput("a", () => { + if (isPlayerTurn) eatChocolate('l') +}) + +/** + * Input Command 'D' + */ +onInput("d", () => { + if (isPlayerTurn) eatChocolate('r') +}) + +/** + * Eating Chocolate Animation + */ +function eatChocolate(direction) { + let eatsSpoiled = false + if (direction === 'u') { + eatsSpoiled = (spoiledRow === 0) + if (!eatsSpoiled) { + chocolateBar.shift() + spoiledRow-- + } + } else if (direction === 'd') { + eatsSpoiled = (spoiledRow === chocolateBar.length - 1) + if (!eatsSpoiled) { + chocolateBar.pop() + } + } else if (direction === 'l') { + eatsSpoiled = (spoiledCol === 0) + if (!eatsSpoiled) { + chocolateBar.forEach(row => row.shift()) + spoiledCol-- + } + } else if (direction === 'r') { + eatsSpoiled = (spoiledCol === chocolateBar[0].length - 1) + if (!eatsSpoiled) { + chocolateBar.forEach(row => row.pop()) + } + } + + if (eatsSpoiled) { + addText("Game Over! You Lost!", { + y: 8, + color: color`6`, + }) + setTimeout(() => initializeGame(5, 5), 2000) + } else { + updateMap() + isPlayerTurn = !isPlayerTurn + if (!isPlayerTurn) { + computerMove() + } + } +} + +/** + * Computer Artificial Intelligence (AI) Move + */ +function computerMove() { + const validMoves = ['u', 'd', 'l', 'r'].filter(dir => isValidMove(dir)) + if (validMoves.length > 0) { + const randomMove = validMoves[Math.floor(Math.random() * validMoves.length)] + eatChocolate(randomMove) + } else { + addText("You Win! Computer Lost!", { + y: 8, + color: color`6`, + }) + setTimeout(() => initializeGame(5, 5), 2000) + } +} + +/** + * Valid Direction Check + */ +function isValidMove(direction) { + if (direction === 'u') return spoiledRow > 0 + if (direction === 'd') return spoiledRow < chocolateBar.length - 1 + if (direction === 'l') return spoiledCol > 0 + if (direction === 'r') return spoiledCol < chocolateBar[0].length - 1 + return false +} diff --git a/games/ClassicPinPon.js b/games/ClassicPinPon.js new file mode 100644 index 0000000000..fc3543ce87 --- /dev/null +++ b/games/ClassicPinPon.js @@ -0,0 +1,232 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: PinPon +@author: pmm-inf +@tags: [] +@addedOn: 2025-01-03 +*/ + +const player1 = "1" +const player2 = "2" +const ball = "b" +const ground = "g" + +setLegend( + [ player1, bitmap` +.......22....... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +.......22.......` ], + [ ball, bitmap` +................ +....22222222.... +...2222222222... +..222222222222.. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +..222222222222.. +...2222222222... +....22222222.... +................`], + [ player2, bitmap` +.......22....... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +......2222...... +.......22.......`], + [ ground, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`] +) + +setBackground(ground) + +setSolids([]) + +addText("Welcome to the", { + x: 3, + y: 5, + color: color`2` +}) + +addText("most boring game.", { + x: 2, + y: 7, + color: color`2` +}) + +addText(":)", { + x: 9, + y: 9, + color: color`2` +}) + +let level = 0 +const levels = [ + map` +ggggggggg +ggggggggg +ggggggggg +ggggggggg +ggggggggg +ggggggggg +ggggggggg +ggggggggg +ggggggggg`, + map` +......... +1........ +......... +......... +....b.... +......... +......... +......... +........2` +] + +setMap(levels[level]) + +setPushables({ + [ player1 ]: [] +}) + +onInput("w", () => { + getFirst(player1).y += -1 +}) + +onInput("s", () => { + getFirst(player1).y += 1 +}) + +onInput("i", () => { + getFirst(player2).y += -1 +}) + +onInput("k", () => { + getFirst(player2).y += 1 +}) + +onInput("a", () => { + if (level == 0) { + clearText() + level += 1 + setMap(levels[level]) + } else { + } +}) + +const interval = setInterval(gameLoop, 200); + +let ball_vx = 1; +let ball_vy = 1; + +score1 = 0; +score2 = 0; + +function showScore() { + clearText(); + addText(score1.toString().padStart(2, "0"), { + x: 0, + y: 1, + color: color`2` + }); + addText(score2.toString().padStart(2, "0"), { + x: 18, + y: 1, + color: color`2` + }); +} + +function gameLoop() { + if (level == 1) { + const b = getFirst(ball); + const p1 = getFirst(player1); + const p2 = getFirst(player2); + b.x += ball_vx; + b.y += ball_vy; + if (b.x == 8) { + ball_vx = -1; + score1 += 1; + showScore(); + } + if (b.x == 0) { + ball_vx = 1; + score2 += 1; + showScore(); + } + if (b.y == 8) { + ball_vy = -1; + } + if (b.y == 0) { + ball_vy = 1; + } + if (b.x == 7) { + if (p2.y == b.y) { + ball_vx = -1 + } + if (ball_vy != 0 && b.y+ball_vy == p2.y) { + ball_vx = -1 + ball_vy = -ball_vy + } + } + if (b.x == 1) { + if (p1.y == b.y) { + ball_vx = 1 + } + if (ball_vy != 0 && b.y+ball_vy == p1.y) { + ball_vx = 1 + ball_vy = -ball_vy + } + } + } +} + +afterInput(() => { + +}) diff --git a/games/CubeCastle.js b/games/CubeCastle.js new file mode 100644 index 0000000000..eea6f60828 --- /dev/null +++ b/games/CubeCastle.js @@ -0,0 +1,469 @@ +/* +@title: Cube Castle +@author: Paylicier +@tags: ['platformer'] +@addedOn: 2024-12-05 +*/ + +const player = "p" +const king = "k" +const princess = "w" +const plateform = "#" +const lava = "@" +const sign = "s" +const fireball = "f" + +const DIAL_SCENE = 0 + +setLegend( + [player, bitmap` +................ +................ +..00000000000000 +..00000000000000 +0000LLLLLLLLLL00 +0000LLLLLLLLLL00 +00LLLLL00LL00L00 +00LLLLL00LL00L00 +00LLLLLLLLLLLL00 +00LLLLLLLLLLLL00 +00LLLLLLLLLLLL00 +00LLLLLLLLLLLL00 +0000LLLLLLLLLL00 +0000LLLLLLLLLL00 +..00000000000000 +..00000000000000`], + [plateform, bitmap` +0000000000000000 +0000000000000000 +0011111111111100 +0011111111111100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011LLLLLLLL1100 +0011111111111100 +0011111111111100 +0000000000000000 +0000000000000000`], + [lava, bitmap` +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999`], + [sign, bitmap` +................ +................ +................ +...CCCCCCCCCC... +..CCCCCCCCCCCC.. +..CC00000000CC.. +..CCCCCCCCCCCC.. +..CCC000000CCC.. +..CCCCCCCCCCCC.. +..CCCC0000CCCC.. +..CCCCCCCCCCCC.. +......FFFF...... +......FFFF...... +......FFFF...... +......FFFF...... +......FFFF......`], + [king, bitmap` +................ +6.66.66.66.66.66 +6.66.66.66.66.66 +6666666666666666 +6666666666666666 +0000000000000000 +0000000000000000 +00L0LLLLLLLL0L00 +00LL0LLLLLL0LL00 +00LLL0LLLL0LLL00 +00L20LLLLLL02L00 +00L20L0LL0L02L00 +00LLLLL00LLLLL00 +00LLLLLLLLLLLL00 +0000000000000000 +0000000000000000`], + [princess, bitmap` +................ +................ +................ +.............H8H +HHHHHHHHHHHHH868 +HHHHHHHHHHHHHH8H +0000000000000000 +00LLLLLLLLLLLL00 +00L20LLLLLL02L00 +00L20LLLLLL02L00 +00LLLLLLLLLLLL00 +00LLLL0000LLLL00 +00LLL0LLLL0LLL00 +00LLLLLLLLLLLL00 +0000000000000000 +0000000000000000`], + [fireball, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +....33333333.... +....39999993.... +....39666693.... +....39622693.... +....39622693.... +....39666693.... +....39999993.... +....33333333....`] +) + +setSolids([plateform, player]) + +let isJumping = false +let isDead = false +let lives = 5 + +let level = 1 +const levels = [ + map` +.`, + map` +.......... +.........s +.......### +...#.#.... +p......... +##########`, + map` +.......... +.........s +.....##.## +....###... +p..####... +#@@#@@#@@@`, + map` +.........# +.........# +p........# +########## +########## +########## +.........s +########## +@@@@@@@@@@`, + map` +............ +............ +.p.......... +.#..#..#...s +@#@@#@@#@@## +@#@@#@@#@@@@`, + map` +............ +..s......... +..##.####... +..........## +.........### +........#... +......##.... +.p.##..#.... +.#..#..#.... +@#@@#@@#@@@@ +@#@@#@@#@@@@`, + map` +................. +....w............ +...###........... +................. +..............k.s +..............### +..p.......###.... +.###..###........ +................. +@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@` +] + +const melody = tune` +185.1851851851852: C4/185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852 + B4/185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: C4/185.1851851851852, +185.1851851851852: C4-185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852 + B4/185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852, +185.1851851851852: C4/185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852 + B4/185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: E4^185.1851851851852, +185.1851851851852: D4-185.1851851851852, +185.1851851851852: C4/185.1851851851852, +185.1851851851852: C4-185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852 + B4/185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852, +185.1851851851852: D4^185.1851851851852, +185.1851851851852: C4-185.1851851851852` +let playback = playTune(melody, Infinity) +let time = 0; + +const dialogues = [{ + level: 1, + text: "In this game,\nyou're a cube\nthat needs\nto free\nthe princess\nfrom the cube\nking.\n\n\nPress L again\nto close", + targetlvl: 2 + }, + { + level: 2, + text: "Welcome to\nthe king's\ncastle\n\n\nPress L again\nto close", + targetlvl: 3 + }, + { + level: 3, + text: "You're\nentering the\nlava hallway\n\nPress L again\nto close", + targetlvl: 4 + }, + { + level: 4, + text: "You're\nentering the\nlava hallway2\n\nPress L again\nto close", + targetlvl: 5 + }, + { + level: 5, + text: "Boss Battle\ntime\n!1!1!1!1!\n\nPress L again\nto close", + targetlvl: 6 + }, + { + level: 6, + text: `You win !\nThe king failed\na jump and\ndied in lava.\n\nTime: {TIME} sec.\n\nPress L to\nrestart`, + targetlvl: 1 + } +] + +function jump(player) { + const plr = getFirst(player); + if (isJumping && player != king) return; + isJumping = true + plr.y -= 1 + setTimeout(function() { + plr.y -= 1 + if (player === king) plr.x -= 1 + setTimeout(function() { + isJumping = false + gravity(player) + }, 120) + }, 60) +} + +function gravity(obj) { + const playerSprite = getFirst(obj) + if (!playerSprite) return; + if (!isJumping) { + const belowSprites = getTile(playerSprite.x, playerSprite.y + 1) + + if (belowSprites.some(sprite => sprite?.type === lava) || belowSprites.some(sprite => sprite?.type === player)) { + if (obj != player && !belowSprites.some(sprite => sprite?.type === player)) return playerSprite.remove(); + // Player touched lava/fireball, reset the game + kill() + return; + } + + if (belowSprites.length === 0) { + isJumping = true + playerSprite.y += 1 + setTimeout(function() { + isJumping = false + gravity(obj) + }, 100) + } else { + if (obj === fireball) { + breakBlock(belowSprites[0].x, belowSprites[0].y) + return playerSprite.remove() + } + isJumping = false + } + } +} + +function kill() { + isDead = true + setMap(levels[DIAL_SCENE]) + lives-- + if (lives === 0) { + addText("Game Over !", { x: 5, y: 5, color: color`0` }) + setTimeout(function() { + isJumping = false + isDead = false + clearText() + level = 1 + lives = 5 + time = 0 + setMap(levels[1]) + }, 1200) + return; + } + addText("You died !\n\nLives:" + lives, { x: 5, y: 5, color: color`0` }) + setTimeout(function() { + isJumping = false + isDead = false + clearText() + setMap(levels[level]) + if (level === 6) bossFight(); + }, 1200) +} + +function spawnFireballs() { + if (level != 3) return; + const fireballX = Math.floor(Math.random() * width()) // Random x coordinate + const fireballY = 0 // Fixed y coordinate + addSprite(fireballX, fireballY, fireball) + gravity(fireball) + setTimeout(function() { + spawnFireballs() + }, Math.floor(Math.random() * 1000) + 100) +} + +function breakBlock(x, y) { + const blockSprite = getTile(x, y)[0] + if (blockSprite?.type === plateform) { + blockSprite.remove() // Remove the block sprite + } +} + +function bossFight() { + setTimeout(function() { + const kingSprite = getFirst(king); + if (kingSprite) { + jump(king); + } + }, 1500) +} + +function interactCheck() { + const playerSprite = getFirst(player) + if (!playerSprite) return; + const adjacentSprites = [ + getTile(playerSprite.x + 1, playerSprite.y)[0], // Right + getTile(playerSprite.x - 1, playerSprite.y)[0], // Left + getTile(playerSprite.x, playerSprite.y - 1)[0] // Up + ] + + const isNearSign = adjacentSprites.some(sprite => sprite?.type === sign) + + if (isNearSign) { + addText("Press L to interact", { x: 0, y: 14, color: color`2` }) + } else { + clearText() + } +} + + +function interact() { + const playerSprite = getFirst(player) + if (!playerSprite) { + if (isDead) return; + const dialogue = dialogues.find((dial) => dial.level === level); + clearText(); + if (dialogue?.targetlvl) level = dialogue.targetlvl + if (level === 3) spawnFireballs(); + setMap(levels[level]); + if (level === 6) bossFight(); + if (level === 1) { + time = 0; + lives = 5; + } + return; + } + const adjacentSprites = [ + getTile(playerSprite.x + 1, playerSprite.y)[0], // Right + getTile(playerSprite.x - 1, playerSprite.y)[0], // Left + ] + + const isNearSign = adjacentSprites.some(sprite => sprite?.type === sign) + + if (isNearSign) { + const dialogue = dialogues.find((dial) => dial?.level === level); + setMap(levels[DIAL_SCENE]) + clearText() + addText(dialogue?.text.replace("{TIME}", time) || "notext", { x: 3, y: 1, color: color`0` }) + } +} + + +setMap(levels[level]) + +setPushables({ + [player]: [] +}) + +onInput("w", () => { + if (!getFirst(player)) return; + jump(player) +}) + +onInput("l", () => { + interact() +}) + +onInput("d", () => { + if (!getFirst(player)) return; + getFirst(player).x += 1 +}) + +onInput("a", () => { + if (!getFirst(player)) return; + getFirst(player).x -= 1 +}) + +onInput("k", () => { + if (playback) { + playback.end() + playback = null + return; + } + playback = playTune(melody, Infinity); + +}) + +afterInput(() => { + if (!isJumping) gravity(player) + interactCheck() +}) + + +//time +setInterval(function() { + time++ +}, 1000) diff --git a/games/Cyan.js b/games/Cyan.js new file mode 100644 index 0000000000..e5399d1f0b --- /dev/null +++ b/games/Cyan.js @@ -0,0 +1,786 @@ +/* +@title: Cyan +@author: Boyce Dyson +@tags: ['puzzle'] +@addedOn: 2024-12-16 +*/ + +let blocky = 0 +let blockx = 0 + +const background = "b" +const cyanblock = "i" +const button = "B" +const leftside = "l" +const rightside = "r" +const top = "t" +const floor = "f" +const topleftcorner = "T" +const toprightcorner = "R" +const bottomleftcorner = "L" +const bottomrightcorner = "F" +const character = "c" +const onbutton = "o" +const cursor = "C" + +setLegend( + [cursor, bitmap` +3333333333333333 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3..............3 +3333333333333333`], + [character, bitmap` +5555555555555555 +5777777777777775 +5777777777777775 +5775577777777775 +5775577777755775 +5777777777755775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5775777777777575 +5777577777555575 +5777755555777775 +5777777777777775 +5555555555555555`], + [leftside, bitmap` +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7...............`], + [rightside, bitmap` +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7`], + [top, bitmap` +7777777777777777 +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [floor, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +7777777777777777`], + [topleftcorner, bitmap` +7777777777777777 +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7...............`], + [toprightcorner, bitmap` +7777777777777777 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7`], + [bottomleftcorner, bitmap` +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7............... +7777777777777777`], + [bottomrightcorner, bitmap` +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +...............7 +7777777777777777`], + [background, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [cyanblock, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [button, bitmap` +5555555555555555 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5000000000000005 +5555555555555555`], + [onbutton, bitmap` +5555555555555555 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5777777777777775 +5555555555555555`] +) + +setSolids([]) + +const WinJingle = tune` +252.10084033613447, +252.10084033613447: G4-252.10084033613447, +252.10084033613447: A4-252.10084033613447, +252.10084033613447: B4-252.10084033613447, +252.10084033613447: C5-252.10084033613447, +252.10084033613447, +252.10084033613447: C5-252.10084033613447 + G4-252.10084033613447, +252.10084033613447: C5-252.10084033613447 + G4-252.10084033613447, +6050.420168067227` + +let LevelFinished = false + +let level = 0 +const levels = [ + map` +TtttR +l...r +l...r +LfffF`, + map` +TtttR +l.B.r +lB.Br +l.B.r +LfffF`, + map` +TttttttttR +l........r +l........r +l........r +l........r +l........r +l........r +LffffffffF`, + map` +iiiiiiiiiiiiiii +iiBBBiiBBBBBiii +iBiiBBBBiBBBiii +iBiiiiiiiBBBBii +iBiBBBiiiBBiBii +iBiBiBBBBBBiBii +iBiBiiiiiiBBBii +iBiBiiiiBBBBiii +iBiBBBBBBiiBiii +iBiiBBBBBBBBiii +iBBBBiiiiiiiiii +iiiiiiiiiiiiiii`, + map` +iiiiiiiiii +iiBBBBBBii +iiBBBBBBii +iiBBBBBBii +iiBBBBBBii +iiBBBBBBii +iiBBBBBBii +iiiiiiiiii`, + map` +iiiiiiiiii +iiiBiiBiii +iiBBBBBBii +iiBBBBBBii +iiBBBBBBii +iiiBBBBiii +iiiiBBiiii +iiiiiiiiii`, + map` +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii +iiiiiiiiii`, +] + +setBackground(background) + +setMap(levels[level]) + +function Win(Level, BackgroundSprite) { + + + + LevelFinished = true + + setBackground(cyanblock) + + while (getFirst(onbutton)) { + OnButtonToDelete = getFirst(onbutton) + clearTile(OnButtonToDelete.x, OnButtonToDelete.y) + } + + addText("Cyan", { + x: 8, + y: 8, + color: color`5` + + }) + + playTune(WinJingle) + + setTimeout(() => { + level++ + setBackground(BackgroundSprite) + clearText() + + if (level != levels.length) { + setMap(levels[level]) + } + + if (level == 1) { + + addText(String(Level), { + x: width() + 12, + y: height() - 4, + color: color`5` + }) + + } else { + + addText(String(Level), { + x: width() + 7, + y: height() - 7, + color: color`5` + }) + + } + + if (level == 3) { + addSprite(1, 1, character) + + addText("i to reset", { + x: width() - 7, + y: height() + 3, + color: color`5` + }) + } + + if (level == 4) { + addSprite(2, 1, cursor) + + addText("i to reset", { + x: width() - 7, + y: height() + 6, + color: color`5` + }) + } + if (level == 5) { + addSprite(3, 1, cursor) + + buffer = 0 + + addText("i to reset", { + x: width() - 7, + y: height() + 6, + color: color`5` + }) + } + + if (level == 6) { + addText("Thanks For Playing", { + x: 1, + y: 7, + color: color`5` + }) + + addText("Cyan!", { + x: 8, + y: 8, + color: color`5` + + }) + } + + LevelFinished = false + + + }, 3000) +} + +function Level2(n) { + + if (level == 2 && LevelFinished != true) { + if (buffer == n) { + for (let i = 0; i < width(); i++) { + addSprite(i, n, cyanblock) + } + buffer++ + + if (buffer == 8) { + Win(4, background) + } + } else if (buffer != n) { + setMap(levels[2]) + buffer = 0 + } + } +} + +function Level3(key) { + if (level == 3 && LevelFinished != true) { + if (key == "w") { + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx, blocky - 1) + while (block[0].type != "i") { + getFirst(character).y -= 1 + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx, blocky - 1) + addSprite(blockx, blocky, cyanblock) + } + } + if (key == "s") { + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx, blocky + 1) + while (block[0].type != "i") { + getFirst(character).y += 1 + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx, blocky + 1) + addSprite(blockx, blocky, cyanblock) + } + } + if (key == "a") { + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx - 1, blocky) + while (block[0].type != "i") { + getFirst(character).x -= 1 + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx - 1, blocky) + addSprite(blockx, blocky, cyanblock) + } + } + if (key == "d") { + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx + 1, blocky) + while (block[0].type != "i") { + getFirst(character).x += 1 + blocky = getFirst(character).y + blockx = getFirst(character).x + block = getTile(blockx + 1, blocky) + addSprite(blockx, blocky, cyanblock) + } + } + } +} + +function Level4(key) { + if (level === 4 && LevelFinished != true) { + const Cursor = getFirst(cursor) + const x = Cursor.x + const y = Cursor.y + + + const middle = getTile(x, y)[1] + const right = getTile(x + 1, y)[0] + const left = getTile(x - 1, y)[0] + const top = getTile(x, y - 1)[0] + const bottom = getTile(x, y + 1)[0] + + if (key === "j") { + if (middle && middle.type === button) { + middle.type = onbutton + } + if (right && right.type === button) { + right.type = onbutton + } + if (left && left.type === button) { + left.type = onbutton + } + if (top && top.type === button) { + top.type = onbutton + } + if (bottom && bottom.type === button) { + bottom.type = onbutton + } + if (middle && middle.type === onbutton) { + middle.type = button + } + if (right && right.type === onbutton) { + right.type = button + } + if (left && left.type === onbutton) { + left.type = button + } + if (top && top.type === onbutton) { + top.type = button + } + if (bottom && bottom.type === onbutton) { + bottom.type = button + } + } + + if (key === "w") { + if (top && top.type !== cyanblock) { + Cursor.y -= 1 + } + } else if (key === "a") { + if (left && left.type !== cyanblock) { + Cursor.x -= 1 + } + } else if (key === "s") { + if (bottom && bottom.type !== cyanblock) { + Cursor.y += 1 + } + } else if (key === "d") { + if (right && right.type !== cyanblock) { + Cursor.x += 1 + } + } else if (key === "i") { + setMap(levels[4]) + addSprite(x, y, cursor) + } + } +} + +function Level5(key) { + if (level === 5 && LevelFinished != true) { + const Cursor = getFirst(cursor) + const x = Cursor.x + const y = Cursor.y + + + const middle = getTile(x, y)[1] + const right = getTile(x + 1, y)[0] + const left = getTile(x - 1, y)[0] + const top = getTile(x, y - 1)[0] + const bottom = getTile(x, y + 1)[0] + + if (key === "j") { + if (buffer == 0){ + if (right && right.type === button) { + right.type = onbutton + } + if (left && left.type === button) { + left.type = onbutton + } + if (right && right.type === onbutton) { + right.type = button + } + if (left && left.type === onbutton) { + left.type = button + } + buffer = 1 + } + + else if (buffer == 1) { + + if (top && top.type === button) { + top.type = onbutton + } + if (bottom && bottom.type === button) { + bottom.type = onbutton + } + if (top && top.type === onbutton) { + top.type = button + } + if (bottom && bottom.type === onbutton) { + bottom.type = button + } + buffer = 0 + } + if (middle && middle.type === button) { + middle.type = onbutton + } + if (middle && middle.type === onbutton) { + middle.type = button + } + } + + if (key === "w") { + if (top && top.type !== cyanblock) { + Cursor.y -= 1 + } + } else if (key === "a") { + if (left && left.type !== cyanblock) { + Cursor.x -= 1 + } + } else if (key === "s") { + if (bottom && bottom.type !== cyanblock) { + Cursor.y += 1 + } + } else if (key === "d") { + if (right && right.type !== cyanblock) { + Cursor.x += 1 + } + } else if (key === "i") { + setMap(levels[4]) + addSprite(x, y, cursor) + buffer = 0 + + } + } +} + +buffer = 0 + +onInput("w", () => { + Level2(0) + Level3("w") + Level4("w") + Level5("w") +}) + +onInput("s", () => { + Level3("s") + Level2(7) + Level4("s") + Level5("s") +}) + +onInput("a", () => { + Level2(6) + Level3("a") + Level4("a") + Level5("a") +}) + +onInput("d", () => { + Level2(3) + Level3("d") + Level4("d") + Level5("d") +}) + +onInput("i", () => { + if (level == 1) { + clearTile(2, 1) + addSprite(2, 1, cyanblock) + } + + if (level == 3) { + setMap(levels[3]) + addSprite(1, 1, character) + } + + Level2(4) + Level4("i") + Level5("i") +}) + +onInput("l", () => { + if (level == 1) { + clearTile(3, 2) + addSprite(3, 2, cyanblock) + } + + Level2(1) +}) + +onInput("j", () => { + if (level == 1) { + clearTile(1, 2) + addSprite(1, 2, cyanblock) + } + + Level2(5) + Level4("j") + Level5("j") +}) + +onInput("k", () => { + if (level == 1) { + clearTile(2, 3) + addSprite(2, 3, cyanblock) + } + + Level2(2) +}) + + + +if (level == 0) { + addText("1", { + x: 17, + y: 1, + color: color`5` + }) +} + +afterInput(() => { + + if (level == 3 && LevelFinished == false) { + if (getAll(cyanblock).length >= 180) { + Win(5, cyanblock) + } + } + + if (level == 0 && LevelFinished == false) { + Win(2, cyanblock) + } + + if (level == 1 && LevelFinished == false) { + if (!getFirst(button)) { + Win(3, background) + } + } + if (level == 4 && LevelFinished == false) { + if (getAll(cyanblock).length + getAll(onbutton).length >= 80) { + getAll(onbutton) + Win(6, cyanblock) + } + } + if (level == 5 && LevelFinished == false) { + if (getAll(cyanblock).length + getAll(onbutton).length >= 80) { + getAll(onbutton) + Win(7, cyanblock) + + } + } +}) diff --git a/games/DVxD.js b/games/DVxD.js new file mode 100644 index 0000000000..6ad836daaf --- /dev/null +++ b/games/DVxD.js @@ -0,0 +1,1803 @@ +/* +@title: DVD Screensaver +@author: YashVardhan Niranjan +@tags: ["utility"] +@addedOn: 2024-09-18 +*/ + + +/*Haloo Everyone !! +Yash Here !!! Hope you all Like this screensaver for sprig*/ + +const dvdwhite1 = "1" +const dvdwhite2 = "2" +const dvdwhite3 = "3" +const dvdwhite4 = "4" +const dvdwhite5 = "5" +const dvdwhite6 = "6" +const dvdwhite7 = "7" +const dvdwhite8 = "8" +const dvdblue1 = "a" +const dvdblue2 = "b" +const dvdblue3 = "c" +const dvdblue4 = "d" +const dvdblue5 = "f" +const dvdblue6 = "g" +const dvdblue7 = "h" +const dvdblue8 = "j" +const background = "z" +const dvdred1 = "q" +const dvdred2 = "w" +const dvdred3 = "e" +const dvdred4 = "r" +const dvdred5 = "t" +const dvdred6 = "y" +const dvdred7 = "u" +const dvdred8 = "i" +const dvdgreen1 = "m" +const dvdgreen2 = "n" +const dvdgreen3 = "o" +const dvdgreen4 = "p" +const dvdgreen5 = "v" +const dvdgreen6 = "x" +const dvdgreen7 = "0" +const dvdgreen8 = "9" +const dvdpurple1 = "!" +const dvdpurple2 = "@" +const dvdpurple3 = "#" +const dvdpurple4 = "$" +const dvdpurple5 = "%" +const dvdpurple6 = "^" +const dvdpurple7 = "&" +const dvdpurple8 = "*" +const dvdyellow1 = "(" +const dvdyellow2 = ")" +const dvdyellow3 = "[" +const dvdyellow4 = "]" +const dvdyellow5 = "{" +const dvdyellow6 = "}" +const dvdyellow7 = "/" +const dvdyellow8 = ":" +const dvdcyan1 = "|" +const dvdcyan2 = "?" +const dvdcyan3 = "<" +const dvdcyan4 = ">" +const dvdcyan5 = "~" +const dvdcyan6 = "-" +const dvdcyan7 = "+" +const dvdcyan8 = "_" + + +setLegend( +[ background, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], +[ dvdblue1, bitmap` +0000000000000000 +0000055555555555 +0000555555555555 +0000555555555555 +0000555555555555 +0000000000005555 +0000000000000005 +0005555500000000 +0005555500000000 +0005555500000000 +0005555500000000 +0005555000000000 +0005555000000000 +0055555000000005 +0055555000000055 +0055555000000555`], +[ dvdblue2, bitmap` +0055555555555555 +0555555555555555 +0555555555555555 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000005 +0000000005555555 +0000055555555555 +0005555555555555 +0055555555555555 +0555555555555555 +0055555555555555 +0005555555555555 +0000055555555555 +0000000055555555`], +[ dvdblue3, bitmap` +0000000000000000 +5555555555550000 +5555555555550000 +5555555555550000 +5555555555550000 +5555555555555000 +5555555555555000 +0555555055555000 +0555555055555000 +0555555055555500 +0555555005555500 +0555555005555500 +0555550005555505 +5555500000555555 +5555000000555555 +5550000000555555`], +[ dvdblue4, bitmap` +5500000000005555 +5000000000005555 +0000000000005555 +0000000000000550 +0000000000000500 +0000000000000000 +5555555555555555 +5555555555555555 +5555555555500000 +5555555000000000 +5555550000000000 +5555555000000000 +5555555555000000 +5555555555500055 +5555555555555555 +5555555555555555`], +[ dvdblue5, bitmap` +0000000000000000 +0000000055555555 +0000000555555555 +0000005555555555 +0000055555555555 +0000555500000000 +0005555500000000 +0055555055555550 +0555555055555550 +5555550055555550 +5555500055555550 +5555000555555550 +5550000555555550 +5550000555555550 +5500000555555500 +5000000555555500`], +[ dvdblue6, bitmap` +5000005555555555 +0000055555555555 +0000055555555555 +0000000000000000 +0000000000000000 +0000000000000000 +5555555555555500 +5555555555555555 +5555555555555555 +0005555555555555 +0000005555555555 +0000005555555555 +0005555555555555 +5555555555555555 +5555555555555555 +5555555555555555`], +[ dvdblue7, bitmap` +0000000000000000 +5555550000000000 +5555555550000000 +5555555555500000 +5555555555550000 +0000005555555000 +0000000055555500 +0000000055555500 +0000000055555500 +0000000055555500 +0000000055555500 +0000000555555000 +0000005555550000 +0000055555500000 +0005555550000000 +5555555500000000`], +[ dvdblue8, bitmap` +5555555000000000 +5555500000000000 +5550000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +5550000000000000 +5555550000000000 +5555555500000000 +5555555550000000 +5555555555000000 +5555555550000000 +5555555500000000 +5555550000000000`], +[ dvdwhite1, bitmap` +0000000000000000 +0000022222222222 +0000222222222222 +0000222222222222 +0000222222222222 +0000000000002222 +0000000000000002 +0002222200000000 +0002222200000000 +0002222200000000 +0002222200000000 +0002222000000000 +0002222000000000 +0022222000000002 +0022222000000022 +0022222000000222`], +[ dvdwhite2, bitmap` +0022222222222222 +0222222222222222 +0222222222222222 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000002 +0000000002222222 +0000022222222222 +0002222222222222 +0022222222222222 +0222222222222222 +0022222222222222 +0002222222222222 +0000022222222222 +0000000022222222`], +[ dvdwhite3, bitmap` +0000000000000000 +2222222222220000 +2222222222220000 +2222222222220000 +2222222222220000 +2222222222222000 +2222222222222000 +0222222022222000 +0222222022222000 +0222222022222200 +0222222002222200 +0222222002222200 +0222220002222202 +2222200000222222 +2222000000222222 +2220000000222222`], +[ dvdwhite4, bitmap` +2200000000002222 +2000000000002222 +0000000000002222 +0000000000000220 +0000000000000200 +0000000000000000 +2222222222222222 +2222222222222222 +2222222222200000 +2222222000000000 +2222220000000000 +2222222000000000 +2222222222000000 +2222222222200022 +2222222222222222 +2222222222222222`], +[ dvdwhite5, bitmap` +0000000000000000 +0000000022222222 +0000000222222222 +0000002222222222 +0000022222222222 +0000222200000000 +0002222200000000 +0022222022222220 +0222222022222220 +2222220022222220 +2222200022222220 +2222000222222220 +2220000222222220 +2220000222222220 +2200000222222200 +2000000222222200`], +[ dvdwhite6, bitmap` +2000002222222222 +0000022222222222 +0000022222222222 +0000000000000000 +0000000000000000 +0000000000000000 +2222222222222200 +2222222222222222 +2222222222222222 +0002222222222222 +0000002222222222 +0000002222222222 +0002222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], +[ dvdwhite7, bitmap` +0000000000000000 +2222220000000000 +2222222220000000 +2222222222200000 +2222222222220000 +0000002222222000 +0000000022222200 +0000000022222200 +0000000022222200 +0000000022222200 +0000000022222200 +0000000222222000 +0000002222220000 +0000022222200000 +0002222220000000 +2222222200000000`], +[ dvdwhite8, bitmap` +2222222000000000 +2222200000000000 +2220000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +2220000000000000 +2222220000000000 +2222222200000000 +2222222220000000 +2222222222000000 +2222222220000000 +2222222200000000 +2222220000000000`], +[ dvdred1, bitmap` +0000000000000000 +0000033333333333 +0000333333333333 +0000333333333333 +0000333333333333 +0000000000003333 +0000000000000003 +0003333300000000 +0003333300000000 +0003333300000000 +0003333300000000 +0003333000000000 +0003333000000000 +0033333000000003 +0033333000000033 +0033333000000333`], +[ dvdred2, bitmap` +0033333333333333 +0333333333333333 +0333333333333333 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000003 +0000000003333333 +0000033333333333 +0003333333333333 +0033333333333333 +0333333333333333 +0033333333333333 +0003333333333333 +0000033333333333 +0000000033333333`], +[ dvdred3, bitmap` +0000000000000000 +3333333333330000 +3333333333330000 +3333333333330000 +3333333333330000 +3333333333333000 +3333333333333000 +0333333033333000 +0333333033333000 +0333333033333300 +0333333003333300 +0333333003333300 +0333330003333303 +3333300000333333 +3333000000333333 +3330000000333333`], +[ dvdred4, bitmap` +3300000000003333 +3000000000003333 +0000000000003333 +0000000000000330 +0000000000000300 +0000000000000000 +3333333333333333 +3333333333333333 +3333333333300000 +3333333000000000 +3333330000000000 +3333333000000000 +3333333333000000 +3333333333300033 +3333333333333333 +3333333333333333`], +[ dvdred5, bitmap` +0000000000000000 +0000000033333333 +0000000333333333 +0000003333333333 +0000033333333333 +0000333300000000 +0003333300000000 +0033333033333330 +0333333033333330 +3333330033333330 +3333300033333330 +3333000333333330 +3330000333333330 +3330000333333330 +3300000333333300 +3000000333333300`], +[ dvdred6, bitmap` +3000003333333333 +0000033333333333 +0000033333333333 +0000000000000000 +0000000000000000 +0000000000000000 +3333333333333300 +3333333333333333 +3333333333333333 +0003333333333333 +0000003333333333 +0000003333333333 +0003333333333333 +3333333333333333 +3333333333333333 +3333333333333333`], +[ dvdred7, bitmap` +0000000000000000 +3333330000000000 +3333333330000000 +3333333333300000 +3333333333330000 +0000003333333000 +0000000033333300 +0000000033333300 +0000000033333300 +0000000033333300 +0000000033333300 +0000000333333000 +0000003333330000 +0000033333300000 +0003333330000000 +3333333300000000`], +[ dvdred8, bitmap` +3333333000000000 +3333300000000000 +3330000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +3330000000000000 +3333330000000000 +3333333300000000 +3333333330000000 +3333333333000000 +3333333330000000 +3333333300000000 +3333330000000000`], +[ dvdgreen1, bitmap` +0000000000000000 +0000044444444444 +0000444444444444 +0000444444444444 +0000444444444444 +0000000000004444 +0000000000000004 +0004444400000000 +0004444400000000 +0004444400000000 +0004444400000000 +0004444000000000 +0004444000000000 +0044444000000004 +0044444000000044 +0044444000000444`], +[ dvdgreen2, bitmap` +0044444444444444 +0444444444444444 +0444444444444444 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000004 +0000000004444444 +0000044444444444 +0004444444444444 +0044444444444444 +0444444444444444 +0044444444444444 +0004444444444444 +0000044444444444 +0000000044444444`], +[ dvdgreen3, bitmap` +0000000000000000 +4444444444440000 +4444444444440000 +4444444444440000 +4444444444440000 +4444444444444000 +4444444444444000 +0444444044444000 +0444444044444000 +0444444044444400 +0444444004444400 +0444444004444400 +0444440004444404 +4444400000444444 +4444000000444444 +4440000000444444`], +[ dvdgreen4, bitmap` +4400000000004444 +4000000000004444 +0000000000004444 +0000000000000440 +0000000000000400 +0000000000000000 +4444444444444444 +4444444444444444 +4444444444400000 +4444444000000000 +4444440000000000 +4444444000000000 +4444444444000000 +4444444444400044 +4444444444444444 +4444444444444444`], +[ dvdgreen5, bitmap` +0000000000000000 +0000000044444444 +0000000444444444 +0000004444444444 +0000044444444444 +0000444400000000 +0004444400000000 +0044444044444440 +0444444044444440 +4444440044444440 +4444400044444440 +4444000444444440 +4440000444444440 +4440000444444440 +4400000444444400 +4000000444444400`], +[ dvdgreen6, bitmap` +4000004444444444 +0000044444444444 +0000044444444444 +0000000000000000 +0000000000000000 +0000000000000000 +4444444444444400 +4444444444444444 +4444444444444444 +0004444444444444 +0000004444444444 +0000004444444444 +0004444444444444 +4444444444444444 +4444444444444444 +4444444444444444`], +[ dvdgreen7, bitmap` +0000000000000000 +4444440000000000 +4444444440000000 +4444444444400000 +4444444444440000 +0000004444444000 +0000000044444400 +0000000044444400 +0000000044444400 +0000000044444400 +0000000044444400 +0000000444444000 +0000004444440000 +0000044444400000 +0004444440000000 +4444444400000000`], +[ dvdgreen8, bitmap` +4444444000000000 +4444400000000000 +4440000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +4440000000000000 +4444440000000000 +4444444400000000 +4444444440000000 +4444444444000000 +4444444440000000 +4444444400000000 +4444440000000000`], +[ dvdpurple1, bitmap` +0000000000000000 +00000HHHHHHHHHHH +0000HHHHHHHHHHHH +0000HHHHHHHHHHHH +0000HHHHHHHHHHHH +000000000000HHHH +000000000000000H +000HHHHH00000000 +000HHHHH00000000 +000HHHHH00000000 +000HHHHH00000000 +000HHHH000000000 +000HHHH000000000 +00HHHHH00000000H +00HHHHH0000000HH +00HHHHH000000HHH`], +[ dvdpurple2, bitmap` +00HHHHHHHHHHHHHH +0HHHHHHHHHHHHHHH +0HHHHHHHHHHHHHHH +0000000000000000 +0000000000000000 +0000000000000000 +000000000000000H +000000000HHHHHHH +00000HHHHHHHHHHH +000HHHHHHHHHHHHH +00HHHHHHHHHHHHHH +0HHHHHHHHHHHHHHH +00HHHHHHHHHHHHHH +000HHHHHHHHHHHHH +00000HHHHHHHHHHH +00000000HHHHHHHH`], +[ dvdpurple3, bitmap` +0000000000000000 +HHHHHHHHHHHH0000 +HHHHHHHHHHHH0000 +HHHHHHHHHHHH0000 +HHHHHHHHHHHH0000 +HHHHHHHHHHHHH000 +HHHHHHHHHHHHH000 +0HHHHHH0HHHHH000 +0HHHHHH0HHHHH000 +0HHHHHH0HHHHHH00 +0HHHHHH00HHHHH00 +0HHHHHH00HHHHH00 +0HHHHH000HHHHH0H +HHHHH00000HHHHHH +HHHH000000HHHHHH +HHH0000000HHHHHH`], +[ dvdpurple4, bitmap` +HH0000000000HHHH +H00000000000HHHH +000000000000HHHH +0000000000000HH0 +0000000000000H00 +0000000000000000 +HHHHHHHHHHHHHHHH +HHHHHHHHHHHHHHHH +HHHHHHHHHHH00000 +HHHHHHH000000000 +HHHHHH0000000000 +HHHHHHH000000000 +HHHHHHHHHH000000 +HHHHHHHHHHH000HH +HHHHHHHHHHHHHHHH +HHHHHHHHHHHHHHHH`], +[ dvdpurple5, bitmap` +0000000000000000 +00000000HHHHHHHH +0000000HHHHHHHHH +000000HHHHHHHHHH +00000HHHHHHHHHHH +0000HHHH00000000 +000HHHHH00000000 +00HHHHH0HHHHHHH0 +0HHHHHH0HHHHHHH0 +HHHHHH00HHHHHHH0 +HHHHH000HHHHHHH0 +HHHH000HHHHHHHH0 +HHH0000HHHHHHHH0 +HHH0000HHHHHHHH0 +HH00000HHHHHHH00 +H000000HHHHHHH00`], +[ dvdpurple6, bitmap` +H00000HHHHHHHHHH +00000HHHHHHHHHHH +00000HHHHHHHHHHH +0000000000000000 +0000000000000000 +0000000000000000 +HHHHHHHHHHHHHH00 +HHHHHHHHHHHHHHHH +HHHHHHHHHHHHHHHH +000HHHHHHHHHHHHH +000000HHHHHHHHHH +000000HHHHHHHHHH +000HHHHHHHHHHHHH +HHHHHHHHHHHHHHHH +HHHHHHHHHHHHHHHH +HHHHHHHHHHHHHHHH`], +[ dvdpurple7, bitmap` +0000000000000000 +HHHHHH0000000000 +HHHHHHHHH0000000 +HHHHHHHHHHH00000 +HHHHHHHHHHHH0000 +000000HHHHHHH000 +00000000HHHHHH00 +00000000HHHHHH00 +00000000HHHHHH00 +00000000HHHHHH00 +00000000HHHHHH00 +0000000HHHHHH000 +000000HHHHHH0000 +00000HHHHHH00000 +000HHHHHH0000000 +HHHHHHHH00000000`], +[ dvdpurple8, bitmap` +HHHHHHH000000000 +HHHHH00000000000 +HHH0000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +HHH0000000000000 +HHHHHH0000000000 +HHHHHHHH00000000 +HHHHHHHHH0000000 +HHHHHHHHHH000000 +HHHHHHHHH0000000 +HHHHHHHH00000000 +HHHHHH0000000000`], +[ dvdyellow1, bitmap` +0000000000000000 +0000066666666666 +0000666666666666 +0000666666666666 +0000666666666666 +0000000000006666 +0000000000000006 +0006666600000000 +0006666600000000 +0006666600000000 +0006666600000000 +0006666000000000 +0006666000000000 +0066666000000006 +0066666000000066 +0066666000000666`], +[ dvdyellow2, bitmap` +0066666666666666 +0666666666666666 +0666666666666666 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000006 +0000000006666666 +0000066666666666 +0006666666666666 +0066666666666666 +0666666666666666 +0066666666666666 +0006666666666666 +0000066666666666 +0000000066666666`], +[ dvdyellow3, bitmap` +0000000000000000 +6666666666660000 +6666666666660000 +6666666666660000 +6666666666660000 +6666666666666000 +6666666666666000 +0666666066666000 +0666666066666000 +0666666066666600 +0666666006666600 +0666666006666600 +0666660006666606 +6666600000666666 +6666000000666666 +6660000000666666`], +[ dvdyellow4, bitmap` +6600000000006666 +6000000000006666 +0000000000006666 +0000000000000660 +0000000000000600 +0000000000000000 +6666666666666666 +6666666666666666 +6666666666600000 +6666666000000000 +6666660000000000 +6666666000000000 +6666666666000000 +6666666666600066 +6666666666666666 +6666666666666666`], +[ dvdyellow5, bitmap` +0000000000000000 +0000000066666666 +0000000666666666 +0000006666666666 +0000066666666666 +0000666600000000 +0006666600000000 +0066666066666660 +0666666066666660 +6666660066666660 +6666600066666660 +6666000666666660 +6660000666666660 +6660000666666660 +6600000666666600 +6000000666666600`], +[ dvdyellow6, bitmap` +6000006666666666 +0000066666666666 +0000066666666666 +0000000000000000 +0000000000000000 +0000000000000000 +6666666666666600 +6666666666666666 +6666666666666666 +0006666666666666 +0000006666666666 +0000006666666666 +0006666666666666 +6666666666666666 +6666666666666666 +6666666666666666`], +[ dvdyellow7, bitmap` +0000000000000000 +6666660000000000 +6666666660000000 +6666666666600000 +6666666666660000 +0000006666666000 +0000000066666600 +0000000066666600 +0000000066666600 +0000000066666600 +0000000066666600 +0000000666666000 +0000006666660000 +0000066666600000 +0006666660000000 +6666666600000000`], +[ dvdyellow8, bitmap` +6666666000000000 +6666600000000000 +6660000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +6660000000000000 +6666660000000000 +6666666600000000 +6666666660000000 +6666666666000000 +6666666660000000 +6666666600000000 +6666660000000000`], +[ dvdcyan1, bitmap` +0000000000000000 +0000077777777777 +0000777777777777 +0000777777777777 +0000777777777777 +0000000000007777 +0000000000000007 +0007777700000000 +0007777700000000 +0007777700000000 +0007777700000000 +0007777000000000 +0007777000000000 +0077777000000007 +0077777000000077 +0077777000000777`], +[ dvdcyan2, bitmap` +0077777777777777 +0777777777777777 +0777777777777777 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000007 +0000000007777777 +0000077777777777 +0007777777777777 +0077777777777777 +0777777777777777 +0077777777777777 +0007777777777777 +0000077777777777 +0000000077777777`], +[ dvdcyan3, bitmap` +0000000000000000 +7777777777770000 +7777777777770000 +7777777777770000 +7777777777770000 +7777777777777000 +7777777777777000 +0777777077777000 +0777777077777000 +0777777077777700 +0777777007777700 +0777777007777700 +0777770007777707 +7777700000777777 +7777000000777777 +7770000000777777`], +[ dvdcyan4, bitmap` +7700000000007777 +7000000000007777 +0000000000007777 +0000000000000770 +0000000000000700 +0000000000000000 +7777777777777777 +7777777777777777 +7777777777700000 +7777777000000000 +7777770000000000 +7777777000000000 +7777777777000000 +7777777777700077 +7777777777777777 +7777777777777777`], +[ dvdcyan5, bitmap` +0000000000000000 +0000000077777777 +0000000777777777 +0000007777777777 +0000077777777777 +0000777700000000 +0007777700000000 +0077777077777770 +0777777077777770 +7777770077777770 +7777700077777770 +7777000777777770 +7770000777777770 +7770000777777770 +7700000777777700 +7000000777777700`], +[ dvdcyan6, bitmap` +7000007777777777 +0000077777777777 +0000077777777777 +0000000000000000 +0000000000000000 +0000000000000000 +7777777777777700 +7777777777777777 +7777777777777777 +0007777777777777 +0000007777777777 +0000007777777777 +0007777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], +[ dvdcyan7, bitmap` +0000000000000000 +7777770000000000 +7777777770000000 +7777777777700000 +7777777777770000 +0000007777777000 +0000000077777700 +0000000077777700 +0000000077777700 +0000000077777700 +0000000077777700 +0000000777777000 +0000007777770000 +0000077777700000 +0007777770000000 +7777777700000000`], +[ dvdcyan8, bitmap` +7777777000000000 +7777700000000000 +7770000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +7770000000000000 +7777770000000000 +7777777700000000 +7777777770000000 +7777777777000000 +7777777770000000 +7777777700000000 +7777770000000000`] +) + +let level = 0 +const levels = [ +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzacfhzzzzzzzzzzzzz +zzzzzbdgjzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzacfhzzzzzzzzzzzzzz +zzzzbdgjzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzacfhzzzzzzzzzzzzzzz +zzzbdgjzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzacfhzzzzzzzzzzzzzzzz +zzbdgjzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zacfhzzzzzzzzzzzzzzzzz +zbdgjzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +1357zzzzzzzzzzzzzzzzzz +2468zzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +z1357zzzzzzzzzzzzzzzzz +z2468zzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zz1357zzzzzzzzzzzzzzzz +zz2468zzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzz1357zzzzzzzzzzzzzz +zzzz2468zzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzz1357zzzzzzzzzzzz +zzzzzz2468zzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzz1357zzzzzzzzzz +zzzzzzzz2468zzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzz1357zzzzzzzz +zzzzzzzzzz2468zzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzz1357zzzzzz +zzzzzzzzzzzz2468zzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzz1357zzzz +zzzzzzzzzzzzzz2468zzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzz1357zz +zzzzzzzzzzzzzzzz2468zz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzqetuz +zzzzzzzzzzzzzzzzzwryiz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzqetuzz +zzzzzzzzzzzzzzzzwryizz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzqetuzzz +zzzzzzzzzzzzzzzwryizzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzqetuzzzz +zzzzzzzzzzzzzzwryizzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzqetuzzzzz +zzzzzzzzzzzzzwryizzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzqetuzzzzzz +zzzzzzzzzzzzwryizzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzqetuzzzzzzz +zzzzzzzzzzzwryizzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzqetuzzzzzzzz +zzzzzzzzzzwryizzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzqetuzzzzzzzzz +zzzzzzzzzwryizzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzqetuzzzzzzzzzz +zzzzzzzzwryizzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzmov0zzzzzzzzzzz +zzzzzzznpx9zzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzmov0zzzzzzzzzzzz +zzzzzznpx9zzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzmov0zzzzzzzzzzzzz +zzzzznpx9zzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzmov0zzzzzzzzzzzzzz +zzzznpx9zzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzmov0zzzzzzzzzzzzzzz +zzznpx9zzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzmov0zzzzzzzzzzzzzzzz +zznpx9zzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zmov0zzzzzzzzzzzzzzzzz +znpx9zzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +!#%&zzzzzzzzzzzzzzzzzz +@$^*zzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +z!#%&zzzzzzzzzzzzzzzzz +z@$^*zzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zz!#%&zzzzzzzzzzzzzzzz +zz@$^*zzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzz!#%&zzzzzzzzzzzzzzz +zzz@$^*zzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzz([{/zzzzzzzzzzzzzzz +zzz)]}:zzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzz([{/zzzzzzzzzzzzzz +zzzz)]}:zzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzz([{/zzzzzzzzzzzzz +zzzzz)]}:zzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzz([{/zzzzzzzzzzzz +zzzzzz)]}:zzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzz([{/zzzzzzzzzzz +zzzzzzz)]}:zzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzz([{/zzzzzzzzzz +zzzzzzzz)]}:zzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzz([{/zzzzzzzzz +zzzzzzzzz)]}:zzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzz([{/zzzzzzzz +zzzzzzzzzz)]}:zzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzz([{/zzzzzzz +zzzzzzzzzzz)]}:zzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzz|<~+zzzzzz +zzzzzzzzzzzz?>-_zzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzz|<~+zzzzzzz +zzzzzzzzzzz?>-_zzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzz|<~+zzzzzz +zzzzzzzzzzzz?>-_zzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzz|<~+zzzzz +zzzzzzzzzzzzz?>-_zzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzz|<~+zzzz +zzzzzzzzzzzzzz?>-_zzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzz|<~+zzz +zzzzzzzzzzzzzzz?>-_zzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzz|<~+zz +zzzzzzzzzzzzzzzz?>-_zz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzz|<~+z +zzzzzzzzzzzzzzzzz?>-_z +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzacfh +zzzzzzzzzzzzzzzzzzbdgj +zzzzzzzzzzzzzzzzzzzzzz`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzacfhzzz +zzzzzzzzzzzzzzzbdgjzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzacfhzzzzzz +zzzzzzzzzzzzbdgjzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +map` +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzacfhzzzzzzzzzzz +zzzzzzzbdgjzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +zzzzzzzzzzzzzzzzzzzzzz +`, +] + + +setMap(levels[level]) + + +setInterval(function(){ + level = (level + 1) % levels.length + setMap(levels[level]) +}, 200); //SPEED For Level Update :) diff --git a/games/Defend-Your-House!.js b/games/Defend-Your-House!.js index 9e94c0b1b5..fbdf302a43 100644 --- a/games/Defend-Your-House!.js +++ b/games/Defend-Your-House!.js @@ -4,10 +4,11 @@ https://sprig.hackclub.com/gallery/getting_started @title: Defend Your House! @author: Gabbs @tags: ['strategy', 'survival', 'music'] -@addedOn: 2024-11-19 +@addedOn: 2024-11-13 */ + const moving = tune` -161.29032258064515: F4~161.29032258064515 + C5~161.29032258064515, +161.29032258064515: F4^161.29032258064515 + C5^161.29032258064515, 5000` const placed = tune` 161.29032258064515: F4^161.29032258064515 + C5^161.29032258064515, @@ -35,38 +36,38 @@ const collision = tune` 84.50704225352112: E5/84.50704225352112, 2450.7042253521126` const win = tune` -178.57142857142858: E5/178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: F5/178.57142857142858 + E5-178.57142857142858 + G5^178.57142857142858, -178.57142857142858: G5/178.57142857142858, -178.57142857142858: G5/178.57142857142858, -178.57142857142858: F5/178.57142857142858 + E5-178.57142857142858 + G5^178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: D5/178.57142857142858 + C5~178.57142857142858, -178.57142857142858: C5/178.57142857142858, -178.57142857142858: C5/178.57142857142858, -178.57142857142858: D5/178.57142857142858 + E5-178.57142857142858 + C5~178.57142857142858, -178.57142857142858: E5/178.57142857142858 + D5~178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: D5/178.57142857142858 + E5-178.57142857142858, -178.57142857142858: D5/178.57142857142858, -178.57142857142858: E5/178.57142857142858 + D5~178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: F5/178.57142857142858 + E5-178.57142857142858 + G5^178.57142857142858, -178.57142857142858: G5/178.57142857142858, -178.57142857142858: G5/178.57142857142858, -178.57142857142858: F5/178.57142857142858 + E5-178.57142857142858 + G5^178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: D5/178.57142857142858, -178.57142857142858: C5/178.57142857142858, -178.57142857142858: C5/178.57142857142858, -178.57142857142858: D5/178.57142857142858 + E5-178.57142857142858 + C5~178.57142857142858, -178.57142857142858: E5/178.57142857142858, -178.57142857142858: D5/178.57142857142858 + E5-178.57142857142858 + C5~178.57142857142858, -178.57142857142858: C5/178.57142857142858, -178.57142857142858: C5/178.57142857142858, +178.57142857142858: F5~178.57142857142858 + E4-178.57142857142858 + F4~178.57142857142858, +178.57142857142858: F5~178.57142857142858 + E4-178.57142857142858 + F4~178.57142857142858, +178.57142857142858: G5^178.57142857142858 + E4-178.57142857142858 + F4-178.57142857142858, +178.57142857142858: G4-178.57142857142858, +178.57142857142858: G4-178.57142857142858, +178.57142857142858: G5^178.57142857142858 + F4-178.57142857142858 + E4-178.57142857142858, +178.57142857142858: E4-178.57142857142858, +178.57142857142858: C5~178.57142857142858 + D4-178.57142857142858 + C4~178.57142857142858, +178.57142857142858: C4-178.57142857142858, +178.57142857142858: C4-178.57142857142858, +178.57142857142858: C5~178.57142857142858 + D4-178.57142857142858 + E4-178.57142857142858 + C4~178.57142857142858, +178.57142857142858: D5~178.57142857142858 + E4-178.57142857142858 + D4~178.57142857142858, +178.57142857142858: E4-178.57142857142858, +178.57142857142858: E4-178.57142857142858 + D4-178.57142857142858, +178.57142857142858: D4-178.57142857142858, +178.57142857142858: D5~178.57142857142858 + E4-178.57142857142858 + D4~178.57142857142858, +178.57142857142858: E4-178.57142857142858, +178.57142857142858: G5^178.57142857142858 + E4-178.57142857142858 + F4-178.57142857142858 + G4^178.57142857142858, +178.57142857142858: G5-178.57142857142858 + G4-178.57142857142858, +178.57142857142858: G5-178.57142857142858 + G4-178.57142857142858, +178.57142857142858: G5^178.57142857142858 + F4-178.57142857142858 + E4-178.57142857142858 + G4^178.57142857142858, +178.57142857142858: E4-178.57142857142858, +178.57142857142858: D4-178.57142857142858, 178.57142857142858: C4-178.57142857142858, -178.57142857142858: C4-178.57142857142858` +178.57142857142858: C4-178.57142857142858, +178.57142857142858: D4-178.57142857142858 + E4-178.57142857142858 + C4~178.57142857142858, +178.57142857142858: E4-178.57142857142858, +178.57142857142858: D4-178.57142857142858 + E4-178.57142857142858 + C4~178.57142857142858, +178.57142857142858: C4-178.57142857142858, +178.57142857142858: C4-178.57142857142858, +178.57142857142858: C4/178.57142857142858, +178.57142857142858: C4/178.57142857142858` var z = 1; var pos = 4; @@ -81,7 +82,7 @@ const wall = "w" const roof = "r" const roofl = "R" const centerR = "C" -const center = "ç" +const center = "k" const centerL = "O" const white = "W" const wood = "o"; @@ -473,17 +474,22 @@ WWW..............WWW WWW..............WWW WWW......rR......WWW WWW.....rCOR.....WWW -WWW....rCççOR....WWW +WWW....rCkkOR....WWW WWW....pppppp....WWW WWW....ppuUpp....WWW WWW....ppdDpp....WWW wwwwwwwwwwwwwwwwwwww` setMap(level) setBackground("g") +setSolids([ cursor, wall, white ]) + onInput("k", () => { // Move the player one tile to the right + if(youLost == false) + { playTune(moving); updateWoodCount(); + } }) onInput("d", () => { @@ -584,14 +590,17 @@ function gameLoop() { if (challenge && youLost == false) { if (randomChallenge == 1) { ZapEvent(); + } else if (randomChallenge == 2) { RockLEvent(); + } else if (randomChallenge == 3) { RockREvent(); + }else if (randomChallenge == 4) { FireBallLEvent(); - }else if(randomChallenge == 4) + }else if(randomChallenge == 5) { FireBallREvent(); } @@ -599,7 +608,7 @@ function gameLoop() { } // Imposta l'intervallo per eseguire la funzione gameLoop ogni tot millisecondi -const interval = setInterval(gameLoop, 500); // Esegui ogni secondo (1000 millisecondi) +const interval = setInterval(gameLoop, 300); // Esegui ogni secondo (1000 millisecondi) function FireBallLEvent() { console.log("The value of z is: " + z); @@ -608,12 +617,12 @@ function FireBallLEvent() { if (z == 1) { z = 1; - pos = 3; + pos = 2; var randomY = Math.floor(Math.random() * (14 - 4 + 1)) + 4; challengeState = true; - addSprite(pos, 4, FIREBALL); + addSprite(pos, 3, FIREBALL); z = 2; - } else { + } else if(z === 2 ){ const fireballSprite = getFirst(FIREBALL); fireballSprite.x += 1; // Move the ROCK sprite down fireballSprite.y += 1; @@ -623,33 +632,36 @@ function FireBallLEvent() { spritesAtFireball.forEach(sprite => { if (sprite.type === wood) { + z = 3; // If the ROCK hits a wood block, remove both sprites sprite.remove(); // Remove the wood block fireballSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } //ATTENTO else if(sprite.type === reinforcedWall) { + z = 3; sprite.remove(); // Remove the wood block addSprite(fireballSprite.x, fireballSprite.y, wood); fireballSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } else if (sprite.type === roof || sprite.type === roofl || sprite.type === pizzaOne || sprite.type === center || sprite.type === centerL || sprite.type === centerR) { + z = 4; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block fireballSprite.remove(); // Remove the ZAP sprite - z = 4; + } }); - if (fireballSprite.x == 18 || z == 3) { + if (fireballSprite.x == 18) { fireballSprite.remove(); challengeState = false; challenge = false; @@ -660,6 +672,17 @@ function FireBallLEvent() { y: 5, color: color`4` }) + }else if (z == 3) + { + challengeState = false; + challenge = false; + z = 1; + pos = 4; + addText("press J", { + x: 7, + y: 5, + color: color`4` + }) } else if (z == 4) { challengeState = false; GameOver(); @@ -677,11 +700,11 @@ function FireBallREvent() { z = 1; pos = 17; - var randomY = Math.floor(Math.random() * (14 - 4 + 1)) + 4; + challengeState = true; - addSprite(pos, 4, FIREBALLR); + addSprite(pos, 3, FIREBALLR); z = 2; - } else { + } else if(z === 2 ) { const fireballSprite = getFirst(FIREBALLR); fireballSprite.x -= 1; // Move the ROCK sprite down fireballSprite.y += 1; @@ -691,33 +714,36 @@ function FireBallREvent() { spritesAtFireball.forEach(sprite => { if (sprite.type === wood) { + z = 3; // If the ROCK hits a wood block, remove both sprites sprite.remove(); // Remove the wood block fireballSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } //ATTENTO else if(sprite.type === reinforcedWall) { + z = 3; sprite.remove(); // Remove the wood block addSprite(fireballSprite.x, fireballSprite.y, wood); fireballSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } else if (sprite.type === roof || sprite.type === roofl || sprite.type === pizzaOne || sprite.type === center || sprite.type === centerL || sprite.type === centerR) { + z = 4; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block fireballSprite.remove(); // Remove the ZAP sprite - z = 4; + } }); - if (fireballSprite.x == 2 || z == 3) { + if (fireballSprite.x == 2) { fireballSprite.remove(); challengeState = false; challenge = false; @@ -728,7 +754,18 @@ function FireBallREvent() { y: 5, color: color`4` }) - } else if (z == 4) { + } else if (z == 3) + { + challengeState = false; + challenge = false; + z = 1; + pos = 4; + addText("press J", { + x: 7, + y: 5, + color: color`4` + }) + }else if (z == 4) { challengeState = false; GameOver(); } @@ -743,12 +780,12 @@ function ZapEvent() { // Move the ZAP sprite down if (z == 1) { z = 1; - pos = 4; + pos = 3; var randomX = Math.floor(Math.random() * (16 - 3 + 1)) + 3; challengeState = true; addSprite(randomX, pos, ZAP); z = 2; - } else { + } else if(z === 2 ){ const zapSprite = getFirst(ZAP); zapSprite.y += 1; // Move the ZAP sprite down @@ -758,34 +795,37 @@ function ZapEvent() { spritesAtZap.forEach(sprite => { if (sprite.type === wood) { + z = 3; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block zapSprite.remove(); // Remove the ZAP sprite playTune(collision); - z = 3; + } //ATTENTO else if(sprite.type === reinforcedWall) { + z = 3; sprite.remove(); // Remove the wood block addSprite(zapSprite.x, zapSprite.y, wood); zapSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } else if (sprite.type === roof || sprite.type === roofl || sprite.type === pizzaOne) { + z = 4; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block zapSprite.remove(); // Remove the ZAP sprite - z = 4; + } }); - if (zapSprite.y == 15 || z == 3) { + if (zapSprite.y == 15) { zapSprite.remove(); challengeState = false; challenge = false; @@ -796,6 +836,17 @@ function ZapEvent() { y: 5, color: color`4` }) + }else if (z == 3) + { + challengeState = false; + challenge = false; + z = 1; + pos = 4; + addText("press J", { + x: 7, + y: 5, + color: color`4` + }) } else if (z == 4) { challengeState = false; GameOver(); @@ -812,12 +863,12 @@ function RockLEvent() { if (z == 1) { z = 1; - pos = 3; + pos = 2; var randomY = Math.floor(Math.random() * (14 - 4 + 1)) + 4; challengeState = true; addSprite(pos, randomY, ROCK); z = 2; - } else { + } else if(z===2){ const rockSprite = getFirst(ROCK); rockSprite.x += 1; // Move the ROCK sprite down @@ -827,33 +878,36 @@ function RockLEvent() { spritesAtRock.forEach(sprite => { if (sprite.type === wood) { + z = 3; // If the ROCK hits a wood block, remove both sprites sprite.remove(); // Remove the wood block rockSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } //ATTENTO else if(sprite.type === reinforcedWall) { + z = 3; sprite.remove(); // Remove the wood block addSprite(rockSprite.x, rockSprite.y, wood); rockSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } else if (sprite.type === roof || sprite.type === roofl || sprite.type === pizzaOne) { + z = 4; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block rockSprite.remove(); // Remove the ZAP sprite - z = 4; + } }); - if (rockSprite.x == 18 || z == 3) { + if (rockSprite.x == 18) { rockSprite.remove(); challengeState = false; challenge = false; @@ -864,7 +918,18 @@ function RockLEvent() { y: 5, color: color`4` }) - } else if (z == 4) { + } else if (z == 3) + { + challengeState = false; + challenge = false; + z = 1; + pos = 4; + addText("press J", { + x: 7, + y: 5, + color: color`4` + }) + }else if (z == 4) { challengeState = false; GameOver(); } @@ -880,12 +945,12 @@ function RockREvent() { if (z == 1) { z = 1; - pos = 17; + pos = 18; var randomY = Math.floor(Math.random() * (14 - 4 + 1)) + 4; challengeState = true; addSprite(pos, randomY, ROCKF); z = 2; - } else { + } else if(z === 2 ) { const rockfSprite = getFirst(ROCKF); rockfSprite.x -= 1; // Move the ROCK sprite down @@ -895,33 +960,36 @@ function RockREvent() { spritesAtRockf.forEach(sprite => { if (sprite.type === wood) { + z = 3; // If the ROCKF hits a wood block, remove both sprites sprite.remove(); // Remove the wood block rockfSprite.remove(); // Remove the ROCKF sprite playTune(collision); - z = 3; + } //ATTENTO else if(sprite.type === reinforcedWall) { + z = 3; sprite.remove(); // Remove the wood block addSprite(rockfSprite.x, rockfSprite.y, wood); rockfSprite.remove(); // Remove the ROCK sprite playTune(collision); - z = 3; + } else if (sprite.type === roof || sprite.type === roofl || sprite.type === pizzaOne) { + z = 4; // If the ZAP hits a wood block, remove both sprites sprite.remove(); // Remove the wood block rockfSprite.remove(); // Remove the ZAP sprite - z = 4; + } }); - if (rockfSprite.x == 2 || z == 3) { + if (rockfSprite.x == 2) { rockfSprite.remove(); challengeState = false; challenge = false; @@ -932,6 +1000,17 @@ function RockREvent() { y: 5, color: color`4` }) + }else if (z == 3) + { + challengeState = false; + challenge = false; + z = 1; + pos = 4; + addText("press J", { + x: 7, + y: 5, + color: color`4` + }) } else if (z == 4) { challengeState = false; diff --git a/games/Frost-and-Fire.js b/games/Frost-and-Fire.js new file mode 100644 index 0000000000..7c6b789815 --- /dev/null +++ b/games/Frost-and-Fire.js @@ -0,0 +1,1841 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: Magic +@author: Layan Jethwa +@tags: [] +@addedOn: 2024-00-00 +*/ + +var isdead = false + +const platform = "m" +const platform_l = "l" +const platform_r = "r" +const platform_lava = "7" +const platform_lava2 = "8" +const platform_lava3 = "9" +const ladder = "a" +const player = "p" +const player2 = "!" +const player3 = "£" +const player4 = "$" +const player5 = "%" +const player6 = "^" +const background = "b" +const n_ladder = "n" +const o_ladder = "o" +const wall = "w" +const t_wall = "t" +const lava = "v" +const stone = "1" +const stone2 = "2" +const stone3 = "3" +const under = "4" +const under2 = "5" +const under3 = "6" +const enemy = "e" +const dead = "d" +const key = "k" +const door = "h" +const playerb = '*' +const playerb2 = '(' +const playerb3 = ')' +const playerb4 = '-' +const red = "+" +const door_o = "_" +const door_o2 = "=" +const heart = "#" +const door_block = "@" +const door_red = "[" +const door_green = "]" +const key_red = "{" +const key_green = "}" +const door_red_o = "<" +const door_red_o2 = "/" +const door_green_o = ">" +const door_green_o2 = "?" +const lava_pool = ":" +const geyser = "g" +const platform_geyser = "z" +const platform_geyser2 = "x" +const platform_geyser3 = "c" +const bridge = "i" +const shoot_geyser = "~" +const shoot_geyser2 = ";" +const shoot_geyser_bridge = "|" +const bridge_l = "L" +const bridge_r = "R" +const door_purple = "Q" +const door_orange = "A" +const key_purple = "W" +const key_orange = "S" +const door_purple_o = "E" +const door_purple_o2 = "T" +const door_orange_o = "D" +const door_orange_o2 = "F" +const rock = "Y" +const stone_rock = "U" + +setLegend( + [ platform, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ wall, bitmap` +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +....LLLLLLLL.... +...LLLLLLLLLL... +..LLLLLLLLLLLL.. +..LLLLLLLLLLLL.. +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ t_wall, bitmap` +11LLLLLLLLLLLL11 +L1LLLLLLLLLLLL1L +11.LLLLLLLLLL.1L +1...LLLLLLLL...1 +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L..... +.....L1LL1L.....`], + [ ladder, bitmap` +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C... +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C... +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ n_ladder, bitmap` +LL19C......9C111 +1119C999CCCCC1LL +11.9CCCCCCCCC.1L +1..9C......9C..1 +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C... +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C... +...9C......9C... +...9C999CCCCC... +...9CCCCCCCCC... +...9C......9C...`], + [ o_ladder, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +2229C......9C222 +2229C999CCCCC222 +2229CCCCCCCCC222 +2229C......9C222`], + [ player, bitmap` +......C22C...... +.....C2020C..... +.....C2992C..... +......3223...... +......2332...... +......2202...... +.......22....... +......2222...... +.....220222..... +.....222222..... +.....722027..... +......7227...... +................ +................ +................ +................`], + [ player2, bitmap` +......C27C...... +.....C7020C..... +.....C2992C..... +......3723...... +......2337...... +......7202...... +.......77....... +......2222...... +.....270272..... +.....222722..... +....577202755... +..5555777755555. +................ +................ +................ +................`], + [ player3, bitmap` +................ +................ +................ +......CCCC...... +.....C2070C..... +.....C7997C..... +......3773...... +......7332...... +.....277072..... +....57207255.... +..55577202755... +.5555577775555.. +................ +................ +................ +................`], + [ player4, bitmap` +................ +................ +................ +................ +......CCCC...... +.....C7090C..... +.....C3779C..... +......7333...... +.....577035..... +....57707755.... +..55577202755... +.5555577775555.. +................ +................ +................ +................`], + [ player5, bitmap` +................ +................ +................ +................ +................ +................ +................ +......CCCC...... +.....C0907C..... +...55C3973C55... +..555773077555.. +.55555777755555. +................ +................ +................ +................`], + [ player6, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +...555C0CC555... +.5555C99535555.. +................ +................ +................ +................`], + [ playerb, bitmap` +......CCCC...... +.....C2222C..... +.....C2222C..... +......3233...... +......2322...... +......2222...... +.......22....... +......2222...... +.....222222..... +.....222222..... +.....722227..... +......7227...... +................ +................ +................ +................`], + [ playerb2, bitmap` +................ +................ +.......CC....... +......C22C...... +......C22C...... +......3233...... +.......32....... +.......22....... +......2222...... +......2222...... +......7227...... +.......77....... +................ +................ +................ +................`], + [ playerb3, bitmap` +................ +................ +................ +................ +................ +.......CC....... +......C22C...... +......3233...... +.......32....... +......2222...... +......2222...... +.......77....... +................ +................ +................ +................`], + [ playerb4, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +.......CC....... +.......33....... +.......32....... +.......22....... +................ +................ +................ +................`], + [ enemy, bitmap` +......0000...... +.....030030..... +.....000000..... +.....003300..... +.....030030..... +......0000...... +....03099030.L.. +...6039996030L.. +.....066990LL1L. +.....000000..L1L +.....00..00...L1 +.....00..00..... +................ +................ +................ +................`], + [ key, bitmap` +................ +................ +................ +................ +................ +..666........... +..6.66666666.... +..666....6.6.... +.........6.6.... +................ +................ +................ +................ +................ +................ +................`], + [ key_red, bitmap` +................ +................ +................ +................ +................ +..333........... +..3.33333333.... +..333....3.3.... +.........3.3.... +................ +................ +................ +................ +................ +................ +................`], + [ key_green, bitmap` +................ +................ +................ +................ +................ +..444........... +..4.44444444.... +..444....4.4.... +.........4.4.... +................ +................ +................ +................ +................ +................ +................`], + [ key_purple, bitmap` +................ +................ +................ +................ +................ +..HHH........... +..H.HHHHHHHH.... +..HHH....H.H.... +.........H.H.... +................ +................ +................ +................ +................ +................ +................`], + [ key_orange, bitmap` +................ +................ +................ +................ +................ +..999........... +..9.99999999.... +..999....9.9.... +.........9.9.... +................ +................ +................ +................ +................ +................ +................`], + [ background, bitmap` +5555555555555555 +5555555555555555 +5556555555555555 +5562655555555555 +5556555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555255555 +5555555552725555 +5555555555255555 +5555555555555555 +5555555555555555 +5555555555555555`], + [ heart, bitmap` +................ +................ +................ +................ +................ +....33....33.... +...3333..3333... +...3223333333... +...322333333C... +....3333333C.... +.....33333C..... +......333C...... +.......3C....... +................ +................ +................`], + [ lava, bitmap` +1111193333311LLL +1LL1133339311111 +1L11L9933339LLL1 +L11LL99339991111 +11LLL9399939L1LL +LLLL933399939L11 +LLL9339996999LLL +LLL99999999999LL +LLL99696669969LL +LLL99966669999LL +LLL69666666699LL +LL699669969669LL +LL666696666696LL +L66996966696666L +116116L61169L116 +1L116LL69LL11L69`], + [ stone, bitmap` +11111111111LLL11 +11LLL1111LL11111 +1111111111111111 +11LLLLLL11LLL111 +1111111111111111 +L1111111LL11111L +L1LL1L11111LLLLL +L11111LLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [ stone2, bitmap` +111111LLL1111111 +111111111L111111 +1111111111111111 +1LLL11111111LLL1 +1111111111111111 +LL11111L11L11111 +LLLL111LL111L11L +L11LLLLLLLLLLLLL +LLLLLLLL1111LLLL +LLLLLLLLLLL1LLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [ stone3, bitmap` +1111111111111111 +1111111111111LL1 +1111LL1111111111 +111LL1111LL11111 +1111111111111111 +L11LL11111L11LLL +LL111LLLL11LLL1L +LLL11LLLLLLLLL1L +LLLL1LLL111LLLLL +LLLL1LLLLLLLLLLL +LLLL11LLLLLL11LL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [ under, bitmap` +11111111111LLL11 +11LLL1111LL11111 +1111111111111111 +11LLLLLL11LLL111 +1111111111111111 +.1111111LL11111. +..LL1L11111..... +...11111........ +................ +................ +................ +................ +................ +................ +................ +................`], + [ under2, bitmap` +111111LLL1111111 +111111111L111111 +1111111111111111 +1LLL11111111LLL1 +1111111111111111 +..11111.11L11111 +....111..111.11. +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [ under3, bitmap` +1111111111111111 +1111111111111LL1 +1111LL1111111111 +111LL1111LL11111 +1111111111111111 +.11LL11111L11... +..111....11..... +...11........... +................ +................ +................ +................ +................ +................ +................ +................`], + [ platform_l, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +22222222222221L1 +222222222221111L +222222222221LL11 +222222222211111L`], + [ platform_r, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +1L11222222222222 +L1LLL22222222222 +1111112222222222 +LLL1L11222222222`], + [ platform_lava, bitmap` +.11.1..11..1L1.L +.L1.1..LLL.11.L1 +.1L..1.1L.....1L +..1.L1..1.....11 +....LLL...L1.... +....1L1...L11... +...........11... +........LL1..... +....11..111..... +.....11..1.L1... +.....LL....1L... +...........1.... +LL16399633339311 +11113993399331LL +1LL1133993631111 +1111113936311LL1`], + [ platform_lava2, bitmap` +.............L11 +.LLL...11....LL1 +.L11L.LL1.LL..L. +.L111.L...LL1... +...........11... +......L11....... +..L.1.LL........ +..LL1...LL1..... +..L11...L11..... +......LL........ +......L11....... +................ +LL13393336399311 +11113633993361LL +1LL1139399331111 +1111113336311LL1`], + [ platform_lava3, bitmap` +111L...L.....LLL +L11L.L11.....1L. +LL...L1L.....111 +.....L....LL.... +L1L...L...L11... +L11..L11..L1.... +.1...LLL........ +L.......LLL..... +...L1L..11L..... +...11L...1L..... +....L........... +................ +LL13633339339311 +11113993639331LL +1LL1199393361111 +1111116399311LL1`], + [ dead, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [ door, bitmap` +................ +.......00....... +......0660...... +....00666600.... +....066CC660.... +....06CCCC60.... +...066CCCC660... +...06CCCCCC60... +...06CCCC0C60... +...06CCCC6C60... +...06CCCCCC60... +...06CCCCCC60... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ red, bitmap` +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333`], + [ door_o, bitmap` +................ +........666..... +.....666CC6..... +....06CCCC60.... +....6CCCCC60.... +....6CCCCC60.... +...06CCCCC650... +...06CCCCC650... +...06CCCC0650... +...06CCCC6650... +...06CCCCC650... +...06CCCCC650... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_o2, bitmap` +................ +.......00....... +......0550...... +....00555500.... +....06555550.... +....06555550.... +...06C5555550... +...06C5555550... +...0605555550... +...0665555550... +...06C5555550... +...06C5555550... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_block, bitmap` +11111111111LLL11 +11LLL1111LL11111 +1111111111111111 +11LLLLLL11LLL111 +1111111111111111 +.1111111LL1111LL +..LL1L1111111111 +..111111111LL111 +..1111111111111. +...LL11LL11111.. +...1111LLL111... +....11111111.... +....11L11LL1.... +......111....... +.......LL....... +.......1........`], + [ door_red, bitmap` +................ +.......00....... +......0330...... +....00333300.... +....033CC330.... +....03CCCC30.... +...033CCCC330... +...03CCCCCC30... +...03CCCC0C30... +...03CCCC3C30... +...03CCCCCC30... +...03CCCCCC30... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_green, bitmap` +................ +.......00....... +......0440...... +....00444400.... +....044CC440.... +....04CCCC40.... +...044CCCC440... +...04CCCCCC40... +...04CCCC0C40... +...04CCCC4C40... +...04CCCCCC40... +...04CCCCCC40... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_red_o, bitmap` +................ +........333..... +.....333CC3..... +....03CCCC30.... +....3CCCCC30.... +....3CCCCC30.... +...03CCCCC350... +...03CCCCC350... +...03CCCC0350... +...03CCCC3350... +...03CCCCC350... +...03CCCCC350... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_red_o2, bitmap` +................ +.......00....... +......0550...... +....00555500.... +....03555550.... +....03555550.... +...03C5555550... +...03C5555550... +...0305555550... +...0335555550... +...03C5555550... +...03C5555550... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_green_o, bitmap` +................ +........444..... +.....444CC4..... +....04CCCC40.... +....4CCCCC40.... +....4CCCCC40.... +...04CCCCC450... +...04CCCCC450... +...04CCCC0450... +...04CCCC4450... +...04CCCCC450... +...04CCCCC450... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_green_o2, bitmap` +................ +.......00....... +......0550...... +....00555500.... +....04555550.... +....04555550.... +...04C5555550... +...04C5555550... +...0405555550... +...0445555550... +...04C5555550... +...04C5555550... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_purple, bitmap` +................ +.......00....... +......0HH0...... +....00HHHH00.... +....0HHCCHH0.... +....0HCCCCH0.... +...0HHCCCCHH0... +...0HCCCCCCH0... +...0HCCCC0CH0... +...0HCCCCHCH0... +...0HCCCCCCH0... +...0HCCCCCCH0... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_orange, bitmap` +................ +.......00....... +......0990...... +....00999900.... +....099CC990.... +....09CCCC90.... +...099CCCC990... +...09CCCCCC90... +...09CCCC0C90... +...09CCCC9C90... +...09CCCCCC90... +...09CCCCCC90... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_purple_o, bitmap` +................ +........HHH..... +.....HHHCCH..... +....0HCCCCH0.... +....HCCCCCH0.... +....HCCCCCH0.... +...0HCCCCCH50... +...0HCCCCCH50... +...0HCCCC0H50... +...0HCCCCHH50... +...0HCCCCCH50... +...0HCCCCCH50... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_purple_o2, bitmap` +................ +.......00....... +......0550...... +....00555500.... +....0H555550.... +....0H555550.... +...0HC5555550... +...0HC5555550... +...0H05555550... +...0HH5555550... +...0HC5555550... +...0HC5555550... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_orange_o, bitmap` +................ +........999..... +.....999CC9..... +....09CCCC90.... +....9CCCCC90.... +....9CCCCC90.... +...09CCCCC950... +...09CCCCC950... +...09CCCC0950... +...09CCCC9950... +...09CCCCC950... +...09CCCCC950... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ door_orange_o2, bitmap` +................ +.......00....... +......0550...... +....00555500.... +....09555550.... +....09555550.... +...09C5555550... +...09C5555550... +...0905555550... +...0995555550... +...09C5555550... +...09C5555550... +2222222222222222 +2222222222222222 +2222222222222222 +2222222222222222`], + [ lava_pool, bitmap` +1111116333911111 +LL11633363331LL1 +1113393333393111 +1LL9939399339311 +1139399993933931 +.11933999393931L +..L193339399LL11 +..11966999669911 +..1LL6966LL9111. +...11L6996L111.. +...111LL6L111... +....1166L111.... +....111L61L1.... +......161....... +.......LL....... +.......1........`], + [ geyser, bitmap` +1111172727711LLL +1LL1127775711111 +1L11L7275577LLL1 +L11LL77727271111 +11LLL2257577L1LL +LLLL755725255L11 +LLL7752797727LLL +LLL97973775532LL +LLL32323233533LL +LLL99333923323LL +LLL96239293933LL +LL699669369699LL +LL626699999626LL +L66996262692666L +116116L61169L116 +1L116LL69LL11L69`], + [ platform_geyser, bitmap` +.11.1..11..1L1.L +.L1.1..LLL.11.L1 +.1L..1.1L.....1L +..1.L1..1.....11 +....LLL...L1.... +....1L1...L11... +...........11... +........LL1..... +....11..111..... +.....11..1.L1... +.....LL....1L... +...........1.... +LL17277772777211 +11117552752551LL +1LL1172755771111 +1111117572711LL1`], + [ platform_geyser2, bitmap` +.............L11 +.LLL...11....LL1 +.L11L.LL1.LL..L. +.L111.L...LL1... +...........11... +......L11....... +..L.1.LL........ +..LL1...LL1..... +..L11...L11..... +......LL........ +......L11....... +................ +LL17757772755711 +11117277557721LL +1LL1175755771111 +1111117772711LL1`], + [ platform_geyser3, bitmap` +111L...L.....LLL +L11L.L11.....1L. +LL...L1L.....111 +.....L....LL.... +L1L...L...L11... +L11..L11..L1.... +.1...LLL........ +L.......LLL..... +...L1L..11L..... +...11L...1L..... +....L........... +................ +LL17277775775711 +11117557275771LL +1LL1155757721111 +1111112755711LL1`], + [ bridge, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +CCCCCCCC999CCCCC +C999CCCCCCCCCCCC +CCCCCCCCCCCC999C +................ +................ +................ +................`], + [ bridge_l, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +...............C +..............CC +.......CCCCCCCCC +2222222CC2CCC1L1 +2222222C92C1111L +2222222C92C1LL11 +2222222CC211111L`], + [ bridge_r, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +C............... +CCC............. +CCCCCCCCC....... +1L11CCCCC2222222 +L1LLL22C92222222 +1111112C92222222 +LLL1L11CC2222222`], + [ shoot_geyser, bitmap` +L..2777275277.L. +11.7572775772.L1 +LL.2527775727... +.L.7575775777..L +L117525725777.L1 +.1L7575275727LL1 +...7575775752... +.L.2525775757... +11.7575272757... +L1.7525777757..L +.L.7775777727.L1 +...7722222757..L +LL17277272777... +11117552752551LL +1LL1172755771111 +1111117572711LL1`], + [ shoot_geyser2, bitmap` +L..2777275277.L. +11.7572775772.L1 +LL.2527775727... +.L.75757757571.L +L117525725757.L1 +.1L7575275757.L1 +...7575775252... +.L.2525775757... +11.7575275757... +L1.752577525711L +.L.2575775752.L1 +...7525225757..L +LL.7575275757... +11.252527525711L +.L.7575775727.11 +...7527277272...`], + [ shoot_geyser_bridge, bitmap` +11.7277277757..1 +LL17577572757.1L +...7577577577.1L +.L175725725721.. +1L.7572577577.11 +.1.7727757527.L1 +...F257C57C27.L1 +..C722F77C55FC.. +.CF775CC57272FC. +CCCCC775775C5CFC +CFC2277522572CCF +CFC7525577525CCF +L1L7575277575L11 +1117275277575L1L +1L17577272775111 +11L77777772251L1`], + [ rock, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [ stone_rock, bitmap` +11111111111LLL11 +11LLL1111LL11111 +1111111111111111 +11LLLLLL11LLL111 +1111111111111111 +11111111LL1111LL +11LL1L1111111111 +11111111111LL111 +1111111111111111 +111LL11LL11111LL +1111111LLL1111L1 +11LL111111111111 +111111L11LL11LL1 +1L111111111111L1 +1LL1111LL1111111 +111111111111L111`] +); + +let level = 0 +const levels = [ + map` +mmmommmmmh +465nt65464 +momawommom +6nt65n46n4 +oawomammao +n54nt6546n +ammawmomma +546546n545 +mml9rmammm +121v312312`, + map` +mmommwommh +64n6t5n654 +omamwmamom +n56@4654n5 +amm[mommam +64545n4@46 +mommmam]mo +5n6t56454n +mamwml9rma +123132v312`, + map` +ommw.wommh +n6@6.6n464 +amQLiRaomm +6564.54n@6 +mmoLiRmaAo +65nt.t@t6n +moaw.wowma +5n65.5n465 +mamlzrammm +1212g32312`, + map` +mmmommmomh +564n5t4n64 +mol7rwmamo +5n4:6t645n +oamQmwl7ra +n546546:45 +ammoLiR]mo +645nU7UU6n +mml7Uv3Uma +132v3YY221` +] + +let lives = 3 + +function level_setup(level) { + if (level == 4) { + win() + } else { + clearText() + haswon = false + isdead = false + exit = false + jumping = false + climbing = false + collided = false + landed = true + setMap(levels[level]) + setBackground(background) + for (let i = 0; i < lives; i++) { + addSprite(i,9,"#") + } + getlava = getAll(lava) + getpool = getAll(lava_pool) + lava_tile = getlava.concat(getpool) + geyser_tile = getFirst(geyser) + inventory = [] + inventory_length = 0 + if (level == 0) { + addSprite(0,8,"p") + addSprite(6,4,"e") + addSprite(6,4,"k") + addSprite(2,2,"e") + } else if (level == 1) { + addSprite(0,8,"p") + addSprite(2,6,"e") + addSprite(4,0,"e") + addSprite(5,2,"}") + addSprite(4,8,"{") + addSprite(3,0,"k") + } else if (level == 2) { + addSprite(0,8,"p") + addSprite(8,2,"e") + addSprite(9,8,"e") + addSprite(6,6,"W") + addSprite(2,0,"S") + addSprite(8,6,"k") + } else if (level == 3) { + addSprite(0,8,"p") + addSprite(6,4,"}") + addSprite(8,8,"W") + addSprite(4,4,"k") + addSprite(6,2,"e") + addSprite(0,0,"e") + } + movedirs = Array.apply(null, Array(getAll(enemy).length)).map(Number.prototype.valueOf,-1) + } +} + +level_setup(level) + +let lava_switch = ["7","8","9"] +let geyser_switch = ["z","x","c"] +var lava_index = 0 +var geyser_index = 0 +var geyser_on = false +var geyser_bubbling = false + +function geyser_eruption_kill() { + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (geyser_tile)) { + if ((tilesWith(player,shoot_geyser).length == 1)||(tilesWith(player,shoot_geyser2).length == 1)||(tilesWith(player,shoot_geyser_bridge).length == 1)) { + tile = getFirst(player) + setTimeout(() => { + setBackground(red) + collided = true + if (getFirst(player)) { + getFirst(player).remove() + } + }, 300); + for (let i = 0; i < melting.length; i++) { + setTimeout(() => { + if (i > 0) { + if (getFirst(melting[i-1])) { + getFirst(melting[i-1]).remove() + } + } else { + if (getFirst(player)) { + getFirst(player).remove() + } + } + addSprite(tile.x,tile.y,melting[i]) + }, i*300); + } + setTimeout(() => { + die() + }, 2000); + } + } +} + +function geyser_erupt() { + if (geyser_tile) { + kill_check = setInterval(geyser_eruption_kill, 10); + geyser_on = true + clearTile(geyser_tile.x, geyser_tile.y-1) + addSprite(geyser_tile.x, geyser_tile.y-1, shoot_geyser) + setTimeout(() => { + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (geyser_tile)) { + clearTile(geyser_tile.x, geyser_tile.y-1) + addSprite(geyser_tile.x, geyser_tile.y-1, platform_geyser) + } + clearInterval(kill_check) + },1700); + for (let i = 7; i >= 0; i--) { + setTimeout(() => { + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (geyser_tile)) { + if(getTile(geyser_tile.x,i).some(s => s.type === bridge)) { + getTile(geyser_tile.x, i).find(s => s.type === bridge).remove() + addSprite(geyser_tile.x,i,shoot_geyser_bridge) + } else { + clearTile(geyser_tile.x,i) + addSprite(geyser_tile.x,i,shoot_geyser2) + } + } + },(7-i)*100); + + setTimeout(() => { + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (geyser_tile)) { + if(getTile(geyser_tile.x,i).some(s => s.type === shoot_geyser_bridge)) { + getTile(geyser_tile.x, i).find(s => s.type === shoot_geyser_bridge).remove() + addSprite(geyser_tile.x,i,bridge) + } else { + clearTile(geyser_tile.x,i) + } + } + },800+(i*100)); + } + } +} + +function level_animation(){ + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(exit))){ + if (lava_tile) { + for (let i = 0; i < lava_tile.length; i++) { + if (!(getFirst(player).x == lava_tile[i].x && getFirst(player).y == lava_tile[i].y-1)){ + clearTile(lava_tile[i].x, lava_tile[i].y-1) + addSprite(lava_tile[i].x, lava_tile[i].y-1,lava_switch[lava_index]) + lava_index += 1 + lava_index %= 3 + } + } + } + if (geyser_tile) { + if ((!(getFirst(player).x == geyser_tile.x && getFirst(player).y == geyser_tile.y-1)) && (!(geyser_on))){ + clearTile(geyser_tile.x, geyser_tile.y-1) + addSprite(geyser_tile.x, geyser_tile.y-1,geyser_switch[geyser_index]) + geyser_index += 1 + geyser_index %= 3 + if ((Math.floor(Math.random()*3) == 2) && (!(geyser_bubbling))) { + geyser_bubbling = true + let timer = Math.floor((Math.random()*5000)+5000); + setTimeout(() => { + geyser_erupt() + }, timer); + setTimeout(() => { + geyser_on = false + geyser_bubbling = false + }, 1700+timer); + } + } + } + } +} +setInterval(level_animation, 500); + +const melting = ["p","!","£","$","%","^"] + +function lava_kill(){ + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (lava_tile)) { + for (let i = 0; i < lava_tile.length; i++) { + if (!(collided)){ + if ((getFirst(player).x == lava_tile[i].x && getFirst(player).y == lava_tile[i].y-1)){ + setBackground(red) + collided = true + lava_collision_index = i + if (getFirst(player)) { + getFirst(player).remove() + } + for (let j = 0; j < melting.length; j++) { + setTimeout(() => { + if (i == lava_collision_index) { + clearTile(lava_tile[i].x,lava_tile[i].y-1) + addSprite(lava_tile[i].x,lava_tile[i].y-1,platform_lava) + addSprite(lava_tile[i].x,lava_tile[i].y-1,melting[j]) + } + }, j*300); + } + setTimeout(() => { + die() + }, 2000); + } + } + } + } +} +setInterval(lava_kill, 10); + + +function geyser_kill(){ + if ((!(isdead)) && (tilesWith(player).length == 1) && (!(collided)) && (geyser_tile)) { + if ((getFirst(player).x == geyser_tile.x && getFirst(player).y == geyser_tile.y-1)){ + setTimeout(() => { + setBackground(red) + collided = true + if (getFirst(player)) { + getFirst(player).remove() + } + }, 300); + for (let i = 0; i < melting.length; i++) { + setTimeout(() => { + clearTile(geyser_tile.x,geyser_tile.y-1) + addSprite(geyser_tile.x,geyser_tile.y-1,platform_geyser) + addSprite(geyser_tile.x,geyser_tile.y-1,melting[i]) + }, i*300); + } + setTimeout(() => { + die() + }, 2000); + } + } +} +setInterval(geyser_kill, 10); + +function die(){ + if (!(isdead)) { + isdead = true + lives -= 1 + } + setMap(map`d`) + addText("Oh no, you died!", { + x: 2, + y: 1, + color: color`3` +}) + addText(`You have ${lives}`, { + x: 4, + y: 5, + color: color`3` + }) + addText("heart(s) left.", { + x: 3, + y: 7, + color: color`3` + }) + addText("Press", { + x: 6, + y: 11, + color: color`3` + }) + addText("j", { + x: 12, + y: 11, + color: color`2` + }) + if (lives > 0) { + addText("to continue.", { + x: 4, + y: 13, + color: color`3` + }) + } else { + addText("to play again.", { + x: 3, + y: 13, + color: color`3` + }) + } +} + +function win(){ + haswon = true + setMap(map`d`) + addText("Well done, you have", { + x: 1, + y: 1, + color: color`3` + }) + addText("won the game!", { + x: 3, + y: 3, + color: color`3` + }) + addText(`You have ${lives}/3`, { + x: 4, + y: 6, + color: color`3` + }) + addText("heart(s) left.", { + x: 3, + y: 8, + color: color`3` + }) + addText("Press", { + x: 6, + y: 11, + color: color`3` + }) + addText("j", { + x: 12, + y: 11, + color: color`2` + }) + addText("to play again.", { + x: 3, + y: 13, + color: color`3` + }) +} + + +let enemy_blocks = [wall,door,door_red,door_green,door_purple,door_orange,bridge,platform_geyser,platform_geyser2,platform_geyser3,shoot_geyser] +function move_enemies(){ + if (!(collided)) { + let es = getAll(enemy); + for (let i = 0; i < es.length; i++) { + if (es[i].x == 9){ + movedirs[i] = -1 + } + else if (es[i].x == 0){ + movedirs[i] = 1 + } else if ((getTile(es[i].x+movedirs[i],es[i].y).some(s => enemy_blocks.includes(s.type)))){ + movedirs[i] = -movedirs[i] + } + + es[i].x += movedirs[i] + } + + if ((!(isdead)) && (tilesWith(player).length == 1)) { + if (tilesWith(player, enemy).length > 0) { + tile = getFirst(player) + collided = true + setTimeout(() => { + setBackground(red) + }, 300); + for (let i = 0; i < melting.length; i++) { + setTimeout(() => { + if (i > 0) { + getFirst(melting[i-1]).remove() + } else { + getFirst(player).remove() + } + addSprite(tile.x,tile.y,melting[i]) + }, i*300); + } + setTimeout(() => { + die() + }, 1800); + } + } + } +} +setInterval(move_enemies, 500); + +inventory_length = 0 +function pick_up_key(){ + if (tilesWith(player, key).length > 0) { + getFirst(key).remove(); + inventory.push("k"); + clearTile(9,0); + addSprite(9,0,"_"); + } else if ( tilesWith(player, key_red).length > 0) { + getFirst(key_red).remove(); + inventory.push("{"); + let current_tile = getFirst(door_red) + clearTile(current_tile.x, current_tile.y); + addSprite(current_tile.x,current_tile.y,"<"); + } else if ( tilesWith(player, key_green).length > 0) { + getFirst(key_green).remove(); + inventory.push("}"); + let current_tile = getFirst(door_green) + clearTile(current_tile.x, current_tile.y); + addSprite(current_tile.x,current_tile.y,">"); + } else if ( tilesWith(player, key_purple).length > 0) { + getFirst(key_purple).remove(); + inventory.push("W"); + let current_tile = getFirst(door_purple) + clearTile(current_tile.x, current_tile.y); + addSprite(current_tile.x,current_tile.y,"E"); + } else if ( tilesWith(player, key_orange).length > 0) { + getFirst(key_orange).remove(); + inventory.push("S"); + let current_tile = getFirst(door_orange) + clearTile(current_tile.x, current_tile.y); + addSprite(current_tile.x,current_tile.y,"D"); + } + if (inventory.length !== inventory_length) { + inventory_length = inventory.length + for (let i = 0; i < inventory_length; i++) { + addSprite(10-inventory_length,9,inventory[i]) + } + } +} +setInterval(pick_up_key,500); + +const leaving = ["p","*","(",")","-"] + +function enter_door(){ + exit = true + inventory = inventory.filter(function (item) { + return item !== 'k'; + }); + for (let i = 0; i < leaving.length; i++) { + setTimeout(() => { + if (i > 0){ + getFirst(leaving[i-1]).remove() + } else { + getFirst(player).remove() + } + addSprite(9,0,leaving[i]) + }, i*150); + } + setTimeout(() => { + addSprite(width()-1,0,leaving[4]) + }, 1500); + setTimeout(() => { + level += 1 + level_setup(level) + }, 2000); +} + + +setSolids([ player, wall, door, door_red, door_green, door_purple, door_orange, rock, stone_rock, door_block ]); + +onInput("d", () => { + if ((!(isdead)) && (tilesWith(player).length == 1) && ((getFirst(player).y %2 == 0) || jumping)) { + getFirst(player).x += 1 + if (tilesWith(door_o, player).length > 0) { + enter_door() + } else if (tilesWith(door_red_o, player).length > 0) { + let tile = getFirst(door_red_o) + getFirst(door_red_o).remove() + addSprite(tile.x,tile.y,door_red_o2) + inventory = inventory.filter(function (item) { + return item !== '{'; + }); + getFirst(key_red).remove(); + } else if (tilesWith(door_green_o, player).length > 0) { + let tile = getFirst(door_green_o) + getFirst(door_green_o).remove() + addSprite(tile.x,tile.y,door_green_o2) + inventory = inventory.filter(function (item) { + return item !== '}'; + }); + getFirst(key_green).remove(); + } else if (tilesWith(door_purple_o, player).length > 0) { + let tile = getFirst(door_purple_o) + getFirst(door_purple_o).remove() + addSprite(tile.x,tile.y,door_purple_o2) + inventory = inventory.filter(function (item) { + return item !== 'W'; + }); + getFirst(key_purple).remove(); + } else if (tilesWith(door_orange_o, player).length > 0) { + let tile = getFirst(door_orange_o) + getFirst(door_orange_o).remove() + addSprite(tile.x,tile.y,door_orange_o2) + inventory = inventory.filter(function (item) { + return item !== 'S'; + }); + getFirst(key_orange).remove(); + } + } +}) + +onInput("a", () => { + if ((!(isdead)) && (tilesWith(player).length == 1) && ((getFirst(player).y %2 == 0) || jumping)) { + getFirst(player).x -= 1 + if (tilesWith(door_red_o, player).length > 0) { + let tile = getFirst(door_red_o) + getFirst(door_red_o).remove() + addSprite(tile.x,tile.y,door_red_o2) + inventory = inventory.filter(function (item) { + return item !== '{'; + }); + getFirst(key_red).remove(); + } else if (tilesWith(door_green_o, player).length > 0) { + let tile = getFirst(door_green_o) + getFirst(door_green_o).remove() + addSprite(tile.x,tile.y,door_green_o2) + inventory = inventory.filter(function (item) { + return item !== '}'; + }); + getFirst(key_green).remove(); + } else if (tilesWith(door_purple_o, player).length > 0) { + let tile = getFirst(door_purple_o) + getFirst(door_purple_o).remove() + addSprite(tile.x,tile.y,door_purple_o2) + inventory = inventory.filter(function (item) { + return item !== 'W'; + }); + getFirst(key_purple).remove(); + } else if (tilesWith(door_orange_o, player).length > 0) { + let tile = getFirst(door_orange_o) + getFirst(door_orange_o).remove() + addSprite(tile.x,tile.y,door_orange_o2) + inventory = inventory.filter(function (item) { + return item !== 'S'; + }); + getFirst(key_orange).remove(); + } + } +}) + +onInput("w", () => { + if ((!(isdead)) && (tilesWith(player).length == 1) && !(climbing)) { + if ((tilesWith(ladder, player).length > 0) && !(jumping)){ + climbing = true + landed = true + getFirst(player).y -= 1 + jumping = false + setTimeout(() => { + jumping = false + climbing = false + getFirst(player).y -= 1 + }, 100); + } else if (tilesWith(n_ladder, player).length > 0) { + jumping = false + climbing = true + landed = true + getFirst(player).y -= 1 + climbing = false + } + else if ((getFirst(player).y %2 == 0) && !(jumping)){ + getFirst(player).y -= 1 + jumping = true + landed = false + climbing = false + setTimeout(() => { + if (!(landed)) { + getFirst(player).y += 1 + jumping = false + landed = true + climbing = false + } + }, 400); + } + } +}) + +onInput("s", () => { + if ((!(isdead)) && (tilesWith(player).length == 1) && !(jumping) && !(climbing)) { + if (tilesWith(o_ladder, player).length > 0) { + climbing = true + landed = true + getFirst(player).y += 1 + jumping = false + setTimeout(() => { + getFirst(player).y += 1 + jumping = false + climbing = false + }, 100); + } + } +}) + +onInput("j", () => { + if (isdead || haswon) { + if (lives == 0 || haswon) { + lives = 3 + level = 0 + } + level_setup(level) + } +}) \ No newline at end of file diff --git a/games/Hole-in-Wall.js b/games/Hole-in-Wall.js new file mode 100644 index 0000000000..781a1e0777 --- /dev/null +++ b/games/Hole-in-Wall.js @@ -0,0 +1,839 @@ +/* +@title: Hole in Wall +@author: udu3324 +@tags: [] +@addedOn: 2024-00-00 +*/ + +let timeoutIDs = [] + +const player = "p" +const floor = "f" +const sky = "s" + +const wallT = "t" +const wallB = "b" +const wallL = "l" +const wallR = "r" + +setLegend( + [player, bitmap` + ......000....... + .....00200...... + ...000222000.... + .000222222200... + 0022222222222000 + 000000000000000. + ..00222222222200 + ..02222222222220 + .002000020000020 + .022222222222220 + .022220222202220 + .002220022202220 + ..02222000022220 + ..00222222222200 + ...000222222000. + .....00000000...`], + [wallT, bitmap` + 3333333333333333 + 3......3...33..3 + 33.....33...3..3 + 333.....33.....3 + 3.33.....33....3 + 3..33.....33...3 + 3...33.....33..3 + 3.....33.....333 + 3.33...333..3.33 + 3..3........33.3 + 3..333.3.....333 + 33.....333.....3 + 333......33....3 + 3.33.......33..3 + 3..333..3...33.3 + 3333333333333333`], + [wallB, bitmap` + 9999999999999999 + 9......9...99..9 + 99.....99...9..9 + 999.....99.....9 + 9.99.....99....9 + 9..99.....99...9 + 9...99.....99..9 + 9.....99.....999 + 99.99...99..9.99 + 9..9........99.9 + 9..999.9.....999 + 99.....999.....9 + 999......99....9 + 9.99.......99..9 + 9..999..9...99.9 + 9999999999999999`], + [wallL, bitmap` + HHHHHHHHHHHHHHHH + H......H...HH..H + HH.....HH...H..H + HHH.....HH.....H + H.HH.....HH....H + H..HH.....HH...H + H...HH.....HH..H + H.....HH.....HHH + HH.HH...HH..H.HH + H..H........HH.H + H..HHH.H.....HHH + HH.....HHH.....H + HHH......HH....H + H.HH.......HH..H + H..HHH..H...HH.H + HHHHHHHHHHHHHHHH`], + [wallR, bitmap` + CCCCCCCCCCCCCCCC + C......C...CC..C + CC.....CC...C..C + CCC.....CC.....C + C.CC.....CC....C + C..CC.....CC...C + C...CC.....CC..C + C.....CC.....CCC + C.CC...CCC..C.CC + C..C........CC.C + C..CCC.C.....CCC + CC.....CCC.....C + CCC......CC....C + C.CC.......CC..C + C..CCC..C...CC.C + CCCCCCCCCCCCCCCC`], + [floor, bitmap` + 4DDDDDDDDDD4DDDD + DDD4DDDDDDDDDDD4 + DDDDDDDDDDD4DDDD + DDDDDD4DDDDDDD4D + DDDD4DDDDDDDDDDD + 4DDDDDDDDDDD4DDD + DD4DDDDDDDDDDDDD + DDDD4DDDDD4DDDDD + DDD4DDDDDDDDDD4D + DDDDDDDDDDDDDDDD + DDD4DDDDD4DDDDDD + DDDD4DDDDDDDDDDD + DDDDDDDDDDDDDD4D + 4DDDDDDD4DDDDDDD + DDDDD4DDDDDDDDDD + DDDDDDDD4DDDD4DD`], + [sky, bitmap` + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777 + 7777777777777777`], +) + +setSolids([ player, wallT, wallB, wallL, wallR ]) + +let level = 0 +const levels = [ + map` +sssssssssssssss +sssssssssssssss +sssssssssssssss +sss.........sss +sss.........sss +sss.........sss +sss.........sss +sss.........sss +sss.........sss +sssssssssssssss +sssssssssssssss +sssssssssssssss` +] + +setMap(levels[level]) + +setPushables({ + [ player ]: [], + [ wallT ]: [ player ], + [ wallB ]: [ player ], + [ wallL ]: [ player ], + [ wallR ]: [ player ], +}) + +//when the game first starts +function splash() { + addText("Hole in Wall", {x: 4, y: 2, color: color`f`}) + addText("Press any button", {x: 2, y: 13, color: color`2`}) + addText("to start!", {x: 2, y: 14, color: color`2`}) +} + +splash() +addSprite(7, 7, player) + +setBackground(floor) + +runStartAnimation() + +let ended = false +let started = false + +let startAnimation = true + +let finishedLevelOne = false +let finishedLevelTwo = false +let finishedLevelThree = false + +function start() { + if (started) { + return + } + + started = true + + if (startAnimation) { + startAnimation = false + + restart() + return + } + + if (!finishedLevelOne) { + levelOne() + } +} + +function levelOne() { + clearText() + addText("Level 1: The Basics", {x: 1, y: 1, color: color`2`}) + wallText(1, 10) + + // ms * 12 = total time + addWall("top", 2, 350) + + let tick = 0 + for (let i = 1; i < 11; i++) { + const timeout = setTimeout(() => { + if (i === 10) { + clearText() + addText("Level 1: The Basics", {x: 1, y: 1, color: color`2`}) + addText("Completed!", {x: 5, y: 2, color: color`4`}) + + addText("Press (right) down", {x: 2, y: 13, color: color`2`}) + addText("to move on!", {x: 2, y: 14, color: color`2`}) + + finishedLevelOne = true + ended = true + } else { + addWall("top", 2, 350) + wallText(i + 1, 10) + } + + }, (4200) * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } +} + +function levelTwo() { + clearText() + addText("Level 2: Bit Harder", {x: 1, y: 1, color: color`2`}) + wallText(1, 25) + + // ms * 12 = total time + addWall("top", 2, 200) + + let tick = 0 + for (let i = 1; i < 26; i++) { + const timeout = setTimeout(() => { + if (i === 25) { + clearText() + addText("Level 2: Bit Harder", {x: 1, y: 1, color: color`2`}) + addText("Completed!", {x: 5, y: 2, color: color`4`}) + + addText("Press (right) down", {x: 2, y: 13, color: color`2`}) + addText("to move on!", {x: 2, y: 14, color: color`2`}) + + finishedLevelTwo = true + ended = true + } else { + addWall("top", 2, 200) + wallText(i + 1, 25) + } + + }, (1200) * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } +} + +//i swear the chain of timeouts was the best way to do it +function levelThree() { + clearText() + addText("Level 3: Good Luck", {x: 1, y: 1, color: color`2`}) + wallText(1, 30) + + // ms * 12 = total time + addWall("bottom", 2, 200) + + timeoutIDs.push(setTimeout(() => { + // ms * 15 = total time + addWall("right", 1, 150) + wallText(2, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(3, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(4, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(5, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(6, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(7, 30) + timeoutIDs.push(setTimeout(() => { + addWall("top", 1, 150) + wallText(8, 30) + timeoutIDs.push(setTimeout(() => { + addWall("bottom", 1, 150) + wallText(9, 30) + timeoutIDs.push(setTimeout(() => { + addWall("bottom", 1, 150) + wallText(10, 30) + timeoutIDs.push(setTimeout(() => { + addWall("bottom", 1, 150) + wallText(11, 30) + timeoutIDs.push(setTimeout(() => { + addWall("bottom", 1, 150) + wallText(12, 30) + timeoutIDs.push(setTimeout(() => { + addWall("bottom", 1, 150) + wallText(13, 30) + timeoutIDs.push(setTimeout(() => { + addWall("top", 1, 150) + wallText(14, 30) + timeoutIDs.push(setTimeout(() => { + addWall("top", 1, 150) + wallText(15, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(16, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(17, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(18, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(19, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(20, 30) + timeoutIDs.push(setTimeout(() => { + addWall("right", 1, 150) + wallText(21, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(22, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(23, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(24, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(25, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(26, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(27, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(28, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(29, 30) + timeoutIDs.push(setTimeout(() => { + addWall("left", 1, 150) + wallText(30, 30) + timeoutIDs.push(setTimeout(() => { + clearText() + addText("Level 3: Good Luck", {x: 1, y: 1, color: color`2`}) + addText("You did it.", {x: 5, y: 2, color: color`4`}) + + addText("You beat the game!", {x: 2, y: 13, color: color`2`}) + addText("Challenge others!", {x: 2, y: 14, color: color`2`}) + + finishedLevelThree = true + ended = true + }, 2250)) + }, 550)) + }, 550)) + }, 550)) + }, 550)) + }, 550)) + }, 550)) + }, 550)) + }, 550)) + }, 2250)) + }, 750)) + }, 750)) + }, 750)) + }, 750)) + }, 750)) + }, 2400)) + }, 2400)) + }, 2400)) + }, 2400)) + }, 1200)) + }, 1200)) + }, 1200)) + }, 2400)) + }, 2250)) + }, 2250)) + }, 2250)) + }, 2250)) + }, 2250)) + }, 2250)) + }, 2400)) +} + +//im too lazy +//function freePlay() { +// clearText() +// addText("Freeplay", {x: 7, y: 1, color: color`2`}) +// +// let time = [] +// let tick = 0 +// for (let i = 1; i < 200; i++) { +// +// +// tick++ +// } +//} + +function wallText(current, total) { + addText(`Wall (${current}/${total})`, {x: 4, y: 2, color: color`0`}) +} + +function runStartAnimation() { + addWall("top", 4, 150) // ms * 12 = total time + + let tick = 0 + for (let i = 0; i < 25; i++) { + const timeout = setTimeout(() => { + if (!startAnimation) { + return + } + getFirst(player).x = 7 + getFirst(player).y = 7 + + removeAllWalls() + + addWall("right", 2, 150) // ms * 15 = total time + + const timeoutNested = setTimeout(() => { + if (!startAnimation) { + return + } + removeAllWalls() + addWall("top", 2, 150) // ms * 12 = total time + }, 2250) + timeoutIDs.push(timeoutNested) + }, (1800 + 2250) * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } +} + +//checks if the player is out of bounds and stops the game there +function checkOutOfBounds() { + //dont get triggered by start animation + if (!started) { + return + } + + if (getFirst(player).y > 8 || getFirst(player).y < 3) { + ended = true + clearText() + + addText("You lost.", {x: 5, y: 1, color: color`2`}) + addText("Don't fall off!", {x: 3, y: 2, color: color`f`}) + + addText("Press (right) down", {x: 2, y: 13, color: color`2`}) + addText("to restart!", {x: 2, y: 14, color: color`2`}) + } + + if (getFirst(player).x < 3 || getFirst(player).x > 11) { + ended = true + clearText() + + addText("You lost.", {x: 5, y: 1, color: color`2`}) + addText("Don't fall off!", {x: 3, y: 2, color: color`f`}) + + addText("Press (right) down", {x: 2, y: 13, color: color`2`}) + addText("to restart!", {x: 2, y: 14, color: color`2`}) + } +} + +function removeAllWalls() { + for (const id of timeoutIDs) { + clearTimeout(id) + timeoutIDs = [] + } + + for (const wallType of [wallT, wallB, wallL, wallR]) { + for (const wall of getAll(wallType)) { + wall.remove() + } + } +} + +function restart() { + //remove all walls left over + removeAllWalls() + + //add player back, but they might be gone + if (getFirst(player) === undefined) { + addSprite(7, 7, player) + } else { + getFirst(player).x = 7 + getFirst(player).y = 7 + } + + //done + clearText() + ended = false + started = false + + splash() +} + +//1-9 holes top/bottom (3, 11) +//1-6 holes left/right (3, 8) + +//side - choose what side the wall is spawned in at +//holes - how many holes there are in the wall +//ms - how fast the wall moves per tile +function addWall(side, holes, ms) { + let wallCluster = [] + let coordinates = [] + + switch (side) { + case "top": { + wallCluster = ["t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t"] + coordinates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + + //randomly remove holes + for (let i = 0; i < holes; i++) { + wallCluster[randomRangeInt(3, 11)] = "" + } + + //add it to the map + for (let i = 0; i < wallCluster.length; i++) { + //ignore holes in array + if (wallCluster[i] !== "") { + addSprite(coordinates[i], 0, wallT) + //addText(`add: ${coordinates[i]}, ${wallCluster[i]}`, {x: 2, y: 14, color: color`2`}) + } + } + + //animate going down + let tick = 0 + for (let y = 0; y < 12; y++) { + //for every ms, move the cluster one tile + const timeout = setTimeout(() => { + //the cluster moved fully to the end. delete it + if (y === 11) { + for (let i = 0; i < wallCluster.length; i++) { + //only remove specific type of tile + const tileList = getTile(coordinates[i], 11) + for (const tile of tileList) { + if (tile.type === wallT) { + tile.remove() + } + } + } + } else { + //for each tile in cluster + for (let i = 0; i < wallCluster.length; i++) { + if (wallCluster[i] !== "") { + //only move specific type of tile + const tileList = getTile(coordinates[i], y) + for (const tile of tileList) { + if (tile.type === wallT) { + tileList[0].y += 1 + } + } + } + } + checkOutOfBounds() + } + }, ms * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } + + break + } + case "bottom": { + wallCluster = ["t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t"] + coordinates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + + //randomly remove holes + for (let i = 0; i < holes; i++) { + wallCluster[randomRangeInt(3, 11)] = "" + } + + //add it to the map + for (let i = 0; i < wallCluster.length; i++) { + //ignore holes in array + if (wallCluster[i] !== "") { + addSprite(coordinates[i], 11, wallB) + } + } + + //animate going up + let tick = 0 + for (let y = 12; y > 0; y--) { + //for every ms, move the cluster one tile + const timeout = setTimeout(() => { + //the cluster moved fully to the end. delete it + if (y === 1) { + for (let i = 0; i < wallCluster.length; i++) { + //only remove specific type of tile + const tileList = getTile(coordinates[i], 0) + for (const tile of tileList) { + if (tile.type === wallB) { + tile.remove() + } + } + } + } else { + //for each tile in cluster + for (let i = 0; i < wallCluster.length; i++) { + if (wallCluster[i] !== "") { + //only move specific type of tile + const tileList = getTile(coordinates[i], (y - 1)) + for (const tile of tileList) { + if (tile.type === wallB) { + tileList[0].y -= 1 + } + } + } + } + checkOutOfBounds() + } + }, ms * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } + + break + } + case "left": { + wallCluster = ["t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t"] + coordinates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + + //random remove holes + for (let i = 0; i < holes; i++) { + wallCluster[randomRangeInt(3, 8)] = "" + } + + //add it to map + for (let i = 0; i < wallCluster.length; i++) { + //ignore holes in array + if (wallCluster[i] !== "") { + addSprite(0, coordinates[i], wallL) + } + } + + //animate it going right + let tick = 0 + for (let x = 0; x < 15; x++) { + const timeout = setTimeout(() => { + //the cluster moved fully to the end + if (x === 14) { + for (let i = 0; i < wallCluster.length; i++) { + //only remove specific type of tile + const tileList = getTile(14, coordinates[i]) + for (const tile of tileList) { + if (tile.type === wallL) { + tile.remove() + } + } + } + } else { + for (let i = 0; i < wallCluster.length; i++) { + if (wallCluster[i] !== "") { + //only move specific type of tile + const tileList = getTile(x, coordinates[i]) + for (const tile of tileList) { + if (tile.type === wallL) { + tileList[0].x += 1 + } + } + } + } + checkOutOfBounds() + } + + }, ms * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } + + break + } + case "right": { + wallCluster = ["t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t"] + coordinates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + + //random remove holes + for (let i = 0; i < holes; i++) { + wallCluster[randomRangeInt(3, 8)] = "" + } + + //add it to map + for (let i = 0; i < wallCluster.length; i++) { + //ignore holes in array + if (wallCluster[i] !== "") { + addSprite(14, coordinates[i], wallR) + } + } + + let tick = 0 + for (let x = 15; x > 0; x--) { + const timeout = setTimeout(() => { + //the cluster moved fully to the end + if (x === 1) { + for (let i = 0; i < wallCluster.length; i++) { + //only remove specific type of tile + const tileList = getTile(0, coordinates[i]) + for (const tile of tileList) { + if (tile.type === wallR) { + tile.remove() + } + } + } + } else { + for (let i = 0; i < wallCluster.length; i++) { + if (wallCluster[i] !== "") { + //only move specific type of tile + const tileList = getTile((x - 1), coordinates[i]) + for (const tile of tileList) { + if (tile.type === wallR) { + tileList[0].x -= 1 + } + } + } + } + checkOutOfBounds() + } + + }, ms * (tick + 1)) + + timeoutIDs.push(timeout) + tick++ + } + + break + } + } +} + +//generates a whole number between min-max +function randomRangeInt(min, max) { + return Math.round(Math.random() * (max - min) + min) +} + +//display coordinates to zone things +function debug() { + addText(`(${getFirst(player).x}, ${getFirst(player).y})`, {x: 0, y: 0, color: color`0`}) +} + +//left side buttons for movement +onInput("w", () => { + start() + if (ended) { + return + } + getFirst(player).y -= 1 +}) + +onInput("a", () => { + start() + if (ended) { + return + } + getFirst(player).x -= 1 +}) + +onInput("s", () => { + start() + if (ended) { + return + } + getFirst(player).y += 1 +}) + +onInput("d", () => { + start() + if (ended) { + return + } + getFirst(player).x += 1 +}) + +//right side buttons for game functions +onInput("i", () => { + //addWall("right", 5, 250) +}) + +onInput("j", () => { + +}) + +onInput("k", () => { + if (finishedLevelOne && ended && !finishedLevelTwo && !finishedLevelThree) { + restart() + levelTwo() + } else if (finishedLevelTwo && ended && !finishedLevelThree) { + restart() + levelThree() + } else if (finishedLevelThree && ended) { + restart() + //freePlay() + } +}) + +onInput("l", () => { +}) + +afterInput(() => { + //debug() + if (ended) { + return + } + checkOutOfBounds() +}) diff --git a/games/Housing.js b/games/Housing.js new file mode 100644 index 0000000000..4e7f7078b7 --- /dev/null +++ b/games/Housing.js @@ -0,0 +1,540 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: Housing +@author: Isaac and Nathan Jones +@tags: ['puzzle'] +@addedOn: 2024-12-05 +Get the spridget home while avoiding the fireballs! + +Press WASD to move the brown "spridget" and IJKL to move +the yellow spridget (if present). The fireballs (red circles) +can move either vertically or horizontally, one space for +each move the player makes. Get all spridgets to home to +advance to the next level! + +--HINTS-- +o The fireballs move even if the player tries to move to an +invalid space, such as off of the board or into a wall (orange). +o Its possible to _switch places_ with a fireball (without +losing). +*/ + +const spridget_brown = "b" +const spridget_yellow = "y" +const home = "h" +const fire_up = "u" +const fire_down = "d" +const fire_left = "l" +const fire_right = "r" +const wall = "w" + +setLegend( + [ spridget_brown, bitmap` +................ +................ +................ +...CCCCCCCCCC... +...C........C... +...C.C....C.C... +...C........C... +...C........C... +...C........C... +...CCCCCCCCCC... +...C........C... +...C........C... +...C........C... +...C........C... +...C........C... +................` ], + [ spridget_yellow, bitmap` +................ +................ +................ +...6666666666... +...6........6... +...6.6....6.6... +...6........6... +...6........6... +...6........6... +...6666666666... +...6........6... +...6........6... +...6........6... +...6........6... +...6........6... +................` ], + [ home, bitmap` +........5....... +.......555...... +......55.55..... +.....55...55.... +....55.....55... +...55.......55.. +...5.........5.. +...5.........5.. +...5..55555..5.. +...5..5...5..5.. +...5..5...5..5.. +...5..5..55..5.. +...5..5...5..5.. +...5..5...5..5.. +...55555555555.. +................` ], + [ fire_up, bitmap` +................ +................ +.....333333..... +...3333333333... +...3333033333... +..333300033333.. +..333030303333.. +..333330333333.. +..333330333333.. +..333330333333.. +..333330333333.. +...3333033333... +...3333333333... +.....333333..... +................ +................` ], + [ fire_down, bitmap` +................ +................ +.....333333..... +...3333333333... +...3333333333... +..333330333333.. +..333330333333.. +..333330333333.. +..333330333333.. +..333030303333.. +..333300033333.. +...3333033333... +...3333333333... +.....333333..... +................ +................` ], + [ fire_left, bitmap` +................ +................ +.....333333..... +...3333333333... +...3333333333... +..333303333333.. +..333033333333.. +..330000000033.. +..333033333333.. +..333303333333.. +..333333333333.. +...3333333333... +...3333333333... +.....333333..... +................ +................` ], + [ fire_right, bitmap` +................ +................ +.....333333..... +...3333333333... +...3333333333... +..333333330333.. +..333333333033.. +..300000000003.. +..333333333033.. +..333333330333.. +..333333333333.. +...3333333333... +...3333333333... +.....333333..... +................ +................` ], + [ wall, bitmap` +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999` ] +) + +setSolids([ spridget_brown, wall ]) + +const levels = [ + map` +.b. +..l +.h.`, + map` +...h +r.w. +.... +b.u.`, + map` +.... +rwb. +.ww. +h.u.`, + map` +b...y +w...l +u.w.u +r.w.w +w.h.w`, + map` +r.by.l +...... +r....l +...... +r....l +h.....`, +map` +b.y +r.l +uhu`, +map` +...b +.www +..dd +wuwh`, +map` +h..... +l..... +.l.... +..l... +..l... +.u.uby`, +map` +b...d.. +wwwwww. +...u.u. +.wwwwww +..u...u +wwwwww. +hu.....`, +map` +..b +l.. +hu.`, +map` +.www.d. +l....w. +ww...w. +bw.h.wy +.w...ww +.w....r +.u.www.`, +map` +...w.... +.w.wuw.. +.wbw.ww. +.www..w. +...wh... +...l..w. +..ww.ww. +.ww..uw. +......w.`, +map` +b...y +ww.ww +uw.wu +..u.. +wwhww`, +map` +b...d +wwww. +...u. +.wwww +..u.. +wwww. +hu...`, +map` +w.bww +ww.ww +lw.wr +..u.. +wwhww`, +map` +..bw... +.wwwdw. +u....w. +.www.w. +..wh.r. +..l...w +w...www`, +map` +....b +.l.w. +..hru +.u... +.....`, +map` +d...d +..d.. +..b.. +.www. +uuhuu`, +map` +...d +..w. +lbwr +wwwh`, +map` +b..d +..u. +.u.. +u..h`, +map` +...b... +.wwwww. +u..w..u +w.www.w +.u.w.u. +ww.w.ww +..uhu..`, +map` +...d +.ww. +.ww. +.bw. +ww.. +huu.`, +map` +...d +ddd. +b..h +uuuu`, +map` +..r. +.w.r +.ww. +bwhr`, +map` +bwdw +...w +w..h +wuww`, +map` +hd.wh +ww.wr +..b.. +lw.ww +hw.uh`, +map` +..b.. +..... +..u.. +.uhu. +u.u.u`, +map` +y..r +b.w. +.w.. +u..h`, +map` +wd.d.d +ww.w.w +wwhw.w +wwww.w +.....w +.wwwww +u.u.ub`, +map` +b..w +u..d +uu.w +uuuh`, +map` +..d...b +.wwwwww +.u.u... +wwwwww. +u...u.. +.wwwwww +.....u. +wwwwww. +h.....u`] + +let level = 0 +setMap(levels[level]) + +onInput("w", () => { + me = getFirst(spridget_brown); + if(me) me.y -= 1 +}) + +onInput("a", () => { + me = getFirst(spridget_brown); + if(me) me.x -= 1 +}) + +onInput("s", () => { + me = getFirst(spridget_brown); + if(me) me.y += 1 +}) + +onInput("d", () => { + me = getFirst(spridget_brown); + if(me) me.x += 1 +}) + +onInput("i", () => { + me = getFirst(spridget_yellow); + if(me) + { + sprites = getTile(me.x, me.y-1) + wallThere = false + for(let i = 0; i < sprites.length; i++) + { + if(sprites[i].type == "w") wallThere = true; + } + if(!wallThere) me.y -= 1 + } +}) + +onInput("j", () => { + me = getFirst(spridget_yellow); + if(me) + { + sprites = getTile(me.x-1, me.y) + wallThere = false + for(let i = 0; i < sprites.length; i++) + { + if(sprites[i].type == "w") wallThere = true; + } + if(!wallThere) me.x -= 1 + } +}) + +onInput("k", () => { + me = getFirst(spridget_yellow); + if(me) + { + sprites = getTile(me.x, me.y+1) + wallThere = false + for(let i = 0; i < sprites.length; i++) + { + if(sprites[i].type == "w") wallThere = true; + } + if(!wallThere) me.y += 1 + } +}) + +onInput("l", () => { + me = getFirst(spridget_yellow); + if(me) + { + sprites = getTile(me.x+1, me.y) + wallThere = false + for(let i = 0; i < sprites.length; i++) + { + if(sprites[i].type == "w") wallThere = true; + } + if(!wallThere) me.x += 1 + } +}) + +afterInput(() => { + spridgets = getAll(spridget_brown) + spridgets = spridgets.concat(getAll(spridget_yellow)); + + let onHome = 0; + + for(let j = 0; j < spridgets.length; j++) + { + if(spridgets[j].x == getFirst(home).x && + spridgets[j].y == getFirst(home).y) onHome++; + } + + if(onHome == spridgets.length) + { + level = level + 1; + + const currentLevel = levels[level]; + + if (currentLevel !== undefined) { + setMap(currentLevel); + } else { + addText("you win!", { y: 4, color: color`D`}); + } + } + else + { + fires_left = getAll(fire_left); + fires_right = getAll(fire_right); + fires_up = getAll(fire_up); + fires_down = getAll(fire_down); + + for(let i = 0; i < fires_left.length; i++) + { + oldX = fires_left[i].x; + fires_left[i].x -= 1; + if(oldX == fires_left[i].x) + { + fires_left[i].type = "r"; + fires_left[i].x += 1; + } + } + + for(let i = 0; i < fires_right.length; i++) + { + oldX = fires_right[i].x; + fires_right[i].x += 1; + if(oldX == fires_right[i].x) + { + fires_right[i].type = "l"; + fires_right[i].x -= 1; + } + } + + for(let i = 0; i < fires_up.length; i++) + { + oldY = fires_up[i].y; + fires_up[i].y -= 1; + if(oldY == fires_up[i].y) + { + fires_up[i].type = "d"; + fires_up[i].y += 1; + } + } + + for(let i = 0; i < fires_down.length; i++) + { + oldY = fires_down[i].y + fires_down[i].y += 1; + if(oldY == fires_down[i].y) + { + fires_down[i].type = "u"; + fires_down[i].y -= 1; + } + } + + for(let j = 0; j < spridgets.length; j++) + { + objs = getTile(spridgets[j].x, spridgets[j].y) + for(let i = 0; i < objs.length; i++) + { + if(objs[i].type == "u" || objs[i].type == "d" || + objs[i].type == "l" || objs[i].type == "r" ) + { + if(spridgets[j].x == objs[i].x && + spridgets[j].y == objs[i].y) + { + setMap(levels[level]); + } + } + } + } + } +}) diff --git a/games/Journey to the Secret Village.js b/games/Journey to the Secret Village.js new file mode 100644 index 0000000000..0889de51e9 --- /dev/null +++ b/games/Journey to the Secret Village.js @@ -0,0 +1,677 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: Journey to the Secret Village +@author: Abigail Loken +@tags: [] +@addedOn: 2024-12-03 +*/ + + +// START INSTRUCTIONS +// HOW TO PLAY +// Press "W" - to move up +// Press "A" - to move left +// Press "D" - to move right +// Press "S" - to move down + +// If you don't teleport after being on the door, move the character back and try to go on the door again + +// END INSTRUCTIONS + + +const player = "p" + +// START Level One Sprites +const boss = "b" +const backDoor = "d" + + +// END Level One Sprites + + +// START LEVEL TWO - THREE (OLD WOMAN) SPRTIES +const oldWoman = "o" + + +// end LEVEL TWO - THREE (OLD WOMAN) SPRTIES + +// START LEVEL FOUR - ????? Sprites MAZE SPRITES +const wall = "w" +const wall3 = "x" +const wall4 = "z" +const spike = "i" +const gold = "g" +const table = "t" +const table2 = "n" +const floor = "f" +const grass = "v" + + +// END LEVEL FOUR - ????? Maze sprites + + + +setLegend( + [player, bitmap` +.....000000..... +...0099999900... +..099999999990.. +.....000000..... +....00CCCC00.... +....0C0CC0C0.... +....0C0CC0C0.... +....0CCCCCC0.... +....00C33CC0.... +......000000.... +....0000000000.. +........0....... +.......000...... +.......0.00..... +.......0..0..... +......00..0.....`], + [boss, bitmap` +..000000000..... +..000000000..... +..000000000..... +..00CCCC000..... +.000C0C0C00..... +..00C0C0C00..... +..00CCCCC0...... +...0C333C0....0. +00..000000...00. +.0...0770...00.. +.0..007700.00... +..0050770500.... +...05077050..... +.000507705000... +00555077055500.. +00000000000000..`], + [backDoor, bitmap` +................ +................ +.....CCCCC...... +....CCCCCCCCC... +....CCCCCCCCCC.. +...CCCCCCCCCCCC. +CCCCCCCCCCCCCCC. +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCC66CCC +CCCCCCCCCCC66CCC +CCCCCCCCCCC66CCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC`], + [wall, bitmap` +1111111111111111 +1111101111111111 +1011110011111001 +1001111100110011 +1100111111110111 +1110111111100111 +1110011111001111 +1111011110011111 +1101111100111111 +0011111101110011 +1111111111111001 +1111111110011101 +1100011110111101 +0111001100111101 +1001100001111111 +1111111111111111`], + [oldWoman, bitmap` +..LLLLLLLLL..... +..LLLLLLLLL..... +..L000000LL..... +..L0CCCC0LL..... +.LL0C0C0C0L..... +..L0C0C0C0L..... +..L0CCCCC0...... +...0C333C0....0. +00..000000...00. +.0...0880...00.. +.0..008800.00... +..00H0880H00.... +...0H0880H0..... +.000H0880H000... +00HHH0880HHH00.. +00000000000000..`], + [wall3, bitmap` +1111111100000011 +1111111011111101 +1101110111111111 +1101101111111111 +1011101110000011 +1001111111111001 +1111110001111101 +0111001110001101 +1001111111101101 +1111111111001111 +1110011111011111 +1110111011011111 +1001111011101111 +1011100111110011 +1111001111111011 +1111111111111111`], + [wall4, bitmap` +0000000000000000 +LLLLLL00111110LL +LLLLLL00111110LL +0000000000000000 +11110LLLLL011110 +11110LLLLL011110 +0000000000000000 +LLLLLL0111110LL0 +LLLLLL0111110LL0 +0000000000000000 +111110LLLL011110 +111110LLLL011110 +0000000000000000 +LLLL01111110LLL0 +LLLL01111110LLL0 +0000000000000000`], + [spike, bitmap` +................ +................ +................ +................ +......33333..... +.....333333..... +.....333333..... +.....333333..... +.....3333333.... +....33333333.... +....33333333.... +...3333333333... +...3333333333... +..333333333333.. +.33333333333333. +3333333333333333`], + [gold, bitmap` +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666`], + [table, bitmap` +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C +CC0CC0CC0CC0CC0C`], + [table2, bitmap` +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +0000000000000000 +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +0000000000000000 +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +0000000000000000 +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +0000000000000000 +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +0000000000000000 +CCCCCCCCCCCCCCCC`], + [floor, bitmap` +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111`], + [grass, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + + + +) + +setSolids([player, wall, wall3, wall4, table, table2]); + +// START Instructions TEXT + +let test1 = 0; +// let currentLevel = 0; + +if (test1 === 0) { + addText("Go to", { x: 5, y: 2, color: color`3` }); + addText("the boss", { x: 4, y: 3, color: color`3` }); +} + +addText("Press L to ", { x: 4, y: 5, color: color`3` }); +addText(" remove text", { x: 4, y: 6, color: color`3` }); + +onInput("l", () => { + clearText(); +}) + +// END Instructions Text + +let level = 0 +const levels = [ + map` +ffffffff +ffffffff +ffffffff +pfffffff +ffffffff +fffffffd +fnnfnnff +tffbfftf`, // Introduction map + map` +vvvvvvvd +vvvvvvvv +vvvvvvwv +vvvvvvww +pvvvvvvv +vvvvvvov +vwvvvvvv +vwwvvvvv`, // meet old woman + map` +iiiii... +.i....i. +.iii.i.. +pi...i.i +...i.i.. +.iii..i. +.ii..i.. +i.iiii.d`, // maze 1 + map` +i.i.i..p +i.iiii.i +.i.ii..i +d.i...ii +i.i.i.i. +i.i.i..i +i.i.i.ii +i...i..i`, // maze 2 + map` +.i.iiiii +i.iii..d +i.iii.ii +p..ii..i +ii..ii.. +i.i.iii. +iii..... +iiii.i.i`, // maze 3 + map ` +i....iii +idii...i +iiii.i.i +piiiii.. +......i. +.iiiiii. +.i.iiii. +........`, // maze 4 + map` +ii.iiii. +i....... +i.i.iii. +..i.i.i. +piiiiii. +.i....i. +.i...i.d +......ii`, // maze 5 + map` +zggggggz +zggggggz +zzzzggzz +vxvzzzvd +vxxvvvwv +wvvvvvxv +vvvvvvvv +vvvpvvxx`, // secret village + map` +........ +........ +........ +........ +........ +........ +........ +........`, // END Credits + +] + +setMap(levels[level]) + +setPushables({ + [player]: [] +}) + +// START PLAYER MOVEMENT + +onInput("s", () => { + getFirst(player).y += 1 // moves the player down +}) + +onInput("w", () => { + getFirst(player).y -= 1 // moves player up +}) + +onInput("d", () => { + getFirst(player).x += 1 // moves the player right +}) + +onInput("a", () => { + getFirst(player).x -= 1 // moves player left +}) + + +onInput("j", () => { + const currentLevel = levels[level]; // get the original map of the level + if (currentLevel !== undefined) { + clearText(""); + setMap(currentLevel); + } +}); +// START BOSS DIALOGUE FUNCTIONS +function firstBoss() { + addText("Step Back", { x: 4, y: 2, color: color`3` }) + addText("then press ", { x: 4, y: 3, color: color`3` }) + addText("(i)", { x: 4, y: 4, color: color`3` }) + onInput("i", () => { + clearText(); + addText("BOSS: Okay you ", { x: 3, y: 2, color: color`C` }) + addText("may have your", { x: 3, y: 3, color: color`C` }) + addText("Big Break", { x: 3, y: 4, color: color`C` }) + addText("(i) To ", { x: 3, y: 5, color: color`C` }) + addText("Continue", { x: 3, y: 6, color: color`C` }) + secondBoss(); + }) +} + +function secondBoss() { + onInput("i", () => { + clearText(); + addText("BOSS: A little ", { x: 3, y: 1, color: color`C` }) + addText("bird told me", { x: 3, y: 2, color: color`C` }) + addText("that there is a", { x: 3, y: 3, color: color`C` }) + addText("Secret Village", { x: 3, y: 4, color: color`C` }) + addText("to be found", { x: 3, y: 5, color: color`C` }) + addText("(i) To ", { x: 3, y: 6, color: color`C` }) + addText("Continue", { x: 3, y: 7, color: color`C` }) + thirdBoss(); + }) +} + +function thirdBoss() { + onInput("i", () => { + clearText(); + addText("BOSS: it may ", { x: 3, y: 1, color: color`C` }) + addText("be a flop or", { x: 3, y: 2, color: color`C` }) + addText("it may be", { x: 3, y: 3, color: color`C` }) + addText("a story", { x: 3, y: 4, color: color`C` }) + addText("(i) To ", { x: 3, y: 6, color: color`C` }) + addText("Continue", { x: 3, y: 7, color: color`C` }) + fourthBoss(); + }) +} + +function fourthBoss() { + onInput("i", () => { + clearText(); + addText("BOSS: You will ", { x: 3, y: 1, color: color`C` }) + addText("go find the ", { x: 3, y: 2, color: color`C` }) + addText("village", { x: 3, y: 3, color: color`C` }) + addText("and figure", { x: 3, y: 4, color: color`C` }) + addText("out the truth", { x: 3, y: 5, color: color`C` }) + addText("(i) To ", { x: 3, y: 6, color: color`C` }) + addText("Continue", { x: 3, y: 7, color: color`C` }) + + fifthBoss(); + }) +} + +function fifthBoss() { + onInput("i", () => { + clearText(); + addText("BOSS: leave ", { x: 3, y: 1, color: color`C` }) + addText("out the ", { x: 3, y: 2, color: color`C` }) + addText("back door", { x: 3, y: 3, color: color`C` }) + sixthBoss(); + }) + + function sixthBoss() { + onInput("i", () => { + clearText(); + }) + + } + +} + + +// END BOSS DIALOGUE FUNCTIONS + +// START OLDWOMAN DIALOGUE FUNCTIONS + +// START INTRODUCTION +function firstOldWoman() { + addText("Step Back", { x: 4, y: 2, color: color`3` }) + addText("then press ", { x: 4, y: 3, color: color`3` }) + addText("(i)", { x: 4, y: 4, color: color`3` }) + onInput("i", () => { + clearText(); + addText("OldWoman:Hello", { x: 3, y: 2, color: color`H` }) + addText("in order to ", { x: 3, y: 3, color: color`H` }) + addText("find the ", { x: 3, y: 4, color: color`H` }) + addText("secret Village ", { x: 3, y: 5, color: color`H` }) + addText(" you must solve ", { x: 3, y: 6, color: color`H` }) + addText(" 5 mazes ", { x: 3, y: 7, color: color`H` }) + + addText("(i) To ", { x: 3, y: 9, color: color`H` }) + addText("Continue", { x: 3, y: 10, color: color`H` }) + secondOldWoman(); + }) +} + +function secondOldWoman() { + onInput("i", () => { + clearText(); + addText("be careful", { x: 3, y: 2, color: color`H` }) + addText("of those", { x: 3, y: 3, color: color`H` }) + addText("spikes", { x: 3, y: 4, color: color`H` }) + + addText("(i) To ", { x: 3, y: 6, color: color`H` }) + addText("Continue", { x: 3, y: 7, color: color`H` }) + thirdOldWoman(); + }) +} + +function thirdOldWoman() { + onInput("i", () => { + clearText(); + addText("Go through", { x: 3, y: 2, color: color`H` }) + addText("the door", { x: 3, y: 3, color: color`H` }) + addText("to accept", { x: 3, y: 4, color: color`H` }) + addText("the challenge ", { x: 3, y: 5, color: color`H` }) + + addText("(i) To ", { x: 3, y: 7, color: color`H` }) + addText("Continue", { x: 3, y: 8, color: color`H` }) + fourthOldWoman(); + }) +} + +function fourthOldWoman() { + onInput("i", () => { + clearText(); + addText("The door ", { x: 3, y: 2, color: color`H` }) + addText("may need a", { x: 3, y: 3, color: color`H` }) + addText("little nudge", { x: 3, y: 4, color: color`H` }) + addText("to open ", { x: 3, y: 5, color: color`H` }) + + addText("(i) To ", { x: 3, y: 7, color: color`H` }) + addText("Continue", { x: 3, y: 8, color: color`H` }) + fifthOldWoman(); + }) +} + +function fifthOldWoman() { + onInput("i", () => { + clearText(); + addText("step back ", { x: 3, y: 2, color: color`H` }) + addText("and try again", { x: 3, y: 3, color: color`H` }) + addText("if the door", { x: 3, y: 4, color: color`H` }) + addText("won't work ", { x: 3, y: 5, color: color`H` }) + + addText("(i) To ", { x: 3, y: 7, color: color`H` }) + addText("Continue", { x: 3, y: 8, color: color`H` }) + sixthOldWoman(); + }) + +} + +function sixthOldWoman() { + + onInput("i", () => { + clearText(); + }) + +} + + +// END OLDWOMAN DIALOGUE FUNCTIONS + + + + + + +// END PLAYER MOEVEMENT +afterInput(() => { + + + // START INTERACT WITH BOSS + //count the number of tiles with BOSS SPRITE + const bossNumber = tilesWith(boss).length; + // count the number of tile with BOSS SPRITE and player SPRITE + const bossPlayer = tilesWith(boss, player).length; + if ((bossNumber === bossPlayer) && test1 === 0) { + clearText(); + firstBoss(); + } + + // END INTERACT WITH BOSS + + // START Interact with Back Door + //count the number of tiles with BACK DOOR + const backDoorNumber = tilesWith(backDoor).length; + // count the number of tile with Back door and player SPRITE + const backDoorPlayer = tilesWith(backDoor, player).length; + if (backDoorNumber === backDoorPlayer) { + + level = level + 1; + + const currentLevel = levels[level] + if (currentLevel !== undefined) { + setMap(currentLevel); + test1 += 1; + clearText(); + + if (test1 === 1) { + addText("Go to", { x: 5, y: 2, color: color`3` }); + addText("the oldlady", { x: 4, y: 3, color: color`3` }); + addText("Press L to ", { x: 4, y: 5, color: color`3` }); + addText(" remove text", { x: 4, y: 6, color: color`3` }); + + } + + + } + + } + + // END INteract with back door + + // START INTERACT WITH OLDWOMAN + //count the number of tiles with OLDWOMAN SPRITE + const oldWomanNumber = tilesWith(oldWoman).length; + // count the number of tile with OLDWOMAN SPRITE and player SPRITE + const oldWomanPlayer = tilesWith(oldWoman, player).length; + + if (test1 === 1) { + if ((oldWomanNumber === oldWomanPlayer)) { + clearText(); + firstOldWoman(); + + + } + } + + // END INTERACT WTH OLDWOMAN + + + if (tilesWith(player, spike).length >= 1) { + // playTune(caught) + setMap(levels[level]) + + } + if (level === 8) { + addText("Congratulations ", { x: 3, y: 3, color: color`3` }) + addText("You have ", { x: 3, y: 2, color: color`3` }) + addText("discovered ", { x: 3, y: 4, color: color`3` }) + addText("The secret ", { x: 3, y: 5, color: color`3` }) + addText("village ", { x: 3, y: 6, color: color`3` }) + + addText("Thank you ", { x: 5, y: 9, color: color`3` }) + addText("for ", { x: 5, y: 10, color: color`3` }) + addText("playing ", { x: 5, y: 11, color: color`3` }) + } + + +}) diff --git a/games/Reach-The-End_Multiplayer.js b/games/Reach-The-End_Multiplayer.js new file mode 100644 index 0000000000..adea81efe3 --- /dev/null +++ b/games/Reach-The-End_Multiplayer.js @@ -0,0 +1,247 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started +@title: Reach The End Multiplayer +@author: Bluelightning26 +@tags: [] +@addedOn: 2024-11-22 +*/ + +//My first attempt at a Sprig Game! Fight your way to the opposing player's endzone while they push back, the twine will get shorter with more pushes. +//Each Player Gets to freeze the other player five times! Use them wisely! + +//vars + +//players +const player1 = "l" +const player2 = "r" + +//twine +const twine = "t" + +//background +const sky = "s" + +//goal +const goal = "g" + + +//Art +setLegend( + [player1, bitmap` +................ +................ +.......000...... +.......090...... +......0990...... +......09990.0... +....0002920.0... +....0.0999000... +....0.03330..... +......09990..... +.....099990..... +.....09990...... +......000....... +......0.0....... +.....00.00...... +................`], + [player2, bitmap` +................ +................ +.......000...... +.......0H0...... +......0HH0...... +......0HHH0.0... +....0002H20.0... +....0.0HHH000... +....0.08880..... +......0HHH0..... +.....0HHHH0..... +.....0HHH0...... +......000....... +......0.0....... +.....00.00...... +................`], + [twine, bitmap` +................ +................ +................ +................ +..D............C +CDDD.....DD...DC +CCCD....DCCCCDCC +.CCC..CCCC.CCCCC +...CCCCDCC..CCCD +....CC.DCD....D. +........D....... +................ +................ +................ +................ +................`], + [sky, bitmap` +7777777755777777 +7777777755775700 +7555777777775700 +0777770000075777 +0555770000075777 +7555777777775777 +7555777555575777 +7555700555575777 +7777700777777775 +7777777777777777 +7777777755577007 +7555555755577007 +7777770055577777 +7777770055575555 +5555557777770007 +5555557777770007`], + [goal, bitmap` +CCCCC55777777CCC +CCCCC55444737CCC +CLLLC57444737CCC +CCCLL574L473CCCC +CCCCL774L477LLLC +CCCC7754L437CCLC +CCC73354L43777CC +CCC7775444377CCC +CCC7L55444777CCC +CCCCL754447LLLCC +CCCCL554447LCCCC +CCCL75544477CCCC +CCCL75544777CCCC +CCCC75544737CCCC +CCCC75337777CCCC +CCCC755577777CCC`] +) + +//background +let level = 0 +const levels = [map` +gsssssssssg +gsssssssssg +gsltttttrsg +gsssssssssg +rsssssssssl`] +setMap(levels[level]) + +//Game Text +addText("1 v 1", { + x: 7, + y: 1, + color: color`3` +}) + +addText("Go GO GO!", { + x: 8, + y: 4, + color: color`2` +}) + +addText("dont stop!!", { + x: 4, + y: 13, + color: color`2` +}) + +//let the obj get pushed +setPushables({ + [player2]: [twine], + [player1]: [twine], + [twine]: [twine] +}) + +//Pausing +let lpaused = false; +let rpaused = false; +let lcount = 0; +let rcount = 0; + +const maxFreezeCount = 5; + +//Freezing Left +onInput("i", () => { + if (lcount < maxFreezeCount) { + if (!lpaused) { + lcount += 1; + lpaused = true; + setTimeout(() => { + lpaused = false; + }, 500); + } + } +}); + +//Freezing Right +onInput("w", () => { + if (rcount < maxFreezeCount) { + if (!rpaused) { + rcount += 1; + rpaused = true; + setTimeout(() => { + rpaused = false; + }, 500); + } + } +}); + +//Moving to the Left +onInput("d", () => { + + if (lpaused == false) + { + getAll(twine).forEach(twineSprite => { + twineSprite.x += 1 + }) + getFirst(player1).x += 1 + getFirst(player2).x += 1 + } + +}) + +//Moving to the Right +onInput("j", () => { + + if (rpaused == false) + { + getAll(twine).forEach(twineSprite => { + twineSprite.x -= 1 + }) + getFirst(player1).x -= 1 + getFirst(player2).x -= 1 + } + +}) + + + + +//Left Won +afterInput(() => { + if (getFirst(player1).x == 10) + { + console.log("P1 (Left) Wins!") + clearText() + addText("P1 (Left) Wins", + { + x: 0, + y: 4, + color: color`2` + }) + } +}) + +//Right Won +afterInput(() => { + if (getFirst(player2).x == 0) + { + console.log("P2 (Right) Wins!") + clearText() + addText("P2 (Right) Wins!", + { + x: 0, + y: 4, + color: color`2` + }) + } +}) diff --git a/games/RockPaperScissors.js b/games/RockPaperScissors.js new file mode 100644 index 0000000000..79b87eae02 --- /dev/null +++ b/games/RockPaperScissors.js @@ -0,0 +1,195 @@ +/* +@title: RockPaperScissors +@author: Andrea Ivanov +@tags: [] +@addedOn: 2024-12-16 +*/ + + +const player = 'p'; +const rock = 'r'; +const paper = 'a'; +const scissors = 's'; +const door = 'd'; + + +setLegend( + [player, bitmap` +................ +................ +.....00000...... +....0.....0..... +....0.0.0.0..... +....0.....0..... +....0.000.0..... +....0.....0..... +.....00000...... +.......0........ +.....00000...... +.......0........ +.......0........ +......0.0....... +.....0...0...... +................`], + [door, bitmap` +................ +......8888...... +.....888888..... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +....88888888.... +................`] +); + +setMap(map` +.p............d`); + + +let gameRunning = true; +let playerChoice = null; +let botChoice = null; +let choices = ['r', 'a', 's']; +let score = 0; +let streak = 0; +let level = 1; + + +onInput('w', () => makeChoice('r')); +onInput('s', () => makeChoice('a')); +onInput('d', () => makeChoice('s')); + + +function makeChoice(choice) { + if (!gameRunning) return; + gameRunning = false; + playerChoice = choice; + botChoice = choices[Math.floor(Math.random() * 3)]; + resolveGame(); +} + + +function resolveGame() { + clearText(); + clearText(); + if (!playerChoice || !botChoice) return; + + let result = ""; + let playerSprite = getFirst(player); + + if (playerChoice === botChoice) { + result = ("Tie! -_-"); + updatePrText('tie'); + + resultColor = color`6`; + } else if ( + (playerChoice === 'r' && botChoice === 's') || + (playerChoice === 'a' && botChoice === 'r') || + (playerChoice === 's' && botChoice === 'a') + ) { + result = "You won >:( !"; + updatePrText('win'); + resultColor = color`7`; + score++; + streak++; + playerSprite.x += 1; + if (playerSprite.x === 14) { + playerSprite.remove(); + addSprite(1, 0, player); + } + } else { + result = "You lost!"; + updatePrText('lose'); + resultColor = color`3`; + playerSprite.x = 1; + streak = 0; + + } + + + if (playerSprite.x === 14) { + level++; + playerSprite.x = 1; + score = 0; + streak = 0; + updateText(`Level ${level}!`, color`6`); + setTimeout(() => { + displayInstructions(); + gameRunning = true; + }, 2500); + return; + } + + updateText(`You chose ${getChoiceName(playerChoice)}. Bot chose ${getChoiceName(botChoice)}.`, resultColor); + addText(result, { x: 5, y: 6, color: resultColor }); + setTimeout(() => { + clearText(); + displayInstructions(); + gameRunning = true; + }, 2500); + resetGame(); +} + + +function getChoiceName(choice) { + if (choice === 'r') return 'Rock'; + if (choice === 'a') return 'Paper'; + if (choice === 's') return 'Scissors'; +} + +function resetGame() { + + playerChoice = null; + botChoice = null; + setTimeout(() => { + displayInstructions(); + }, 2500); +} + +function updatePrText(outcome) { + const texts = { + win: ["Not bad...!", "Luck!", "Impossible!"], + lose: ["Try Again", "Try harder!"], + tie: ["That's all?", "Seriously?", "Wow"] + }; + + const randomText = texts[outcome][Math.floor(Math.random() * texts[outcome].length)]; + addText(randomText, { x: 0, y: 14, color: color`1` }); +} + + +function updateText(message, colorCode) { + + const lines = message.split('. '); + lines.forEach((line, index) => { + addText(line, { x: 0, y: index, color: colorCode }); + }); + + addText(`Score: ${score}`, { x: 0, y: 10, color: color`2` }); + addText(`Streak: ${streak}`, { x: 0, y: 11, color: color`2` }); + addText(`Level: ${level}`, { x: 0, y: 12, color: color`2` }); +} + +function displayInstructions(resetColor = false) { + addText('Press W for Rock', { x: 0, y: 0, color: color`3` }); + addText('Press S for Paper', { x: 0, y: 1, color: color`4` }); + addText('Press D for Scissors', { x: 0, y: 2, color: color`5` }); + addText("Ready?", { x: 0, y: 6, color: color`3` }); + addText("!", { x: 19, y: 6, color: color`6` }); + const scoreColor = color`2`; + addText(`Score: ${score}`, { x: 0, y: 10, color: scoreColor }); + addText(`Streak: ${streak}`, { x: 0, y: 11, color: scoreColor }); + addText(`Level: ${level}`, { x: 0, y: 12, color: scoreColor }); +} + +clearText(); +displayInstructions(); + diff --git a/games/Saving-Blob.js b/games/Saving-Blob.js new file mode 100644 index 0000000000..49aad8b8c7 --- /dev/null +++ b/games/Saving-Blob.js @@ -0,0 +1,292 @@ +/* +@title: Saving Blob +@author: ARTISM30 +@tags: [] +@addedOn: 2024-11-12 +*/ + +// define the sprites in our game +const player = "p"; +const blob = "b"; +const portal = "g"; +const wall = "w"; +const fake = "f"; +const copy = "c"; + +// assign bitmap art to each sprite +setLegend( + [ player, bitmap` +................ +................ +...100....001... +......0..0...... +....00000000.... +....0......0.... +....044..440.... +....08....80.... +....0.L..L.0.... +....0..LL..0.... +....00000000.... +......0...0..... +....000...000... +................ +................ +................`], + [ blob, bitmap` +................ +................ +................ +...88888888888.. +...88888888888.. +...88222822288.. +...882FF8FF288.. +...882FF8FF288.. +...88888888888.. +...88888888888.. +...888H888H888.. +...8888HHH8888.. +...88888888888.. +...88888888888.. +................ +................`], + [ portal, bitmap` +..333333333333.. +.39999999999993. +3966666666666693 +9644444444444469 +6455555555555546 +45HHHHHHHHHHHH54 +5H222222222222H5 +H22222222222222H +H22222222222222H +5H222222222222H5 +45HHHHHHHHHHHH54 +6455555555555546 +9644444444444469 +3966666666666693 +.39999999999993. +..333333333333..`], + [ wall, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [ fake, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +L00000000000000L`], + [ copy, bitmap` +..333333333333.. +.39999999999993. +3966666666666693 +9644444444444469 +6455555555555546 +45HHHHHHHHHHHH54 +5H222222222222H5 +H22222222222222H +H22222222222222H +5H222222222222H5 +45HHHHHHHHHHHH54 +6455555555555546 +9644444444444469 +3966666666666693 +.39999999999993. +..333333333333..`], +); +// create game levels +let level = 0; // this tracks the level we are on +const levels = [ + map` +.....w... +.....wg.. +p..b.ww.. +...ww.... +...w..... +......... +.........`, + map` +...ww....g +..bw...www +p......wg. +......ww.. +...b.ww... +.......... +..........`, + map` +p..w... +.b.w... +...f.g. +wwww... +....... +.......`, + map` +....... +fwwww.. +p...w.. +....fb. +....w.. +g...w..`, + map` +pw..... +fw...f. +....wgw +.w...w. +fbf.... +.w.....`, + map` +..f.... +..fb... +wfwwfww +.pw.... +..w.... +.wwfw.. +ww.g.w.`, + map` +........wwwwwwww +........fffffffw +ffwwww..wwwffffg +..pw.f........w. +.b.f.w........w. +...f.w........w.`, + map` +....... +pb..... +..w...f +..f.w.f +...wgf. +..f.w.w +..f...w`, + map` +..wwffwwwwww +..ffffwwwwww +p.wwwfwwwffg +..wwffwwwffw +.bwwfffffffw +..wwwwwwwffw`, + map` +p..f.w... +.bbw.w... +...f.fw.. +wfww.ffwg +.....fw.. +.....w... +fw...f... +gw...w...`, + map` +...wf.. +.p.w.w. +.bww.w. +ffw.fwf +...ff.f +wf.w.wf +.fww.w. +.fw...g`, + map` +..ffffwwwwgfffffw +.pwfbfffffffffffw +..wwwwgwwwwffffww +.bffwwfwffffbwwff +..fffffwfwwffffff +..wfbffffgwwwwwwg`, + map` +wwwwwwwww +w.p.p...w +wp.p..p.w +wpp..p..w +w.p.p...w +w.......w +wwwwwwwww` +]; + +// set the map displayed to the current level +const currentLevel = levels[level]; +setMap(currentLevel); + +setSolids([ player, blob, wall ]); // other sprites cannot go inside of these sprites + +// allow certain sprites to push certain other sprites +setPushables({ + [player]: [blob], + [blob]: [blob] +}); + +// inputs for player movement control +onInput("s", () => { + getFirst(player).y += 1; // positive y is downwards +}); + +onInput("d", () => { + getFirst(player).x += 1; +}); + + onInput("w", () => { + getFirst(player).y -= 1; +}); + +onInput("a", () => { + getFirst(player).x -= 1; + +}); + +// input to reset level +onInput("j", () => { + const currentLevel = levels[level]; // get the original map of the level + + // make sure the level exists before we load it + if (currentLevel !== undefined) { + clearText(""); + setMap(currentLevel); + } +}); + +// these get run after every input +afterInput(() => { + // count the number of tiles with portals + const targetNumber = tilesWith(portal).length; + + // count the number of tiles with portals and blobs + const numberCovered = tilesWith(portal, blob).length; + + // if the number of portals is the same as the number of portals covered + // all portals are covered and we can go to the next level + if (numberCovered === targetNumber) { + // increase the current level number + level = level + 1; + + const currentLevel = levels[level]; + + // make sure the level exists and if so set the map + // otherwise, we have finished the last level, there is no level + // after the last level + if (currentLevel !== undefined) { + setMap(currentLevel); + } else { + addText("Blob has made it back home!", { y: 4, color: color`3` }); + } + } +}); diff --git a/games/Shapes-That-Go-Portable.js b/games/Shapes-That-Go-Portable.js new file mode 100644 index 0000000000..e2a1677b68 --- /dev/null +++ b/games/Shapes-That-Go-Portable.js @@ -0,0 +1,776 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: Shapes_That_Go +@author: Parritz +@tags: [] +@addedOn: 2024-11-23 +*/ + +const playerChar = "p" +const squareChar = "s" +const pogChar = "o" +const bounceChar = "b" +const spikeChar = "i" +const upsideDownSpikeChar = "u" +const levelX = 12 +const levelY = 9 +let gameStarted = false +let gameEnded = false + +// Define sprites +setLegend( + [playerChar, bitmap` +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333`], + [squareChar, bitmap` +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555`], + [pogChar, bitmap` +....00000000.... +...0111111110... +..011111111110.. +.01111111111110. +0111111555111110 +0111115111511110 +0111115111511111 +0111115111511110 +0111115555111110 +0111115111111110 +0111115111111110 +0111115111111110 +.01111111111110. +..011111111110.. +...0111111110... +....00000000....`], + [bounceChar, bitmap` +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444`], + [spikeChar, bitmap` +................ +.......66....... +......6666...... +......6666...... +.....666666..... +.....666666..... +....66666666.... +....66666666.... +...6666666666... +...6666666666... +..666666666666.. +..666666666666.. +.66666666666666. +.66666666666666. +6666666666666666 +6666666666666666`], + [upsideDownSpikeChar, bitmap` +6666666666666666 +6666666666666666 +.66666666666666. +.66666666666666. +..666666666666.. +..666666666666.. +...6666666666... +...6666666666... +....66666666.... +....66666666.... +.....666666..... +.....666666..... +......6666...... +......6666...... +.......66....... +................`], +) + +/// Levels + +const startingChunk = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1,1,0,0,0,1,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk2 = [ + [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk3 = [ + [0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,7,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,1,1,0,1,0,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk4 = [ + [0,0,0,0,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,5,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk5 = [ + [0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0], + [0,0,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk6 = [ + [0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,2,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk7 = [ + [1,1,1,1,1,1,1,1,1,1,1,3,3,3,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,7,7,7,0,0,0,0,0,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,1,1,1,1,1,4,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,4,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,0,0,0,7,7,6,8,7,7,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk8 = [ + [0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,4,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0], + [0,0,0,0,0,0,0,0,0,0,7,7,7,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,7,7,5,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0], + [1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk9 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,4,4,1,1,1,1,1,1,1,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0], + [0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,0], + [0,0,7,7,7,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,7,7,8,8,7,7,7,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk10 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,8,7,7,7,7,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,7,7,6,7,7,0,0], + [0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0], + [0,0,0,0,0,0,7,0,0,7,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk11 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,0,0,0], + [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,1,0,0], + [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,1,0,0], + [0,0,7,7,7,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,7,7,7,7,0,0,0,1,1,1,0,8,8,1,0,0], + [1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk12 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,0,2,0,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1] +]; + +chunk13 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,6,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1] +]; + +chunk14 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,1,1,1,1,1,1,1,7,7,7,8,7,7,7,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +chunk15 = [ + [0,0,0,0,0,0,0,0,1,1,1,1,1,4,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0], + [0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,7,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], + [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1] +]; + +chunk16 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], + [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3], + [0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2], + [0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], + [0,0,0,0,0,0,0,0,0,0,1,7,7,1,0,0,0,7,7,7,7,0,0,0,0,0,0,0,1,7,7,7,7,7,7,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +]; + +chunk17 = [ + [0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1], + [1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2], +]; + +chunk18 = [ + [0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,3,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,2,2,0,0,7,7,0,0,8,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +]; + +chunk19 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +]; + +chunk20 = [ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], +]; + +bonus = [ + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], + [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +]; + +const chunks = [chunk2,chunk2,chunk3,chunk4,chunk5,chunk6,chunk7,chunk8,chunk9,chunk10, chunk11,chunk12,chunk13, chunk14, chunk15, chunk16, chunk17, chunk18, chunk19, chunk20, bonus]; + +let level = 0 +const levels = { + game: map` +............ +.p.......... +............ +............ +............ +............ +............ +............ +............ +............`, + gameOver: map` +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp +ppppppppppp` +} + +setMap(levels.game) + +// Get the player then set some values +let player = getFirst(playerChar) +let isJumping = false +let jumpingStage = 0 +let gravityFlipped = false +let playerYVelocity = 0 + +let score = 0 +function setScore(score) { + clearText() + addText("Score: " + score, { + x: 1, + y: 1, + color: color`0` + }) +} + +function scrollLevel(player) { + const obstacles = [ + ...getAll(squareChar), + ...getAll(spikeChar), + ...getAll(upsideDownSpikeChar) + ] + const bounces = getAll(bounceChar) + const pogs = getAll(pogChar); + + // Handle obstacles + for (const obstacle of obstacles) { + const nextXPosition = obstacle.x - 1; + + // Handle collision + // If the next position of the obstacle is the player, then end the game + if (nextXPosition == player.x && obstacle.y == player.y) { + endGame() + } else { + if (obstacle.x == 0) { + clearTile(0, obstacle.y); + } + } + + obstacle.x = nextXPosition; + } + + // Handle pogs + for (const pog of pogs) { + const nextXPosition = pog.x - 1; + + // Handle collision + if (nextXPosition == player.x && pog.y == player.y) { + score += 1000 + clearTile(pog.x, pog.y) + } else { + if (pog.x == 0) { + clearTile(0, pog.y) + } + } + pog.x = nextXPosition + } + + for (const bounce of bounces) { + const nextXPosition = bounce.x - 1; + + // Handle collision + let isAffected = (gravityFlipped ? bounce.y + 1 : bounce.y - 1) == player.y; + if (nextXPosition == player.x && isAffected) { + playerYVelocity = 6 + } else { + if (bounce.x == 0) { + clearTile(0, bounce.y) + } + } + + bounce.x = nextXPosition + } +} + +function getRandomInt(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function getRandomChunk() { + const randomNumber = getRandomInt(0, chunks.length); + return chunks[randomNumber]; +} + +let chunkPassed = true +let currentChunk = null +let streamedChunkX = 0; +let streamedChunkY = 0; + +function loadChunk(chunk, isPartialStream) { + if (!chunk) { + return; + } + + if (chunk[0].length > levelX) { + // Stream the chunk as it overflows on the x-axis + chunkPassed = false; + + if (isPartialStream) { + // Load as much as possible from left to right + for (let chunkY = 0; chunkY < chunk.length; chunkY++) { + if (chunkY > levelY) { + continue; + } + + for (let chunkX = 0; chunkX < Math.min(levelX, chunk[0].length); chunkX++) { + if (chunk[chunkY][chunkX] == 1) { + addSprite(chunkX, chunkY, squareChar); + } + } + } + } else { + // Normal streaming logic + for (let chunkY = 0; chunkY < chunk.length; chunkY++) { + if (chunkY > levelY) { + continue; + } + + if (!gameEnded) { + switch (chunk[chunkY][streamedChunkX]) { + case 1: { + addSprite(levelX - 1, chunkY, squareChar); + break; + } + case 2: { + addSprite(levelX - 1, chunkY, spikeChar); + break; + } + case 3: { + addSprite(levelX - 1, chunkY, upsideDownSpikeChar); + break; + } + case 4: { + addSprite(levelX - 1, chunkY, bounceChar); + break; + } + case 7: { + addSprite(levelX - 1, chunkY, pogChar); + break; + } + } + + } + } + + if (streamedChunkX == chunk[0].length - 1) { + streamedChunkX = 0; + chunkPassed = true; + } else { + streamedChunkX += 1; + } + } + } else { + // Level does not overflow, we're safe to load the full thing + for (let y = 0; y < chunk.length; y++) { + for (let x = 0; x < chunk[y].length; x++) { + // Check if the value is non-zero and within the x limit + if (chunk[y][x] == 1 && x < levelX) { + addSprite(x, y, squareChar); + } + } + } + } +} + +function isPlayerOnGround(player, isGravityFlipped) { + const yPosToCheck = isGravityFlipped ? player.y - 1 : player.y + 1; + const tiles = getTile(player.x, yPosToCheck); + if (tiles != "") { + switch (tiles[0]._type) { + case "s": { + return true; + } + case "b": { + return true; + } + case "i": { + return false; + } + case "u": { + return false; + } + } + } + return false; +} + +// Set default score +setScore(0) + +addText("Up to start", { + x: 1, + y: 3, + color: color`0` +}) + +/// Game loop +function beginGameLoop() { + // Load map + setMap(levels.game) + + // Get the player then set some values + player = getFirst(playerChar); + isJumping = false; + gravityFlipped = false; + score = 0; + jumpingStage = 0; + playerYVelocity = 0; + gameStarted = true; + gameEnded = false; + + // Reset chunk data + chunkPassed = true + currentChunk = null + streamedChunkX = 0; + streamedChunkY = 0; + + // Load starting level + loadChunk(startingChunk, true) + currentChunk = startingChunk + + const gameInterval = setInterval(() => { + if (player) { + // Apply gravity or jumping logic + if (!isPlayerOnGround(player, gravityFlipped) && !isJumping) { + // Gravity pulls the player down + player.y += gravityFlipped ? -1 : 1; + } else if (isJumping) { + // Jumping logic with stages for smoother ascent and descent + if (jumpingStage == 0) { + player.y -= gravityFlipped ? -2 : 2; // Strong initial jump + } else if (jumpingStage == 1) { + player.y -= gravityFlipped ? -1 : 1; // Mid-air slowdown + } else if (jumpingStage == 2) { + player.y -= gravityFlipped ? 0 : 0; // Pause briefly at the top + } + + jumpingStage += 1; + + // End jump after 3 stages + if (jumpingStage >= 3) { + isJumping = false; + jumpingStage = 0; + } + } + + if (player.y == levelY || player.y == 0) { + endGame() + } + } + + // Handle player y velocity + if (playerYVelocity > 0) { + player.y -= gravityFlipped ? -2 : 2; + playerYVelocity -= playerYVelocity >= 2 ? 2 : 1; + } + + if (gameStarted) { + // Load next chunk + const chunk = chunkPassed ? getRandomChunk() : currentChunk; + if (chunkPassed) { + currentChunk = chunk + } + + scrollLevel(player) + loadChunk(chunk) + + // Add to the player's score + score += 100 + setScore(score) + } + + if (gameEnded) { + // End the game loop + clearInterval(gameInterval); + + // Game over screen text + addText("Game Over", { + x: 5, + y: 6, + color: color`0` + }); + + addText("Up to reset", { + x: 4, + y: 8, + color: color`0` + }); + } + }, 65) + + return gameInterval +} + +// Create the game loop +let gameInterval = beginGameLoop() + +// Handle game end +function endGame() { + gameEnded = true; + gameStarted = false; + setMap(levels.gameOver); +} + +// Handle game restarting +function restartGame() { + gameInterval = beginGameLoop() +} + +/// User input + +// Handle game starting +onInput("w", () => { + if (!gameStarted && !gameEnded) { + // Begin the game + gameStarted = true; + clearText() + } else if (gameEnded) { + // Restart the game + restartGame() + } +}) + +// Handle jumping +onInput("s", () => { + if (!isJumping && isPlayerOnGround(player, gravityFlipped)) { + isJumping = true + } +}) + +// Handle gravity flipping +onInput("k", () => { + if (isPlayerOnGround(player, gravityFlipped)) { + gravityFlipped = !gravityFlipped; + } +}) \ No newline at end of file diff --git a/games/Simple-Platformer.js b/games/Simple-Platformer.js new file mode 100644 index 0000000000..92755d9e65 --- /dev/null +++ b/games/Simple-Platformer.js @@ -0,0 +1,359 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: Platformer +@author: Adam Xu +@tags: [] +@addedOn: 2025-01-03 +*/ + +const player = "p" +const grass = "g" +const platform = "c" +const platform_left = "l" +const platform_right = "r" +const end_1 = "e" +const end_2 = "f" +const sky = "s" +const dirt = "d" + +setLegend( + [ player, bitmap` +......0000...... +.....002200..... +.....022220..... +.....022200..... +.....00220...... +......0000...... +.......L0....... +.......L0....... +.......0L....... +.......0L....... +.......0L....... +.......00....... +.......0.0...... +......0..0...... +......0..0...... +......0..0......` ], + [ platform, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDCDDDDDDDCDCDD +CCDCCCDCDDCCCCCD +CCCCCCCCCCCCCCCC +CC9CCCCCCC9CCCCC +9CCCCCC9CCCCC9CC +CCCCCCCCCCCCCCCC +................ +................ +................ +................ +................ +................ +................ +................` ], + [ platform_left, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDCDDDDDDDCDCDD +CCDCCCDCDDCCCCCD +.CCCCCCCCCCCCCCC +.CCC9CCCCC9CCCCC +..CCCCC9CCCCC9CC +....CCCCCCCCCCCC +................ +................ +................ +................ +................ +................ +................ +................` ], + [ platform_right, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDCDDDDDDDCDCDD +CCDCCCDCDDCCCCCD +CCCCCCCCCCCCC9C. +CC9CCCCCCC9CCCC. +9CCCCCC9CCCCCC.. +CCCCCCCCCCCC.... +................ +................ +................ +................ +................ +................ +................ +................` ], + [ grass, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDCDDDDDDDCDCDD +CCDCCCDCDDCCCCCD +CCCCCCCCCCCCCCCC +CCCCCCCCCC9CCCCC +CC9CCC9CCCCCC9CC +CCCCCCCCCCCCCCCC +CCCCCCCC9CCCCCCC +CCCCCCCCCCCCC9CC +C9CCC9CCCCCCCCCC +CCCCCCCCCCCCCCCC +CCC9CCCC9CCC9CCC +9CCCCCCCCCCCCCC9 +CCCCCCCCCCCCCCCC +CCCCC9CCCCC9CCCC` ], + [ dirt, bitmap` +CCCC9CCCCCCCCCCC +C9CCCCCCC9CCCCCC +CCCCCCCCCCCCCC9C +CCCC9CCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCC9CCCCC +CC9CCC9CCCCCC9CC +CCCCCCCCCCCCCCCC +CCCCCCCC9CCCCCCC +CCCCCCCCCCCCC9CC +C9CCC9CCCCCCCCCC +CCCCCCCCCCCCCCCC +CCC9CCCC9CCC9CCC +9CCCCCCCCCCCCCC9 +CCCCCCCCCCCCCCCC +CCCCC9CCCCC9CCCC` ], + [ end_1, bitmap` +....57777775.... +...5775555777... +..755555555577.. +.75577777555577. +7577755577755575 +5575557777755577 +5755577557775557 +7755775757575577 +7555755775575575 +7755775555775775 +5755577777755755 +5575555555557757 +.55775555557757. +..557775777555.. +...5557775555... +....77777777....` ], + [ end_2, bitmap` +....77777777.... +...5557775555... +..557775777555.. +.55775555557757. +5575555555557757 +5755577777755755 +7755775555775775 +7555755775575575 +7755775757575577 +5755577557775557 +5575557777755577 +7577755577755575 +.75577777555577. +..755555555577.. +...5775555777... +....57777775....` ], + [ sky, bitmap` +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272 +2727272727272727 +7272727272727272` ], +) + +// setBackground(sky) + +setSolids([player, grass, platform, platform_left, platform_right, dirt]) + +let level = 0 +const levels = [ + map` +.......... +.......... +.......... +.lccccr... +.......... +.......... +.p......e. +gggggggggg`, + map` +.......... +.......... +.........e +........lr +.....lr... +.......... +p..lr..... +gg........`, + map` +p......... +ggr....... +dd..lr.... +dd.......e +dd......lg +dd.......d +dd.......d +dd.......d`, + map` +.......... +p......... +g..gcccr.. +d..d...... +d..de....l +d..dcr.... +d..d...... +d..d......`, + map` +e......... +r......... +.......... +cr....lr.. +.......... +.........l +p......... +ggg....ggg`, + map` +g........g +d........d +d...p....d +.lccccccr. +.........e +.......... +.......... +..........` +] + +setMap(levels[level]) + +setPushables({ + [ player ]: [] +}) + +addText(" W^", { + x: 3, + y: 4, + color: color`D` +}) + +isJumping = false; +isDied = false; + +function gravity() { + let prev_y = getFirst(player).y; + const gravity_interval = setInterval(function() { + if (isDied) { + clearInterval(gravity_interval); + return; + } + prev_y = getFirst(player).y; + getFirst(player).y += 1; + if (getFirst(player).y == prev_y) { + clearInterval(gravity_interval); + isJumping = false; + } else if (getFirst(player).y == 7) { + clearInterval(gravity_interval); + isDied = true; + setMap(map` +.......... +.......... +.......... +.......... +.......... +cccccccccc +.......... +..........`); + addText("You Died", { + x: 6, + y: 7, + color: color`D` + }); + return; + } + after_move(); + }, 250); + // clearInterval(gravity_interval); +} + +onInput("w", () => { + if (!isDied) { + if (!isJumping) { + isJumping = true + getFirst(player).y -= 1; + setTimeout(function(){ getFirst(player).y -= 1;}, 50); + setTimeout(gravity, 100); + } + } +}); +onInput("a", () => { + if (!isDied) { + getFirst(player).x -= 1; + if (!isJumping) gravity(); + } +}); +onInput("d", () => { + if (!isDied) { + getFirst(player).x += 1; + if (!isJumping) gravity(); + } +}); + +function after_move() { + if (tilesWith(player, end_1).length == 1 || tilesWith(player, end_2).length == 1) { + level = level + 1; + + const currentLevel = levels[level]; + + if (currentLevel !== undefined) { + setMap(currentLevel); + animation = false; + clearText(); + if (level == 5) { + addText("Thanks for playing!", { + x: 1, + y: 14, + color: color`D` + }) + } + } + } +} + +afterInput(() => { + after_move(); +}) + +var animation = false + +const portal_animate = setInterval(function() { + if (!isDied) { + if (animation) { + animation = false + let tmp = getFirst(end_2) + clearTile(tmp.x, tmp.y) + addSprite(tmp.x, tmp.y, end_1) + } else { + animation = true + let tmp = getFirst(end_1) + clearTile(tmp.x, tmp.y) + addSprite(tmp.x, tmp.y, end_2) + } + } else { + clearInterval(portal_animate); + } +}, 250); + + + diff --git a/games/Sprong.js b/games/Sprong.js new file mode 100644 index 0000000000..49188ac41e --- /dev/null +++ b/games/Sprong.js @@ -0,0 +1,341 @@ +/* +@title: Sprong +@author: Licnex +@tags: ['retro', 'endless', 'multiplayer'] +@addedOn: 2024-11-12 +*/ + +let singlePlayer = false; + +const player1 = "1"; +const player2 = "2"; +let player1Score = 0; +let player2Score = 0; +const background = "b" + +const playerSpeed = 4; +let aiSpeed = 3; + +let aiMoving = false; + +const ball = "o"; +let ballDx = 0; +let ballDy = 0; +const hitSound1 = tune` +133.92857142857142: g4~133.92857142857142, +4151.785714285714` +const hitSound2 = tune` +500: a4-500 + f4-500, +15500` +let soundOne = true; +const pointSound = tune` +416.6666666666667: c5-416.6666666666667 + e5-416.6666666666667 + g5-416.6666666666667, +416.6666666666667: c5-416.6666666666667 + e5-416.6666666666667 + g5-416.6666666666667, +416.6666666666667: a5-416.6666666666667 + d5-416.6666666666667 + f5-416.6666666666667, +12083.333333333334` +const loseSound = tune` +211.26760563380282: a4-211.26760563380282, +211.26760563380282: f4-211.26760563380282, +211.26760563380282: c4-211.26760563380282, +6126.760563380281` + +setLegend( + [player1, bitmap` +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222....... +...222222.......`], + [player2, bitmap` +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222... +.......222222...`], + [background, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [ball, bitmap` +................ +....22222222.... +...2222222222... +..222222222222.. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +.22222222222222. +..222222222222.. +...2222222222... +....22222222.... +................`] +); + +setBackground(background); + +setSolids([player1, player2]); + +let level = 0; +const levels = [ + map` +..... +..... +.....`, + map` +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +.1.......................................................2. +.1.......................................................2. +.1...........................o...........................2. +.1.......................................................2. +.1.......................................................2. +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +........................................................... +...........................................................`, +]; + +function menu() { + setMap(levels[level]) + clearText(); + addText("Select Game Mode:", { y: 5, color: color`2` }); + addText("A. Single Player", { y: 8, color: color`2` }); + addText("L. Multiplayer", { y: 10, color: color`2` }); + + onInput("a", () => { + if (level === 0) { + singlePlayer = true; + aiMoving = true + level += 1 + setMap(levels[level]); + clearText(); + } + }); + + onInput("l", () => { + if (level === 0) { + singlePlayer = false; + aiMoving = false + level += 1 + setMap(levels[level]); + clearText(); + } + }); +} + +menu(); +setTimeout(() => { + ballDx = Math.random() < 0.5 ? -1 : 1; + ballDy = Math.random() < 0.5 ? -2 : 2; +}, 1000); + + +onInput("w", () => { + getAll(player1).forEach(p => { + p.y -= playerSpeed; + }) +}); + +onInput("s", () => { + getAll(player1).reverse().forEach(p => { + p.y += playerSpeed; + }) +}); +onInput("i", () => { + getAll(player2).forEach(p => { + if (singlePlayer === false) { + p.y -= playerSpeed; + } + }) +}); + +onInput("k", () => { + getAll(player2).reverse().forEach(p => { + if (singlePlayer === false) { + p.y += playerSpeed; + } + }) +}); + +setPushables({ + [player1]: [player1], + [player2]: [player2] +}); + +function dist(x1, y1, x2, y2) { + const dx = x1 - x2; + const dy = y1 - y2; + return Math.sqrt(dx * dx + dy * dy) +} + +function writeScore() { + clearText() + addText(`${player1Score} - ${player2Score}`, { + y: 1, + color: color`2` + }); +} + +function restart(sprite) { + if (level > 0) { + writeScore() + ballDx = 0; + ballDy = 0; + sprite.x = Math.round(width() / 2); + sprite.y = Math.round(height() / 2); + setTimeout(() => { + ballDx = Math.random() < 0.5 ? -1 : 1; + ballDy = Math.random() < 0.5 ? -2 : 2; + }, 1000); + } +} + +function makeSound() { + if (soundOne) { + playTune(hitSound1); + } else { + playTune(hitSound1); + } + soundOne = !soundOne +} +setInterval(() => { + if (level > 0) { + const sprite = getFirst(ball); + sprite.x += ballDx; + sprite.y += ballDy; + + if (sprite.y >= height() - 2) { + ballDy = Math.abs(ballDy) * -1; + makeSound() + } else if (sprite.y <= 2) { + ballDy = Math.abs(ballDy); + makeSound() + } + const isPast = (s) => { + const d = dist(sprite.x, sprite.y, s.x, s.y); + return d >= 1 && d <= 2; + } + if (getAll(player2).some(isPast) && ballDx > 0) { + ballDx = ballDx * -1; + makeSound() + } else if (sprite.x >= width() - 1) { + player1Score += 1; + playTune(pointSound); + restart(sprite) + } + if (getAll(player1).some(isPast) && ballDx < 0) { + ballDx = ballDx * -1; + makeSound() + } else if (sprite.x <= 1 & singlePlayer === true) { + player2Score += 1; + playTune(loseSound); + restart(sprite) + } else if (sprite.x <= 1 & singlePlayer === false) { + player2Score += 1; + playTune(pointSound); + restart(sprite) + } + } +}, 60) + +let aiYValues; +setInterval(() => { + if (level > 0 && singlePlayer === true) { + const sprite = getFirst(ball); + if (ballDx < 0) { + aiSpeed = 1; + } else { + aiSpeed = 2; + } + + if (aiMoving) { + if ((Math.random() * 100) < 40) { + aiMoving = false; + setTimeout(() => { + aiMoving = true; + }, 40); + }; + } + if (!aiMoving) return; + + aiYValues = getAll(player2).map(e => e.y); + if (Math.min(...aiYValues) > sprite.y) { + getAll(player2).forEach(p => { + p.y -= 2; + }) + } else if (Math.max(...aiYValues) < sprite.y) { + getAll(player2).reverse().forEach((p, i) => { + p.y += 2; + }) + } + } +}, 10) \ No newline at end of file diff --git a/games/StickRunner.js b/games/StickRunner.js index 12a129318e..d19a4984cb 100644 --- a/games/StickRunner.js +++ b/games/StickRunner.js @@ -282,7 +282,6 @@ hghghghghghghghghghghghghghghg`, x: 1, y: 5, }) - } addText("" + score, { x: 1, y: 5, diff --git a/games/The-Floor-Is-Lava.js b/games/The-Floor-Is-Lava.js new file mode 100644 index 0000000000..62ba5566c8 --- /dev/null +++ b/games/The-Floor-Is-Lava.js @@ -0,0 +1,410 @@ +/* +@title: The Floor is Lava +@author: Knaifu0030 +@tags: [] +@addedOn: 2024-12-18 +*/ +// Define sprites +const player = "p"; +const lava = "l"; +const preLava = "r"; // Lava warning state +const couch = "c"; +const table = "t"; +const snack = "s"; +const goal = "g"; +const addTime = "a"; // Adds 2 seconds +const removeTime = "t"; // Removes 3 seconds +const debris = "d"; // Temporary obstacle + +setLegend( + [player, bitmap` +.3333........... +CCC206.......... +CCCCC6.......... +.CCCC........... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [lava, bitmap` +.9999........... +999999.......... +.9999........... +999999.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [preLava, bitmap` +1.1.1........... +.1.1............ +1.1.1........... +.1.1............ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [couch, bitmap` +CCCCCC.......... +CCCCCC.......... +CCLLCC.......... +CCLLCC.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [table, bitmap` +CCCCCC.......... +CFFFFC.......... +CFFFFC.......... +CCCCCC.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [snack, bitmap` + .555. + 55555 + .555. + `], + [goal, bitmap` +363636.......... +636363.......... +363636.......... +636363.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [addTime, bitmap` + ..... + .333. + .323. + .333. + ..... + `], + [removeTime, bitmap` + ..... + .444. + .424. + .444. + ..... + `], + [debris, bitmap` + 99999 + 99999 + 99999 + 99999 + `] +); + +// Game reset function with random furniture and levels +let currentLevel = 1; +let gameWon = false; +let gameOver = false; +let goalUnlocked = false; +let furnitureTimers = {}; +let timeLeft = 30; + +function resetGame() { + clearText(); + gameWon = false; + gameOver = false; + goalUnlocked = false; + furnitureTimers = {}; + timeLeft = 30; + + // Remove any existing timed items + tilesWith(addTime).forEach(([item]) => item.remove()); + tilesWith(removeTime).forEach(([item]) => item.remove()); + + // Randomly place furniture + function placeFurniture(furnitureType, count) { + let placed = 0; + while (placed < count) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + if (getTile(x, y).length === 0) { + addSprite(x, y, furnitureType); + placed++; + } + } + } + + // Load Level 1 or 2 + if (currentLevel === 1) { + setMap(map` + llllllll + l....l.l + l......l + l....l.l + llll.... + `); + placeFurniture(couch, 2); + placeFurniture(table, 2); + } else if (currentLevel === 2) { + setMap(map` + llllllll + l..c.... + l.t....l + l....t.l + l.c....l + llllllll + `); + placeFurniture(couch, 3); + placeFurniture(table, 3); + } + + addSprite(3, 3, player); +} +// Player movement +onInput("w", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).y -= 1; +}); +onInput("s", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).y += 1; +}); +onInput("a", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).x -= 1; +}); +onInput("d", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).x += 1; +}); + +// Lava spreading mechanics with warning phase +function spreadLava() { + const maxLavaTiles = Math.floor((width() * height()) * 0.5); // Max 50% of the map can be lava + const currentLavaTiles = tilesWith(lava).length + tilesWith(preLava).length; + + let newLavaCount = 0; + while (newLavaCount < 3 && currentLavaTiles + newLavaCount < maxLavaTiles) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + const hasFurnitureOrGoal = tile.some(t => t.type === couch || t.type === table); + + if (!hasFurnitureOrGoal && tile.every(t => t.type !== lava && t.type !== preLava)) { + addSprite(x, y, preLava); + newLavaCount++; + setTimeout(() => { + const preLavaTile = getTile(x, y).find(t => t.type === preLava); + if (preLavaTile) { + preLavaTile.remove(); + addSprite(x, y, lava); + + // Check if the player is on the lava tile + const playerTile = getTile(x, y).find(t => t.type === player); + if (playerTile) { + gameOver = true; + addText("Game Over! Press I to reset", { x: 2, y: 4 }); + } + } + }, 800); // Lava warning duration + } + } + + let removedLavaCount = 0; + const lavaTiles = tilesWith(lava); + while (removedLavaCount < 3 && lavaTiles.length > 0) { + const randomLava = lavaTiles[Math.floor(Math.random() * lavaTiles.length)]; + if (randomLava) { + randomLava[0].remove(); + removedLavaCount++; + } + } +} +setInterval(spreadLava, 1000); // Spread lava every second + +// Prevent camping on furniture +function checkFurniture() { + tilesWith(player, couch).forEach(([playerTile, couchTile]) => { + const key = `${couchTile.x}-${couchTile.y}`; + if (!furnitureTimers[key]) { + furnitureTimers[key] = setTimeout(() => { + couchTile.remove(); + delete furnitureTimers[key]; + }, 2000); // Sink furniture after 2 seconds + } + }); + + tilesWith(player, table).forEach(([playerTile, tableTile]) => { + const key = `${tableTile.x}-${tableTile.y}`; + if (!furnitureTimers[key]) { + furnitureTimers[key] = setTimeout(() => { + tableTile.remove(); + delete furnitureTimers[key]; + }, 2000); + } + }); +} +setInterval(checkFurniture, 1000); + +// Goal spawning logic +function spawnGoal() { + let placed = false; + while (!placed) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + if (tile.every(t => t.type !== lava && t.type !== preLava && t.type !== player && t.type !== couch && t.type !== table)) { + addSprite(x, y, goal); + placed = true; + } + } +} + +// Live timer in bottom left corner +function updateTimer() { + if (!gameWon && !gameOver) { + clearText(); + addText(`Time: ${timeLeft}s`, { x: 0, y: 13 }); + + if (timeLeft > 0) { + timeLeft -= 1; + } else if (!goalUnlocked) { + goalUnlocked = true; // Unlock the goal + spawnGoal(); // Spawn the goal at a random location + addText("Goal spawned!", { x: 2, y: 2 }); + } + } +} +setInterval(updateTimer, 1000); + +// Random timed items +function spawnTimedItems() { + if (Math.random() < 0.25) { // Adjusted spawn rate: favor addTime + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + if (tile.every(t => t.type !== lava && t.type !== preLava)) { + const itemType = Math.random() < 0.7 ? addTime : removeTime; // 70% chance for addTime + addSprite(x, y, itemType); + setTimeout(() => { + const itemTile = getTile(x, y).find(t => t.type === itemType); + if (itemTile) itemTile.remove(); + }, 3000); // Item disappears after 3 seconds + } + } +} +setInterval(spawnTimedItems, 5000); + +// Falling debris +function spawnDebris() { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + if (getTile(x, y).every(t => t.type !== lava && t.type !== preLava)) { + addSprite(x, y, debris); + setTimeout(() => { + const debrisTile = getTile(x, y).find(t => t.type === debris); + if (debrisTile) debrisTile.remove(); + }, 3000); // Debris disappears after 3 seconds + } +} +setInterval(spawnDebris, 7000); + +// Collect snacks and detect timed items and lava collisions +afterInput(() => { + if (gameWon || gameOver) return; + + const goalTile = tilesWith(player, goal); + if (goalTile.length && goalUnlocked) { + if (currentLevel === 1) { + currentLevel = 2; + resetGame(); + return; + } else { + gameWon = true; + addText("You Win! Press I to reset", { x: 2, y: 4 }); + return; + } + } + + const lavaTiles = tilesWith(player, lava); + if (lavaTiles.length) { + gameOver = true; + addText("Game Over! Press I to reset", { x: 2, y: 4 }); + return; + } + + const addTimeTiles = tilesWith(player, addTime); + addTimeTiles.forEach((tile) => { + const item = tile.find(t => t.type === addTime); + if (item) { + timeLeft += 2; + item.remove(); + addText("+2 Seconds!", { x: 2, y: 2, color: color`5` }); + } + }); + + const removeTimeTiles = tilesWith(player, removeTime); + removeTimeTiles.forEach((tile) => { + const item = tile.find(t => t.type === removeTime); + if (item) { + timeLeft = Math.max(0, timeLeft - 3); + item.remove(); + addText("-3 Seconds!", { x: 2, y: 2, color: color`5` }); + } + }); +}); + +// Restart game +onInput("i", () => { + if (gameWon || gameOver) { + resetGame(); + } +}); + +// Start the game +resetGame(); + + + + diff --git a/games/TheTombOfAThousandTerrors.js b/games/TheTombOfAThousandTerrors.js index 9e9ec6f36c..3ab3bbe5bb 100644 --- a/games/TheTombOfAThousandTerrors.js +++ b/games/TheTombOfAThousandTerrors.js @@ -346,7 +346,7 @@ function startLevel() { levelState.mapSizeX = def.size[0]; levelState.mapSizeY = def.size[1]; - levelState.map = getGrid(levelState.mapSizeX, levelState.mapSizeY); + levelState.map = getGridFunction(levelState.mapSizeX, levelState.mapSizeY); levelState.map = generatePrimMaze(levelState.map); let objects = []; @@ -567,7 +567,7 @@ function setTile(x,y, tile) { } // Maze generation -function getGrid(width, height) { +function getGridFunction(width, height) { var grid = []; for (let y = 0; y < height; y++) { diff --git a/games/The_Hidden_Cheese.js b/games/The_Hidden_Cheese.js new file mode 100644 index 0000000000..2230b08b71 --- /dev/null +++ b/games/The_Hidden_Cheese.js @@ -0,0 +1,966 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: The Hidden Cheese +@author: Jayden Chun +@tags: ['puzzle', 'memory'] +@addedOn: 2024-12-12 + +A simple mind-stretching single player game to warm-up your mind! +Consume as many pieces of cheese as you can! +Dodge enemies! +Memorize patterns! + +W - Move Up +A - Move Left +S - Move Down +D - Move Right +*/ + + +const ground = "g" +const poison = "n" +const player = "p" +const upPlayer = "1" +const downPlayer = "2" +const leftPlayer = "3" +const mimicPlayer = "P" +const upPlayerM = "4" +const downPlayerM = "5" +const leftPlayerM = "6" +const enemy = "e" +const mimicEnemy = "E" +const enemy3 = "8" +const enemy4 = "9" +const door = "d" +const key = "k" +const glasses = "l" +const cheese = "c" +const wall = "w" +const box = "b" +const mimicBox = "B" +const inverser = "i" +const mimicInverser = "I" +const text = "t" + +let positionTimer = 10 +//decrement as the levels progress +let mimicMovement = 1 +let playerMovement = 1 +let enemyMovement = 1 + +//music +const backgroundMusic = new Audio('Downloads/mouseGame.mp3') +//const playback = playTune(backgroundMusic, Infinity) +backgroundMusic.loop = true; // Loop the music +backgroundMusic.volume = 1.0 +backgroundMusic.play(); + +setLegend( + [player, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDCCCCCCCCD4 +DDDDDDDDDDDDDDDD +8DDDDD1DD1DDDDDD +88DLL1L11LDDDDDD +D88L111010DDDDCC +DDDL11L1118DD4CD +DDDLLLLLLLDDD4CD +DDDD1DDD1DDDD4DD +D4DDDDDDDDDDD4DD +DD4DDDDDDDDDDCDD +DD44CC4CCC4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [upPlayer, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDD11111CCCCCD4 +DDDD11111DDDDDDD +4DDDLL11LDDDDDDD +DDDDL111LDDD44DD +D4DD1L11LDDD4DCC +DDDD11111DD4D4CD +DDDD11111DD4D4CD +DDDDDD84DDDDD4DD +D4DDDDD84DDDD4DD +DD4DDDDD8DDDDCDD +DD44CC48CC4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [downPlayer, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDD88CCCCCD4 +DDDDDD88DDDDDDDD +4DDDDD8DDDDDDDDD +DDDDDD8DDDDD44DD +D4DD11111DDD4DCC +DDDD1111LDD4D4CD +DDDDL11LLDD4D4CD +DDDDL11L1DDDD4DD +D4DDL11L1DDDD4DD +DD4D11111DDDDCDD +DD4411111C4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [leftPlayer, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDCCCCCCCCD4 +DDDDDDDDDDDDDDDD +DDD1DD1DDDDD8DDD +DDDL11L1LLD88DDD +DDD010111L88DDCC +DD8111111LDDD4CD +DDDLLLLLLLDDD4CD +DDDD1DDD1DDDD4DD +D4DDDDDDDCCDDD44 +DD4DDDDDDCCDDDDD +DD44CC4CDDDC44CD +DDCCDDDDCD44DCCD +DDDDDDDDDDDDDDDD`], + [upPlayerM, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDD11111CCCCCD4 +DDDD11111DDDDDDD +4DDDLL11LDDDDDDD +DDDDL111LDDD44DD +D4DD1L11LDDD4DCC +DDDD11111DD4D4CD +DDDD11111DD4D4CD +DDDDDD84DDDDD4DD +D4DDDDD84DDDD4DD +DD4DDDDD8DDDDCDD +DD44CC48CC4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [downPlayerM, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDD88CCCCCD4 +DDDDDD88DDDDDDDD +4DDDDD8DDDDDDDDD +DDDDDD8DDDDD44DD +D4DD11111DDD4DCC +DDDD1111LDD4D4CD +DDDDL11LLDD4D4CD +DDDDL11L1DDDD4DD +D4DDL11L1DDDD4DD +DD4D11111DDDDCDD +DD4411111C4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [leftPlayerM, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDCCCCCCCCD4 +DDDDDDDDDDDDDDDD +DDD1DD1DDDDD8DDD +DDDL11L1LLD88DDD +DDD010111L88DDCC +DD8111111LDDD4CD +DDDLLLLLLLDDD4CD +DDDD1DDD1DDDD4DD +D4DDDDDDDCCDDD44 +DD4DDDDDDCCDDDDD +DD44CC4CDDDC44CD +DDCCDDDDCD44DCCD +DDDDDDDDDDDDDDDD`], + [text, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [mimicPlayer, bitmap` +DCDCCCDDDDDDDDDD +CDDDDCDCCDDDDDDD +CCD444DDCCDDD444 +DDDDDDCCCCCCCCD4 +DDDDDDDDDDDDDDDD +8DDDDD1DD1DDDDDD +88DLL1L11LDDDDDD +D88L111010DDDDCC +DDDL11L1118DD4CD +DDDLLLLLLLDDD4CD +DDDD1DDD1DDDD4DD +D4DDDDDDDDDDD4DD +DD4DDDDDDDDDDCDD +DD44CC4CCC4CCDDD +DDCCDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`], + [enemy, bitmap` +DDDDDDDDDD3333DD +33DDDDDDDDDDD33D +33DD11111111DD3D +3DD1L000000L1DDD +3D1L00000000L1DD +3D100300003001DD +DD100030030001DD +DD100000000001DD +3D100000000001DD +DD100033330001DD +DD1L03000030L1DD +DDD1L000000L1DDD +33DD11111111DD3D +33DDDDDDDDDDD33D +D33DDDDDDDDDD33D +DD33DDDDDDDDD3DD`], + [mimicEnemy, bitmap` +................ +................ +....11111111.... +...1L000000L1... +..1L00000000L1.. +..100300003001.. +..100030030001.. +..100000000001.. +..100000000001.. +..100033330001.. +..1L03000030L1.. +...1L000000L1... +....11111111.... +................ +................ +................`], + [enemy3, bitmap` +................ +................ +....11111111.... +...1L000000L1... +..1L00000000L1.. +..100300003001.. +..100030030001.. +..100000000001.. +..100000000001.. +..100033330001.. +..1L03000030L1.. +...1L000000L1... +....11111111.... +................ +................ +................`], + [enemy4, bitmap` +................ +................ +....11111111.... +...1L000000L1... +..1L00000000L1.. +..100300003001.. +..100030030001.. +..100000000001.. +..100000000001.. +..100033330001.. +..1L03000030L1.. +...1L000000L1... +....11111111.... +................ +................ +................`], + [glasses, bitmap` +................ +................ +................ +................ +..111........... +.117111......... +11777711........ +1777777711111111 +1777777711111111 +17777771........ +17777771........ +11777711........ +.111111......... +................ +................ +................`], + [key, bitmap` +................ +................ +................ +................ +................ +...6............ +..6.666666...... +...6...6.6...... +................ +................ +................ +................ +................ +................ +................ +................`], + [cheese, bitmap` +................ +................ +................ +........00000... +....0000666600.. +..000666666600.. +.00666666F6600.. +.00F6F66F6660... +..066666666660.. +..0666F6666F60.. +..066666666660.. +..06FF6F66660... +..06666666000... +..00000000...... +................ +................`], + [door, bitmap` +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCC66CDDD +DDCCCCCCCC66CDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD +DDCCCCCCCCCCCDDD`], + [wall, bitmap` +DDDDD11111DDDDDD +DDDDD11111DDDDDD +DDCDD11111DDDDDD +DDCDD11111HDDD8D +DDDDD11111DDDDDD +DDDDD11111DCDDDD +DDDCD11111DDDDDD +DDDCD11111HDDCDD +DDDDD11111DDDCDD +CCCCD11111DDDCDD +DCCDD11111DDDDDD +DDCDC11111DDCDDD +DDDDC11111DDCDDD +DDDDD11111CCCDDD +DDDDD11111DDDDDD +DDDDD11111DDDDDD`], + [box, bitmap` +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CC999999999999CC +CC9CCCFFFCCC99CC +CC9CFFCFCCC999CC +CC9CCCCFC99C9FCC +C99999FFF9CC9FCC +C9FCFC96FCFC9FCC +C9FCCFF69FCC9FCC +C9FCFCFFF9CCC9CC +C99CFCCFCC9CC9CC +CC9CFCCCCC99C9CC +CC9CCCCFFFCCC9CC +CC999999999999CC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC`], + [mimicBox, bitmap` +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CC333333333333CC +CC3333FFFCCC33CC +CC33FF3FCCC333CC +CC33333FC99C3FCC +C33333FFF9CC3FCC +C3FCFC96FCFC3FCC +C3FCCFF69FCC3FCC +C3FCFCFFF9CCC3CC +C33CFCCFCC9CC3CC +CC3CFCCCCC99C3CC +CC3CCCCFFFCCC3CC +CC333333333333CC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC`], + [inverser, bitmap` +5555555555555555 +5555555555555555 +5555555555355555 +5555555555535555 +5555555555553555 +5555555555555355 +5555555555555535 +5333333333333333 +5555555555555535 +5555555555555355 +5555555555553555 +5555555555535555 +5555555555355555 +5555555555555555 +5555555555555555 +5555555555555555`], + [mimicInverser, bitmap` +5555555555555555 +5555555555555555 +5555565555555555 +5555655555555555 +5556555555555555 +5565555555555555 +5655555555555555 +6666666666666665 +5655555555555555 +5565555555555555 +5556555555555555 +5555655555555555 +5555565555555555 +5555555555555555 +5555555555555555 +5555555555555555`], + [ground, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDD8DDD44D +DDCCDCCCCCDD4D4D +DDD48DDDDD4DCDD4 +DD4DD444DDDDD8DD +DCCDDDD4D4DDDCDD +DCDCDDD444DDDDDD +CDDDDDD44CDDDDD8 +C44DDDDDDD8DDDDD +CDDCDDDDDDDDDD44 +DDDC8DDCDDCDDDC4 +DD8DDCDDDDC4DDDC +DDDDDD4DDDD4DDDD +D444D4DDDD44444D +DDDD44D4DD4DDDDD +DDDDDDDDDDDDDDD8`] +) + + +let level = 0 +const levels = [ + map` +ttttttttttttt +ggggggwgggggg +ggggggwgggggg +ggggggwgggggg +ggggggwgggggg +ggggggwgggggg +ggggggwgggggg +ggggggwgggggg`, + map` +ttttttttttttt +ggwgggwggwggw +ggwgggwggwggw +ggwgggwggwggg +ggwggggggwgwg +ggwgggwggggwg +ggwgggwgwggwg +ggggggwgwggwg`, + map`` +] +let scoreIncrement = 1; + + +setMap(levels[level]) +setSolids([text, player, upPlayer, downPlayer, leftPlayer, mimicPlayer, upPlayerM, downPlayerM, leftPlayerM, wall, box, mimicBox]) +setPushables({ + [player]: [box, mimicBox], + [mimicPlayer]: [box, mimicBox], + [enemy]: [] +}) + + +let score = 0; +let timer = 0; +let gameOver = false; +let completeCurrLevel = false; +const gameHeight = height(); +const gameWidth = width(); +const wallPos = Math.floor(gameWidth / 2); + + +const sprites = [] + +let enemyX1 = Math.floor(Math.random() * wallPos) +let enemyY1 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +while (enemyY1 === 1) { + enemyY1 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +} +let enemyUp1 = true +//enemy2 only mimic +let enemyXM = Math.floor(Math.random() * wallPos) + 7 + + + +//enemy3 only main +let enemyX3 = Math.floor(Math.random() * wallPos) +let enemyY3 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +while (enemyY3 === 1) { + enemyY3 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +} +let enemyUp3 = true +//enemy4 only mimic +let enemyX4 = Math.floor(Math.random() * wallPos) +let enemyY4 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +while (enemyY4 === 1) { + enemyY4 = Math.floor(Math.random() * (gameHeight - 1)) + 1 +} +let enemyUp4 = true + + +let cheeseX = Math.floor(Math.random() * (gameWidth - wallPos)) + wallPos; +let cheeseY = Math.floor(Math.random() * (gameHeight - 1)) + 1; + +//glasses positioning works +let glassesX = Math.floor(Math.random() * (wallPos - 1)); +let glassesY = Math.floor(Math.random() * (gameHeight - 1)) + 1; + + + +let doorsX = Math.floor(Math.random() * (wallPos - 1)); +let doorsY = Math.floor(Math.random() * (gameHeight - 1)) + 1; +//so that the door and the glasses don't overlap each other +while (doorsX === glassesX) { + doorsX = Math.floor(Math.random() * (wallPos - 1)); +} + +//makes sure these objects don't spawn in the wall +while (cheeseX === 6) { + cheeseX = Math.floor(Math.random() * (gameWidth - wallPos)) + wallPos; +} + + + +addSprite(5, 1, player) +addSprite(7, 1, mimicPlayer) +addSprite(glassesX, glassesY, glasses) + + +let playerX = getFirst(player).x +let playerY = getFirst(player).y + +let mimicX = getFirst(mimicPlayer).x +let mimicY = getFirst(mimicPlayer).y + + + + + +//checks the collision of two objects, doesn't have to be just the player and enemy +//returns true or false +function checkCollision(player, enemy) { + const playerPosition = getFirst(player) + const enemyPosition = getFirst(enemy) + if (playerPosition && enemyPosition) { + return (playerPosition.x === enemyPosition.x && playerPosition.y === enemyPosition.y) + } +} + +function checkCollisionPosition(player, objectX, objectY) { + const playerPosition = getFirst(player) + if (playerPosition) { + return (playerPosition.x === objectX && playerPosition.y === objectY) + } +} + +//inverses the controls of both player and mimicPlayer when colliding with the inverser sprite +function inverse(player, mimicPlayer, inverser, mimicInverser) { + if (checkCollision(player, inverser) || checkCollision(mimicPlayer, )) { + mimicMovement *= -1 + playerMovement *= -1 + } +} +//increments the score if either players touch the cheese +function incrementScore(player, mimicPlayer, cheese) { + if (checkCollisionPosition(mimicPlayer, cheeseX, cheeseY) || checkCollisionPosition(downPlayerM, cheeseX, cheeseY) || checkCollisionPosition(leftPlayerM, cheeseX, cheeseY) || checkCollisionPosition(upPlayerM, cheeseX, cheeseY)) { + score += scoreIncrement; + cheeseX = Math.floor(Math.random() * (gameWidth - wallPos - 1)) + wallPos + 1; + cheeseY = Math.floor(Math.random() * (gameHeight - 1)) + 1; + if (score === 15) { + scoreIncrement++; + } + else if (score >= 40) { + scoreIncrement++; + } + if (score >= 75) { + scoreIncrement++; + } + if (score >= 100) { + scoreIncrement++; + } + } +} + +function deleteAllSprites() { + for (let x = 0; x < gameWidth; x++) { + for (let y = 1; y < gameHeight; y++) { + addSprite(x, y, text); + } + } +} + +function setPositions(level) { + if (level === 1) { + addSprite(0, 3, player); + playerX = 0, playerY = 3; + enemyX1 = Math.floor(Math.random() * 3) + 3 + enemyY1 = Math.floor(Math.random() * (gameHeight - 1)) + 1 + while (enemyY1 === 1) { + enemyY1 = Math.floor(Math.random() * (gameHeight - 1)) + 1 + } + enemyUp1 = true + addSprite(enemyX1, enemyY1, enemy); + } +} + + +function endGame() { + clearInterval(updateEverything) + clearText() + deleteAllSprites(); + addText("You lost.....", { x: 3, y: 5, color: color`2` }) + addText("Score: " + score, { x: 5, y: 7, color: color`2` }) + addText("Time Elapsed: " + timer, { x: 3, y: 9, color: color`2` }) + deleteAllSprites(); +} + +function wonGame() { + clearInterval(updateEverything) + clearText() + deleteAllSprites(); + addText("YOU WON IDK HOW", { x: 3, y: 5, color: color`2` }) + addText("Score: " + score, { x: 5, y: 7, color: color`2` }) + addText("Time Elapsed: " + timer, { x: 3, y: 9, color: color`2` }) + deleteAllSprites(); +} +onInput("s", () => { + if (!gameOver) { + playerY += playerMovement; + if (playerY > gameHeight - 1) playerY = gameHeight - 1 + if (!getFirst(downPlayer)) { + if (getFirst(player)) { + getFirst(player).remove(); + } else if (getFirst(upPlayer)) { + getFirst(upPlayer).remove(); + } else if (getFirst(leftPlayer)) { + getFirst(leftPlayer).remove(); + } + addSprite(playerX, playerY, downPlayer); + } else if (getFirst(downPlayer)) { + getFirst(downPlayer).y += playerMovement + } + mimicY += mimicMovement; + if (mimicY > gameHeight - 1) mimicY = gameHeight - 1 + if (!getFirst(downPlayerM) && level != 1) { + if (getFirst(mimicPlayer)) { + getFirst(mimicPlayer).remove(); + } else if (getFirst(upPlayerM)) { + getFirst(upPlayerM).remove(); + } else if (getFirst(leftPlayerM)) { + getFirst(leftPlayerM).remove(); + } + addSprite(mimicX, mimicY, downPlayerM); + } else if (getFirst(downPlayerM)) { + getFirst(downPlayerM).y += playerMovement + } + if (level != 1) { + mimicY = getFirst(downPlayerM).y + } + } +}) + +onInput("w", () => { + if (!gameOver) { + playerY -= playerMovement; + if (playerY < 1) playerY = 1 + if (!getFirst(upPlayer)) { + addSprite(playerX, playerY, upPlayer) + if (getFirst(player)) { + getFirst(player).remove(); + } else if (getFirst(downPlayer)) { + getFirst(downPlayer).remove(); + } else if (getFirst(leftPlayer)) { + getFirst(leftPlayer).remove(); + } + } else if (getFirst(upPlayer)) { + getFirst(upPlayer).y -= playerMovement + } + playerY = getFirst(upPlayer).y + mimicY -= mimicMovement; + if (mimicY < 1) mimicY = 1 + if (!getFirst(upPlayerM) && level != 1) { + addSprite(mimicX, mimicY, upPlayerM) + if (getFirst(mimicPlayer)) { + getFirst(mimicPlayer).remove(); + } else if (getFirst(downPlayerM)) { + getFirst(downPlayerM).remove(); + } else if (getFirst(leftPlayerM)) { + getFirst(leftPlayerM).remove(); + } + } else if (getFirst(upPlayerM)) { + getFirst(upPlayerM).y -= mimicMovement + } + if (level != 1) { + mimicY = getFirst(upPlayerM).y + } + } +}) + +onInput("d", () => { + if (!gameOver) { + if (!getFirst(player)) { + addSprite(playerX, playerY, player) + getFirst(player).x += playerMovement + if (getFirst(upPlayer)) { + getFirst(upPlayer).remove(); + } else if (getFirst(downPlayer)) { + getFirst(downPlayer).remove(); + } else if (getFirst(leftPlayer)) { + getFirst(leftPlayer).remove(); + } + } else if (getFirst(player)) { + getFirst(player).x += playerMovement + } + playerX = getFirst(player).x + + mimicX += mimicMovement; + if (mimicX === gameWidth) mimicX = gameWidth - 1 + if (!getFirst(mimicPlayer) && level != 1) { + addSprite(mimicX, mimicY, mimicPlayer) + if (getFirst(upPlayerM)) { + getFirst(upPlayerM).remove(); + } else if (getFirst(downPlayerM)) { + getFirst(downPlayerM).remove(); + } else if (getFirst(leftPlayerM)) { + getFirst(leftPlayerM).remove(); + } + } else if (getFirst(mimicPlayer)) { + getFirst(mimicPlayer).x += mimicMovement + } + if (level != 1) { + mimicX = getFirst(mimicPlayer).x; + } + } +}) + +onInput("a", () => { + if (!gameOver) { + if (playerX < 0) playerX = 0 + if (!getFirst(leftPlayer)) { + addSprite(playerX, playerY, leftPlayer) + getFirst(leftPlayer).x -= playerMovement + if (getFirst(upPlayer)) { + getFirst(upPlayer).remove(); + } else if (getFirst(downPlayer)) { + getFirst(downPlayer).remove(); + } else if (getFirst(player)) { + getFirst(player).remove(); + } + } else { + getFirst(leftPlayer).x -= playerMovement + } + playerX = getFirst(leftPlayer).x + + if (!getFirst(leftPlayerM) && level != 1) { + addSprite(mimicX, mimicY, leftPlayerM) + getFirst(leftPlayerM).x -= playerMovement + if (getFirst(upPlayerM)) { + getFirst(upPlayerM).remove(); + } else if (getFirst(downPlayerM)) { + getFirst(downPlayerM).remove(); + } else if (getFirst(mimicPlayer)) { + getFirst(mimicPlayer).remove(); + } + } else if (getFirst(leftPlayerM)) { + getFirst(leftPlayerM).x -= playerMovement + } + if (level != 1) { + mimicX = getFirst(leftPlayerM).x; + } + } + //console.log(playerX, playerY) +}) + + +afterInput(() => { + let playersExist = (player || downPlayer || upPlayer || leftPlayer) && (mimicPlayer || upPlayerM || downPlayerM || leftPlayerM); + let mainPlayerExists = player || downPlayer || upPlayer || leftPlayer; + let mimicPlayerExists = mimicPlayer || upPlayerM || downPlayerM || leftPlayerM; + const cheeseSprite = getFirst(cheese); + const enemySprite = getFirst(enemy); + const enemySprite2 = getFirst(mimicEnemy); + const enemySprite3 = getFirst(enemy3); + const enemySprite4 = getFirst(enemy4); + if (mainPlayerExists && (checkCollision(glasses, player) || checkCollision(glasses, downPlayer) || checkCollision(glasses, upPlayer) || + checkCollision(glasses, leftPlayer))) { + if (!enemySprite) { + addSprite(enemyX1, enemyY1, enemy); + if (score >= 10 && level === 0) { + addSprite(enemyXM, enemyY1, mimicEnemy); + } + if (score >= 30 && level === 0) { + addSprite(enemyX3, enemyY3, enemy3); + } + if (score >= 100 && level === 0) { + addSprite(enemyX4, enemyY4, enemy4); + } + } + } else if (mainPlayerExists && !(checkCollision(glasses, player) || checkCollision(glasses, downPlayer) || checkCollision(glasses, upPlayer) || + checkCollision(glasses, leftPlayer))) { + if (enemySprite) { + enemySprite.remove(); + } + if (enemySprite2) { + enemySprite2.remove(); + } + if (enemySprite3) { + enemySprite3.remove(); + } + if (enemySprite4) { + enemySprite4.remove(); + } + } + if (playersExist) { + if (checkCollision(glasses, player) || checkCollision(glasses, downPlayer) || + checkCollision(glasses, upPlayer) || checkCollision(glasses, leftPlayer) && + !cheeseSprite && !completeCurrLevel) { + addSprite(cheeseX, cheeseY, cheese); //if hits glasses: show Cheese + } else if (!(checkCollision(glasses, player) || checkCollision(glasses, downPlayer) || + checkCollision(glasses, upPlayer) || checkCollision(glasses, leftPlayer)) && + cheeseSprite) { + cheeseSprite.remove(); + } + } + incrementScore(player, mimicPlayer, cheese) + if (gameOver) { + deleteAllSprites(); + } + if (checkCollision(door, player) || checkCollision(door, downPlayer) || + checkCollision(door, upPlayer) || checkCollision(door, leftPlayer)) { + level = level + 1; + setMap(levels[level]); + setPositions(level); + } +}) + + + +//adds the score and timer at the top +let index = 0 +let enemyIncrement = 1; +const updateEverything = setInterval(() => { //timer is set to seconds + const enemySprite = getFirst(enemy) + const enemySprite2 = getFirst(mimicEnemy) + const enemySprite3 = getFirst(enemy3) + const enemySprite4 = getFirst(enemy4) + clearText() + addText("Time Elapsed: " + timer, { x: 0, y: 0, color: color`2` }) + addText("Score: " + score, { x: 0, y: 1, color: color`2` }) + index++; + if (index % 100 === 0) { + timer++; + index = 0; + } + + if (index % 100 === 0) { + if (enemyY1 > gameHeight - 2 || enemyY1 <= 1) { + enemyUp1 = !enemyUp1; + } + if (enemyUp1) { + enemyY1 += enemyMovement; + if (enemySprite) { + enemySprite.y += enemyMovement; + } + if (enemySprite2) { + enemySprite2.y += enemyMovement; + } + } else { + enemyY1 -= enemyMovement; + if (enemySprite) { + enemySprite.y -= enemyMovement; + } + if (enemySprite2) { + enemySprite2.y -= enemyMovement; + } + } + if (enemyY3 > gameHeight - 2 || enemyY3 <= 1) { + enemyUp3 = !enemyUp3; + } + if (enemyUp3) { + enemyY3 += enemyMovement; + if (enemySprite3) { + enemySprite3.y += enemyMovement; + } + } else { + enemyY3 -= enemyMovement; + if (enemySprite3) { + enemySprite3.y -= enemyMovement; + } + } + if (enemyY4 > gameHeight - 2 || enemyY4 <= 1) { + enemyUp4 = !enemyUp4; + } + if (enemyUp4) { + enemyY4 += enemyMovement; + if (enemySprite4) { + enemySprite4.y += enemyMovement; + } + } else { + enemyY4 -= enemyMovement; + if (enemySprite4) { + enemySprite4.y -= enemyMovement; + } + } + } //why is there a removal delay; edit: fixed it + if (checkCollisionPosition(player, enemyX1, enemyY1) || checkCollisionPosition(upPlayer, enemyX1, enemyY1) || + checkCollisionPosition(downPlayer, enemyX1, enemyY1) || checkCollisionPosition(leftPlayer, enemyX1, enemyY1) || + checkCollisionPosition(mimicPlayer, enemyX1, enemyY1) || checkCollisionPosition(upPlayerM, enemyX1, enemyY1) || + checkCollisionPosition(downPlayerM, enemyX1, enemyY1) || checkCollisionPosition(leftPlayerM, enemyX1, enemyY1)) { + endGame(); + gameOver = true; + } + if (score >= 10 && (checkCollisionPosition(player, enemyXM, enemyY1) || checkCollisionPosition(upPlayer, enemyXM, enemyY1) || + checkCollisionPosition(downPlayer, enemyXM, enemyY1) || checkCollisionPosition(leftPlayer, enemyXM, enemyY1) || + checkCollisionPosition(mimicPlayer, enemyXM, enemyY1) || checkCollisionPosition(upPlayerM, enemyXM, enemyY1) || + checkCollisionPosition(downPlayerM, enemyXM, enemyY1) || checkCollisionPosition(leftPlayerM, enemyXM, enemyY1))) { + endGame(); + gameOver = true; + } + if (score >= 30 && (checkCollisionPosition(player, enemyX3, enemyY3) || checkCollisionPosition(upPlayer, enemyX3, enemyY3) || + checkCollisionPosition(downPlayer, enemyX3, enemyY3) || checkCollisionPosition(leftPlayer, enemyX3, enemyY3) || + checkCollisionPosition(mimicPlayer, enemyX3, enemyY3) || checkCollisionPosition(upPlayerM, enemyX3, enemyY3) || + checkCollisionPosition(downPlayerM, enemyX3, enemyY3) || checkCollisionPosition(leftPlayerM, enemyX3, enemyY3))) + { + endGame(); + gameOver = true; + } + if (score >= 100 && (checkCollisionPosition(player, enemyX4, enemyY4) || checkCollisionPosition(upPlayer, enemyX4, enemyY4) || + checkCollisionPosition(downPlayer, enemyX4, enemyY4) || checkCollisionPosition(leftPlayer, enemyX4, enemyY4) || + checkCollisionPosition(mimicPlayer, enemyX4, enemyY4) || checkCollisionPosition(upPlayerM, enemyX4, enemyY4) || + checkCollisionPosition(downPlayerM, enemyX4, enemyY4) || checkCollisionPosition(leftPlayerM, enemyX4, enemyY4))) + { + endGame(); + gameOver = true; + } + + if (score >= 350) { + wonGame() + } + +}, 1); diff --git a/games/The_floor_is_lava.js b/games/The_floor_is_lava.js new file mode 100644 index 0000000000..ad644a6fdb --- /dev/null +++ b/games/The_floor_is_lava.js @@ -0,0 +1,446 @@ +/* +@title: The Floor is Lava +@author: Knaifu0030 +@tags: [] +@addedOn: 2024-12-18 +Keys: +- W to go up +- A to move left +- S to move down +- D to move right +Objective: +- Survive the lava till the timer runs out +- Use the furniture for help (it'll disappear after a while) +- Collect items to reduce timer +- Reach the goal once the timer ends before the lava gets you!! +*/ + +// Define sprites +const player = "p"; +const lava = "l"; +const preLava = "r"; // Lava warning state +const couch = "c"; +const table = "t"; +const snack = "s"; +const goal = "g"; +const addTime = "a"; // Adds 2 seconds +const removeTime = "t"; // Removes 3 seconds +const debris = "d"; // Temporary obstacle + +setLegend( + [player, bitmap` +.3333........... +CCC206.......... +CCCCC6.......... +.CCCC........... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [lava, bitmap` +.9999........... +999999.......... +.9999........... +999999.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [preLava, bitmap` +1.1.1........... +.1.1............ +1.1.1........... +.1.1............ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [couch, bitmap` +CCCCCC.......... +CCCCCC.......... +CCLLCC.......... +CCLLCC.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [table, bitmap` +CCCCCC.......... +CFFFFC.......... +CFFFFC.......... +CCCCCC.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [snack, bitmap` + .555. + 55555 + .555. + `], + [goal, bitmap` +363636.......... +636363.......... +363636.......... +636363.......... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [addTime, bitmap` + ..... + .333. + .323. + .333. + ..... + `], + [removeTime, bitmap` + ..... + .444. + .424. + .444. + ..... + `], + [debris, bitmap` + 99999 + 99999 + 99999 + 99999 + `] +); + +// Game reset function with random furniture and levels +let currentLevel = 1; +let gameWon = false; +let gameOver = false; +let goalUnlocked = false; +let furnitureTimers = {}; +let timeLeft = 30; + +// Define start screen state +let onStartScreen = true; + +// Function to show start screen +function showStartScreen() { + clearText(); + addText("THE FLOOR IS LAVA!", { x: 2, y: 4, color: color`2` }); + addText("Survive the lava, find the goal,", { x: 1, y: 6 }); + addText("Mo", { x: 1, y: 7 }); + addText("Press K to Play", { x: 3, y: 10, color: color`3` }); +} + +// Detect input for play button +onInput("k", () => { + if (onStartScreen) { + onStartScreen = false; + resetGame(); + } +}); + +// Only show the start screen initially +if (onStartScreen) { + showStartScreen(); +} + +function resetGame() { + clearText(); + gameWon = false; + gameOver = false; + goalUnlocked = false; + furnitureTimers = {}; + timeLeft = 30; + + // Remove any existing timed items + tilesWith(addTime).forEach(([item]) => item.remove()); + tilesWith(removeTime).forEach(([item]) => item.remove()); + + // Randomly place furniture + function placeFurniture(furnitureType, count) { + let placed = 0; + while (placed < count) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + if (getTile(x, y).length === 0) { + addSprite(x, y, furnitureType); + placed++; + } + } + } + + // Load Level 1 or 2 + if (currentLevel === 1) { + setMap(map` + llllllll + l....l.l + l......l + l....l.l + llll.... + `); + placeFurniture(couch, 2); + placeFurniture(table, 2); + } else if (currentLevel === 2) { + setMap(map` + llllllll + l..c.... + l.t....l + l....t.l + l.c....l + llllllll + `); + placeFurniture(couch, 3); + placeFurniture(table, 3); + } + + addSprite(3, 3, player); +} +// Player movement +onInput("w", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).y -= 1; +}); +onInput("s", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).y += 1; +}); +onInput("a", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).x -= 1; +}); +onInput("d", () => { + if (!gameWon && !gameOver && getFirst(player)) getFirst(player).x += 1; +}); + +// Lava spreading mechanics with warning phase +function spreadLava() { + const maxLavaTiles = Math.floor((width() * height()) * 0.5); // Max 50% of the map can be lava + const currentLavaTiles = tilesWith(lava).length + tilesWith(preLava).length; + + let newLavaCount = 0; + while (newLavaCount < 3 && currentLavaTiles + newLavaCount < maxLavaTiles) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + const hasFurnitureOrGoal = tile.some(t => t.type === couch || t.type === table); + + if (!hasFurnitureOrGoal && tile.every(t => t.type !== lava && t.type !== preLava)) { + addSprite(x, y, preLava); + newLavaCount++; + setTimeout(() => { + const preLavaTile = getTile(x, y).find(t => t.type === preLava); + if (preLavaTile) { + preLavaTile.remove(); + addSprite(x, y, lava); + + // Check if the player is on the lava tile + const playerTile = getTile(x, y).find(t => t.type === player); + if (playerTile) { + gameOver = true; + addText("Game Over! Press I to reset", { x: 2, y: 4 }); + } + } + }, 800); // Lava warning duration + } + } + + let removedLavaCount = 0; + const lavaTiles = tilesWith(lava); + while (removedLavaCount < 3 && lavaTiles.length > 0) { + const randomLava = lavaTiles[Math.floor(Math.random() * lavaTiles.length)]; + if (randomLava) { + randomLava[0].remove(); + removedLavaCount++; + } + } +} +setInterval(spreadLava, 1000); // Spread lava every second + +// Prevent camping on furniture +function checkFurniture() { + tilesWith(player, couch).forEach(([playerTile, couchTile]) => { + const key = `${couchTile.x}-${couchTile.y}`; + if (!furnitureTimers[key]) { + furnitureTimers[key] = setTimeout(() => { + couchTile.remove(); + delete furnitureTimers[key]; + }, 2000); // Sink furniture after 2 seconds + } + }); + + tilesWith(player, table).forEach(([playerTile, tableTile]) => { + const key = `${tableTile.x}-${tableTile.y}`; + if (!furnitureTimers[key]) { + furnitureTimers[key] = setTimeout(() => { + tableTile.remove(); + delete furnitureTimers[key]; + }, 2000); + } + }); +} +setInterval(checkFurniture, 1000); + +// Goal spawning logic +function spawnGoal() { + let placed = false; + while (!placed) { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + if (tile.every(t => t.type !== lava && t.type !== preLava && t.type !== player && t.type !== couch && t.type !== table)) { + addSprite(x, y, goal); + placed = true; + } + } +} + +// Live timer in bottom left corner +function updateTimer() { + if (!gameWon && !gameOver) { + clearText(); + addText(`Time: ${timeLeft}s`, { x: 0, y: 13 }); + + if (timeLeft > 0) { + timeLeft -= 1; + } else if (!goalUnlocked) { + goalUnlocked = true; // Unlock the goal + spawnGoal(); // Spawn the goal at a random location + addText("Goal spawned!", { x: 2, y: 2 }); + } + } +} +setInterval(updateTimer, 1000); + +// Random timed items +function spawnTimedItems() { + if (Math.random() < 0.25) { // Adjusted spawn rate: favor addTime + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + const tile = getTile(x, y); + if (tile.every(t => t.type !== lava && t.type !== preLava)) { + const itemType = Math.random() < 0.7 ? addTime : removeTime; // 70% chance for addTime + addSprite(x, y, itemType); + setTimeout(() => { + const itemTile = getTile(x, y).find(t => t.type === itemType); + if (itemTile) itemTile.remove(); + }, 3000); // Item disappears after 3 seconds + } + } +} +setInterval(spawnTimedItems, 5000); + +// Falling debris +function spawnDebris() { + const x = Math.floor(Math.random() * width()); + const y = Math.floor(Math.random() * height()); + if (getTile(x, y).every(t => t.type !== lava && t.type !== preLava)) { + addSprite(x, y, debris); + setTimeout(() => { + const debrisTile = getTile(x, y).find(t => t.type === debris); + if (debrisTile) debrisTile.remove(); + }, 3000); // Debris disappears after 3 seconds + } +} +setInterval(spawnDebris, 7000); + +// Collect snacks and detect timed items and lava collisions +afterInput(() => { + if (gameWon || gameOver) return; + + const goalTile = tilesWith(player, goal); + if (goalTile.length && goalUnlocked) { + if (currentLevel === 1) { + currentLevel = 2; + resetGame(); + return; + } else { + gameWon = true; + addText("You Win! Press I to reset", { x: 2, y: 4 }); + return; + } + } + + const lavaTiles = tilesWith(player, lava); + if (lavaTiles.length) { + gameOver = true; + addText("Game Over! Press I to reset", { x: 2, y: 4 }); + return; + } + + const addTimeTiles = tilesWith(player, addTime); + addTimeTiles.forEach((tile) => { + const item = tile.find(t => t.type === addTime); + if (item) { + timeLeft += 2; + item.remove(); + addText("+2 Seconds!", { x: 2, y: 2, color: color`5` }); + } + }); + + const removeTimeTiles = tilesWith(player, removeTime); + removeTimeTiles.forEach((tile) => { + const item = tile.find(t => t.type === removeTime); + if (item) { + timeLeft = Math.max(0, timeLeft - 3); + item.remove(); + addText("-3 Seconds!", { x: 2, y: 2, color: color`5` }); + } + }); +}); + +// Restart game +onInput("i", () => { + if (gameWon || gameOver) { + resetGame(); + } +}); + +// Start the game +resetGame(); + + + + diff --git a/games/The_impossible_game_l1.js b/games/The_impossible_game_l1.js index 3ff533abea..1ce3147e69 100644 --- a/games/The_impossible_game_l1.js +++ b/games/The_impossible_game_l1.js @@ -594,3 +594,4 @@ var gameLoop = setInterval(() => { } }, 1000); +*/ \ No newline at end of file diff --git a/games/Trapped.js b/games/Trapped.js new file mode 100644 index 0000000000..5de3088245 --- /dev/null +++ b/games/Trapped.js @@ -0,0 +1,958 @@ +/* +@title: Trapped +@author: Lockloo50 +@tags: ['puzzle'] +@addedOn: 2024-11-30 +*/ + +/* +Controls - +a - move left +d - move right +w - interact with doors and objects +s - exit menus and move down +j - open letter +l - pick up object +i - start game +k - mute music +*/ + +const player = "p" +const ePlayer = "n" +const background = "b" +const specialBackground = "y" +const eDoor = "e" +const door = "d" +const door2 = "r" +const black = "z" +const safe = "s" +const window = "w" +const key = "k" +const crowbar = "c" +const letter = "l" +const rock = "o" +const lGray = "g" +const gray = "m" +const ladder = "t" +const sLadder = "f" +const blue = "h" +const oWindow = "u" +const car = "v" + +setLegend( + [player, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F66611111111666F +F6F6111111116F6F +FF6F11111111F6FF +F66111111111166F +F61111111111116F +FF600000000006FF +F66099999999066F +F6F0990990990F6F +FF609909909906FF +F66099999999066F +F6F0999999990F6F +FF609999999906FF +F66000000000066F` ], + [ePlayer, bitmap` +................ +................ +................ +....11111111.... +....11111111.... +....11111111.... +...1111111111... +..111111111111.. +...0000000000... +...0999999990... +...0990990990... +...0990990990... +...0999999990... +...0999999990... +...0999999990... +...0000000000...` ], + [background, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F`], + [specialBackground, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F`], + [eDoor, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLL00LLL666F +F6F6LLL00LLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F +F6F6L00LLLLL6F6F +FF6FLLL0LLLLF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F`], + [door, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLL00LLL666F +F6F6LLL00LLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F +F6F6L00LLLLL6F6F +FF6FLLL0LLLLF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F`], + [door2, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLL00LLL666F +F6F6LLL00LLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F +F6F6L00LLLLL6F6F +FF6FLLL0LLLLF6FF +F666LLLLLLLL666F +F6F6LLLLLLLL6F6F +FF6FLLLLLLLLF6FF +F666LLLLLLLL666F`], + [safe, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F000000000006F6F +F00LLLLLLLLL06FF +F0L0LLLLLLLLL06F +F0LL00000000006F +F0LL0LLLL1LLL0FF +F0LL0LLL111LL06F +F0LL0LL1L1L1L06F +F0LL0L11111110FF +F0LL0LL1L1L1L06F +F0LL0LLL111LL06F +FF0L0LLLL1LLL0FF +F66000000000006F`], + [window, bitmap` +F666F666666F666F +FCC6F66FF66F6CCF +FCCC00000000CCCF +F0CCC770077CCC0F +F07CCC7007CCC70F +F000CCC00CCC000F +F0777CCCCCC7770F +F07L77CCCC777L0F +F0LLL7CCCC777L0F +F0LLLCCCCCCL7L0F +F000CCC00CCC000F +F0LCCCL007CCCL0F +F0CCC7L007LCCC0F +FCCC00000000CCCF +FCCFF6F66F6FFCCF +F666F666666F666F`], + [oWindow, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +F00000000000000F +F0FFFFF00FFFFF0F +F0FFFFF00FFFFF0F +F00000000000000F +F0FFFFF00FFFFF0F +F0FFFFF00FFFFF0F +F0FFFFF00FFFFF0F +F0FFFFF00FFFFF0F +F00000000000000F +F0FFFFF00FFFFF0F +F0FFFFF00FFFFF0F +F00000000000000F +FF6FF6F66F6FF6FF +F666F666666F666F`], + [key, bitmap` +F666F666666F666F +F6F6FLLLLLLF6F6F +FF6FLLLLLLLLF6FF +F666LL6666LL666F +F6F6LL6FF6LL6F6F +FF6FLLF66FLLF6FF +F666LLLLLLLL666F +F6F6FLLLLLLF6F6F +FF6FF6FLLF6FF6FF +F666F66LL66F666F +F6F6F66LLLLF6F6F +FF6FF6FLLLLFF6FF +F666F66LL66F666F +F6F6F66LLLLF6F6F +FF6FF6FLLLLFF6FF +F666F666666F666F`], + [crowbar, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLL000LL +LLLLLLLLLL02220L +LLLLLLLLL033020L +LLLLLLLL0330L0LL +LLLLLLL0330LLLLL +LLLLLL0330LLLLLL +LLLLL0330LLLLLLL +LLLL0330LLLLLLLL +LLL0330LLLLLLLLL +LLL030LLLLLLLLLL +LLL00LLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [letter, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLL000000LLLL +LLLLL0222220LLLL +LLLLL020020LLLLL +LLLLL022220LLLLL +LLLLL020020LLLLL +LLLLL022220LLLLL +LLLL020020LLLLLL +LLLL022220LLLLLL +LLLL020020LLLLLL +LLLL000000LLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [rock, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF11F +F666F666666F1111`], + [ladder, bitmap` +F66000666600066F +F6F0006FF6000F6F +FF6F16F66F61F6FF +F66611111111666F +F6F6166FF6616F6F +FF6F11111111F6FF +F66616666661666F +F6F6111111116F6F +FF6F16F66F61F6FF +F66611111111666F +F6F6166FF6616F6F +FF6F11111111F6FF +F66616666661666F +F6F6166FF6616F6F +FF6000F66F0006FF +F66000666600066F`], + [sLadder, bitmap` +F66000666600066F +F6F0006FF6000F6F +FF6F16F66F61F6FF +F66611111111666F +F6F6166FF6616F6F +FF6F11111111F6FF +F66616666661666F +F6F6111111116F6F +FF6F16F66F61F6FF +F66611111111666F +F6F6166FF6616F6F +FF6F11111111F6FF +F66616666661666F +F6F6166FF6616F6F +FF6000F66F0006FF +F66000666600066F`], + [car, bitmap` +F666F666666F666F +F6F6F66FF66F6F6F +FF6FF6F66F6FF6FF +F666LLLLLLLL666F +F6FLL222012LLF6F +FFLL22220122LLFF +LLL1222201222LLF +L111111101111LLL +L1111001011001LL +L11111110111111L +L11111110111111L +L11111110111111L +LLLLLLLLLLLLLLLL +F600066FF660006F +FF0206F66F6020FF +F60006666660006F`], + [lGray, bitmap` +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111`], + [gray, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [blue, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [black, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`] +) + +setSolids([player]) + +let level = 0 +const levels = [ + map` +b........b +....b..b.. +..b.n..... +......b... +b...b..... +..b...b..b +...b...... +.b........ +......b... +.b..b....b`, + map` +bbbbb +bbbbb +bbbbd`, + map` +bbbbb +bbbbb +ebdbr`, + map` +bbbbb +bbbbb +sbrbw`, + map` +bbbbb +bbkbb +dbybo`, + map` +mggggggggm +gmmmmmmmmg +gmmmmmmmmg +gmmmmmmmmg +gmmlmmcmmg +gmmmmmmmmg +gmmmmmmmmg +gmmmmmmmmg +gmmmmmmmmg +mggggggggm`, + map` +.......... +.......... +.......... +.......... +.......... +.......... +.......... +.......... +.......... +..........`, + map` +utbub +btbbb +ufbub`, + map` +tbbbb +tbbbb +tbdbv`, + map` +.......... +.......... +.......... +.......... +.......... +.......... +.......... +.......... +.......... +..........` +] + +setMap(levels[level]) + +setPushables({ + [ player ]: [] +}) + +var haveKey = false; +var haveCrowbar = false; +var haveRock = false; +var playMusic = true; +var kCheck = true; + +const music = tune` +300: C5~300, +300: B5~300, +300: C5~300 + F5^300 + A4^300, +300, +300: C5~300 + A4^300 + F5^300, +300, +300: C5~300, +300: B5~300, +300: C5~300, +300, +300: C5~300, +300, +300: C5~300, +300: B5~300, +300: C5~300 + F5^300 + A4^300, +300, +300: C5~300 + F5^300 + A4^300, +300, +300: D5-300, +300: B4-300, +300: D5-300, +300: E5-300, +300: F5-300, +300: D5-300, +300: B4-300, +300: D5-300, +300: F5^300 + C5~300 + A4^300, +300, +300: C5~300 + F5^300 + A4^300, +300, +300: C5~300, +300` +const collectionSound = tune` +150: F5~150, +150: A5~150, +150: B5~150, +4350` +const doorSound = tune` +500: E4/500 + F4~500, +15500` +var playback = playTune(music, Infinity); + +// Start Screen Text +if(level == 0){ + addText("Press i to Start", {x: 2, y: 5, color:color`0`}); + addText("Trapped", {x: 6, y: 1, color:color`9`}); + addText(" Press k to \n Mute Music", {x: 3, y: 13, color:color`9`}); +} + +// Starts the game +onInput("i", () => { + kCheck = false; + if(level == 0){ + level = 1; + const cLevel = levels[level]; + if (cLevel != undefined) { + setMap(cLevel); + clearText(); + addSprite(0, 2, player); + addText("I was sent to\nthis apartment\nto find a wanted\nman,\nlittle did I know \nwhat would happen.", {x: 0, y: 4, color:color`0`}); + } + } +}); + +let isMusicPlaying = true; + +onInput("k", () => { + kCheck = true; + isMusicPlaying = !isMusicPlaying; + if (isMusicPlaying) { + playMusic = true; + } else { + playMusic = false; + } +}); + +// Moves the player left +onInput("a", () => { + kCheck = false; + if(level != 0 && level != 5 && level != 6 && level != 7 && level != 9){ + getFirst(player).x -= 1; + } +}); + + +// Moves the player Right +onInput("d", () => { + kCheck = false; + if(level != 0 && level != 5 && level != 6 && level != 7 && level != 9){ + getFirst(player).x += 1; + } +}); + +// Enters door +onInput("w", () => { + kCheck = false; + if(level == 1){ + const doorNum = tilesWith(door).length; + const doorCovered = tilesWith(door, player).length; + + if(doorNum == doorCovered){ + level = 2; + const cLevel = levels[level]; + if (cLevel != undefined) { + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + playTune(doorSound); + } + } + } + + if (level == 2){ + const doorNum = tilesWith(door).length; + const door2Num = tilesWith(door2).length; + const doorCovered = tilesWith(door, player).length; + const door2Covered = tilesWith(door2, player).length; + + if(doorNum == doorCovered){ + level = 3; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + playTune(doorSound); + } + else if(door2Num == door2Covered){ + level = 4; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + playTune(doorSound); + if(haveRock == true){ + getFirst(rock).remove(); + addSprite(4, 2, background) + } + if(haveKey == true){ + getFirst(key).remove(); + addSprite(2, 1, background) + addText("Key Obtained", {x: 4, y: 5, color:color`0`}); + } + } + } + + if(level == 3){ + const door2Num = tilesWith(door2).length; + const door2Covered = tilesWith(door2, player).length; + const safeNum = tilesWith(safe).length; + const safeCovered = tilesWith(safe, player).length; + const windowNum = tilesWith(window).length; + const windowCovered = tilesWith(window, player).length; + + if(door2Num == door2Covered){ + level = 2; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + playTune(doorSound); + } + else if(safeNum == safeCovered && haveKey){ + level = 5; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addText("Press s to exit Safe", {x: 0, y: 15, color:color`2`}); + addText("Press j to Open \n Letter", {x: 3, y: 3, color:color`2`}); + playTune(doorSound); + + if(!haveCrowbar){ + addText("Press l to Take \n Crowbar", {x: 3, y: 10, color:color`2`}); + } + else if(haveCrowbar){ + getFirst(crowbar).remove(); + addSprite(6, 4, gray) + } + + } + else if(windowNum == windowCovered && haveCrowbar){ + level = 7; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 0, player); + playTune(doorSound); + } + + } + + if(level == 4){ + const doorNum = tilesWith(door).length; + const doorCovered = tilesWith(door, player).length; + const rockNum = tilesWith(rock).length; + const rockCovered = tilesWith(rock, player).length; + const specialBackgroundNum = tilesWith(specialBackground).length; + const specialBackgroundCovered = tilesWith(specialBackground, player).length; + const keyNum = tilesWith(key).length; + + if(doorNum == doorCovered){ + level = 2; + const cLevel = levels[level]; + if (cLevel != undefined) { + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + playTune(doorSound); + } + } + + if(rockNum == rockCovered && rockNum != 0){ + haveRock = true; + getFirst(rock).remove(); + addSprite(4, 2, background) + playTune(collectionSound); + } + + if(specialBackgroundNum == specialBackgroundCovered && keyNum != 0 && haveRock){ + haveKey = true + getFirst(key).remove(); + addSprite(2, 1, background) + addText("Key Obtained", {x: 4, y: 5, color:color`0`}); + playTune(collectionSound); + } + + } + + if(level == 8){ + const carNum = tilesWith(car).length; + const carCovered = tilesWith(car, player).length; + + if(carNum == carCovered){ + level = 9; + const cLevel = levels[level]; + if (cLevel != undefined) { + setMap(cLevel); + clearText(); + addText(" You did it, \nyou finally made \n it out", {x: 2, y: 3, color:color`0`}); + addText("this time...", {x: 4, y: 8, color:color`3`}); + addText(" Thank you for \n playing :)", {x: 1, y: 11, color:color`9`}); + addText(" Press s to \n Go Back to Menu", {x: 1, y: 14, color:color`9`}); + playTune(doorSound); + } + + } + } + +}); + +onInput("j", () => { + kCheck = false; + if(level == 5){ + level = 6; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addText("Well well well \ndetective, after \nall this time I \nhave to let you \non a little... \nSecret.", {x: 2, y: 1, color:color`0`}); + addText("Eua'bk hkkt \ningyotm \ng mnuyz... \nUrj Lxoktj", {x: 4, y: 8, color:color`3`}); + addText("Press s to \nexit Safe", {x: 4, y: 13, color:color`0`}); + } +}); + +onInput("l", () => { + kCheck = false; + if(level == 5){ + if(!haveCrowbar){ + haveCrowbar = true; + getFirst(crowbar).remove(); + addSprite(6, 4, gray); + addText(" ", {x: 3, y: 10, color:color`2`}); + addText(" ", {x: 3, y: 11, color:color`2`}); + playTune(collectionSound); + } + } +}); + +onInput("s", () => { + kCheck = false; + if(level == 5){ + level = 3; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + } + else if(level == 6){ + level = 3; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + } + else if(level == 7){ + const sLadderNum = tilesWith(sLadder).length; + const sLadderCovered = tilesWith(sLadder, player).length; + const ladderNum = tilesWith(ladder).length; + const ladderCovered = tilesWith(ladder, player).length; + + getFirst(player).y += 1; + if(sLadderNum == sLadderCovered){ + level = 8; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addSprite(1, 2, player); + } + } + else if(level == 9){ + level = 0; + const cLevel = levels[level]; + setMap(cLevel); + clearText(); + addText("Press i to Start", {x: 2, y: 5, color:color`0`}); + addText("Trapped", {x: 6, y: 1, color:color`9`}); + addText(" Press k to \n Mute Music", {x: 3, y: 13, color:color`9`}); + haveKey = false; + haveCrowbar = false; + haveRock = false; + } +}); + +afterInput(() => { + +// If hover over door, then show text + if(level == 1){ + const doorNum = tilesWith(door).length; + const doorCovered = tilesWith(door, player). length; + + if(doorNum == doorCovered){ + addText("Press w to Enter", {x: 0, y: 2, color:color`0`}); + } + else{ + addText(" ", {x: 0, y: 2, color:color`0`}); + } + } + +// If hover over door, then show text + if(level == 2){ + const doorNum = tilesWith(door).length; + const eDoorNum = tilesWith(eDoor).length; + const door2Num = tilesWith(door2).length; + const doorCovered = tilesWith(door, player).length; + const eDoorCovered = tilesWith(eDoor, player).length; + const door2Covered = tilesWith(door2, player).length; + + if(eDoorNum == eDoorCovered){ + if(!haveKey){ + addText("It locked behind me!\nI have to find a \nway out!", {x: 0, y: 2, color:color`0`}); + } + else if(haveKey){ + addText("This key doesnt\nwork here", {x: 0, y: 2, color:color`0`}); + } + } + else if(doorNum == doorCovered){ + addText("Press w to Enter", {x: 0, y: 2, color:color`0`}); + } + else if(door2Num == door2Covered){ + addText("Press w to Enter", {x: 0, y: 2, color:color`0`}); + } + else{ + addText(" \n \n ", {x: 0, y: 2, color:color`0`}); + } + } + +// If hover over Item, then show text + if(level == 3){ + const door2Num = tilesWith(door2).length; + const door2Covered = tilesWith(door2, player).length; + const safeNum = tilesWith(safe).length; + const safeCovered = tilesWith(safe, player).length; + const windowNum = tilesWith(window).length; + const windowCovered = tilesWith(window, player).length; + + if(door2Num == door2Covered){ + addText("Press w to Enter", {x: 0, y: 2, color:color`0`}); + } + else if(safeNum == safeCovered){ + if(!haveKey){ + addText("Why does this \nSafe need a Key?", {x: 0, y: 2, color:color`0`}); + } + else if(haveKey){ + addText("Press w to Open Safe", {x: 0, y: 2, color:color`0`}); + } + } + else if(windowNum == windowCovered){ + if(!haveCrowbar){ + addText("It's boarded, \nI need something to \nBreak it Open", {x: 0, y: 2, color:color`0`}); + } + else if(haveCrowbar){ + addText("Press w to Escape", {x: 0, y: 2, color:color`0`}); + } + } + else{ + addText(" \n \n ", {x: 0, y: 2, color:color`0`}); + } + } + +// If hover over Item, then show text + if(level == 4){ + const doorNum = tilesWith(door).length; + const doorCovered = tilesWith(door, player).length; + const rockNum = tilesWith(rock).length; + const rockCovered = tilesWith(rock, player).length; + const specialBackgroundNum = tilesWith(specialBackground).length; + const specialBackgroundCovered = tilesWith(specialBackground, player).length; + const keyNum = tilesWith(key).length; + + if(doorNum == doorCovered){ + addText("Press w to Enter", {x: 0, y: 2, color:color`0`}); + } + else if(rockNum == rockCovered && rockNum != 0){ + addText("Press w to Pick Up\nRock", {x: 0, y: 2, color:color`0`}); + } + else if(specialBackgroundNum == specialBackgroundCovered && keyNum != 0){ + if(!haveRock){ + addText("That key is too high\nmaybe if I \nthrow something.", {x: 0, y: 2, color:color`0`}); + } + else if(haveRock){ + addText("Press w to Throw\nRock at Key", {x: 0, y: 2, color:color`0`}); + } + } + else{ + addText(" \n \n ", {x: 0, y: 2, color:color`0`}); + } + } + + if(level == 7){ + const sLadderNum = tilesWith(sLadder).length; + const sLadderCovered = tilesWith(sLadder, player).length; + const ladderNum = tilesWith(ladder).length; + const ladderCovered = tilesWith(ladder, player).length; + + if((ladderNum - 1) == ladderCovered){ + addText("Press s to Go \nDown", {x: 2, y: 3, color:color`2`}); + } + else if(sLadderNum == sLadderCovered){ + addText("Press s to Go \nDown", {x: 2, y: 3, color:color`2`}); + } + else{ + addText(" \n \n ", {x: 2, y: 3, color:color`0`}); + } + + } + + if(level == 8){ + const doorNum = tilesWith(door).length; + const doorCovered = tilesWith(door, player).length; + const carNum = tilesWith(car).length; + const carCovered = tilesWith(car, player).length; + + if(doorNum == doorCovered){ + addText("Don't want to go in \nthere again", {x: 0, y: 3, color:color`0`}); + } + else if(carNum == carCovered){ + addText("Press w to get out \nof here", {x: 0, y: 3, color:color`0`}); + } + else{ + addText(" \n \n ", {x: 0, y: 3, color:color`0`}); + } + + } + + if (isMusicPlaying && kCheck) { + playback = playTune(music, Infinity) + } + else if(!isMusicPlaying && kCheck) { + playback.end() + } + +}) diff --git a/games/WCfinal.js b/games/WCfinal.js new file mode 100644 index 0000000000..97113166ba --- /dev/null +++ b/games/WCfinal.js @@ -0,0 +1,434 @@ +/* +@title: WCfinal +@author: pulvis16 +@tags: [] +@addedOn: 2024-12-04 +*/ + +const melody = tune` +188.67924528301887: E4^188.67924528301887, +188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5~188.67924528301887, +188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5~188.67924528301887, +188.67924528301887: A4^188.67924528301887 + A5-188.67924528301887 + C4^188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5-188.67924528301887 + D4^188.67924528301887, +188.67924528301887, +188.67924528301887: A4^188.67924528301887 + C4/188.67924528301887, +188.67924528301887: G4^188.67924528301887 + G5-188.67924528301887 + C4/188.67924528301887, +188.67924528301887: A4^188.67924528301887 + A5-188.67924528301887 + C4/188.67924528301887, +188.67924528301887: C4/188.67924528301887, +188.67924528301887: A4^188.67924528301887, +188.67924528301887: G4^188.67924528301887, +188.67924528301887: E4^188.67924528301887, +188.67924528301887: G4^188.67924528301887 + G5/188.67924528301887, +188.67924528301887: E4^188.67924528301887, +188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5~188.67924528301887, +188.67924528301887: C4/188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5~188.67924528301887 + C4/188.67924528301887, +188.67924528301887: A4^188.67924528301887 + A5-188.67924528301887 + C4/188.67924528301887, +188.67924528301887: B4^188.67924528301887 + B5-188.67924528301887 + C4/188.67924528301887, +188.67924528301887, +188.67924528301887: A4^188.67924528301887 + C4^188.67924528301887, +188.67924528301887: G4^188.67924528301887 + G5-188.67924528301887 + D4^188.67924528301887, +188.67924528301887: A4^188.67924528301887 + A5-188.67924528301887, +188.67924528301887, +188.67924528301887: A4^188.67924528301887, +188.67924528301887: G4^188.67924528301887, +188.67924528301887: E4^188.67924528301887, +188.67924528301887: G4^188.67924528301887 + G5/188.67924528301887` + + +const background= "h" +const player = "p" +const car = "c" +const spring = "s" +const spring2= "S" +const spring3= "r" +const spring4= "R" +const ball= "b" +const player2 ="P" +const goal ="g" +const goal2 ="G" +var isGoal = false; +var stopGoal = false; +let i = 3; +let goalP1 = 0; +let goalP2 = 0; + +setLegend( + [ player, bitmap` +.....7777777.... +...77777777777.. +..777407774077.. +..7777777777777. +7777788888877777 +7777777887777777 +77..77777777..77 +77..33333333...7 +77..33.33.33...7 +7...33.33.33.... +....L3....L3.... +....1L....1L.... +....1L....1L.... +....11....11.... +....100...100... +....000...000...` ], + [ player2, bitmap` +.....HHHHHHH.... +...HHHHHHHHHHH.. +..HHH50HHH50HH.. +..HHHHHHHHHHHHH. +HHHHH888888HHHHH +HHHHHHH88HHHHHHH +HH..HHHHHHHH..HH +HH..99999999...H +HH..99.99.99...H +H...99.99.99.... +....69....69.... +....F6....F6.... +....F6....F6.... +....FF....FF.... +....F00...F00... +....000...000...` ], + [ ball, bitmap` +................ +................ +................ +................ +......00000..... +.....0000000.... +....022000220... +....022000220... +....000200000... +....000000000... +....022002000... +.....0200220.... +......00000..... +................ +................ +................` ], + [ car, bitmap` +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111 +1111111111111111` ], + [ spring, bitmap` +9933CC11C1110000 +99331CCCCCCCCC0C +99331CCCC1CCLC0C +9333111CCCCCCC0C +9333C111CCCCCCCC +3333C111CCCL0CCC +3333CC11CCCL0LCC +3333CC11CCCCCC0C +9333CC11CCCCCCLC +9333CC1LL0CC0CLC +9933CCLLLCCC0CLC +9933CLLLLCCCLC0C +9933LLLCFFCLLCFC +9933L0CCCCCLCFFC +9993CCCCCCCCCFFF +9993CCCCCCFCFCFF` ], + [ spring2, bitmap` +0CCCCCCCCCCCCCFF +0000CCC0LLL0FFFF +0CCCCCLCCCCCCFFC +0CLCC00CC00LLCCF +1CCCCLLCCCCCLLCC +1CCCCCCCCCCCCCCF +1C1CCCCCC0CCFCCC +CCCCCCCCCLLLFCCC +1CCC11111LLLCCCC +1CC1111111LLLCCC +CCC111CCCCCLL0CC +C111CCCCCCCCLLCC +3333333333333333 +3333333333333399 +9993333333999999 +9999933399999999` ], + [ spring3, bitmap` +0000111C11CC3399 +C0CCCCCCCCC13399 +C0CLCC1CCCC13399 +C0CCCCCCC1113339 +CCCCCCCC111C3339 +CCC0LCCC111C3333 +CCL0LCCC11CC3333 +C0CCCCCC11CC3333 +CLCCCCCC11CC3339 +CLC0CC0LL1CC3339 +CLC0CCCLLLCC3399 +C0CLCCCLLLLC3399 +CFCLLCFFCLLL3399 +CFFCLCCCCC0L3399 +FFFCCCCCCCCC3999 +FFCFCFCCCCCC3999` ], + [ spring4, bitmap` +9999933399999999 +9993333333999999 +3333333333333399 +3333333333333333 +C111CCCCCCCCLLCC +CCC111CCCCCLL0CC +1CC1111111LLLCCC +1CCC11111LLLCCCC +CCCCCCCCCLLLFCCC +1C1CCCCCC0CCFCCC +1CCCCCCCCCCCCCCF +1CCCCLLCCCCCLLCC +0CLCC00CC00LLCCF +0CCCCCLCCCCCCFFC +0000CCC0LLL0FFFF +0CCCCCCCCCCCCCFF` ], + [ background, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD` ], + [ goal, bitmap` +2.2.2.2..2..2..2 +.2.2.2.2..2..22. +..2.2.2.2..2.22. +2..2.2.2.2..2..2 +.2..2.2.2.22.2.. +..2..2.2.222..2. +2..2..2.222.2..2 +.2..2..222.2.2.. +..2..2.22.2.2.2. +2..2..2..2.2.2.2 +.2..22.2..2.2.2. +..2.22..2..2.2.2 +2..22.2..2..2.2. +.22..2.2..2..2.2 +.22..22.2..2..2. +2..22..2.2..2..2`], + [ goal2, bitmap` +2.2.2.2..2..2..2 +.2.2.2.2..2..22. +..2.2.2.2..2.22. +2..2.2.2.2..2..2 +.2..2.2.2.22.2.. +..2..2.2.222..2. +2..2..2.222.2..2 +.2..2..022.2.2.. +..2..2022.2.2.2. +2..2..2..2.2.2.2 +.2..22.2..2.2.2. +..2.22..2..2.2.2 +2..22.2..2..2.2. +.22..2.2..2..2.2 +.22..22.2..2..2. +2..22..2.2..2..2`] +) + +setSolids([ball, player, player2]) +setBackground("h") +let level = 0 +const levels = [ + map` +cSSSSSScggggcSSSSSSc +rhhhhhhcccccchhhhhhs +rh................hs +rh................hs +rh.......P........hs +rh................hs +rh................hs +rh................hs +rh.......b........hs +rh................hs +rh................hs +rh........p.......hs +rh................hs +rh................hs +rhhhhhhcccccchhhhhhs +cRRRRRRcGGGGcRRRRRRc` +] + +setMap(levels[level]) +const playback = playTune(melody, Infinity) +setPushables({ + [player]: [ ball, player ], + [player2]: [ ball, player2 ] +}) +onInput("s", () => { + getFirst(player).y += 1 +}) +onInput("a", () => { + getFirst(player).x -= 1 +}) +onInput("w", () => { + getFirst(player).y -= 1 +}) +onInput("d", () => { + getFirst(player).x += 1 +}) + +onInput("k", () => { + getFirst(player2).y += 1 +}) +onInput("j", () => { + getFirst(player2).x -= 1 +}) +onInput("i", () => { + getFirst(player2).y -= 1 +}) +onInput("l", () => { + getFirst(player2).x += 1 +}) + +afterInput(() => { + +}) +function gameLoop() { + SpringBehaviour(); + NetBehaviour(); + DisplayScore(); + +} +function gameTimer() +{ + + + if(isGoal) + { + clearText(); + if(i > 0) + { + + addText(`Starting in: ${i}`, { + x: 3, + y: 6, + color: color`9` + }); + i--; + + } + else + { + i = 3; + isGoal = false; + setMap(levels[level]); + stopGoal = false; + } + + } + + +} +const interval = setInterval(gameLoop, 200); +const intervals = setInterval(gameTimer, 1000); +function SpringBehaviour() +{ + const ballSprite = getFirst(ball); + const spritesAtSprings = getTile(ballSprite.x, ballSprite.y); + + spritesAtSprings.forEach(sprite => { + if (sprite.type === spring) + { + ballSprite.x -= 2 + + + + }else if(sprite.type === spring2) + { + ballSprite.y += 2 + + } + else if(sprite.type === spring3) + { + ballSprite.x += 2 + } + else if(sprite.type === spring4) + { + ballSprite.y -= 2 + } + }); + + + + + + + +} +function NetBehaviour() +{ + const ballSprite = getFirst(ball); + const spritesAtSprings = getTile(ballSprite.x, ballSprite.y); + + spritesAtSprings.forEach(sprite => { + if (sprite.type === goal) + { + addText("Gooooooooooal!!!!", { + x: 2, + y: 4, + color: color`2` + }) + + isGoal = true; + if(stopGoal === false) + { + goalP1++; + stopGoal = true; + } + + } else if(sprite.type === goal2) + { + addText("Gooooooooooal!!!!", { + x: 2, + y: 4, + color: color`2` + }) + + isGoal = true; + if(stopGoal === false) + { + goalP2++; + stopGoal = true; + } + + }}); + + +} +function DisplayScore() +{ + + addText(`${goalP1}`, { + x: 0, + y: 0, + color: color`5` + }) + addText(`${goalP2}`, { + x: 19, + y: 0, + color: color`3` + }) + +} diff --git a/games/beyblade_battle.js b/games/beyblade_battle.js new file mode 100644 index 0000000000..1d0fa2e477 --- /dev/null +++ b/games/beyblade_battle.js @@ -0,0 +1,585 @@ +/* +@title: Beyblade Battle +@author: Shweta Shaw +@tags: ['multiplayer'] +@addedOn: 2024-12-6 + +Instructions: + +Hit "run" to execute the code and +start the game (you can also press shift+enter). + +Controls for Player 1: + w -> UP + a -> LEFT + s -> DOWN + d -> RIGHT + +Controls for Player 2: + i -> UP + j -> LEFT + k -> DOWN + l -> RIGHT + +i for next level +w to reset the game +*/ + +const player1 = "1"; +const player2 = "2"; +const image1 = "b"; +const image2 = "o"; +const image3 = "u"; +const image4 = "n"; +const image5 = "d"; +const image6 = "a"; +const image7 = "r"; +const image8 = "y"; +const image9 = "c"; +const image10 = "l"; +const image11 = "i"; +const image12 = "p"; +const a = "x"; +const b = "t"; +const c = "m"; +const d = "z"; +const fillWhite = "9"; +const fillBlue = "6"; + +// win bool +let v = 0; +const play1 = tune` +612.2448979591836, +612.2448979591836: C5-612.2448979591836 + B4^612.2448979591836 + A4^612.2448979591836 + D5~612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + A4^612.2448979591836 + G4^612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + E4^612.2448979591836 + F5~612.2448979591836 + E5/612.2448979591836, +612.2448979591836: C5-612.2448979591836 + B4-612.2448979591836 + E4^612.2448979591836 + F5~612.2448979591836 + G5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + E4^612.2448979591836 + F4^612.2448979591836 + G4^612.2448979591836 + G5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + G4^612.2448979591836 + A4^612.2448979591836 + G5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + A4^612.2448979591836 + G4^612.2448979591836 + G5~612.2448979591836 + F5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + C5-612.2448979591836 + G4^612.2448979591836 + F4^612.2448979591836 + F5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + E5~612.2448979591836 + D5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + E4^612.2448979591836 + D5~612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + B4-612.2448979591836 + E4^612.2448979591836 + F4^612.2448979591836 + G4^612.2448979591836, +612.2448979591836: B4-612.2448979591836 + G4^612.2448979591836 + A4^612.2448979591836 + G5~612.2448979591836 + A5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + A4^612.2448979591836 + A5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + C5-612.2448979591836 + A4^612.2448979591836 + G4^612.2448979591836 + A5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + A5~612.2448979591836 + G5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + E4^612.2448979591836 + G5~612.2448979591836 + F5~612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + B4-612.2448979591836 + E4^612.2448979591836 + F4^612.2448979591836 + G4^612.2448979591836, +612.2448979591836: B4-612.2448979591836 + A4^612.2448979591836 + D5~612.2448979591836 + E5~612.2448979591836 + F5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + A4^612.2448979591836 + G4^612.2448979591836 + G5~612.2448979591836 + A5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + C5-612.2448979591836 + G4^612.2448979591836 + F4^612.2448979591836 + A5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + E4^612.2448979591836 + G5~612.2448979591836 + F5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + E4^612.2448979591836 + D4^612.2448979591836 + F5~612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + D4^612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + B4-612.2448979591836 + D4^612.2448979591836 + E5~612.2448979591836, +612.2448979591836: B4-612.2448979591836 + E4^612.2448979591836 + F4^612.2448979591836 + G4^612.2448979591836 + A4^612.2448979591836, +612.2448979591836: B4-612.2448979591836 + A4^612.2448979591836 + A5~612.2448979591836 + D5/612.2448979591836, +612.2448979591836: B4-612.2448979591836 + C5-612.2448979591836 + A4^612.2448979591836 + A5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + A4^612.2448979591836 + G4^612.2448979591836 + G5~612.2448979591836 + F5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + G4^612.2448979591836 + F4^612.2448979591836 + D5~612.2448979591836 + E5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + D5~612.2448979591836 + E5~612.2448979591836 + A5~612.2448979591836, +612.2448979591836: C5-612.2448979591836 + F4^612.2448979591836 + G5~612.2448979591836 + F5~612.2448979591836 + E5~612.2448979591836`; + +setLegend( + [player1, bitmap` +....00000000.... +...0000000000... +..000000000000.. +.00006666660000. +0000666666660000 +0006666666666000 +0006663333666000 +0006663333666000 +0006663333666000 +0006663333666000 +0006666666666000 +0000666666660000 +.00006666660000. +..000000000000.. +...0000000000... +....00000000....`], + [player2, bitmap` +....00000000.... +...0000000000... +..000000000000.. +.00003333330000. +0000333333330000 +0003333333333000 +0003332222333000 +0003332222333000 +0003332222333000 +0003332222333000 +0003333333333000 +0000333333330000 +.00003333330000. +..000000000000.. +...0000000000... +....00000000....`], + [image1, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +0000000000000000 +0000000000000000 +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666`], + [image2, bitmap` +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666`], + [image9, bitmap` +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600..........`], + [image3, bitmap` +6666666666666666 +6666666666666666 +6666666666666666 +6666666666666666 +0000000000000000 +0000000000000000 +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [image4, bitmap` +..............00 +..............00 +............0066 +............0066 +............0066 +............0066 +............0066 +..........000066 +..........000066 +..........000066 +..........000066 +..........006666 +..........006666 +..........006666 +..........006666 +..........006666`], + [image5, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +........00000000 +........00000000 +..00000000006666 +..00000000006666 +0066666666666666 +0066666666666666`], + [image6, bitmap` +..........006666 +..........006666 +..........006666 +..........006666 +..........006666 +..........000066 +..........000066 +..........000066 +............0066 +............0066 +............0066 +............0066 +............0066 +............0066 +..............00 +..............00`], + [image8, bitmap` +0066666666666666 +0066666666666666 +..00000000066666 +..00000000066666 +.......000000000 +.......000000000 +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [image7, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +000000000....... +000000000....... +66666000000000.. +66666000000000.. +6666666666666600 +6666666666666600`], + [image10, bitmap` +00.............. +00.............. +6600............ +6600............ +6600............ +6600............ +6600............ +6600............ +660000.......... +660000.......... +660000.......... +666600.......... +666600.......... +666600.......... +666600.......... +666600..........`], + [image11, bitmap` +666600.......... +666600.......... +666600.......... +666600.......... +666600.......... +660000.......... +660000.......... +660000.......... +660000.......... +6600............ +6600............ +6600............ +6600............ +6600............ +00.............. +00..............`], + [image12, bitmap` +6666666666666600 +6666666666666600 +66666000000000.. +66666000000000.. +000000000....... +000000000....... +................ +................ +................ +................ +................ +................ +................ +................ +................ +................`], + [fillWhite, bitmap` +................ +................ +................ +................ +................ +................ +......2222...... +......2222...... +......2222...... +......2222...... +................ +................ +................ +................ +................ +................`], + [fillBlue, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [a, bitmap` +6666667777777777 +6666667777777777 +6666677777777777 +6666677777777777 +6666777777777777 +6677777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [b, bitmap` +7777777777666666 +7777777777666666 +7777777777766666 +7777777777766666 +7777777777776666 +7777777777777766 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [c, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +6677777777777777 +6666777777777777 +6666677777777777 +6666677777777777 +6666667777777777 +6666667777777777`], + [d, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777766 +7777777777776666 +7777777777766666 +7777777777766666 +7777777777666666 +7777777777666666`], +); +let level = 0; + +const lvl0 = map` +.dbbbbbr. +nx.....tl +o.9...9.c +o.1.9.2.c +o.9...9.c +am.....zi +.yuuuuup.`; +const lvl1 = map` +.dbbbbbr. +nx..9..tl +o.......c +o91...29c +o.......c +am..9..zi +.yuuuuup.`; +const lvl2 = map` +.dbbbbbr. +nx9...9tl +o.......c +o91.9.29c +o.......c +am9...9zi +.yuuuuup.`; +const lvl3 = map` +9dbbbbbr9 +nx..9..tl +o9.....9c +o91.9.29c +o9.....9c +am..9..zi +9yuuuuup9`; +if(level==0){ + setMap(lvl0); +} + + +setSolids([player1, player2]); + +let playback = playTune(play1, Infinity); + +setBackground(fillBlue); + +setPushables({ + [player1]: [player2], + [player2]: [player1] +}); + +onInput("w", () => { + if (v == 1){ + setMap(lvl0); + level=0; + setSolids([player1,player2]); + clearText(); + v=0; + playback = playTune(play1, Infinity); + return; + } + if (v == 0) getFirst(player1).y -= 1; +}); +onInput("s", () => { + if (v == 0) getFirst(player1).y += 1; +}); +onInput("a", () => { + if (v == 0) getFirst(player1).x -= 1; +}); +onInput("d", () => { + if (v == 0) getFirst(player1).x += 1; +}); + +onInput("i", () => { + // reset the game if the game is over + if (v == 1) { + if(level==1){ + setMap(lvl1); + clearText(); + setSolids([fillWhite,player1,player2]); + } + if(level==2){ + setMap(lvl2); + clearText(); + setSolids([fillWhite,player1,player2]); + } + if(level==3){ + setMap(lvl3); + clearText(); + setSolids([fillWhite,player1,player2]); + } + playback = playTune(play1, Infinity); + v=0; + return; + } + if (v == 0) getFirst(player2).y -= 1 +}); +onInput("k", () => { + if (v == 0) getFirst(player2).y += 1; +}); +onInput("j", () => { + if (v == 0) getFirst(player2).x -= 1; +}); +onInput("l", () => { + if (v == 0) getFirst(player2).x += 1; +}); + +// winning logic +afterInput(() => { + // player 1 is out of the stadium + if (getFirst(player1).x == 0 || getFirst(player1).x == 8 || getFirst(player1).y == 0 || getFirst(player1).y == 6) { + addText("Player2 wins", { + x: 4, + y: 7, + color: color`5`, + }); + level++; + if(level<=3){ + addText("Press i for Level " + level, { + x: 1, + y: 9, + color: color`C`, + }); + } + if(level==4){ + addText("Press w to ResetGame", { + x: 0, + y: 9, + color: color`C`, + }); + } + v = 1; + playback.end(); + } + // player 2 is out of the stadium + if (getFirst(player2).x == 0 || getFirst(player2).x == 8 || getFirst(player2).y == 0 || getFirst(player2).y == 6) { + addText("Player1 Wins", { + x: 4, + y: 7, + color: color`5`, + }); + level++; + if(level<=3){ + addText("Press i for Level " + level, { + x: 1, + y: 9, + color: color`C`, + }); + } + if(level==4){ + addText("Press w to ResetGame", { + x: 0, + y: 9, + color: color`C`, + }); + } + v = 1; + playback.end(); + } +}); diff --git a/games/catch-the-banana.js b/games/catch-the-banana.js new file mode 100644 index 0000000000..cea1dad21a --- /dev/null +++ b/games/catch-the-banana.js @@ -0,0 +1,278 @@ +/* +@title: Catch The Banana +@author: Sayed Hashim +@tags: ["timed", "retro"] +@addedOn: 2024-11-29 +*/ + +const player = "p"; +const banana = "b"; +const blueBanana = "t" +const lava = "l"; +const backgroundTune = tune` +202.7027027027027: C4^202.7027027027027, +202.7027027027027: C4/202.7027027027027, +202.7027027027027, +202.7027027027027: E4/202.7027027027027, +202.7027027027027: E4-202.7027027027027, +202.7027027027027: E4-202.7027027027027, +202.7027027027027: F4/202.7027027027027, +202.7027027027027: G4/202.7027027027027, +202.7027027027027, +202.7027027027027: B4/202.7027027027027, +202.7027027027027: C5/202.7027027027027, +202.7027027027027, +202.7027027027027: A4/202.7027027027027, +202.7027027027027: G4/202.7027027027027, +202.7027027027027, +202.7027027027027: G4^202.7027027027027, +202.7027027027027: G4-202.7027027027027, +202.7027027027027: F4-202.7027027027027, +202.7027027027027, +202.7027027027027: B4^202.7027027027027, +202.7027027027027: A4-202.7027027027027, +202.7027027027027: G4-202.7027027027027, +405.4054054054054, +202.7027027027027: B4/202.7027027027027, +202.7027027027027: C5/202.7027027027027, +202.7027027027027, +202.7027027027027: B4/202.7027027027027, +202.7027027027027: A4/202.7027027027027, +202.7027027027027, +202.7027027027027: C4^202.7027027027027, +202.7027027027027: C4/202.7027027027027` +const catchSound = tune` +71.59904534606206: B5~71.59904534606206, +71.59904534606206: B5~71.59904534606206, +71.59904534606206: B5~71.59904534606206 + A5~71.59904534606206, +71.59904534606206: B5~71.59904534606206 + A5~71.59904534606206, +71.59904534606206: B5~71.59904534606206 + A5~71.59904534606206, +1933.1742243436754` +const burnSound = tune` +99.00990099009901: A5/99.00990099009901 + B5/99.00990099009901, +99.00990099009901: B5/99.00990099009901 + A5/99.00990099009901 + G5~99.00990099009901, +99.00990099009901: B5/99.00990099009901 + A5/99.00990099009901 + G5~99.00990099009901, +99.00990099009901: B5/99.00990099009901 + A5/99.00990099009901 + G5~99.00990099009901, +99.00990099009901: B5/99.00990099009901 + A5/99.00990099009901 + G5~99.00990099009901, +2673.267326732673` +playTune(backgroundTune, Infinity) + + + +setLegend( + [player, bitmap` +................ +................ +................ +................ +................ +................ +................ +................ +..000000000000.. +.0LLLLLLLLLLLL0. +0LLLLLLLLLLLLLL0 +00LLLLLLLLLLLL00 +0100000000000010 +0111111111111110 +.01111111111110. +..000000000000..`], + [banana, bitmap` +................ +................ +.......000...... +.......060...... +....0.0660...... +....0.06660.0... +....0003630.0... +......0666000... +......05550..... +......05650..... +.....066660..... +.....06660...... +......000....... +......0.0....... +......0.0....... +.....0...0......`], + [blueBanana, bitmap` +................ +................ +.......000...... +.......050...... +....0.0550...... +....0.05550.0... +....0003530.0... +......0555000... +......07770..... +......07570..... +.....055550..... +.....05550...... +......000....... +......0.0....... +......0.0....... +.....0...0......`], + [lava, bitmap` +................ +.......699999... +....6999966696.. +96..966996969669 +6969966969999969 +9999999999666699 +6966966699999669 +6999999999699999 +6699669669999969 +6996999999699999 +9999666699999999 +9966999699996966 +9696999999666669 +9999666666996996 +9999999996699999 +6669666999999666`] +); + +setSolids([]); + +let level = 0; +const levels = [ + map` +....b.... +......... +......... +......... +......... +....p.... +lllllllll` +]; + +setMap(levels[level]); + +setPushables({ + [player]: [] +}); + +let gameOver = false; + +const gameOverFunction = () => { + gameOver = true; + addText("Game Over\npress j to restart", { x: 1, y: 7, color: color`3` }); + addText("Score: " + score.toString(), { x: 1, y: 9, color: color`3` }); +}; + +onInput("d", () => { + if (!gameOver) { + const playerSprite = getFirst(player); + if (playerSprite.x < width() - 1) { + playerSprite.x += 1; + } + } +}); + +onInput("a", () => { + if (!gameOver) { + const playerSprite = getFirst(player); + if (playerSprite.x > 0) { + playerSprite.x -= 1; + } + } +}); + +let score = 0; +let timer = 60; + +onInput("j", () => { + gameOver = false; + score = 0; + timer = 60; + setMap(levels[level]); + clearText(); +}); + +function handleBananaCollision(bananaSprite, points, timeBonus = 0) { + const playerSprite = getFirst(player); + if (bananaSprite.y === playerSprite.y && bananaSprite.x === playerSprite.x) { + playTune(catchSound); + score += points; + timer += timeBonus; + bananaSprite.y = 0; + bananaSprite.x = Math.floor(Math.random() * width()); + return true; + } + return false; +} + +function handleLavaCollision(bananaSprite) { + const lavaSprite = getFirst(lava); + if (bananaSprite.y === lavaSprite.y) { + playTune(burnSound); + return true; + } + return false; +} + +setInterval(() => { + if (gameOver) return; + + if (timer > 0) { + timer -= 1; + } else { + gameOverFunction(); + } +}, 1000); + + +setInterval(() => { + if (gameOver) return; + + const bananaSprite = getFirst(banana); + getFirst(banana).y += 1; + + addText("Score: " + score.toString().padStart(2, '0'), { x: 0, y: 0, color: color`6` }); + addText("Time: " + timer.toString().padStart(2, '0'), { x: 0, y: 1, color: color`6` }); + const playerSprite = getFirst(player); + if (bananaSprite.y === playerSprite.y && bananaSprite.x === playerSprite.x) { + playTune(catchSound); + bananaSprite.y = 0; + bananaSprite.x = Math.floor(Math.random() * width()); + score += 1; + } + + const lavaSpirte = getFirst(lava); + if (bananaSprite.y === lavaSpirte.y) { + playTune(burnSound); + if (score > 0) { + bananaSprite.y = 0; + bananaSprite.x = Math.floor(Math.random() * width()); + score -= 1; + } else { + gameOverFunction(); + } + } + +}, 250); + +setInterval(() => { + if (gameOver) return; + + if (!getFirst(blueBanana) && Math.random() < 0.05) { + addSprite(Math.floor(Math.random() * width()), 0, blueBanana); + } + + const blueBananaSprite = getFirst(blueBanana); + if (blueBananaSprite) { + blueBananaSprite.y += 1; + + const playerSprite = getFirst(player); + if (blueBananaSprite.y === playerSprite.y && blueBananaSprite.x === playerSprite.x) { + blueBananaSprite.remove(); + score += 3; + timer += 5; + playTune(catchSound); + } + + const lavaSprite = getFirst(lava); + if (blueBananaSprite.y === lavaSprite.y) { + blueBananaSprite.remove(); + playTune(burnSound); + } + } +}, 250); diff --git a/games/giggler_puzzles.js b/games/giggler_puzzles.js new file mode 100644 index 0000000000..b429684ffb --- /dev/null +++ b/games/giggler_puzzles.js @@ -0,0 +1,1020 @@ +/* +@title: Giggler Puzzles +@author: Portable-Certified +@addedOn: 2025-01-03 +@tags: [] +Hi! This is a puzzle game. That's about it. + +YOUR OBJECTIVE: + - Traverse with your smiling friend to reach the giggler by + moving boxes, identifying suspicious walls, filling pressure plates + which opens locks, AND EVENTUALLY REACHING THE GIGGLER! + + YOU ARE NOT ALONE. + + CONTROLS: + - WASD to move + - I to reset level + - K to skip a level (5 Max) +*/ + +const smile = "p" +const block = "b" +const giggler = "g" +const fakegiggler = "f" +const broken = "r" +const fakeblock = "v" +const gaggler = "k" +const fake = "a" +const kill = "q" +const bg = "t" +const pressure = "s" +const lock = "l" +var move = 0 //enables or disables moving +var four = 0 +//used to prevent the message on lvl. 4 from repeating +var levelStart = 0 +//Not the most important var but +//it allows pressure to make a sound when covered +lockHere = 1 //is the lock enabled? +var skips = 0 + +setLegend( + [smile, bitmap` +................ +................ +................ +................ +................ +..............0. +...0............ +...............0 +..0...........00 +..0...........0. +..00.........00. +...000....0000.. +......00000..... +................ +................ +................`], + [fake, bitmap` +000.00..0.0.000. +0..0..0.00..0... +00.0000.0.0.00.. +0..0..0.0.0.0... +0..0..0.0.0.000. +................ +000.00..000.000. +0.0.0.0..0..0... +0.0.00...0..00.. +0.0.0.0..0..0... +000.00..00..000. +................ +....000.000.0.0. +.00.0....0..0.0. +....0....0...... +....000..0..0.0.`], + [kill, bitmap` +0...0.0.0..0.... +0...0.0.0..0.... +0...0.0.0..0.... +0.0.0.0.0..0.... +00.00.0.00.00... +................ +0.0.0.0..0...... +00..0.0..0...... +0.0.0.0..0...... +0.0.0.00.00..... +................ +0...0.0000.0..0. +.0.0..0..0.0..0. +..0...0..0.0..0. +..0...0..0.0..0. +..0...0000.0000.`], + [fakegiggler, bitmap` +....66666666.... +...6666666666... +..666666666666.. +.66666666666666. +6666276666276666 +6666756666756666 +6666666666666666 +6666666666666666 +6576666666666756 +6557666666667556 +6655776666775566 +6665577777755666 +.66655555555666. +..666666666666.. +...6666666666... +....66666666....`], + [giggler, bitmap` +....66666666.... +...6666666666... +..666666666666.. +.66666666666666. +6666276666276666 +6666756666756666 +6666666666666666 +6666666666666666 +6676666666666766 +6657666666667566 +6655776666775566 +6665577777755666 +.66655555555666. +..666666666666.. +...6666666666... +....66666666....`], + [gaggler, bitmap` +....66666666.... +...6666666666... +..666666666666.. +.66666666666666. +6666726666726666 +6666576666576666 +6666666666666666 +6666666666666666 +6656666666666566 +6557666666667556 +6655776666775566 +6665577777755666 +.66655555555666. +..666666666666.. +...6666666666... +....66666666....`], + [pressure, bitmap` +6666666666666666 +6..............6 +6.666666666666.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.6..........6.6 +6.666666666666.6 +6..............6 +6666666666666666`], + [broken, bitmap` +FF6F6FFFFFF6F6FF +666F66666666F666 +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +6666666666666666 +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +6666666666666666 +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +F6F6F6FFFF6F6F6F +666F66666666F666 +FF6F6FFFFFF6F6FF`], + [fakeblock, bitmap` +3333333333333333 +3300LLLLLLLL0033 +303LLLLLLLLLL303 +30L31LLLLLL13L03 +3LL1322222231LL3 +3LLL23222232LLL3 +3LLL22322322LLL3 +3LLL22233222LLL3 +3LLL22233222LLL3 +3LLL22322322LLL3 +3LLL23222232LLL3 +3LL1322222231LL3 +30L31LLLLLL13L03 +303LLLLLLLLLL303 +3300LLLLLLLL0033 +3333333333333333`], + [bg, bitmap` +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999 +9999999999999999`], + [block, bitmap` +3333333333333333 +3300LLLLLLLL0033 +303LLLLLLLLLL303 +30L3122222213L03 +3LL1322222231LL3 +3LL2232222322LL3 +3LL2223223222LL3 +3LL2222332222LL3 +3LL2222332222LL3 +3LL2223223222LL3 +3LL2232222322LL3 +3LL1322222231LL3 +30L3122222213L03 +303LLLLLLLLLL303 +3300LLLLLLLL0033 +3333333333333333`], + [lock, bitmap` +00.0333333330.00 +0003333333333000 +.0333......3330. +0333........3330 +333.3FFFFFF3.333 +33..F3FFFF3F..33 +33..FF3FF3FF..33 +33..FFF33FFF..33 +33..FFF33FFF..33 +33..FF3FF3FF..33 +33..F3FFFF3F..33 +333.3FFFFFF3.333 +0333........3330 +.0333......3330. +0003333333333000 +00.0333333330.00`]) + +setSolids([smile, block, broken, lock]) +setBackground(bg) + +let level = 1 +const levels = [ + map` +vvgvv +kbbbk +vbpbv`, //screen + map` +... +..g +b.. +..b +b.. +bb. +p..`, //intro -1 + map` +b.g.. +.r... +..b.q +...bk +pbafb`, //movable block introduction -2 + map` +g.r. +b.b. +b.b. +b.bp +b.b. +b.b. +f.r.`, //choose wisely -3 + map` +.....b.b +aaa..bpb +vvvbvbrb +...bab.b +.g.vr..b +bbbb...b`, //fake block introduction -4 + map` +avr...r. +.brr..r. +.b..rr.g +.b.r...r +pbr..rr.`, //practice -5 + map` +.s.....bg +.v.....bl +vvv...... +.v....... +.vvvvvvr. +......... +bbbbbbb.b +..r.....s +b.bbbbbbb +s......rp`, //pressure -6 + map` +.....p. +..rr... +br.rrrr +....rr. +r.rr..v +.r.r.r. +r..rrg. +.kr..r.`, //ooo spooky + e7 + map` +bvvvvbb +bvbbvbf +vvbvvbv +vbbvbbv +vbbpvbv +vvvbvbv +bbvbvbv +gvvbvvv`, //find a small path -8 + map` +....b.r.....r...b..bk +b..bbbbfb...bb..bp.b. +.r.b.f.bb..bfb.rfbr.. +b...r.b.bb.b..r.b..bb +fr.bb.bbb..b.b.....b. +b..bbb...b.fbbbb..... +..bb...bb.bb..b...bb. +b....bbbb.gbb......b. +.bbb..r..rr.b..bbb... +kb..r.bb.....bb....b. +.b.b..b.r...bb.r.r... +.bb...r..b.b...r.bb.b +r.bb..bbbbbr..bbbbbr. +.rbbb..b....rbbf.r..r +b.bb.r...bb..b.b.b.f. +b.......r..r.b.brr..r +..b..bbbbb..b..b.brbr +b.b...b....r...b..rb. +b.b.brbb.......b.bb.. +..b.bbfb.bbbbb.b.b... +fbb.r...r..r.......bb`, //og map + 9e + map` +b.b....r..b.sr....... +b....b.bb.b.rlbbbb... +.kbbb.b.b...rb....bb. +..bbb.b....b.b.p.r.br +bv.b.r..b.bg.b..r.r.. +b.r..b.bb..brfb.r...r +bb...b..bb...bbb.rbr. +bb....b..a.bbb.brb... +f.rbbbbbbrbbb....br.. +bb..b..vr..b..r.r...r +bb.rbr......r.....bb. +bb.....rbbbbb.r.b..b.`, //find a path -10 + map` +.r..r.rr...rr +r.r..r..r.r.r +r.r.r..r.r... +pr.rr.r.r.rrr +.r.r.rr.r.r.. +.rrr..r.rbvbb +rr.r.rrbrr..r +...rr....r..r +.r..r.rrbrrr. +.rrr.r.r..r.. +rr.rr.b.r..r. +.r...rv..rr.r +..r.rrb.g..r.`, //one real way and a blocked way -11 + map` +.r..r.r..r..p.........r +...r...r.r.r..rr.b.b.rr +bb...r.rrb......r..r.rf +fb.rr.r.r.bbrb.rb.r...b +..r..rr..r...rb...r.rrb +rb.b..b.b.k.rr.r..b..rr +...rb.r..r..r.r.b..r.br +b...rb.brbrb...brbr.... +...b.r..rrrbrr..r.bb... +.b......r.r.rb.r.rb.b.. +r.b..r.....b........... +...rr..r.b....f....b.r. +.r.rr.bb..r..rb....r... +.rbf.rb...r.rbb.rr..b.. +....r.b.r.b.bbr..r.br.f +r...r..brbbbr........r. +b.b.r.rr.r...rr.rbb.... +..r...b....rb..bbb.bbb. +rr...r.brr..r...bb..b.. +..rbrr.r.br..rbrgb...b. +r..b.b.b....bbb..b..r.. +.bb..rrbb...br.brb...bb +fb.br..rb.r.bb..r...r.. +.b.f.v.....bbfbb.r..b.. +b...rb....b...r...rbf..`, //huge map + e12 + map` +ffffgff +fffffff +fffffff +fffffff +fffffff +fffffff +fffffff +fffpfff +fffffff +fffffff +fffffff +fffffff +fffffff +fffffff +fffffff`, //find it -13 + map` +b...b....... +.....bb.b... +.r...b...... +..b....v.... +.bb..bb..b.b +bpb.......s. +.rb......b.. +..b..bvbbbb. +..b..b.r.b.. +......bgb... +.......lb..s`, //fake level -14 + map` +r...r.....rr..r. +.gb.brrr.rrr.rr. +r.b.br....r.r.r. +r.brbr.rr.rr..r. +.rb.b.r.rrr.rrr. +r.b.b..r.rrr..b. +..r.vr....r..rrp +.rb.b.rrr.r...b.`, //red wall -15 + map` +..rr..rr..vr.vr..vr.r... +rr.f.vvrvvrvvrvrrvvvvrgr +r.r.rvr.rr..r.r.f..rvr.. +bfbbbbbrbbrb.bbrbbrbbbbb +b..r.vr.r.krr.r....rv..b +b.r..v..rr...rr.r.rrvr.b +b.b.rvr.r.vrvvrr....r.rb +b.br.rr.r.v.r.rvr.rrv..b +b.b.rr.r.rvr.vvv..rsvr.b +b.b...rr.rv..r..r..rvr.b +b.bbbb..r.vvvvrvvvrvv..b +b.b.kb.r..r.r..rr.rkr..b +b.vl.br.r..r.r..rr....rb +bpbbbbbbbbbbbbbrbbbbbbbb`, //spiral -16 + map` +.r..r.....rr...... +r.r..rr.rr..r.r.r. +rr.rr.r.r.r..rr..r +....rr....r.rr.... +prrr..rrrr....r.r. +.rr.r..r.rrrrr.b.. +.r..rrrr....r...b. +r.rrr.r.r.rr..rb.r +...r..r..rrr.rr.b. +.r.r.r..rr.r.rr.g. +.r.r.r.r...rr...b.`, //boxes everywhere -17 + map` +r.r..f.r.r....r..f... +gr.rbbr.b.rr.brvrvrrr +rv..b..b..f.b..r.bb.. +brb.rr..br.b..bb.r.rb +...r.v.b....rr.b.rv.. +.br...bfbrbr..bfbr.b. +..b.rr....b.b.r...r.. +b..bb.brb....b..b..br +..r..br..b.rb.brb.b.. +rb..r..frbb.........b +fb.b.b.....r..br.b... +.b.r..bbb.r.bbfv..b.. +.b.br.r.rr.r..b.bb.rb +b.r...rfb.brr..r..rf. +r..b.b.r.r..r.b...r.. +.r.br.b..bb....r.b.b. +r.rb....r.rbbr...r..r +p..r..r...r....bbfb..`, //fake wall to escape. -18 + map` +bbbvvvbbvpbbbbb +bbbvbvbbvbbbbbb +bvvvbvbbvvbvbbb +vvbbvvvgbvbvbbb +vbvbbbbbvvbvbbb +vbvbvvvvvvvvbfb +vbvbvbbbvvbvbvb +vbvbvbvvvbbvbbb +vvvbvvbbvvvvbvb +vvvbbvbvvvbvbvb +bbvbbvbbbbbvvvb +bvvvvvvvvvvvbbb +bbbbvbvbbbbbbbb +bbbbvbvbbbbbbbb +bbbbvbvbbbbbbbb +fvvbbbvvvbvvvvb +bbvbbbbbvbvbvvb +bbvbbbbbvvvbbvb +bbvbbbbbvbbbbvb +bbvvvvvvvvvvvvb +bbbbbbbbbbbbbbb`, //horrific maze -19 + map` +prbvrvrvrbvrvrs.g +..brvrrvvvrvvrrl. +r.brvvbrvvbvr.rrr +r.bvrbbvvrvvvv.r. +sr...rkrvrbrrvr.. +r.b.brvrrrrbrrbbb +.r.rb..b..r..bb.r +..r..r.b.rsvb.r.. +.r.br..r.rbvvv.r. +rsr.r.b.r..bbr.rf`, //so many paths + e20 + map` +...ra...b....r.r +.r.rgrr.rv..rv.s +r.brrr..b.r.rvrr +...r.brrbr.rrrrr +r.r.rr..r.r.b.r. +rr..rl..rr.rb..r +..rr.r.rr.r.v.rp +kr.rrrr.rrrrb.r.`, //3rd last level + e21 + map` +ffffffffffffffffffffff +ffffffffffffffffffffff +ffgfffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffpfffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +ffffffffffffffffffffff +fffffffffffffffffffkff +ffffffffffffffffffffff +ffffffffffffffffffffff`, //haha I lied + e22 + map` +rr.rrrr.r....rrrr.rr +r.rrrr.r.rr.r.rr..rp +.r.r..rr.rr..r.r...r +..r.r.r...rrr..rrrr. +rr.rrrr.rr.r..rr.rs. +.rr.s.rr..rrrr.rr.rf +r..r.r.rr.r..rs.r..r +rrr.r.r.r.rrr.rrrrrr +r.rr..rr...r.r.r.rrr +..rr.r..r.r.rrrrr.rr +rrr.rrrrrr.rrr..rrr. +r..rr..rlr.rrr...rrr +rrrr.r.r..r...r..rrr +..r.r.r.r.rr..rfrr.r +g.r..r.v.rr.rr.rr.rr +.rr.rbr.r..r..rr..r. +r..r.r.r..r.r.rr.r.r +...r..r.rr.rr.brr.r. +rrr.rrrr...r..r....r +.rrrr..r..r.kr.r.r.r`, //:P + e23 + map` +f............. +bbb.b...b.bbb. +b...bl.rb.b.pb +bb..bgbkb.vrrb +b...br.vb.v.sb +bbb.b...b.bbbf +..............`, //end + e24 + map` +karaargvraaraaaraaars +avrrravaarrrraraarraa +rarbarrrraraararaarrr +arbarrararaaraarraraa +aaraarrraarraaraarrar +rrabaaablraaarrravrar +aaararvaaarraarararap`, //lied again. pressure mechanic + e25 + map` +v.v...v..r..r.v.... +r.v..vfv.r.v...rvv. +..b..vv.rr..rr.vf.. +.rbb.b.r..r...r..rs +.rrv.r.rrvbbr..bvrb +..b...r..ra.r.v...r +rgr..v.rvvf..r.r... +bbvvvbbrvvrbb..r.r. +.sv.r...r.r..vv..vr +v.rvrr.rr....r.r... +r..r.b.b..vr..r...r +rrrrvr.r..f.b.b.r.. +r..rv..br...brr...b +.rvv.rr....v.v..r.v +bl..v...r..rvrr.rr. +k.r..r.rv.b..b..r.p`, //random + e26 + map` +....vvv +.r.sbvb +.srrbvv +s.s.bbv +..r.bvv +sr.sbvb +ssrrbvb +srs.bvv +r.r.bbv +.s.sbbv +sr.rbbv +rs..bvv +.r..bvb +psr.l.g`, // cover them all -27 + map` +.r..rrrsrr.rr.....r.sr.g.. +..rr.r.rr..srr..r..rbrrr.r +r.srr.r.rr.r..r..br.bk.r.r +.r..r..r.rr.r...rb.rb.b.r. +.r.r.r..r...s.r..b..b..r.r +bbbbbbbbbbbbbbb..b..br.rr. +s.....r.......b.rr.rb.rlrr +r.sr...p.sr.s.br.bv.br..r. +s..rsrs.s.rs.rb.rb..br.rr. +.rssrsr.r.rsr.br.r.rb.r.rr +.s.rsrrs.rs..sb..rr.br.... +.r.s.rs...rss.b.r..rr..r.r +r....srrsrrr..brrrr.rrr.r. +s..sr.srrss...b..b....r.rr +.s.r..s...sr...r.r.rbrrrsr`, //large map with pressures + e28 + map` +bbbbbbbbbbbbb +b...k.......b +b.k...kkbbb.b +b.bbbbbk....b +..b...fbbb.kb +.kb.bbbbb...b +..b...fkffb.b +vvbbbbbbb.b.b +bg......l.b.b +bbbbbbbbb.b.b +bffr..ff..p.b +bsffr.sfff..b +b.rf.r..bbbbb +brr.frrr.ffsb +brf.fff.rrf.b +brrs..sss.rfb +bfrrrfsss.rrb +brrrrfbbbffff +bfffr.s.rrrrb +bbbbbbbbbbbbb`, //Careful. +++ e29 + map` +bbbbbbvvvvvbbbbbb +v....b...r.b..b.. +v....b..bb.....s. +v.bb.b...sbbbbvvb +b.bb.b.bbbvvb.v.. +b.bb.b.s..vvb.v.. +b.bv.b.bbb..vb... +b.bv........vb.bb +b.bvvbbblb..b.... +brb.r..b.br.bb.r. +bpb...sbgb..sb...`, //lil unblock + e30 + map` +r.r...r..r...r.r +r.bbbvvvb.rbr.r. +.r....rrgrrb.rbk +...r.brrr.rb..b. +r.rrrb.r.r.r..b. +.r...b...r.br.rr +p.r.rfr.r..b.r..`, //simple task + e31 + map` +k....kkkkkkk...kkkkk..k +k.kb.......k.k...kk...k +k..fkkkkkk.k..kk.kk.k.k +kkkkkkkkkk..k..k.k..k.k +.......kkkk..k.k.k.kk.k +.kkkkk...kkk.kfk...kk.k +.k....kk.....kbkkkkk... +...kk...kkkkk........k. +kkkkfbk.......kkkkkkk.. +...k..kkkkkkkk........k +.k.kk..........kkkkkkkk +.k...k.kkkk.k.k........ +..kk.kk....k..k.kkkkkk. +k.k..k..kk...kk.kk..... +k.k.k..k..k.k....kp...b +k.k.k.k....k...k.kkkkkg +k.k.k.k..k...kk..k...k. +k.k...kk..kkkk..kk.k... +k.k.kkkkk..k...kkk..kkk +k.kk...kkk.k.kk...k...k +k.k..k.kk..k.k..k.kkk.k +k...kk....kk...k......k +k.kkkkkkkkkkkkkkkkkkkkk`, //Gaggker Maze + e32 + map` +glf +srv +kvp`, //small + e33 + map` +vvvvvvbvbb +vbvvbvvvbb +vvvvvvvvlg +vvbbbvbbbl +bvvvvvvvvv +vvbbbbbbvb +rr.rrrrr.r +s.rr.r.r.. +rr..rrr.rs +r.rrr.r.rr +r.rr.r.... +.r..r..rrr +..r.r..r.r +r.r.rr.r.r +vkkkkskkkv +s.......sk +k..k...kkk +bk.kkkkkbb +k..kkkkkbb +.........k +...kkkk..k +kkkkkk...k +.......r.k +..kkvk...k +krks.....k +p.kkkkkkkb`, //last level + e34 + map` +p..................................... +.rrrrr.r..r..rr..r...r.r..r........... +...r...r..r.r..r.rr..r.r.r............ +...r...rrrr.rrrr.r.r.r.rr............. +...r...r..r.r..r.r..rr.r.r............ +...r...r..r.r..r.r...r.r..r........... +...................................... +...r...r.rrrr.r..r....rrrr.rrrr.rrrr.. +....r.r..r..r.r..r....r....r..r.r..r.. +.....r...r..r.r..r....r....r..r.r..r.. +.....r...r..r.r..r....rrr..r..r.rrr... +.....r...r..r.r..r....r....r..r.r.r... +.....r...rrrr.rrrr....r....rrrr.r..r.. +...................................... +...rrr..r.....rr..r...r.r.r...r.rrrr.. +...r..r.r....r..r..r.r..r.rr..r.r..... +...r..r.r....rrrr...r...r.rrr.r.r..... +...rrr..r....r..r...r...r.r.rrr.r.rrr. +...r....r....r..r...r...r.r..rr.r..gr. +...r....rrrr.r..r...r...r.r...r.rrrrr. +......................................`, //End -35 + map` +bg +pb`, //logo +] + +//sets the map (HIGHLY IMPORTANT): setMap(levels[level]); +setMap(levels[level]); + +//INTRO ONLY FOR LEVEL 1. +//ELSE DISABLES INTRO +if(level == 1){ + addText("Objecive:", { x: 1, y: 1, color: color`5` }); + addText("Get the", {x: 13, y: 5, color: color`5` }); + addText("Giggler", {x: 13, y: 7, color: color`5` }); + const objective = tune` +113.20754716981132: C5~113.20754716981132 + F5^113.20754716981132 + G5/113.20754716981132, +113.20754716981132, +113.20754716981132: C5~113.20754716981132, +113.20754716981132: G5^113.20754716981132 + F5/113.20754716981132, +113.20754716981132: D5~113.20754716981132, +113.20754716981132, +113.20754716981132: E5~113.20754716981132 + G5^113.20754716981132 + A5/113.20754716981132, +113.20754716981132: D5~113.20754716981132 + G5^113.20754716981132 + A5-113.20754716981132, +113.20754716981132: G5^113.20754716981132, +2603.7735849056603`; + playTune(objective); + setTimeout(() => { + clearText(); + move = 1 + const controls = tune` +122.44897959183673: G5~122.44897959183673 + F4^122.44897959183673 + F5-122.44897959183673, +122.44897959183673: F4^122.44897959183673, +122.44897959183673: G5~122.44897959183673 + F5-122.44897959183673, +122.44897959183673: D5~122.44897959183673 + A4^122.44897959183673 + F5-122.44897959183673, +122.44897959183673: C5~122.44897959183673 + B4^122.44897959183673, +122.44897959183673: F5-122.44897959183673, +122.44897959183673: B5~122.44897959183673 + F4^122.44897959183673, +122.44897959183673: B5~122.44897959183673 + G4^122.44897959183673 + F5-122.44897959183673, +122.44897959183673: B5~122.44897959183673 + B4^122.44897959183673 + G5-122.44897959183673, +122.44897959183673, +122.44897959183673: D4/122.44897959183673, +122.44897959183673, +122.44897959183673: C4/122.44897959183673, +2326.530612244898` + playTune(controls); + addText("WASD TO MOVE.", { y: 5, color: color`5` }); + addText("I TO RESET.", { y: 7, color: color`5` }); + addText("K AS A LAST RESORT.", { y: 9, color: color`5` }); + setTimeout(() => { + clearText(); + }, 4000) + }, 2000) +}else{ + move = 1 +} + +setPushables({ + [smile]: [broken] +}) + +onInput("s", () => { + if (move == 1) { + getFirst(smile).y += 1 + } +}) + +onInput("w", () => { + if (move == 1) { + getFirst(smile).y -= 1 + } +}) + +onInput("a", () => { + if (move == 1) { + getFirst(smile).x -= 1 + } +}) + +onInput("d", () => { + if (move == 1) { + getFirst(smile).x += 1 + } +}) + +//resets the level +onInput("i", () => { + setMap(levels[level]); + lockHere = 1; //enables the lock + const stuck = tune` +119.5219123505976: D5~119.5219123505976 + E5^119.5219123505976 + A4-119.5219123505976, +119.5219123505976: C5~119.5219123505976, +119.5219123505976: B4~119.5219123505976 + D5^119.5219123505976 + A4-119.5219123505976, +239.0438247011952, +119.5219123505976: D5~119.5219123505976 + E5^119.5219123505976, +119.5219123505976: B4~119.5219123505976 + D5^119.5219123505976, +2988.04780876494` + playTune(stuck); + levelStart = 0; //enables pressure sound mechanic to avoid repeating. +}) + +onInput("k", () => { + if(skips < 5){ + skips++ + clearText(); + level = level + 1; + const currentLevel = levels[level]; + // after the last level + if (currentLevel !== undefined) { + setMap(currentLevel); + } + lockHere = 1; //enables the lock + const skip = tune` +113.20754716981132: C5~113.20754716981132 + B4-113.20754716981132, +113.20754716981132: B4/113.20754716981132, +113.20754716981132: C4/113.20754716981132, +3283.0188679245284` + playTune(skip); + levelStart = 0; //enables pressure sound mechanic to avoid repeating. + } +}) + +afterInput(() => { + const killerNumber = tilesWith(gaggler).length; + //Killer num counts the amount of killers (mainly 1) + const killerCovered = tilesWith(smile, gaggler).length; + //If player is on killer + const playerNumber = tilesWith(giggler).length; + //counts num of player(1) + const targetCovered = tilesWith(smile, giggler).length; + //If player is on giggler + const pressureNumber = tilesWith(pressure).length; + //counts pressures + const pressureCovered = tilesWith(broken, pressure).length; + //how many pressures have boxes on them + + //enables the pressure sound + if(levelStart == 0){ + curNum = pressureNumber-1 + levelStart = 1 + } + + //Player reaching the giggler + if (targetCovered == playerNumber) { + clearText(); //pre-existng text is erased + setMap(levels[level]); + move = 0; + //(710-711) stops player movement, resets map / + //cheating is now impossible + addText("You found the", { y: 5, color: color`5` }); + addText("Giggler.", { y: 7, color: color`5` }); + //standard win test and music + const win = tune` +113.20754716981132: C5~113.20754716981132 + G5^113.20754716981132 + E5-113.20754716981132 + C4-113.20754716981132, +113.20754716981132: B4~113.20754716981132 + A5^113.20754716981132 + D4-113.20754716981132, +113.20754716981132: F4^113.20754716981132 + D5~113.20754716981132 + G5^113.20754716981132, +113.20754716981132: G4^113.20754716981132 + B4~113.20754716981132 + A5^113.20754716981132, +113.20754716981132: A4^113.20754716981132 + C5~113.20754716981132 + G5^113.20754716981132 + E5-113.20754716981132, +113.20754716981132: G4^113.20754716981132 + E4~113.20754716981132, +113.20754716981132: D4~113.20754716981132 + F4^113.20754716981132 + C4/113.20754716981132, +2830.188679245283` + playTune(win); + + //Moves the level up, allows the player to move, + //and resets the lock mechanic + setTimeout(() => { + clearText(); + level = level + 1; + const currentLevel = levels[level]; + // after the last level + if (currentLevel !== undefined) { + setMap(currentLevel); + move = 1 + lockHere = 1 + levelStart = 0 + } + }, 1000); + } + + //pressure and lock mechanic + //If there is a pressure - Lock exists + if ((pressureNumber > 0) && (lockHere == 1)){ + //if all pressures have boxes + if (pressureNumber == pressureCovered){ + lockHere = 0; //lock no longer exists + clearText(); + addText("Unlocked.", { y: 1, color: color`6` }); + XLOCK = getFirst(lock).x; //lock x + YLOCK = getFirst(lock).y; //lock y + clearTile(XLOCK, YLOCK); //deletes lock + console.log("Unlocked"); + const unlocked = tune` +56.49717514124294: D5/56.49717514124294 + C5^56.49717514124294, +56.49717514124294: E5/56.49717514124294 + G5-56.49717514124294, +1694.9152542372883`; //sound effect + playTune(unlocked); + }else{ + let num = pressureNumber - pressureCovered //how many pressures without boxes + clearText() + addText("pressure: " + num, { y: 1, color: color`6` }); + // adds the number of pressures left on screen + if(num == curNum){ + const stillLocked = tune` +90.6344410876133: F5~90.6344410876133, +90.6344410876133: F5^90.6344410876133, +2719.0332326283988`; + playTune(stillLocked); + curNum -- + //if a pressure is on, sound plays and 1 is renoved from curNum + //so that sound plays when it is covered + }else if((curNum + 2) == num){ + curNum++ + //allows sound to play again pressure is removed and added again + } + } + } + + //Gaggler mechanic + // if Killer exists + if (killerNumber > 0){ + //if player is on gaggler + if (killerCovered == (killerNumber - (killerNumber - 1))) { + addText("Gaggler got you.", { y: 1, x: 0, color: color`3` }); + addText("(retry)", { y: 10, x: 0, color: color`3` }); + const died = tune` +118.11023622047244: G4^118.11023622047244 + B4~118.11023622047244, +118.11023622047244: D5/118.11023622047244 + B5-118.11023622047244, +118.11023622047244: F5/118.11023622047244 + G4^118.11023622047244, +118.11023622047244: D5/118.11023622047244, +118.11023622047244: C5/118.11023622047244 + F4^118.11023622047244 + G5-118.11023622047244, +118.11023622047244: B4/118.11023622047244 + G4~118.11023622047244, +118.11023622047244: D5/118.11023622047244 + F4^118.11023622047244 + F5-118.11023622047244, +118.11023622047244: B4/118.11023622047244 + D4^118.11023622047244, +118.11023622047244: D4~118.11023622047244, +118.11023622047244: G4/118.11023622047244 + D4^118.11023622047244 + B4-118.11023622047244, +118.11023622047244: C4^118.11023622047244, +118.11023622047244: F4/118.11023622047244 + G4-118.11023622047244, +118.11023622047244: C4~118.11023622047244, +118.11023622047244: D4-118.11023622047244, +118.11023622047244: C4~118.11023622047244, +118.11023622047244: C4-118.11023622047244, +118.11023622047244: C4/118.11023622047244, +1771.6535433070867`; //sound effect + playTune(died); + console.log("You were tricked.") + const currentLevel = levels[0]; // sets map to level 0 + if (currentLevel !== undefined) { + setMap(currentLevel); + level = 0 + } + } + } + + //Fake wall notice on level four + if ((level == 4) && (four == 0)) { + clearText(); //clears existing text + four = 1 //prevents message from replaying + const notice = tune` +86.20689655172414: E5~86.20689655172414, +86.20689655172414: F5~86.20689655172414, +86.20689655172414: F5~86.20689655172414, +86.20689655172414: F5~86.20689655172414 + E5~86.20689655172414 + D5~86.20689655172414 + C5~86.20689655172414, +86.20689655172414: C5~86.20689655172414, +86.20689655172414: C5~86.20689655172414, +86.20689655172414: B4~86.20689655172414, +86.20689655172414: C5~86.20689655172414 + D5~86.20689655172414, +86.20689655172414: D5~86.20689655172414, +86.20689655172414: D5~86.20689655172414, +1896.5517241379312`; + playTune(notice); + addText("NOTICE: SOME WALLS", { y: 1, color: color`6` }); + addText("ARE FAKE.", { y: 3, color: color`6` }); + } + +}); diff --git a/games/img/ChocolateNimGame.png b/games/img/ChocolateNimGame.png new file mode 100644 index 0000000000..a927f5a563 Binary files /dev/null and b/games/img/ChocolateNimGame.png differ diff --git a/games/img/CubeCastle.png b/games/img/CubeCastle.png new file mode 100644 index 0000000000..2634588a70 Binary files /dev/null and b/games/img/CubeCastle.png differ diff --git a/games/img/DVxD.png b/games/img/DVxD.png new file mode 100644 index 0000000000..50e5d22529 Binary files /dev/null and b/games/img/DVxD.png differ diff --git a/games/img/Frost-and-Fire.png b/games/img/Frost-and-Fire.png new file mode 100644 index 0000000000..5f3433bb7d Binary files /dev/null and b/games/img/Frost-and-Fire.png differ diff --git a/games/img/Hole-in-Wall.png b/games/img/Hole-in-Wall.png new file mode 100644 index 0000000000..60bf56fa7a Binary files /dev/null and b/games/img/Hole-in-Wall.png differ diff --git a/games/img/Journey to the Secret Village.png b/games/img/Journey to the Secret Village.png new file mode 100644 index 0000000000..f00ed478f0 Binary files /dev/null and b/games/img/Journey to the Secret Village.png differ diff --git a/games/img/Simple-Platformer.png b/games/img/Simple-Platformer.png new file mode 100644 index 0000000000..8bab58b917 Binary files /dev/null and b/games/img/Simple-Platformer.png differ diff --git a/games/img/Trapped.png b/games/img/Trapped.png new file mode 100644 index 0000000000..7133d1b8d6 Binary files /dev/null and b/games/img/Trapped.png differ diff --git a/games/img/beyblade_battle.png b/games/img/beyblade_battle.png new file mode 100644 index 0000000000..ea9acc44bf Binary files /dev/null and b/games/img/beyblade_battle.png differ diff --git a/games/img/giggler_puzzles.png b/games/img/giggler_puzzles.png new file mode 100644 index 0000000000..40be287778 Binary files /dev/null and b/games/img/giggler_puzzles.png differ diff --git a/games/img/maze_game.png b/games/img/maze_game.png new file mode 100644 index 0000000000..8ff04c6e4b Binary files /dev/null and b/games/img/maze_game.png differ diff --git a/games/img/papermc.png b/games/img/papermc.png new file mode 100644 index 0000000000..c641c8e96b Binary files /dev/null and b/games/img/papermc.png differ diff --git a/games/img/self-sabotage.png b/games/img/self-sabotage.png new file mode 100644 index 0000000000..55db7b1245 Binary files /dev/null and b/games/img/self-sabotage.png differ diff --git a/games/img/sneki.png b/games/img/sneki.png new file mode 100644 index 0000000000..fb5e33a04f Binary files /dev/null and b/games/img/sneki.png differ diff --git a/games/img/the_floor_is_lava.png b/games/img/the_floor_is_lava.png new file mode 100644 index 0000000000..7fd32ad4ab Binary files /dev/null and b/games/img/the_floor_is_lava.png differ diff --git a/games/img/wanna_see_me_speedrun.png b/games/img/wanna_see_me_speedrun.png new file mode 100644 index 0000000000..de3bbb3730 Binary files /dev/null and b/games/img/wanna_see_me_speedrun.png differ diff --git a/games/mailman.js b/games/mailman.js index d428f93142..df56e22ff1 100644 --- a/games/mailman.js +++ b/games/mailman.js @@ -347,19 +347,19 @@ function checkHit() { -function checkHit() { - const badBoxHitbox = tilesWith(BADBOX).length; - const evilBoxHitbox = tilesWith(EVILBOX).length; +// function checkHit() { +// const badBoxHitbox = tilesWith(BADBOX).length; +// const evilBoxHitbox = tilesWith(EVILBOX).length; - const badBoxDamage = tilesWith(BADBOX, player).length; - const evilBoxDamage = tilesWith(EVILBOX, player).length; +// const badBoxDamage = tilesWith(BADBOX, player).length; +// const evilBoxDamage = tilesWith(EVILBOX, player).length; - // Get the current level's map - const currentLevelMap = levels[level]; +// // Get the current level's map +// const currentLevelMap = levels[level]; - if (badBoxDamage > 0 || evilBoxDamage > 0) { - // You're being hit by either BADBOX or EVILBOX - setMap(currentLevelMap); // Reset the current level - // console.log("HIT!"); - } -} +// if (badBoxDamage > 0 || evilBoxDamage > 0) { +// // You're being hit by either BADBOX or EVILBOX +// setMap(currentLevelMap); // Reset the current level +// // console.log("HIT!"); +// } +// } diff --git a/games/maze_game.js b/games/maze_game.js new file mode 100644 index 0000000000..bd3a845f2b --- /dev/null +++ b/games/maze_game.js @@ -0,0 +1,714 @@ +/* +@title: 2_character_maze_game +@author: ivg1 +@tags: ['maze', 'puzzle'] +@addedOn: 2024-12-13 +controls: + w = up + s = down + a = left + d = right + j = restart level +info on sprites: + player: two player sprites per level, each controlled at the same time + wall: a wall + moveable_wall: a wall that you can push around + keys: open doors, have to also collect all of them + door: door exist and block path -> key open door -> door disappear + goal: BOTH players have to be on a goal to go to next level (and have all keys in a level collected) + gem: a cool little collectible to extend levels + huh: a way to beat a level by only ONE player standing on it (the ??? thing) + huh_key: key to open huh_door to the huh portal + huh_door: door exist -> door question -> door teleport :) + thats it I believe. +*/ + +const player = "p"; +const wall = "w"; +const moveable_wall = "e"; +const key = "k"; +const key2 = "l"; +const key3 = ";"; +const door = "b"; +const door2 = "n"; +const door3 = "m"; +const goal = "g"; +const restart = "r"; +const gem = "v"; +const huh = "?"; +const huh_key = ">"; +const huh_door = "<"; + +let keys_needed = 1; +let keys_collected = 0; +let level = 0; +let can_proceed = false; +let gems_collected = 0; + +//music section + +const controls_tune = tune` +250: C5~250 + E4-250, +250: E5~250, +250: G5~250 + F4-250, +250, +250: D5~250 + E4-250, +250: F5~250, +250: A5~250 + D4-250, +250: E4-250, +250: C5~250 + F4-250, +250: E5~250 + E4-250, +250: G5~250 + D4-250, +250, +250: D4-250 + A4~250, +250: C5~250 + F4-250, +250: E5~250 + D4-250, +250, +250: F4-250 + C5~250, +250: E5~250, +250: G5~250, +250: G4-250, +250: D5~250, +250: F5~250, +250: A5~250 + E4-250, +250: F4-250, +250: C5~250, +250: E5~250, +250: G5~250, +250: D4-250, +250: B4~250 + E4-250, +250: D5~250 + D4-250, +250: F5~250 + C4-250, +250: D4-250 + A5~250`; +// let controls_music = playTune(controls_tune, Infinity); + +const level_tune = tune` +500: C4^500, +500: E4^500, +500: G4^500, +500: E4^500, +500: C4^500, +500: E4^500, +500: G4^500, +500: B4^500, +500: C5^500, +500: A4^500, +500: F4^500, +500: A4^500, +500: C5^500, +500: A4^500, +500: D5^500, +500: C5^500, +500: B4^500, +500: G4^500, +500: E4^500, +500: G4^500, +500: B4^500, +500: G4^500, +500: C5^500, +500: B4^500, +500: A4^500, +500: F4^500, +500: D4^500, +500: F4^500, +500: G4^500, +500: E4^500, +500: F4^500, +500: D4^500`; +let level_music = playTune(controls_tune, Infinity); // playTune(level_tune, Infinity); +const beat_game_music = tune` +500: C4~500, +500: E4~500, +500: G4~500, +500: B4~500, +500: C5~500, +500: A4~500, +500: F4~500, +500: A4~500, +500: C5~500, +500: A4~500, +500: D5~500, +500: C5~500, +500: B4~500, +500: G4~500, +500: E4~500, +500: G4~500, +500: B4~500, +500: C5~500, +500: D5~500, +500: C5~500, +500: E5~500, +500: C5~500, +500: D5~500, +500: E5~500 + C5~500, +500: F5~500 + B4~500, +500: E5~500 + A4~500, +500: D5~500 + B4~500, +500: C5~500 + A4~500, +500: B4~500 + G4~500, +500: A4~500 + D4~500, +500: G4~500 + C4~500, +500: F4~500 + D4~500`; + +const beat_level_sfx = tune` +300: C4/300 + F4/300, +300: D4/300 + G4/300, +300: E4/300 + C5/300, +8700`; +const key_sfx = tune` +150: A4~150 + E5~150 + C5~150, +150: F5~150 + D5~150 + B4~150, +4500`; +const gem_sfx = tune` +150: G5-150 + B5-150 + E5-150, +150: E5-150 + C5-150 + A4-150, +150: C5-150, +150: D5-150 + A5-150, +150: B5-150 + G5-150 + E5-150, +4050`; +const huh_key_sfx = tune` +500: C4^500 + F4^500 + B4^500 + E5^500 + A5^500, +15500`; +const beat_game_sfx = tune` +200: G4/200 + E4/200 + C4/200, +200: C4/200 + E4/200 + G4/200, +200: C4/200 + E4/200 + G4/200, +200: C4/200 + F4/200 + A4/200 + E5/200 + C5/200, +200: E5/200 + C5/200 + A4/200 + F4/200 + D4/200, +5400`; + +setLegend( + [ player, bitmap` +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555 +5555555555555555` ], + [ wall, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000` ], + [ key, bitmap` +................ +................ +................ +................ +.666666......... +.666666......... +.666666......... +.66446666666666. +.66446666666666. +.666666..6.6.6.. +.666666..6...... +.666666......... +................ +................ +................ +................` ], + [ key2, bitmap` +................ +................ +................ +................ +.666666......... +.666666......... +.666666......... +.66336666666666. +.66336666666666. +.666666..6.6.6.. +.666666..6...... +.666666......... +................ +................ +................ +................` ], + [ key3, bitmap` +................ +................ +................ +................ +.666666......... +.666666......... +.666666......... +.66556666666666. +.66556666666666. +.666666..6.6.6.. +.666666..6...... +.666666......... +................ +................ +................ +................` ], + [ door, bitmap` +0440044004400440 +4CCCCCCCCCCCCCC4 +4C444444444CCCC4 +0C444444444CCCC0 +0C444444444CCCC0 +4C444444444CCCC4 +4C444444444CCCC4 +0C444444444C66C0 +0C444444444C66C0 +4C444444444CCCC4 +4C444444444CCCC4 +0C444444444CCCC0 +0C444444444CCCC0 +4C444444444CCCC4 +4CCCCCCCCCCCCCC4 +0440044004400440`], + [ door2, bitmap` +0330033003300330 +3CCCCCCCCCCCCCC3 +3C333333333CCCC3 +0C333333333CCCC0 +0C333333333CCCC0 +3C333333333CCCC3 +3C333333333CCCC3 +0C333333333C66C0 +0C333333333C66C0 +3C333333333CCCC3 +3C333333333CCCC3 +0C333333333CCCC0 +0C333333333CCCC0 +3C333333333CCCC3 +3CCCCCCCCCCCCCC3 +0330033003300330`], + [ door3, bitmap` +0550055005500550 +5CCCCCCCCCCCCCC5 +5C555555555CCCC5 +0C555555555CCCC0 +0C555555555CCCC0 +5C555555555CCCC5 +5C555555555CCCC5 +0C555555555C66C0 +0C555555555C66C0 +5C555555555CCCC5 +5C555555555CCCC5 +0C555555555CCCC0 +0C555555555CCCC0 +5C555555555CCCC5 +5CCCCCCCCCCCCCC5 +0550055005500550`], + [ goal, bitmap` +................ +................ +................ +.......44....... +.......44....... +.......44....... +.....444444..... +......4444...... +.......44....... +................ +....44444444.... +................ +................ +................ +................ +................` ], + [ restart, bitmap` +................ +....33333333.... +...33......33... +..33........33.. +.33..........33. +.3............3. +.3............3. +.3............3. +.3............3. +.3..........3.3. +.3.........33.3. +.33.......33333. +..33.......33... +...33.......3... +....33333....... +................` ], + [ moveable_wall, bitmap` +0000000000000000 +0C9CCCC99CCCC9C0 +0999999999999990 +0C9CCCCCCCCCC9C0 +0C9C99999999C9C0 +0C9C9CCCCCC9C9C0 +0C9C9C9999C9C9C0 +099C9C9CC9C9C990 +099C9C9CC9C9C990 +0C9C9C9999C9C9C0 +0C9C9CCCCCC9C9C0 +0C9C99999999C9C0 +0C9CCCCCCCCCC9C0 +0999999999999990 +0C9CCCC99CCCC9C0 +0000000000000000` ], + [ gem, bitmap` +.......5..5..... +...5............ +5...77777777.5.. +...7755555577... +..775255552577.5 +.77555555555577. +575555555555557. +.75555555525557. +.77555555555577. +..775255555577.5 +5..7755555577... +....77555577.... +..5..775577..5.. +......7777...... +.....5.77....... +..........5.....` ], + [ huh, bitmap` +................ +.0000.0000.0000. +.0..0.0..0.0..0. +.0..0.0..0.0..0. +....0....0....0. +..000..000..000. +..0....0....0... +..0....0....0... +................ +..0....0....0... +................ +..0.0.0.0.0.0.0. +.0.0.0.0.0.0.0.. +..0.0.0.0.0.0.0. +.0.0.0.0.0.0.0.. +................` ], + [ huh_key, bitmap` +................ +................ +................ +00000000........ +06666660........ +0600006000000000 +0606606666666660 +0606600006066660 +0600666666666660 +0666666006060600 +066666600600000. +06666660000..... +00000000........ +................ +................ +................` ], + [ huh_door, bitmap` +0660066006600660 +6CCCCCCCCCCCCCC6 +6C666666666CCCC6 +0C660000066CCCC0 +0C660666066CCCC0 +6C660666066CCCC6 +6C666666066CCCC6 +0C666600066C66C0 +0C666606666C66C0 +6C666606666CCCC6 +6C666606666CCCC6 +0C666666666CCCC0 +0C666606666CCCC0 +6C666666666CCCC6 +6CCCCCCCCCCCCCC6 +0660066006600660` ] +); + +setSolids([player, wall, moveable_wall, door, door2, door3, huh_door]); + +const levels = [ + map` +............... +............... +............... +............... +............... +............... +............... +............... +............... +............... +...............`, //controls + map` +............... +............... +p....k......... +............... +..............g +wwwwwwwwwwwwwww +............... +............... +p.............. +............... +..............g`, //how to + map` +vw...w...w...gw +.w...w...w....w +bw.......w....w +.....w...wwwwbw +pw...w........w +wwwwwwwwwwwwwww +p..w..........w +ww.w.w.www.ww.w +kw.w.w.w.w..w.w +.w.www.w.ww.www +.......w.....gw`, // basic level + map` +...........w... +.w.wwwww.wkw.w. +.w.bn.vw.www.w. +ww.wwwww.b...w. +p........wwwwwg +wwwwwwwwwwwwwww +p........w..... +wwww.wwwww.w.ww +..lw.....n.wg.. +.www.wwwww.www. +.....w.........`, // medium level + map` +....w...kw..... +.wwww.wwwwwnww. +.w........wg.w. +.www.wwww.wwww. +p.......w...... +wwwwwwwwwwwwwww +p........w..... +wwww.wwwwwwwww. +.bvw......wg.b. +.www.wwww.wwww. +.....wl........`, // medium level + map` +....w...n.>w... + { + if (level === 0) return; + getAll(player).forEach(item => { + item.x -= 1; + }); +}); +onInput("d", () => { + if (level === 0) return; + getAll(player).forEach(item => { + item.x += 1; + }); +}); +onInput("w", () => { + if (level === 0) return; + getAll(player).forEach(item => { + item.y -= 1; + }); +}); +onInput("s", () => { + if (level === 0) return; + getAll(player).forEach(item => { + item.y += 1; + }); +}); +onInput("j", () => { + if (level === 0) { + level++; + } + level_music.end(); + level_music = playTune(level_tune, Infinity); + + setMap(levels[level]); + keys_collected = 0; + clearText(); + addText(`level ${level+1}`, {x: 1, y: 1, color: color`3`}); + addText(`keys ${keys_collected}/${keys_needed}`, {x: 10, y: 1, color: color`3`}); +}); + +const check_keys = () => { + if (keys_collected >= keys_needed) { + // console.log("all keys collected!"); + can_proceed = true; + } else { + can_proceed = false; + } +} + +afterInput(() => { + if (level === 0) return; + if (level < levels.length) { + if (tilesWith(key, player).length > 0) { + // console.log("key collected!"); + keys_collected++; + playTune(key_sfx); + getFirst(key).remove(); + getAll(door).forEach(item => { + item.remove(); + }); + check_keys(); + } + if (tilesWith(key2, player).length > 0) { + // console.log("key collected!"); + keys_collected++; + playTune(key_sfx); + getFirst(key2).remove(); + getAll(door2).forEach(item => { + item.remove(); + }); + check_keys(); + } + if (tilesWith(key3, player)) { + if (tilesWith(key3, player).length > 0) { + // console.log("key collected!"); + keys_collected++; + playTune(key_sfx); + getFirst(key3).remove(); + getAll(door3).forEach(item => { + item.remove(); + }); + check_keys(); + } + } + + if (tilesWith(huh_key, player)) { + if (tilesWith(huh_key, player).length > 0) { + // console.log("key collected! (huh)"); + getFirst(huh_key).remove(); + playTune(huh_key_sfx); + getAll(huh_door).forEach(item => { + item.remove(); + }); + } + } + if (tilesWith(huh, player)) { + if (tilesWith(huh, player).length > 0) { + // console.log("huh?! player teleported to next level!"); + level++; + keys_needed = objectives[level]; + keys_collected = 0; + playTune(beat_level_sfx); + setMap(levels[level]); + } + } + if (tilesWith(gem, player)) { + if (tilesWith(gem, player).length > 0) { + gems_collected++; + playTune(gem_sfx); + getFirst(gem).remove(); + } + } + + if (can_proceed && tilesWith(goal, player).length > 1) { + // console.log("players reached goals! (switching map)"); + level++; + keys_needed = objectives[level]; + keys_collected = 0; + playTune(beat_level_sfx); + setMap(levels[level]); + } + } else { + keys_needed = objectives[level]; + keys_collected = 0; + + setMap(levels[level]); + } + + clearText(); + if (level < levels.length-1) { + addText(`level ${level}`, {x: 1, y: 1, color: color`3`}); + addText(`keys ${keys_collected}/${keys_needed}`, {x: 10, y: 1, color: color`3`}); + } else { + level_music.end(); + level_music = playTune(beat_game_sfx); + level_music = playTune(beat_game_music, Infinity); + addText(`all levels passed!`, {x: 1, y: 1, color: color`3`}); + addText(`collected ${gems_collected}/${levels.length-3} gems.`, {x: 1, y: 8, color: color`3`}); + } +}); diff --git a/games/monty_hall_problem.js b/games/monty_hall_problem.js new file mode 100644 index 0000000000..943f8c9ac7 --- /dev/null +++ b/games/monty_hall_problem.js @@ -0,0 +1,238 @@ +/* +@title: Monty Hall Game +@author: NOT-Bugha +@tags: ['puzzle'] +@addedOn: 2024-01-01 +*/ + +const door = "d" +const openDoor = "o" +const prizeDoor = "p" +const goatDoor = "g" + +setLegend( + [ door, bitmap` +0000000000000000 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0222222222222220 +0000000000000000`], + [ openDoor, bitmap` +0000000000000000 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0111111111111110 +0000000000000000`], + [ prizeDoor, bitmap` +0000000000000000 +0111111111111110 +0111111111111110 +0111100CC1111110 +0111100CC1111110 +0111100CC1111110 +0111133CC1111110 +0111133CC1111110 +0111133CC1111110 +0111133CC1111110 +0111133CC1111110 +0111133CC1111110 +0111111111111110 +0111111111111110 +0111111111111110 +0000000000000000`], + [ goatDoor, bitmap` +0000000000000000 +0111111111111110 +0111111111111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111155551111110 +0111111111111110 +0111111111111110 +0111111111111110 +0000000000000000`] +) + +const levels = [ + map` +ddd` +] + +let message = "" +let canSwitch = false + +setMap(levels[0]) + +let selectedDoor = -1 +let revealedDoor = -1 +let prizeDoorIndex = Math.floor(Math.random() * 3) +let gameState = "selection" // states: selection, reveal, final, result + +onInput("a", () => { + if (gameState === "selection" && selectedDoor > 0) { + selectedDoor-- + } +}) + +onInput("d", () => { + if (gameState === "selection" && selectedDoor < 2) { + selectedDoor++ + } +}) + +function wrapText(text, maxWidth) { + const words = text.split(' ') + const lines = [] + let currentLine = words[0] + + for (let i = 1; i < words.length; i++) { + if (currentLine.length + words[i].length + 1 <= maxWidth) { + currentLine += ' ' + words[i] + } else { + lines.push(currentLine) + currentLine = words[i] + } + } + lines.push(currentLine) + return lines +} + +onInput("k", () => { + if (gameState === "selection") { + if (selectedDoor === -1) { + selectedDoor = 0 // Start with first door selected + } else { + // Confirm door selection and reveal goat + let revealedDoorIndex = -1 + for (let i = 0; i < 3; i++) { + if (i !== selectedDoor && i !== prizeDoorIndex) { + revealedDoorIndex = i + revealedDoor = i // Store revealed door + break + } + } + clearTile(revealedDoorIndex, 0) + addSprite(revealedDoorIndex, 0, goatDoor) + message = `Door ${revealedDoorIndex + 1} has a GOAT!!\n\n\nPress K to stick\nPress J to switch` + gameState = "reveal" + canSwitch = true + } + } else if (gameState === "reveal" && canSwitch) { + // Stay with current door + message = "Staying with original choice..." + showFinalResult(selectedDoor) + } +}) + +onInput("j", () => { + if (gameState === "reveal" && canSwitch) { + // Switch to the other unopened door + const newDoor = 3 - selectedDoor - revealedDoor + message = "Switching..." + selectedDoor = newDoor + showFinalResult(selectedDoor) + } else if (gameState === "result") { + // Reset game + selectedDoor = -1 + revealedDoor = -1 + prizeDoorIndex = Math.floor(Math.random() * 3) + gameState = "selection" + canSwitch = false + message = "Pick door (Press K)" + + // Reset doors + setMap(levels[0]) + } +}) + +function showFinalResult(finalChoice) { + // Clear screen and add black background + for (let i = 0; i < 3; i++) { + clearTile(i, 0) + } + + // Add extra newlines and credits + message = finalChoice === prizeDoorIndex ? + "YOUU WON!!\n\n\n\nA game by\nTechnoblade_SM\n\n\n\nPress J to try again" : + "YOU LOST, TRY AGAIN\n\n\n\nA game by\nTechnoblade_SM\n\n\n\nPress J to try again" + gameState = "result" + canSwitch = false +} + +afterInput(() => { + if (gameState === "selection") { + for (let i = 0; i < 3; i++) { + clearTile(i, 0) + addSprite(i, 0, i === selectedDoor ? openDoor : door) + } + message = selectedDoor === -1 ? + "Pick door (Press K)" : + `Door ${selectedDoor + 1} selected.\nPress K to confirm.` + } + + clearText() + if (gameState === "reveal") { + // Special formatting for reveal state + const [announcement, ...instructions] = message.split('\n\n\n') + addText(announcement, { y: 2, color: color`3` }) + instructions[0].split('\n').forEach((line, index) => { + addText(line, { y: 6 + index, color: color`3` }) + }) + } else if (gameState === "result") { + // Split message into result, credits, and replay + const parts = message.split('\n\n\n\n') + + // Revert win/lose message to original position + addText(parts[0], { y: 2, color: color`3` }) + + // Keep centered credits + const creditLines = parts[1].split('\n') + addText(creditLines[0], { y: 7, color: color`9`, x: 5 }) // "A game by" + addText(creditLines[1], { y: 8, color: color`9`, x: 2 }) // "Technoblade_SM" + + // Revert replay prompt to original position + addText(parts[2], { y: 12, color: color`3` }) + } else { + // Normal text wrapping for other states + const wrapped = wrapText(message, 20) + wrapped.forEach((line, index) => { + addText(line, { y: 4 + index, color: color`3` }) + }) + } +}) diff --git a/games/offline_t-rex_game.js b/games/offline_t-rex_game.js index 716c54653a..d14dfe2a82 100644 --- a/games/offline_t-rex_game.js +++ b/games/offline_t-rex_game.js @@ -1,8 +1,9 @@ /* @title: offline_t-rex_game -@author: zoya hussain */ +@author: zoya hussain @tags: ['endless'] @addedOn: 2022-12-31 +*/ let vy = 0; diff --git a/games/papermc.js b/games/papermc.js new file mode 100644 index 0000000000..716874904f --- /dev/null +++ b/games/papermc.js @@ -0,0 +1,447 @@ +/* +First time? Check out the tutorial game: +https://sprig.hackclub.com/gallery/getting_started + +@title: papermc +@author: nulladmin1 +@tags: [] +@addedOn: 2024-12-24 +*/ + +// The player sprite +const player = "p" + +// Different blocks in the game +const grass = "g" +const wood = "w" +const planks = "o" +const leaves = "l" +const cobblestone = "c" +const tnt = "t" +const diamond = "d" + +// The sky +const sky = "s" + +// Black screen in the beginning +const black = "b" + +// Gravity +let gravity = 1 + +// The direction the player is facing +let direction = "down" + +setLegend( + [player, bitmap` +................ +.....CCCCCC..... +.....CFFFFC..... +.....F5FF5F..... +.....FFFFFF..... +.....F0000F..... +.....FFFFFF..... +...DDDDDDDDDD... +...FFDDDDDDFF... +...FFDDDDDDFF... +...FFDDDDDDFF... +...FFDDDDDDFF... +.....55555D..... +.....555555..... +.....55..55..... +.....55..55.....`], + [grass, bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDCC +CDDDDDDDDDDDDCCC +CCDCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC`], + [wood, bitmap` +CC0CCCCCCCCCCCCC +CC0C0CCCC00CCC0C +CC0C0C0CC0CCCC0C +CC0C0C0CC00CCC0C +CC0C0C00CCC0CCCC +CC0CCCC0CCC0CCCC +CC0CCCC0CCC00CCC +CC0CCCC0CCCC0C0C +CC0CCCCCC0CCCC0C +C0CC0CCC00CCCC0C +C00C0CC00CCCCC0C +CC0C0CCCCCCC000C +C0CCC0CC00CC0CCC +C0CCC0CC0CC00CCC +C0CCC0CC0CC0CCCC +CCCCC0CC0CC0CC0C`], + [planks, bitmap` +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC +CCCCCCCCCCCCCCCC`], + [leaves, bitmap` +DDDDDDDDDDDDDDDD +D..DDD.DDDDD...D +DD.DDDD.DD.D.DDD +D.D.DDDD.D.DD.DD +D.D.DD.DD.D.D.DD +D.DD.D.DDD.D.D.D +D..D.D.DD.DD.DDD +DDD.D..DD.DDD.DD +D.DD.DDD.D.DD.DD +D..DD.D.DDD.DDDD +DD.DDD.D.DDD..DD +DDD.D..DD..DDD.D +DDD..DDDDDD.D.DD +D.D.DDDD...DD.DD +D.......DDD..DDD +DDDDDDDDDDDDDDDD`], + [cobblestone, bitmap` +111111111LLL1111 +1LL1111111L11LL1 +1LL1LLLL11111LL1 +1L11LLLL111111L1 +1111LLLL111LLL11 +L111111111LLL11L +L111LL1L11LLL11L +111LLL1L11111111 +111LLL111LLLL111 +1LL11L11LLLLL1L1 +1LL11L11LLLLLLL1 +111L11111LLL1LL1 +11LLL1LL11111LL1 +11LLL1LL11111111 +11LLL1LL11LLLL11 +111111111LLLLLL1`], + [tnt, bitmap` +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +2200020220200022 +2220220020220222 +2220220200220222 +2220220220220222 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333 +3333333333333333`], + [diamond, bitmap` +5555555555555555 +5777777777777775 +5777777777777775 +5722277777777275 +5727777777772225 +5722722272277275 +5727727272777275 +5727722272777275 +5777777777777775 +5777772772777775 +5777777722272275 +5722272772727275 +5727272772722775 +5727272772772275 +5777777777777775 +5555555555555555`], + [sky, bitmap` +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777 +7777777777777777`], + [black, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], +) + +let currentBlockIndex = 0 +const blocks = { + grass: "g", + wood: "w", + planks: "o", + leaves: "l", + cobblestone: "c", + tnt: "t", + diamond: "d" +} +// Levels +let level = 0 +const levels = [ + map` +bbbbbbbbbb +bbbbbbbbbb +bbbbbbbbbb +bbbbbbbbbb +bbbbbbbbbb +bbbbbbbbbb`, + map` +.......... +.....lll.. +.p...lll.. +....llwll. +.....lwl.. +......w... +gggggggggg +cccccccccc`, +] + +setSolids([player, ...Object.values(blocks)]) + +// Set background +setBackground(sky); + +// Gravity +function applyGravity() { + const playerSprite = getFirst(player) + if (playerSprite) { + const belowTile = getTile(playerSprite.x, playerSprite.y + 1) + if (!belowTile.some(sprite => Object.keys(blocks).includes(sprite))) { + playerSprite.y += gravity + } + } +} +// Start screen +setMap(levels[level]) + +addText("Controls:", { + x: 1, + y: 1, + color: color`2`, +}) + +addText("WASD - to move", { + x: 2, + y: 2, + color: color`2`, +}) + +addText("\nK, L - \nto place, destroy \nblocks", { + x: 2, + y: 3, + color: color`2`, +}) + +addText("\nI - \ncycle through\nblocks", { + x: 2, + y: 7, + color: `2`, +}) + +addText("\nJ - reset map", { + x: 2, + y: 11, + color: color`2` +}) + +setPushables({ + [player]: [] +}) + +// Start Game Function +function startGame() { + clearText() + level = 1 + setMap(levels[level]) +} + +function getCurrentBlock() { + return Object.values(blocks)[currentBlockIndex] +} + +// Gravity interval +let gravityInterval = setInterval(applyGravity, 300) + +// Movement Keys +onInput("w", () => { + if (level == 0) startGame() + clearText() + const playerSprite = getFirst(player) + if (playerSprite) { + const aboveTile = getTile(playerSprite.x, playerSprite.y - 1) + const isSolidAbove = aboveTile.some(sprite => Object.keys(blocks).includes(sprite)) + if (!isSolidAbove) { + playerSprite.y -= 1 + direction = "up" + } + } +}) + + +onInput("a", () => { + if (level == 0) startGame() + clearText() + playerSprite = getFirst(player) + playerSprite.x -= 1 + if (playerSprite) { + const leftTile = getTile(playerSprite.x - 1, playerSprite.y) + const isSolidLeft = leftTile.some(sprite => Object.keys(blocks).includes(sprite)) + if (!isSolidLeft) { + direction = "left" + } + } +}) + +onInput("d", () => { + if (level == 0) startGame() + clearText() + playerSprite = getFirst(player) + playerSprite.x += 1 + + if (playerSprite) { + const rightTile = getTile(playerSprite.x + 1, playerSprite.y) + const isSolidRight = rightTile.some(sprite => Object.keys(blocks).includes(sprite)) + if (!isSolidRight) { + direction = "right" + } + } +}) + +onInput("s", () => { + if (level == 0) startGame() + clearText() + const playerSprite = getFirst(player) + if (playerSprite) { + const belowTile = getTile(playerSprite.x, playerSprite.y + 1) + const isSolidBelow = belowTile.some(sprite => Object.keys(blocks).includes(sprite)) + if (!isSolidBelow) { + direction = "down" + } + } +}) + +// Place block +onInput("k", () => { + if (level == 0) startGame() + clearText() + const playerSprite = getFirst(player) + if (playerSprite) { + let targetX = playerSprite.x + let targetY = playerSprite.y + + if (direction === "up") { + targetY -= 1 + } else if (direction === "down") { + targetY += 1 + } else if (direction === "left") { + targetX -= 1 + } else if (direction === "right") { + targetX += 1 + } + + const targetTile = getTile(targetX, targetY) + const isTargetEmpty = targetTile.length === 0 + + if (isTargetEmpty) { + addSprite(targetX, targetY, getCurrentBlock()) + } + } +}) + +// Destroy block +onInput("l", () => { + if (level == 0) startGame() + clearText() + const playerSprite = getFirst(player) + if (playerSprite) { + let targetX = playerSprite.x + let targetY = playerSprite.y + + if (direction === "up") { + targetY -= 1 + } else if (direction === "down") { + targetY += 1 + } else if (direction === "left") { + targetX -= 1 + } else if (direction === "right") { + targetX += 1 + } + + const targetTile = getTile(targetX, targetY) + const isTargetEmpty = targetTile.length === 0 + + if (!isTargetEmpty) { + clearTile(targetX, targetY) + } + } +}) + +// Cycle through available blocks +onInput("i", () => { + if (level == 0) startGame() + clearText() + currentBlockIndex = (currentBlockIndex + 1) % Object.keys(blocks).length + addText("Current block: ", { + x: 3, + y: 4, + color: color`3` + }) + addText(Object.keys(blocks)[currentBlockIndex], { + x: 3, + y: 5, + color: color`5` + }) +}) + +// Reset Level +onInput("j", () => { + if (level == 0) startGame() + const currentLevel = levels[level]; + + if (currentLevel !== undefined) { + clearText(); + setMap(currentLevel); + } +}); + +afterInput(() => {}) diff --git a/games/self-sabotage.js b/games/self-sabotage.js new file mode 100644 index 0000000000..fa39bdd3c7 --- /dev/null +++ b/games/self-sabotage.js @@ -0,0 +1,279 @@ +/* +@title: You Are the Enemy +@author: Suratii +@addedOn: 2024-12-03 +@tags: [] +*/ + +const player = "p"; +const terrain = "t"; +const enemy = "e"; +const bullet = "b"; +const target = "g"; +const tear = "x"; + +let playerHP = 10; +let hits = 0; +let level = 0; +let gameStarted = false; + +const levels = [ + { targetHits: 3, enemiesPerHit: 2 }, + { targetHits: 5, enemiesPerHit: 3 }, + { targetHits: 10, enemiesPerHit: 5 } +]; + +setLegend( + [player, bitmap` +0000000DD0000000 +000000D4D0000000 +00000D4D00000000 +0002222200000000 +0022000220000000 +0020202020000000 +0020202020000000 +0020000021110000 +0022000221000000 +0002222200000000 +0000202000000000 +0000202000000000 +0002202200000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [terrain, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [enemy, bitmap` +0000000CC0000000 +000000CCC0000000 +00000CCC00000000 +000LLLLL00000000 +00LL000LL0000000 +00L0L0L0L0000000 +00L0L0L0L0000000 +00L00000L0000000 +00LL000LL0000000 +000LLLLL00000000 +0000L0L000000000 +0000L0L000000000 +000LL0LL00000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [bullet, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000600000000 +0000000L00000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [target, bitmap` +3333333333333333 +3222222222222223 +3233333333333323 +3232222222222323 +3232333333332323 +3232322222232323 +3232323333232323 +3232323223232323 +3232323223232323 +3232323333232323 +3232322222232323 +3232333333332323 +3232222222222323 +3233333333333323 +3222222222222223 +3333333333333333`] +); + +setSolids([player]); + +// Display the start screen +const startMap = map` +......... +......... +......... +......... +......... +......... +......... +......... +.........`; +setMap(startMap); +setBackground(terrain) + +const textMap = map` +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +.................. +..................`; + +addText("SELF SABATOGE", { x: 2, y: 3, color: color`0` }); +addText("WASD to move", { x: 3, y: 5, color: color`3` }); +addText("Press J to start", { x: 2, y: 7, color: color`5` }); + +// Start the game +onInput("j", () => { + if (!gameStarted) { + gameStarted = true; + startLevel(); + } +}); + +function startLevel() { + clearText(); + setMap(map` +......... +......... +....g.... +......... +......... +......... +....p.... +......... +.........`); + hits = 0; + updateHP(); +} + +// Player movement restricted to avoid the target +onInput("w", () => movePlayer(0, -1)); +onInput("s", () => movePlayer(0, 1)); +onInput("a", () => movePlayer(-1, 0)); +onInput("d", () => movePlayer(1, 0)); + +function movePlayer(dx, dy) { + const p = getFirst(player); + const t = getFirst(target); + const newX = p.x + dx; + const newY = p.y + dy; + + // Prevent movement within 3 pixels of the target + if ( + Math.abs(newX - t.x) < 3 && + Math.abs(newY - t.y) < 3 + ) return; + + if (newX >= 0 && newX <= 8 && newY >= 0 && newY <= 8) { + p.x = newX; + p.y = newY; + } +} + +// Shooting mechanism +onInput("i", () => { + const p = getFirst(player); + if (p) addSprite(p.x, p.y - 1, bullet); +}); + +setInterval(() => { + // Move bullets upward and detect hits + const bullets = getAll(bullet); + bullets.forEach(b => { + b.y -= 1; + if (tilesWith(target, bullet).length > 0) { + hits += 1; + b.remove(); + spawnEnemies(levels[level].enemiesPerHit); + + // Level completion check + if (hits >= levels[level].targetHits) { + level += 1; + if (level >= levels.length) { + addText("You Win!", { x: 4, y: 4, color: color`5` }); + } else { + startLevel(); + } + } + } + }); +}, 200); + +// Spawn enemies +function spawnEnemies(count) { + for (let i = 0; i < count; i++) { + const x = Math.floor(Math.random() * 9); + const y = Math.floor(Math.random() * 9); + addSprite(x, y, enemy); + } +} + +// Enemy movement and player damage +setInterval(() => { + const enemies = getAll(enemy); + const p = getFirst(player); + enemies.forEach(e => { + const dx = p.x > e.x ? 1 : -1; + const dy = p.y > e.y ? 1 : -1; + e.x += dx; + e.y += dy; + + if (tilesWith(player, enemy).length > 0) { + playerHP -= 1; + e.remove(); + if (playerHP <= 0) gameOver(); + } + }); +}, 500); + +function gameOver() { + setMap(textMap) + addText(" YOU DIED", { x: 2, y: 4, color: color`F` }); + addText("k to give up", { x: 6, y: 6, color: color`grey` }); + + onInput("l", () => { + setMap(startMap) + playerHP = 10; // Reset health + startLevel(); + }); + + onInput("k", () => { + gameStarted = false; + setMap(startMap); + clearText(); + addText("SELF SABOTAGE", { x: 2, y: 3, color: color`8` }); + addText("WASD to move", { x: 3, y: 5, color: color`3` }); + addText("Press J to start", { x: 2, y: 7, color: color`5` }); + }); +} + +// HP display at the top right corner +function updateHP() { + clearText(); + addText(`HP: ${playerHP}`, { x: 7, y: 0, color: color`green` }); +} diff --git a/games/sneki.js b/games/sneki.js new file mode 100644 index 0000000000..046f0476ad --- /dev/null +++ b/games/sneki.js @@ -0,0 +1,734 @@ +/* +@title: snek +@author: spacefall +@tags: [] +@addedOn: 2025-01-02 +*/ + +const left = "l"; +const right = "r"; +const up = "u"; +const down = "d"; +const tail = "t"; + +const apple = "a"; +const melon = "m"; +const cherry = "h"; +const orange = "o"; +const pear = "p"; +const pretzel = "z"; +const bread = "b"; +const cocktail = "k"; + +const food = [ + apple, + melon, + cherry, + orange, + pear, + pretzel, + bread, + cocktail, +]; + +let taillessTimeout = null; + +const foodEffects = { + [melon]: { + action: () => { + swapTail(); + return "Head => Tail"; + }, + skipUpdate: true, + }, + [cherry]: { + action: () => { + if (randInt(2)) { + msBetweenMoves *= 0.75; + return "+25% speed"; + } + msBetweenMoves *= 1.25; + return "-25% speed"; + }, + skipUpdate: false, + }, + [orange]: { + action: () => { + if (taillessTimeout) { + clearTimeout(taillessTimeout); + } + for (const t of getAll(tail)) { + t.remove(); + } + taillessTimeout = setTimeout(() => { + taillessTimeout = null; + }, 5000); + return "No tail, trapped"; + }, + skipUpdate: true, + }, + [pretzel]: { + action: () => { + if (randInt(2) && tailLength >= 8) { + tailLength -= 5; + return "-4 length"; + } + tailLength += 3; + return "+4 length"; + }, + skipUpdate: false, + }, + [pear]: { + action: () => { + const x = randInt(width() - 2) + 1; + const y = randInt(height() - 2) + 1; + getFirst(player).remove(); + for (const t of getAll(tail)) { + t.remove(); + } + const tileElems = getTile(x, y); + if (tileElems.length > 0) { + tileElems[0].remove(); + addSprite(x, y, player); + spawnNewFruit(); + } else { + addSprite(x, y, player); + } + return "Teleport"; + }, + skipUpdate: true, + }, + [bread]: { + action: () => { + swappedControls = false; + msBetweenMoves = defmsBetweenMoves; + if (taillessTimeout) { + clearTimeout(taillessTimeout); + } + taillessTimeout = null; + return "Removed effects"; + }, + skipUpdate: false, + }, + [cocktail]: { + action: () => { + swappedControls = !swappedControls; + return "Inverted controls"; + }, + skipUpdate: false, + }, +}; + +const defmsBetweenMoves = 200; + +const eatTune = tune` +70.58823529411765: G4-70.58823529411765, +70.58823529411765: G4/70.58823529411765 + A4-70.58823529411765, +70.58823529411765: A4/70.58823529411765 + B4-70.58823529411765, +70.58823529411765: B4/70.58823529411765 + C5-70.58823529411765, +70.58823529411765: C5/70.58823529411765, +1905.8823529411766`; + +const turnTune = { + [up]: tune` +92.3076923076923: C5^92.3076923076923, +92.3076923076923: F5^92.3076923076923, +2769.230769230769`, + [down]: tune` +92.3076923076923: E5^92.3076923076923, +92.3076923076923: B4^92.3076923076923, +2769.230769230769`, + [left]: tune` +64.51612903225806: C5^64.51612903225806, +64.51612903225806: A4~64.51612903225806, +64.51612903225806: B4~64.51612903225806, +1870.967741935484`, + [right]: tune` +64.51612903225806: B4^64.51612903225806, +64.51612903225806: D5~64.51612903225806, +64.51612903225806: C5~64.51612903225806, +1870.967741935484`, +} + +const gameoverTune = tune` +92.3076923076923: C5/92.3076923076923, +92.3076923076923: F4/92.3076923076923, +92.3076923076923: E4/92.3076923076923, +92.3076923076923: D4/92.3076923076923, +92.3076923076923: C4/92.3076923076923, +2492.3076923076924`; + +setLegend( + [ + "v", //v for void, was origially black, now it's grass + bitmap` +4444444444444444 +4D4D444444444444 +44D4444444444D44 +4D4D44444444D444 +4444444444444444 +4444444444444444 +4444444444444444 +44D44444D4D44444 +444D44444D444444 +4444444444444444 +4444444444444444 +444D444444444444 +44D4D4444444D444 +44444444444D4D44 +4444444444444444 +4444444444444444`, + ], + [ + right, + bitmap` +DDDDDDDDDDDD.... +DDDDDDDDDDDDDD.. +DDDDDDDDDDDDDDD. +DDDDDD2222DDDDDD +DDDDDD2222DDDDDD +DDDDDD2200DDDDDD +DDDDDD2200DDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDD2200DDDDDD +DDDDDD2200DDDDDD +DDDDDD2222DDDDDD +DDDDDD2222DDDDD. +DDDDDDDDDDDDDD.. +DDDDDDDDDDDD....`, + ], + [ + left, + bitmap` +....DDDDDDDDDDDD +..DDDDDDDDDDDDDD +.DDDDD2222DDDDDD +DDDDDD2222DDDDDD +DDDDDD0022DDDDDD +DDDDDD0022DDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDD0022DDDDDD +DDDDDD0022DDDDDD +DDDDDD2222DDDDDD +DDDDDD2222DDDDDD +.DDDDDDDDDDDDDDD +..DDDDDDDDDDDDDD +....DDDDDDDDDDDD`, + ], + [ + down, + bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DD2222DDD2222DDD +DD2222DDD2222DDD +DD2200DDD0022DDD +DD2200DDD0022DDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +.DDDDDDDDDDDDDD. +.DDDDDDDDDDDDDD. +..DDDDDDDDDDDD.. +...DDDDDDDDDD...`, + ], + [ + up, + bitmap` +...DDDDDDDDDD... +..DDDDDDDDDDDD.. +.DDDDDDDDDDDDDD. +.DDDDDDDDDDDDDD. +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDD2200DDD0022DD +DDD2200DDD0022DD +DDD2222DDD2222DD +DDD2222DDD2222DD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`, + ], + [ + tail, + bitmap` +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD +DDDDDDDDDDDDDDDD`, + ], + [ + apple, + bitmap` +................ +.......000...... +..00000090000... +.0033309033300.. +.03333393333300. +.03333333333330. +.03333333333330. +.03333333333330. +.03333333332330. +.03333333332330. +.00333333323300. +..033333333330.. +..003333333300.. +...0033033300... +....00000000.... +................`, + ], + [ + melon, + bitmap` +...000.......... +...0D000000..... +...00DDDDD0..... +....000D000..... +...000424000.... +..00444D44400... +..04D2D444D40... +.0044D442D4400.. +.042D444D4D440.. +.04D442D442D40.. +.042D444D44440.. +.0044D2D2D4400.. +..0444D444D40... +..004D444D400... +...00044D000.... +.....00000......`, + ], + [ + cherry, + bitmap` +................ +...........0000. +.........000990. +.......00099990. +......009909000. +..00000900090... +.003339000900... +.033393309000... +.0333330393300.. +.0323303393330.. +.0332303333330.. +.0033303233330.. +..000003323330.. +......00333300.. +.......000000... +................`, + ], + [ + orange, + bitmap` +................ +........0000.... +......00044000.. +......0CDDD440.. +...0000C044400.. +..0099CCC99900.. +.009999C9999900. +.09999999999990. +.09999999999990. +.09999999999990. +.09999999999990. +.00999999999900. +..099999999990.. +..000999999000.. +....00000000.... +................`, + ], + [ + pear, + bitmap` +.......0000..... +......00CC0..... +.....00C000..... +.....04C40...... +....0044400..... +....0444440..... +....0444440..... +...004444400.... +...044444440.... +..00444444400... +..04424444440... +..04424444440... +..04442444440... +..00444444400... +...004444400.... +....0000000.....`, + ], + [ + pretzel, + bitmap` +..00000.000000.. +.00299000209900. +.099999909999900 +0099009009902990 +0990000099000990 +0990000990000990 +0990000990000990 +0992002909000990 +0099009909909920 +.009099000909900 +..0009900099000. +..0099099909900. +.00990099909920. +.09920000000990. +.00000.....0000. +................`, + ], + [ + bread, + bitmap` +.......000000... +.....000999900.. +....00999999900. +.000022299999900 +0099992222999990 +0222299222299990 +0222229922299990 +0222222922299900 +002222299299990. +.02222992299990. +.02222992299990. +.02222992299990. +.02222990299900. +.0022299000000.. +..0022990....... +...000000.......`, + ], + [ + cocktail, + bitmap` +................ +...00000........ +..0066600....... +..0666660..000.. +..066626000020.. +..066629999920.. +..006629999920.. +...00029992920.. +.....029992920.. +.....029929920.. +.....022999220.. +.....002222200.. +......0002000... +......0002000... +......0222220... +......0000000...`, + ], +); + +const maps = [ + map` +.................... +.vvv.v..v.vvv.v.v.v. +.v...vv.v.v...v.v... +.vvv.v.vv.vv..vv..v. +...v.v..v.v...v.v.v. +.vvv.v..v.vvv.v.v.v. +.................... +.................... +.................... +.................... +.................... +r................... +.................... +.................... +.................... +....................`, + map` +............... +............... +............... +............... +........a...... +............... +r.......a...... +............... +........a...... +............... +............... +...............`, +]; + +let player = right; +let tailLength = 1; +let msBetweenMoves = defmsBetweenMoves; +let movementBlock = false; +let clearTextTimeout; +let swappedControls = false; +let gameover = false; +let score = 0; + +// Title Screen, "snek" written with sprites +setMap(maps[0]); + +addText("Press k to start", { y: 8, color: color`0` }); + +// Listens to "k" input +// It starts the game if on the title screen or restarts it if in the game +onInput("k", () => { + setBackground("v"); + // Reset score + tailLength = 1; + score = 0; + + // Remove effects + msBetweenMoves = defmsBetweenMoves; + swappedControls = false; + movementBlock = false; + clearText(); + setMap(maps[1]); + addText("Score: 0", { color: color`0` }); + player = right; + if (taillessTimeout) { + clearTimeout(taillessTimeout); + } + taillessTimeout = null; + if (gameover) { + checkGameover(); + gameover = false; + } +}); + +checkGameover(); + +// Player input +onInput("s", () => changeDirection(down, up)); +onInput("w", () => changeDirection(up, down)); +onInput("d", () => changeDirection(right, left)); +onInput("a", () => changeDirection(left, right)); + +function changeDirection(newDir, oppositeDir) { + // Return if movement is blocked + if (movementBlock) return; + + // Change direction based on effect + const targetDir = swappedControls ? oppositeDir : newDir; + const blockedDir = swappedControls ? newDir : oppositeDir; + const moves = { + [down]: { x: 0, y: 1 }, + [up]: { x: 0, y: -1 }, + [left]: { x: -1, y: 0 }, + [right]: { x: 1, y: 0 }, + }; + + // Prevent moving in blocked direction + if (player === blockedDir || player === targetDir) return; + const snek = getFirst(player); + const move = moves[targetDir]; + if (!isMovementValid(snek.x + move.x, snek.y + move.y)) return; + + // Update snake head direction + snek.type = targetDir; + player = targetDir; + playTune(turnTune[targetDir]); + //moved = true; +} + +// Checks if the movement is valid: if snake is not touching the tail +function isMovementValid(x, y) { + return !getTile(x, y).some((sprite) => sprite.type === tail); +} + +// Spawns new fruit in a random position (and not occupied by other sprites) +// Will always spawn an apple if the score is less than 5 +function spawnNewFruit() { + let x; + let y; + + do { + x = randInt(width()); + y = randInt(height()); + } while (getTile(x, y).length > 0); + + const fruitType = score < 5 ? apple : food[randInt(food.length)]; + addSprite(x, y, fruitType); +} + +// Process food item in tile specified, returns bool to permit/deny tail update +function processFood(x, y) { + for (const sprite of getTile(x, y)) { + if (!food.includes(sprite.type)) continue; + + // Handle fruit consumption + sprite.remove(); + tailLength++; + score += swappedControls ? 2 : 1; + playTune(eatTune); + + // Apply fruit effect + const effect = foodEffects[sprite.type]; + if (effect) { + showText(effect.action()); + spawnNewFruit(); + return effect.skipUpdate; + } + + // Default apple behavior + clearText(); + addText(`Score: ${score}`, { color: color`0` }); + spawnNewFruit(); + return false; + } + return false; +} + +function getValidCoords(x, y) { + if (x >= width()) { + x = 0; + } else if (x < 0) { + x = width() - 1; + } + if (y >= height()) { + y = 0; + } else if (y < 0) { + y = height() - 1; + } + return { x, y }; +} + +// Main function for movement, calculates the next position, checks if it is valid, processes food items, and updates the tail +// Retuns false is movement is invalid, aka game over +function move() { + const snek = getFirst(player); + const moves = { + [down]: { x: 0, y: 1 }, + [up]: { x: 0, y: -1 }, + [left]: { x: -1, y: 0 }, + [right]: { x: 1, y: 0 }, + }; + const move = moves[player]; + + // Fix position if at borders + let coords = { x: snek.x + move.x, y: snek.y + move.y }; + if (taillessTimeout == null) { + coords = getValidCoords(coords.x, coords.y); + // Return false if movement is invalid (snake if eating itself) -> Game Over + if (!isMovementValid(coords.x, coords.y)) return false; + } else { + if (coords.x < 0 || coords.x >= width() || + coords.y < 0 || coords.y >= height() || + !isMovementValid(coords.x, coords.y)) return false; + } + + // Eat food item if present + const skipTail = processFood(coords.x, coords.y); + + // Skip tail update if fruit effect is blocking it + if (!skipTail && taillessTimeout == null) { + // Update tail if movement is valid + let currTailLength = 0; + for (const thisTail of getAll(tail).reverse()) { + if (currTailLength < tailLength) { + currTailLength++; + continue; + } + thisTail.remove(); + } + + addSprite(snek.x, snek.y, tail); + // Update head position + } + + snek.x = coords.x; + snek.y = coords.y; + + // Unlock head movement + movementBlock = false; + return true; +} + +// Swaps the head with the tail +function swapTail() { + const tailSwapDef = [ + { dx: 1, dy: 0, dir: left }, + { dx: -1, dy: 0, dir: right }, + { dx: 0, dy: 1, dir: up }, + { dx: 0, dy: -1, dir: down }, + ]; + + const lastTail = getFirst(tail); + if (!lastTail) return; + + // Transform head into tail + getFirst(player).type = tail; + + // Find direction of last tail piece + player = tailSwapDef.find(({ dx, dy }) => { + const pos = getValidCoords(lastTail.x + dx, lastTail.y + dy); + const tile = getTile(pos.x, pos.y); + return tile.length > 0 && tile[0].type === tail; + })?.dir; + + // Change last tail piece into head with the direction found + lastTail.type = player; + + // Recreate the tail pieces, so that the snake continues and doesn't look like it used a portal + const tailList = getAll(tail).reverse(); + for (const tailSpr of tailList) { + addSprite(tailSpr.x, tailSpr.y, tail); + tailSpr.remove(); + } +} + +// Clears the text, writes, and sets a timeout to restore the score text +function showText(text) { + clearTimeout(clearTextTimeout); + clearText(); + addText(text, { color: color`0` }); + clearTextTimeout = setTimeout(() => { + clearText(); + addText(`Score: ${score}`, { color: color`0` }); + }, 2000); +} + +// Gets a random intager up to max, nothing more +function randInt(max) { + return ~~(Math.random() * ~~max); +} + +// Moves the snake and checks for game over every msBetweenMoves +function checkGameover(atRisk = false) { + if (!move()) { + if (!atRisk) { + movementBlock = false; + setTimeout(checkGameover(true), msBetweenMoves / 4); + } else { + clearText(); + clearTimeout(clearTextTimeout); + addText("Game Over", { color: color`0` }); + addText(`Score: ${score}`, { y: 1, color: color`0` }); + addText("Press k to retry", { y: 2, color: color`0` }); + playTune(gameoverTune); + // Lock movement + movementBlock = true; + gameover = true; + } + } else { + setTimeout(checkGameover, msBetweenMoves); + } +} diff --git a/games/wanna_see_me_speedrun.js b/games/wanna_see_me_speedrun.js new file mode 100644 index 0000000000..5a33dafad6 --- /dev/null +++ b/games/wanna_see_me_speedrun.js @@ -0,0 +1,767 @@ +/* +@title: Wanna See Me Speedrun +@author: alex tran +@tags: ['action', 'strategy', 'real-time'] +@addedOn: 2024-12-12 + +modified from tutorial + +game description: +think and move fast as you speed past mazes on a 3 second timer! dodge enemies and reach +the file to go onto the next level, picking up bonuses and time extensions on your way. + +this game is meant to be replayed! try again to get better, and then try +again once you beat the game to get a better rank! + +controls: +WASD to move +k to restart (sends back to first level) + +inspirations: +Pizza Tower by Tour De Pizza (speed-based gameplay, the majority of the game lol) +ULTRAKILL by Arsi "Hakita" Patala (ranking system and final screen) +*/ + +//game hints below, expand the comments to see +/* +1. time refreshes can be used multiple times. use this to wait out enemies! +2. bonuses, which are the small smiling chips, can be picked up once per level and contribute +to final rank. pick up 3 bonuses to move up a rank! +3. mash your keyboard. +4. there is a tier above s rank, which is the coveted PERFECT rank. acheive this by obtaining an s +rank and moving up a tier with bonuses! +*/ + + + +// define the sprites in our game +const player = "p"; +const box = "x"; +const goal = "g"; +const wall = "w"; +const deco1 = "1"; +const background = "o" +const death = "d" +const black = "b" +const deadPlayer = "e" +const floorArrow = "a" +const timeReset = "t" +const hubert = "h" +const dangerLine = "l" + +// make yo beats dre +const melody = tune` +500: C4~500, +15500` +const crash = tune` +500: G4^500 + B4^500 + A4^500 + F4^500 + C5^500, +15500` +const timerTune = tune` +200: A5^200 + F5^200 + D5^200, +200: E5^200 + G5^200 + A5^200, +6000` +const bonusTune = tune` +250: B4^250, +250: C5^250, +250: E5^250 + C5^250 + B4^250, +7250` +const pRank = tune` +187.5: A5/187.5, +187.5: G5/187.5, +187.5: A5/187.5, +187.5: B5/187.5 + C4/187.5, +187.5: B5/187.5 + F5/187.5 + C4/187.5, +5062.5` + +//extra variables idk +let count = 3 +let pettedHubert = false +let bonuses = 0 +let bigTimer = 0 +let restarts = 0 + +// assign bitmap art to each sprite +setLegend( + [player, bitmap` +................ +.00000000000.... +.0LLLLLLL11110.. +.0L00000000010.. +.0L00000000010.. +.0L00000000010.. +.0L04000400010.. +.0L00000000010.. +.0L00000000010.. +.01000000000L0.. +.0111LLLLLLLL0.. +..0000LLL00000.. +.00000000000000. +.0LLLLLLLL4L4L0. +.00000000000000. +................`], + [box, bitmap` +.............00. +.............010 +............0000 +.00000000000000. +.0LLLLLLLLLLLL0. +.01111111111LL0. +.00000000000000. +..0..........0.. +..0..........0.. +..0..........0.. +.00000000000000. +.0LLLLLLLLLLLL0. +.00000000000000. +..010......010.. +...0........0... +................`], + [goal, bitmap` +................ +................ +................ +.....00000000... +....002022020... +...0022000020... +...0222000020... +...0222222220... +...0200000020... +...0200404020... +...0200000020... +...0222222220... +...0000000000... +................ +................ +................`], + [black, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [death, bitmap` +................ +.............9.. +...000000....9.. +..00000000...9.. +.00LLLLL000..... +.0LLLLLLL00..9.. +.0L3LL3LL000.... +.0LLLLLLL000.... +.00LLLLLL0000... +.000LLL000000... +..000000000000.. +..000000000000.. +...00000000000.. +...00000000000.. +...000.0000..... +................`], + [wall, bitmap` +0000000000000000 +0LLLLLLLLLLLLLL0 +0L111111111111L0 +0L111111111111L0 +0LLLLLLLLLLLLLL0 +0L000000000000L0 +0L004444444400L0 +0LLLLLLLLLLLLLL0 +0L111111111111L0 +0L111111111111L0 +0LLLLLLLLLLLLLL0 +0L111111111111L0 +0L111111111111L0 +0LLLLLLLLLLLLLL0 +0L4L4LLLLLLLLLL0 +0000000000000000`], + [deco1, bitmap` +0000000000000000 +0LLLLLLLLLLLLLL0 +0L111111111111L0 +0L100000000001L0 +0LL0040404000LL0 +0L100000000401L0 +0L104004000001L0 +0LL0000400040LL0 +0LL0400440000LL0 +0L100000000401L0 +0L104000000001L0 +0LL0004040400LL0 +0L100000000001L0 +0L111111111111L0 +0L4L4L4LLLLLLLL0 +0000000000000000`], + [background, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [deadPlayer, bitmap` +................ +.000............ +.0L000000000000. +.0500LL11111110. +.0L00L777777710. +.0500L777272710. +.0L00L777777710. +.0L0LL7772227L0. +.0L0LL7272727L0. +.0L0LL7277777L0. +.0L00L7272777L0. +.0L0017272777L0. +.0L0017777777L0. +.0L0011LLLLLLL0. +.00000000000000. +................`], + [floorArrow, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLL0LLLLLL +LLLLLLLL060LLLLL +LLLLLLLL0600LLLL +LLLLLLLL06660LLL +L0000000066600LL +L06666666666660L +L06666666666660L +LL000000066600LL +LLLLLLLL06660LLL +LLLLLLLL0600LLLL +LLLLLLLL060LLLLL +LLLLLLLL00LLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`], + [timeReset, bitmap` +................ +................ +................ +.......0000000.. +.......0660660.. +..000000FF0FF00. +.0DDDDDDDDDDDD0. +.0DDD0DD666DDD0. +.0DD000DD6DDDD0. +.0DDD0DDD6DDDD0. +.0LLLLLLLLLLLL0. +.0000000000000.. +................ +................ +................ +................`], + [hubert, bitmap` +................ +................ +....000..000.... +....0L0..0L0.... +....0L0000L0.... +....0DDDDDD0.... +....0D6DDDD0.... +....0DDDD6D0.... +....0D6DDDD0.... +....0DD66DD0.... +....0DDDDDL0.... +....00000000.... +................ +................ +................ +................`], + [dangerLine, bitmap` +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLL33LLL33LLL33L +LL333LL333LL333L +L333LL333LL333LL +L333LL333LL333LL +LL333LL333LL333L +LLL33LLL33LLL33L +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL`] +); + +// set background +setBackground([background]) + +// create game levels +let level = 0; // this tracks the level we are on +const levels = [ + map` +bwwwwwwb +bw....wb +bwpaagwb +bw....wb +bwwwww1b`, + map` +bwwwwwwb +bw.a..wb +bw.1w.wb +bwpwwgwb +bwwwwwwb`, + map` +bwwwwwwb +bw.w.gwb +bwpxa.wb +bwwwwwwb`, + map` +bwwwwwwb +bw....wb +bwpwax.b +bww1w.wb +bwx.g.wb +bwwwwwwb`, + map` +bwwwwwwbb +bwp.wgwbb +bw.x...bb +bwwwwwwbb +bwelldwbb +b1wwwwwbb`, + map` +bwwwwwwwb +bw.a.1.wb +bwplldgwb +bwwwwwwwb`, + map` +bwwwwwwb +bwplldwb +bwllldwb +bw1.xg.b +bwwwwwwb`, + map` +bwwwwwwb +bwpwxgwb +bwllldwb +b1..wwwb +bwwa.gwb +bwwwwwwb`, + map` +bwwwwwwwb +bwpw...wb +bw.w.w.wb +bw.wtw.wb +bw.w.wgwb +bw..llldb +bwwwwwwwb`, + map` +bwwwwwwb +bwp.wgwb +bwllwdwb +bw....wb +bwhw.gwb +bwwwwwwb`, + map` +bwwwwwwwb +bw.pwg.wb +bw..w..wb +bwlllddwb +bw..1..wb +bw.....wb +bwwwwwwwb`, + map` +bwwwwwwwwb +bw1p....wb +bw.llld.wb +bwlld.wwwb +bw.llldxwb +bw.w.wwwwb +bw.g.x..wb +bwwwwwwwwb`, + map` +wwwwwwwww +w...llldw +wpllld..w +wwww.wwww +w.gwtx..w +w..w1w..w +w...llldw +w...t..xw +wwwwwwwww`, + map` +wwwwwww1w +w...t...w +w.wwww..w +wllldwx.w +w.w..w.xw +wlld.wxgw +w.w..w.xw +wpw..1..w +wwwwwwwww`, + map` +wwwwwwww +wllld..w +w.wwww.w +w....w.w +w.tp.wgw +w..xxw.w +w.wwww.w +w..lhldw +wwwwwwww`, + map` +bbwwwwwwwwwb +bbw...llld1b +bbwpllld..gb +bbw.x.llldwb +bbwwwwwwwwwb`, + map` +wwww.wwww +wg.lllddw +w..w.w..w +w.wwxwwww +...xpxld. +w.wwxwwww +w.hw.w..w +w.......w +wwww.wwww`, + map` +wwwwww +w.p.ww +w....w +wddddw +w.w.tw +w.1.ww +w.wxhw +w.g.xw +wwwwww`, + map` +bwwwtwwwb +bw..llldb +bw.www.wb +bw..pwtwb +bwwwww.wb +bwxg...1b +bwwwwwwwb`, + map` +bwwwwwwwb +bwpllldwb +bwww.wwwb +bw.llldwb +bw.wwwwwb +bw.t..1wb +bwg..xh.b +bwwwwwwwb`, + map` +bbbbbbb +bbbbbbb +bbbbbbb +bwwwwwb +bw.p.wb +bwwwwwb +bbbbbbb` // index 20, win screen +]; + +// set the map displayed to the current level +const currentLevel = levels[level]; +setMap(currentLevel); + +setSolids([player, box, wall, black, deco1]); // other sprites cannot go inside of these sprites + +// allow certain sprites to push certain other sprites +setPushables({ + [player]: [box], + [box]: [box] +}); + +// make a variable to disable movement when off +let gameRunning = 0; + +// inputs for player movement control +onInput("s", () => { + if (gameRunning == 0) { + getFirst(player).y += 1; // positive y is downwards + playTune(melody) + } +}); + +onInput("w", () => { + if (gameRunning == 0) { + getFirst(player).y -= 1; + playTune(melody) + } +}); + +onInput("d", () => { + if (gameRunning == 0) { + getFirst(player).x += 1; // positive y is downwards + playTune(melody) + } +}); + +onInput("a", () => { + if (gameRunning == 0) { + getFirst(player).x -= 1; // positive y is downwards + playTune(melody) + } +}); + +onInput("k", () => { + clearText() + //manage timers + clearInterval(playerTimer); + clearInterval(countdown); + createTimers() + //manage variables + count = 3 + pettedHubert = false + bonuses = 0 + level = 0 + // bigTimer = 0 //disabled for restart punishment + restarts += 1 + addText("3", { x: 1, y: 7, color: color`4` }); + //reset to first map + setMap(map` +bwwwwwwb +bw....wb +bwpaagwb +bw....wb +bwwwww1b`) +}); //restart game + +// these get run after every input +afterInput(() => { + // win condition + const reachedGoal = tilesWith(goal, player).length; + + //death tile + const touchedDeath = tilesWith(death, player).length; + + //time reset + const timeReseted = tilesWith(timeReset, player).length; + + //bonus counter + const petHubert = tilesWith(hubert, player).length; + + // if the number of goals is the same as the number of goals covered + // all goals are covered and we can go to the next level + if (reachedGoal == 1) { + // increase the current level number + level = level + 1; + // reset hubert state (one hubert per level) + pettedHubert = false + + const currentLevel = levels[level]; + + // make sure the level exists and if so set the map + // otherwise, we have finished the last level, there is no level + // after the last level + if (currentLevel !== undefined) { + setMap(currentLevel); + + // make sure the level exists before we load it + if (currentLevel !== undefined) { + clearText(""); + setMap(currentLevel); + + // Clear the existing level timer if it exists + if (playerTimer) { + clearInterval(playerTimer); + } + + //reset countdown if it exists + if (countdown) { + clearInterval(countdown) + count = 3 + } + //reset timers using my nifty new function wow + createTimers(); + } + + } + } + + // if the player touches a ghost, lose the game + if (touchedDeath == 1) { + loseGame() + } + + // if the player touches a time bonus, reset the time counters + if (timeReseted == 1) { + //reset intervals + clearInterval(playerTimer); + clearInterval(countdown); + count = 3 + //create new timers + createTimers(); + //play dopamine inducing sound + playTune(timerTune) + } + + // if the player touches a bonus chip, add one to the bonus counter + if (petHubert == 1) { + playTune(bonusTune) + if (pettedHubert == false) { + bonuses += 1 + } + pettedHubert = true + } + + // if the player is on the level 20 (win screen), autowin + if (level == 20) { + clearText() + //stats + addText("you win!", { y: 1, color: color`4` }); + addText("bonus:", { x: 2, y: 3, color: color`2` }); + addText("" + bonuses, { x: 12, y: 3, color: color`9` }); + addText("time:", { x: 2, y: 4, color: color`2` }); + clearInterval(gameTimer); + addText("" + bigTimer, { x: 12, y: 4, color: color`9` }); + addText("restarts:", { x: 2, y: 5, color: color`2` }); + addText("" + restarts, { x: 12, y: 5, color: color`9` }); + /* + rank calculation + s rank - sub 35 + a rank - sub 40 + b rank - sub 50 + c rank - sub 60 + d rank - 60+ + + if 3 bonuses are collected, move up a rank + p rank if s rank time + 3 bonuses + */ + if (bigTimer < 45) { //s rank + if (bonuses >= 3) { + addText("PERFECT!", { y: 14, color: color`H` }); + playTune(pRank); + } else { + addText("S RANK", { y: 14, color: color`3` }); + } + } else if (bigTimer < 53) { //a rank + if (bonuses >= 3) { + addText("S RANK", { y: 14, color: color`3` }); + } else { + addText("A RANK", { y: 14, color: color`9` }); + } + } else if (bigTimer < 60) { //b rank + if (bonuses >= 3) { + addText("A RANK", { y: 14, color: color`9` }); + } else { + addText("B RANK", { y: 14, color: color`6` }); + } + } else if (bigTimer < 70) { //c rank + if (bonuses >= 3) { + addText("B RANK", { y: 14, color: color`6` }); + } else { + addText("C RANK", { y: 14, color: color`4` }); + } + } else if (bigTimer >= 70) { //d rank + if (bonuses >= 3) { + addText("C RANK", { y: 14, color: color`4` }); + } else { + addText("D RANK", { y: 14, color: color`7` }); + } + } + //gameplay things + gameRunning = 1 + if (playerTimer) { + clearInterval(playerTimer); + clearInterval(countdown); + } + } + +}); + +// Start the initial timer for the first level (remove /* to activate, currently off) +let playerTimer = setTimeout(() => { + // Stop the player after 3 seconds on the initial level + loseGame() +}, 3000); // 3000 milliseconds = 3 seconds + + +//make a countdown timer +addText("" + count, { x: 1, y: 7, color: color`4` }); +let countdown = setInterval(() => { + count -= 1; // Subtract 1 from count + addText("" + count, { x: 1, y: 7, color: color`4` }); +}, 1000); // 1000 milliseconds = 1 second + +//add text showing TIME vertically +addText("T", { x: 1, y: 2, color: color`2` }); +addText("I", { x: 1, y: 3, color: color`2` }); +addText("M", { x: 1, y: 4, color: color`2` }); +addText("E", { x: 1, y: 5, color: color`2` }); + +//add an interval to move all enemies left every 0.5 seconds +let moveEnemies = setInterval(() => { + const shmoovers = getAll(death); + shmoovers.forEach(sprite => { + sprite.x -= 1; // Move the sprite to the left + }); + + //check if the enemy is on the player + const touchedDeath = tilesWith(death, player).length; + + if (touchedDeath == 1) { + loseGame(); + } +}, 1000); + +function createTimers() { + gameRunning = 0; // Reset gameRunning to allow player movement + //gameplay timer + playerTimer = setTimeout(() => { + loseGame() + }, 3000); // 3000 milliseconds = 3 seconds + //countdown timer + addText("T", { x: 1, y: 2, color: color`2` }); + addText("I", { x: 1, y: 3, color: color`2` }); + addText("M", { x: 1, y: 4, color: color`2` }); + addText("E", { x: 1, y: 5, color: color`2` }); + addText("" + count, { x: 1, y: 7, color: color`4` }); + countdown = setInterval(() => { + count -= 1; // Subtract 1 from count + addText("" + count, { x: 1, y: 7, color: color`4` }); + }, 1000); // 1000 milliseconds = 1 second +} + +function loseGame() { + setMap(map` +bbbbbbb +bbbbbbb +bbbbbbb +bwwwwwb +bw.p.wb +bwwwwwb +bbbbbbb`); + + clearText() + //stats + addText("game over...", { y: 1, color: color`3` }); + addText("press k to restart", { y: 3, color: color`2` }); + addText("current deaths:" + (restarts + 1), {y:5, color: color`6`}); + + //gameplay things + gameRunning = 1; + playTune(crash) + clearInterval(playerTimer); + clearInterval(countdown); +} + +//set up a timer to track total play length +let gameTimer = setInterval(() => { + bigTimer = bigTimer + 0.01 +}, 10); diff --git a/games/yellow_fish_swimming12.js b/games/yellow_fish_swimming12.js new file mode 100644 index 0000000000..a547fd4df1 --- /dev/null +++ b/games/yellow_fish_swimming12.js @@ -0,0 +1,252 @@ +/* +@title: yellowman12 +@author: cheter +@tags: [] +@addedOn: 2024-12-13 +*/ + +const player = "p" +const box = "b" +const goal = "g" +const playera = "a" +const shark = "s" +const aqua = "a" +const kelp = "k" + +setLegend( + [player, bitmap` +................ +................ +................ +...666.......... +...66666........ +...6666666...... +.66666666666.... +.666666660666... +.996666666666... +...66666669..... +...6666699...... +...66669........ +...9999......... +................ +................ +................`], + [box, bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000`], + [shark, bitmap` +..........0..... +.........00..... +........010..... +.......0110..... +...0000111000... +..0111111111L0.0 +.0111101111L1L0L +03232111111L1L10 +02323111111L1L10 +.01111111111L101 +..0111111111L0.0 +...0000011100... +.......01110.... +........010..... +.........0...... +................`], + [goal, bitmap` +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444 +4444444444444444`], + [playera, bitmap` +................ +................ +...6666......... +...666666....... +...666666666.... +...666666666.... +.6666666606666.. +.6666600066663.. +.6666606666666.. +...666666666.... +...66666........ +...666.......... +................ +................ +................ +................`], + [aqua, bitmap` +2775777777777577 +7777727777777777 +7777777727775777 +7777777777777777 +7727577777777277 +7777777777727777 +7777777727777777 +7777777777777777 +5777277777775777 +7777777775777757 +7777777577777777 +7777777777727777 +7577277777777577 +7777777727757777 +7777777777277777 +7777277777777777`], + [kelp, bitmap` +.........D...... +.........D...... +.........D...... +.........D...... +.........D...... +D........D...... +DD......D......D +..DD....D....DDD +...DD...D...DD.. +....DD..D.DDD... +D....DD.D.D..... +.DDD..D.D.D...DD +...DDDDDDDDDDD.. +......DDDDD..... +......DDDDD..... +......DDDDD.....`] +) +levels = [map` +..............g +..............g +..............g +p.............g +..............g +..............g +..............g`] + +level = 0 +levelCount = 0; +speed=650 +setMap(levels[level]) + +setPushables({ + [player]: [] +}) + +setSolids([player, kelp]) + +setBackground(aqua) + +function spawnkelp() { + randomnumber = Math.floor(Math.random() * 3)+4 + for (let i = 0; i < randomnumber; i++) { + randomykelp = Math.floor(Math.random() * height()) + randomxkelp = Math.floor(Math.random() * (width() - 2)) + addSprite(randomxkelp, randomykelp, kelp) + } +} + +spawnkelp() +function sharkfunc() { + randomy = Math.floor(Math.random() * height()) + randomx = Math.floor(Math.random() * 3)+1 + addSprite(width()-randomx, randomy, shark) + sharks = getAll(shark) + for (let i = 0; i < sharks.length; i++) { + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + clearText(); + spawnkelp() + speed=650 + } + + if (sharks[i].x<1) { + clearTile(sharks[i].x, sharks[i].y) + } + if (sharks[i].x>0) { + sharks[i].x-=1 + } + + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + clearText(); + spawnkelp() + speed=650 + } + } + clearText() + addText("level: " + levelCount, {x: 6, y: 1, color: color`9`}) + setTimeout(() => { + sharkfunc() + }, speed) +} + +setTimeout(() => { + sharkfunc() +}, speed) +onInput("s", () => { + getFirst(player).y += 1 + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + spawnkelp() + speed=650 + } +}) +onInput("w", () => { + getFirst(player).y -= 1 + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + spawnkelp() + speed=650 + } +}) + +onInput("d", () => { + getFirst(player).x += 1 + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + spawnkelp() + speed=650 + } +}) + +afterInput(() => { + if (tilesWith(player, goal).length > 0) { + setMap(levels[level]) + levelCount++; + spawnkelp() + if (speed>100) { + speed-=60 + } + } + if (tilesWith(player, shark).length > 0) { + setMap(levels[level]) + levelCount = 0; + spawnkelp() + speed=650 + } +}) diff --git a/package.json b/package.json index 1c65720e10..7637bec281 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start": "astro dev", "build": "astro build", "test": "deno run --allow-read ./tests/sprigfuzzy.js", - "test:unit": "vitest" + "test:unit": "cross-env PUBLIC_MAX_ITERATIONS=2000 PUBLIC_MAX_LOOP_TIME_MS=1500 vitest" }, "dependencies": { "@astrojs/preact": "^2.0.1", @@ -29,6 +29,7 @@ "@wcj/markdown-to-html": "^3.0.2", "astro": "2.7.0", "bcryptjs": "^2.4.3", + "cross-env": "^7.0.3", "dotenv": "^16.3.1", "firebase-admin": "^11.10.1", "js-beautify": "^1.15.1", diff --git a/src/components/GalleryGame.tsx b/src/components/GalleryGame.tsx new file mode 100644 index 0000000000..1cac156119 --- /dev/null +++ b/src/components/GalleryGame.tsx @@ -0,0 +1,60 @@ +import { useEffect, useState, useRef } from "preact/hooks"; +import { loadThumbnailUrl } from "../lib/thumbnail"; + +type GalleryGameProps = { + filename: string + title: string + author: string + tags: string[] + isNew: boolean + show: boolean + filter: any, + setFilter: Function +} + +export default function GalleryGame({ setFilter, filter, show, filename, title, author, tags, isNew }: GalleryGameProps) { + const [thumbnailUrl, setThumbnailUrl] = useState(null); + const gameRef = useRef(null); + + useEffect(() => { + const observer = new IntersectionObserver(entries => { + entries.forEach(async entry => { + if (entry.isIntersecting) { + const thumbnail = await loadThumbnailUrl(filename) + setThumbnailUrl(thumbnail); + } + }) + }, { threshold: 0.1 }); + + observer.observe(gameRef.current!); + return () => { + observer.unobserve(gameRef.current!); + } + }, []); + + if (!show) return null; + return ( +
window.open(`/gallery/${filename}`, '_blank')} + > + {tags.includes("tutorial") ? ( + Tutorial + ) : isNew ? ( + New + ) : null} + + {thumbnailUrl && thumbnail } + +

{title}

+

by @{author}

+

e.stopPropagation()}> + + {tags.map((tag) => + setFilter((_filter: any) => ({ ..._filter, tags: [...filter.tags, tag] }))}>#{tag} + )} +

+
+ ) +} \ No newline at end of file diff --git a/src/components/big-interactive-pages/editor.tsx b/src/components/big-interactive-pages/editor.tsx index 3fbe7d66e3..a2d8f4e9c2 100644 --- a/src/components/big-interactive-pages/editor.tsx +++ b/src/components/big-interactive-pages/editor.tsx @@ -16,7 +16,7 @@ import { import { useEffect, useRef, useState} from "preact/hooks"; import { codeMirror, errorLog, isNewSaveStrat, muted, PersistenceState, RoomState, screenRef, cleanupRef } from "../../lib/state"; import EditorModal from "../popups-etc/editor-modal"; -import { runGame } from "../../lib/engine"; +import { runGame, _performSyntaxCheck } from "../../lib/engine"; import DraftWarningModal from "../popups-etc/draft-warning"; import { debounce } from "throttle-debounce"; import Help from "../popups-etc/help"; @@ -36,6 +36,15 @@ import { PersistenceStateKind } from "../../lib/state"; let screenShakeSignal: Signal | null = null; +const performSyntaxCheck = () => { + const code = codeMirror.value?.state.doc.toString() ?? ""; + const res = _performSyntaxCheck(code); + if (res.error) { + errorLog.value = []; + errorLog.value = [res.error]; + } +} + export const onRun = async () => { foldAllTemplateLiterals(); if (!screenRef.value) return; @@ -262,6 +271,12 @@ export default function Editor({ persistenceState, cookies, roomState }: EditorP const [sessionId] = useState(nanoid()); + useEffect(() => { + setInterval(() => { + performSyntaxCheck(); + }, 2000); + }, []); + useEffect(() => { const channel = new BroadcastChannel('session_channel'); channel.onmessage = (event) => { diff --git a/src/components/navbar.module.css b/src/components/navbar.module.css index e483c34c4a..c463bf7485 100644 --- a/src/components/navbar.module.css +++ b/src/components/navbar.module.css @@ -11,8 +11,6 @@ position: relative; text-align: center; justify-content: space-between; - white-space: nowrap; /* P3baf */ - overflow: hidden; /* Pad2a */ } .container ul { diff --git a/src/global.css b/src/global.css index 193ace7d3f..ac65a16b82 100644 --- a/src/global.css +++ b/src/global.css @@ -33,9 +33,9 @@ body { --fg-muted: #9d9d9d; --fg-muted-on-accent: #8fcabb; --error: #e03131; - --accent: #399F6E; + --accent: #078969; --accent-light: #80c3a0; - --accent-dark: #0B6F3B; /* #136853; */ + --accent-dark: #136853; --fg-switch-low: #515151; --fg-switch-high: #f3f3f3; diff --git a/src/lib/custom-babel-transforms.ts b/src/lib/custom-babel-transforms.ts index de79d4f06e..ca97488827 100644 --- a/src/lib/custom-babel-transforms.ts +++ b/src/lib/custom-babel-transforms.ts @@ -121,4 +121,19 @@ export function BuildDuplicateFunctionDetector(engineApiKeys: string[]) { } } +} + +export function dissallowBackticksInDoubleQuotes() { + return { + visitor: { + StringLiteral(path: any) { + const { value, extra } = path.node; + if (value.includes('`')) { + const loc = path.node.loc.start; + const quoteType = extra.raw[0]; + throw path.buildCodeFrameError(`Backtick found within ${quoteType === '"' ? 'double' : 'single'}-quoted string at (${loc.line}:${loc.column})`); + } + } + } + } } \ No newline at end of file diff --git a/src/lib/engine/error.test.ts b/src/lib/engine/error.test.ts index d290b5ef2d..997c450285 100644 --- a/src/lib/engine/error.test.ts +++ b/src/lib/engine/error.test.ts @@ -1,8 +1,52 @@ import { expect, test } from "vitest" +import TransformDetectInfiniteLoop, { BuildDuplicateFunctionDetector, dissallowBackticksInDoubleQuotes} from "../custom-babel-transforms"; +import * as Babel from "@babel/standalone"; +import { baseEngine } from "../../../engine/src/base"; import {normalizeGameError} from "./error" // SyntaxErrors (not in evals) seem to go through babel (i.e. have an error.code), so they are not tested here +export function transformAndThrowErrors(code: string, engineAPIKeys: string[], runCb: (code: any) => any) { + try { + const transformedCode = Babel.transform(code, { + plugins: [TransformDetectInfiniteLoop, BuildDuplicateFunctionDetector(engineAPIKeys), dissallowBackticksInDoubleQuotes], + retainLines: true + }); + runCb(transformedCode); + return null; + } catch (error: any) { + return normalizeGameError({ kind: "runtime", error }); + } +} + +test('detect infinite while loops', () => { + const code = 'while (true) {}' + const engine = baseEngine(); + const res = transformAndThrowErrors(code, Object.keys(engine.api), (transformedCode) => { + const fn = new Function(transformedCode.code); + fn(); + }); + + const workDir = process.cwd(); + const expectedError = `RangeError: Potential infinite loop + at eval (${workDir}/src/lib/engine/error.test.ts:1:152)`; + expect(res?.description).toBe(expectedError); +}); + +test('detect infinite for loop', () => { + const code = 'for (;;) {}' + const engine = baseEngine(); + const res = transformAndThrowErrors(code, Object.keys(engine.api), (transformedCode) => { + const fn = new Function(transformedCode.code); + fn(); + }); + + const workDir = process.cwd(); + const expectedError = `RangeError: Potential infinite loop + at eval (${workDir}/src/lib/engine/error.test.ts:1:148)`; + expect(res?.description).toBe(expectedError); +}); + test('calls a mistyped console.log function (line 2)', () => { const payload = {kind: "runtime", error: new TypeError("console.llog is not a function")} payload.error.stack = `TypeError: console.llog is not a function diff --git a/src/lib/engine/index.ts b/src/lib/engine/index.ts index 7d6b630ba1..2ebe17f0be 100644 --- a/src/lib/engine/index.ts +++ b/src/lib/engine/index.ts @@ -2,10 +2,10 @@ import { playTune } from './tune' import { normalizeGameError } from './error' import { bitmaps, NormalizedError } from '../state' import type { PlayTuneRes } from '../../../engine/src/api' -import { textToTune } from '../../../engine/src/base' +import { baseEngine, textToTune } from '../../../engine/src/base' import { webEngine } from '../../../engine/src/web' import * as Babel from "@babel/standalone" -import TransformDetectInfiniteLoop, { BuildDuplicateFunctionDetector } from '../custom-babel-transforms' +import TransformDetectInfiniteLoop, { BuildDuplicateFunctionDetector, dissallowBackticksInDoubleQuotes } from '../custom-babel-transforms' import {logInfo} from "../../components/popups-etc/help"; interface RunResult { @@ -37,6 +37,26 @@ function parseErrorStack(err?: Error): [number | null, number | null] { return [null, null]; } +export function transformAndThrowErrors(code: string, engineAPIKeys: string[], runCb: (code: any) => any) { + try { + const transformedCode = Babel.transform(code, { + plugins: [TransformDetectInfiniteLoop, BuildDuplicateFunctionDetector(engineAPIKeys), dissallowBackticksInDoubleQuotes], + retainLines: true + }); + runCb(transformedCode); + return null; + } catch (error: any) { + return normalizeGameError({ kind: "runtime", error }); + } +} + +export function _performSyntaxCheck(code: string): { error: NormalizedError | null, cleanup: () => void } { + const game = baseEngine(); + + const engineAPIKeys = Object.keys(game.api); + return { error: transformAndThrowErrors(code, engineAPIKeys, () => {}), cleanup: () => void 0 }; +} + export function runGame(code: string, canvas: HTMLCanvasElement, onPageError: (error: NormalizedError) => void): RunResult | undefined { const game = webEngine(canvas) const tunes: PlayTuneRes[] = [] @@ -112,19 +132,11 @@ export function runGame(code: string, canvas: HTMLCanvasElement, onPageError: (e } const engineAPIKeys = Object.keys(api); - try { - const transformResult = Babel.transform(code, { - plugins: [TransformDetectInfiniteLoop, BuildDuplicateFunctionDetector(engineAPIKeys)], - retainLines: true - }); - logInfo.value = []; - const fn = new Function(...engineAPIKeys, transformResult.code!); - fn(...Object.values(api)); - return { error: null, cleanup }; - } catch (error: any) { - onPageError(normalizeGameError({ kind: "runtime", error })); - return { error: normalizeGameError({ kind: "runtime", error }), cleanup }; - } + return { error: transformAndThrowErrors(code, engineAPIKeys, (transformedCode) => { + logInfo.value = []; + const fn = new Function(...engineAPIKeys, transformedCode.code!) + fn(...Object.values(api)) + }), cleanup }; } export function runGameHeadless(code: string): void { diff --git a/src/lib/state.ts b/src/lib/state.ts index 0d2b7fe37c..15526ffa16 100644 --- a/src/lib/state.ts +++ b/src/lib/state.ts @@ -139,6 +139,7 @@ type Theme = { navbarIcon: string, accent: string, accentDark: string, + accentLight: string, fgMutedOnAccent: string, background: string, color: string @@ -149,6 +150,7 @@ const baseTheme: Theme = { navbarIcon: "/SPRIGDINO.png", accent: "#078969", accentDark: "#136853", + accentLight: '#80c3a0', fgMutedOnAccent: "#8fcabb", background: "#2f2f2f", color: "black", @@ -170,6 +172,7 @@ export const themes: Partial> = { navbarIcon: "/PENNY_HEAD.png", accent: "#FFAE06", accentDark: "#ff9d00", + accentLight: "#06b0ffb0", fgMutedOnAccent: "#6d83ff", background: "#3E29ED", } @@ -188,6 +191,7 @@ export const switchTheme = (themeType: ThemeType) => { documentStyle.background = themeValue?.background?? ''; document.documentElement.style.setProperty(`--accent`, themeValue?.accent?? ''); document.documentElement.style.setProperty(`--accent-dark`, themeValue?.accentDark?? ''); + document.documentElement.style.setProperty(`--accent-light`, themeValue?.accentLight?? ''); document.documentElement.style.setProperty(`--fg-muted-on-accent`, themeValue?.fgMutedOnAccent?? ''); documentStyle.color = themeValue?.color ?? ''; diff --git a/src/pages/gallery/gallery.tsx b/src/pages/gallery/gallery.tsx index a4c812a905..d4b5e29da9 100644 --- a/src/pages/gallery/gallery.tsx +++ b/src/pages/gallery/gallery.tsx @@ -1,9 +1,9 @@ import { useState, useEffect } from "preact/hooks"; -import { loadThumbnailUrl } from "../../lib/thumbnail"; import { GameMetadata } from "../../lib/game-saving/gallery"; import Button from "../../components/design-system/button"; import Input from "../../components/design-system/input"; import { IoCaretDown, IoSearch } from "react-icons/io5"; +import GalleryGame from "../../components/GalleryGame"; import "./gallery.css"; enum SortOrder { @@ -54,6 +54,7 @@ export default function Gallery({ games, tags }: { games: GameMetadata[], tags: } countTags(_games) + sortGames(gamesState, SortOrder.TUTORIALS_AND_CHRONOLOGICAL); }, [filter]); function sortGames(games: GameMetadata[], order: SortOrder): GameMetadata[] { @@ -93,59 +94,6 @@ export default function Gallery({ games, tags }: { games: GameMetadata[], tags: setTagCount(tags) } - useEffect(() => { - sortGames(gamesState, SortOrder.TUTORIALS_AND_CHRONOLOGICAL); - - interface GameCard { - element: HTMLLIElement; - filename: string; - title: string; - author: string; - tags: string[]; - isNew: boolean; - } - for (const element of document.querySelectorAll("#games > .game")) { - element.querySelector("img")?.setAttribute("data-loaded", "false"); - } - - const loadImage = async (gameCard: GameCard): Promise => { - const img = gameCard.element.querySelector( - "img" - ) as HTMLImageElement; - if (["loading", "true"].includes(img.dataset.loaded!)) return; - img.dataset.loaded = "loading"; - const thumbnail = await loadThumbnailUrl(gameCard.filename); - img.src = thumbnail; - img.dataset.loaded = "true"; - }; - - const gameCards: GameCard[] = []; - for (const _element of document.querySelectorAll( - "#games > .game" - )) { - const element = _element as HTMLLIElement; - const gameCard = { - element, - filename: element.dataset.filename!, - title: element.dataset.title!, - author: element.dataset.author!, - tags: element.dataset.tags!.split(","), - isNew: element.dataset.isNew === "true", - }; - - gameCards.push(gameCard); - new IntersectionObserver((_update) => { - const update = (_update[0] || - _update) as IntersectionObserverEntry; - if (update.isIntersecting) loadImage(gameCard); - }).observe(element); - } - - setTimeout(() => { - for (const gameCard of gameCards) loadImage(gameCard); - }, 500); - }, [gamesState]); - return (
@@ -236,39 +184,17 @@ export default function Gallery({ games, tags }: { games: GameMetadata[], tags:
- { - gamesState.map((game: GalleryGameMetadata) => ( -
window.open(`/gallery/${game.filename}`, '_blank')} - data-filename={game.filename} - data-title={game.title} - data-author={game.author} - data-tags={game.tags.join(",")} - data-is-new={String(game.isNew)} - > - {game.tags.includes("tutorial") ? ( - Tutorial - ) : game.isNew ? ( - New - ) : null} - - {`preview -

{game.title}

-

by @{game.author}

-

e.stopPropagation()}> - - {game.tags.map((tag) => - setFilter(_filter => ({ ..._filter, tags: [...filter.tags, tag] }))}>#{tag} - )} -

-
- )) - } + {gamesState.map((game) => ( + + ))}
) diff --git a/yarn.lock b/yarn.lock index 3bf51cf848..c09eee6ea6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -157,6 +157,27 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz" integrity sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw== +"@babel/core@>=7.0.0-0 <8.0.0", "@babel/core@^7.9.6": + version "7.20.12" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz" + integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helpers" "^7.20.7" + "@babel/parser" "^7.20.7" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.12" + "@babel/types" "^7.20.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + "@babel/core@^7.22.5": version "7.23.0" resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz" @@ -178,27 +199,6 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/core@^7.9.6", "@babel/core@>=7.0.0-0 <8.0.0": - version "7.20.12" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz" - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helpers" "^7.20.7" - "@babel/parser" "^7.20.7" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.12" - "@babel/types" "^7.20.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" - "@babel/generator@^7.20.7": version "7.20.14" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz" @@ -676,6 +676,56 @@ resolved "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.0.tgz" integrity sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + "@esbuild/darwin-arm64@0.17.19": version "0.17.19" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz" @@ -691,6 +741,276 @@ resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@fastify/busboy@^1.2.1": version "1.2.1" resolved "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz" @@ -728,7 +1048,7 @@ "@firebase/util" "1.9.3" tslib "^2.1.0" -"@firebase/database-types@^0.10.4", "@firebase/database-types@0.10.4": +"@firebase/database-types@0.10.4", "@firebase/database-types@^0.10.4": version "0.10.4" resolved "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz" integrity sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ== @@ -871,22 +1191,22 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - "@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@1.4.14": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13": version "1.4.14" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== @@ -901,15 +1221,7 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.14": - version "0.3.19" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.17": +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.17": version "0.3.19" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz" integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== @@ -987,7 +1299,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1121,11 +1433,86 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@rollup/rollup-android-arm-eabi@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54" + integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA== + +"@rollup/rollup-android-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e" + integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA== + "@rollup/rollup-darwin-arm64@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz" integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA== +"@rollup/rollup-darwin-x64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724" + integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb" + integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA== + +"@rollup/rollup-linux-arm-musleabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3" + integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw== + +"@rollup/rollup-linux-arm64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496" + integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA== + +"@rollup/rollup-linux-arm64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065" + integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d" + integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw== + +"@rollup/rollup-linux-riscv64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983" + integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg== + +"@rollup/rollup-linux-s390x-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58" + integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g== + +"@rollup/rollup-linux-x64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b" + integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== + +"@rollup/rollup-linux-x64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127" + integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== + +"@rollup/rollup-win32-arm64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5" + integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ== + +"@rollup/rollup-win32-ia32-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2" + integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ== + +"@rollup/rollup-win32-x64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818" + integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== + "@sendgrid/client@^7.7.0": version "7.7.0" resolved "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz" @@ -1256,7 +1643,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@1.0.6": +"@types/estree@*", "@types/estree@1.0.6", "@types/estree@^1.0.0": version "1.0.6" resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -1529,7 +1916,7 @@ estree-walker "^3.0.3" magic-string "^0.30.11" -"@vitest/pretty-format@^2.1.2", "@vitest/pretty-format@2.1.2": +"@vitest/pretty-format@2.1.2", "@vitest/pretty-format@^2.1.2": version "2.1.2" resolved "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz" integrity sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA== @@ -1553,7 +1940,7 @@ magic-string "^0.30.11" pathe "^1.1.2" -"@vitest/spy@^2.1.0-beta.1", "@vitest/spy@2.1.2": +"@vitest/spy@2.1.2", "@vitest/spy@^2.1.0-beta.1": version "2.1.2" resolved "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz" integrity sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A== @@ -1611,16 +1998,16 @@ unified "^11.0.0" vfile "^6.0.0" -abbrev@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz" - integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== - abbrev@1: version "1.1.1" resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abbrev@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz" + integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -2021,15 +2408,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2067,7 +2446,7 @@ check-error@^2.1.1: resolved "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz" integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== -chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0": +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2142,16 +2521,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@^1.1.4, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@^1.1.4, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-support@^1.1.2: version "1.1.3" resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" @@ -2222,6 +2601,13 @@ crelt@^1.0.5: resolved "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz" integrity sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA== +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -2231,6 +2617,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.1: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + css-selector-parser@^3.0.0: version "3.0.5" resolved "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.5.tgz" @@ -2241,7 +2636,7 @@ cssfontparser@^1.2.1: resolved "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz" integrity sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg== -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.6, debug@4: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.6: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -2359,7 +2754,7 @@ eastasianwidth@^0.2.0: resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== -ecdsa-sig-formatter@^1.0.11, ecdsa-sig-formatter@1.0.11: +ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== @@ -2582,11 +2977,16 @@ estraverse@^5.1.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.1, estree-walker@2.0.2: +estree-walker@2.0.2, estree-walker@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== +estree-walker@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.0.tgz" + integrity sha512-s6ceX0NFiU/vKPiKvFdR83U1Zffu7upwZsGwpoqfg5rbbq1l50WQ5hCeIvM6E6oD4shUHCYMsiFPns4Jk0YfMQ== + estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz" @@ -2594,11 +2994,6 @@ estree-walker@^3.0.3: dependencies: "@types/estree" "^1.0.0" -estree-walker@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.0.tgz" - integrity sha512-s6ceX0NFiU/vKPiKvFdR83U1Zffu7upwZsGwpoqfg5rbbq1l50WQ5hCeIvM6E6oD4shUHCYMsiFPns4Jk0YfMQ== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" @@ -2679,7 +3074,9 @@ fast-text-encoding@^1.0.0, fast-text-encoding@^1.0.3: integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w== fast-xml-parser@^4.2.2: - version "4.3.1" + version "4.5.1" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.5.1.tgz#a7e665ff79b7919100a5202f23984b6150f9b31e" + integrity sha512-y655CeyUQ+jj7KBbYMc4FG01V8ZQqjN+gDYGJ50RtfsUB8iG9AmwmwoAgeKLJdmueKKMrH1RJ7yXHTSoczdv5w== dependencies: strnum "^1.0.5" @@ -3347,7 +3744,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@^2.0.4, inherits@2: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4739,7 +5136,7 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -4766,6 +5163,13 @@ mimic-fn@^4.0.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +minimatch@9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" + integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.1.1: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -4787,13 +5191,6 @@ minimatch@^9.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0: version "1.2.7" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" @@ -5025,14 +5422,7 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.1: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-limit@^3.0.2: +p-limit@^3.0.1, p-limit@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -5309,10 +5699,10 @@ protobufjs-cli@1.1.1: tmp "^0.2.1" uglify-js "^3.7.7" -protobufjs@^7.0.0: - version "7.2.2" - resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz" - integrity sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q== +protobufjs@7.2.4: + version "7.2.4" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz" + integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -5327,10 +5717,10 @@ protobufjs@^7.0.0: "@types/node" ">=13.7.0" long "^5.0.0" -protobufjs@7.2.4: - version "7.2.4" - resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz" - integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ== +protobufjs@^7.0.0: + version "7.2.2" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz" + integrity sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -5764,7 +6154,7 @@ sade@^1.7.3: dependencies: mri "^1.1.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0: +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5803,21 +6193,7 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.2: - version "7.3.8" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.5: - version "7.3.8" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.8: +semver@^7.1.2, semver@^7.3.5, semver@^7.3.8: version "7.3.8" resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== @@ -5913,7 +6289,7 @@ slash@^4.0.0: resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -source-map-js@^1.2.1, "source-map-js@>=0.6.2 <2.0.0": +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -5967,13 +6343,6 @@ streamsearch@^1.1.0: resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -5992,7 +6361,7 @@ string_decoder@^1.1.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1: +string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -6001,14 +6370,12 @@ string-width@^5.0.1: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + safe-buffer "~5.2.0" stringify-entities@^4.0.0: version "4.0.3" @@ -6124,11 +6491,6 @@ svelte-hmr@^0.15.1: resolved "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz" integrity sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA== -svelte@^3.54.0: - version "3.55.1" - resolved "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz" - integrity sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ== - svelte2tsx@^0.5.11: version "0.5.23" resolved "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.5.23.tgz" @@ -6137,6 +6499,11 @@ svelte2tsx@^0.5.11: dedent-js "^1.0.1" pascal-case "^3.1.1" +svelte@^3.54.0: + version "3.55.1" + resolved "https://registry.npmjs.org/svelte/-/svelte-3.55.1.tgz" + integrity sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ== + synckit@^0.8.4: version "0.8.5" resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" @@ -6309,13 +6676,6 @@ underscore@~1.13.2: resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== -undici@^5.22.0: - version "5.25.2" - resolved "https://registry.npmjs.org/undici/-/undici-5.25.2.tgz" - integrity sha512-tch8RbCfn1UUH1PeVCXva4V8gDpGAud/w0WubD6sHC46vYQ3KDxL+xv1A2UxK0N6jrVedutuPHxe1XIoqerwMw== - dependencies: - busboy "^1.6.0" - undici@5.20.0: version "5.20.0" resolved "https://registry.npmjs.org/undici/-/undici-5.20.0.tgz" @@ -6323,6 +6683,13 @@ undici@5.20.0: dependencies: busboy "^1.6.0" +undici@^5.22.0: + version "5.25.2" + resolved "https://registry.npmjs.org/undici/-/undici-5.25.2.tgz" + integrity sha512-tch8RbCfn1UUH1PeVCXva4V8gDpGAud/w0WubD6sHC46vYQ3KDxL+xv1A2UxK0N6jrVedutuPHxe1XIoqerwMw== + dependencies: + busboy "^1.6.0" + unherit@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz" @@ -6341,33 +6708,7 @@ unified@^10.0.0, unified@^10.1.2: trough "^2.0.0" vfile "^5.0.0" -unified@^11.0.0: - version "11.0.4" - resolved "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz" - integrity sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ== - dependencies: - "@types/unist" "^3.0.0" - bail "^2.0.0" - devlop "^1.0.0" - extend "^3.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^6.0.0" - -unified@^11.0.3: - version "11.0.4" - resolved "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz" - integrity sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ== - dependencies: - "@types/unist" "^3.0.0" - bail "^2.0.0" - devlop "^1.0.0" - extend "^3.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^6.0.0" - -unified@~11.0.0: +unified@^11.0.0, unified@^11.0.3, unified@~11.0.0: version "11.0.4" resolved "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz" integrity sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ== @@ -6497,16 +6838,7 @@ unist-util-visit@^4.0.0, unist-util-visit@^4.1.0, unist-util-visit@^4.1.2: unist-util-is "^5.0.0" unist-util-visit-parents "^5.1.1" -unist-util-visit@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz" - integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== - dependencies: - "@types/unist" "^3.0.0" - unist-util-is "^6.0.0" - unist-util-visit-parents "^6.0.0" - -unist-util-visit@~5.0.0: +unist-util-visit@^5.0.0, unist-util-visit@~5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz" integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== @@ -6588,17 +6920,7 @@ vfile-message@^4.0.0: "@types/unist" "^3.0.0" unist-util-stringify-position "^4.0.0" -vfile@^5.0.0: - version "5.3.6" - resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz" - integrity sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -vfile@^5.3.2: +vfile@^5.0.0, vfile@^5.3.2: version "5.3.6" resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz" integrity sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA== @@ -6721,7 +7043,7 @@ vscode-jsonrpc@8.0.2: resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz" integrity sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ== -vscode-languageserver-protocol@^3.17.1, vscode-languageserver-protocol@3.17.2: +vscode-languageserver-protocol@3.17.2, vscode-languageserver-protocol@^3.17.1: version "3.17.2" resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2.tgz" integrity sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg== @@ -6734,7 +7056,7 @@ vscode-languageserver-textdocument@^1.0.1, vscode-languageserver-textdocument@^1 resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@^3.15.1, vscode-languageserver-types@^3.17.1, vscode-languageserver-types@^3.17.2, vscode-languageserver-types@3.17.2: +vscode-languageserver-types@3.17.2, vscode-languageserver-types@^3.15.1, vscode-languageserver-types@^3.17.1, vscode-languageserver-types@^3.17.2: version "3.17.2" resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz" integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==