diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..b5bc6e5 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,4 @@ +export * from './pipes' +export * from './scenes' +export * from './tags' +export * from './tiles' diff --git a/src/constants/pipes.ts b/src/constants/pipes.ts new file mode 100644 index 0000000..daa37f5 --- /dev/null +++ b/src/constants/pipes.ts @@ -0,0 +1,36 @@ +export enum EmptyPipe { + '═' = '═', + '║' = '║', + '╔' = '╔', + '╗' = '╗', + '╚' = '╚', + '╝' = '╝', + '╠' = '╠', + '╣' = '╣', + '╦' = '╦', + '╩' = '╩', + '╬' = '╬', +} + +export enum FilledPipe { + '━' = '━', + '┃' = '┃', + '┏' = '┏', + '┓' = '┓', + '┗' = '┗', + '┛' = '┛', + '┣' = '┣', + '┫' = '┫', + '┳' = '┳', + '┻' = '┻', + '╋' = '╋', +} + +export enum DirectionPipe { + '△' = '△', + '▷' = '▷', + '▽' = '▽', + '◁' = '◁', +} + +export const pipes = [...Object.values(EmptyPipe), ...Object.values(FilledPipe)] diff --git a/src/types/scene.ts b/src/constants/scenes.ts similarity index 62% rename from src/types/scene.ts rename to src/constants/scenes.ts index 6bc9ad9..93ae260 100644 --- a/src/types/scene.ts +++ b/src/constants/scenes.ts @@ -1,3 +1,4 @@ export enum Scene { game = 'game', + preload = 'preload', } diff --git a/src/constants/tags.ts b/src/constants/tags.ts new file mode 100644 index 0000000..b5fec25 --- /dev/null +++ b/src/constants/tags.ts @@ -0,0 +1,3 @@ +export enum Tag { + pipe = 'pipe', +} diff --git a/src/constants/tiles.ts b/src/constants/tiles.ts new file mode 100644 index 0000000..84f556f --- /dev/null +++ b/src/constants/tiles.ts @@ -0,0 +1 @@ +export const TILE_SIZE = 234 diff --git a/src/events/cursors.ts b/src/events/cursors.ts deleted file mode 100644 index 5df6674..0000000 --- a/src/events/cursors.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Player } from '../types' - -// pixels per second -const SPEED = 320 - -export function addCursorKeys(player: Player) { - onKeyDown('left', () => { - player.move(-SPEED, 0) - }) - - onKeyDown('right', () => { - player.move(SPEED, 0) - }) - - onKeyDown('up', () => { - player.move(0, -SPEED) - }) - - onKeyDown('down', () => { - player.move(0, SPEED) - }) -} diff --git a/src/events/index.ts b/src/events/index.ts deleted file mode 100644 index 0d26bb1..0000000 --- a/src/events/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './cursors' diff --git a/src/gameobjects/enemy.ts b/src/gameobjects/enemy.ts deleted file mode 100644 index 6d0fe84..0000000 --- a/src/gameobjects/enemy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ghosty } from '../sprites' - -export function addEnemy(x: number, y: number) { - return add([ghosty, pos(x, y), anchor('center')]) -} diff --git a/src/gameobjects/index.ts b/src/gameobjects/index.ts deleted file mode 100644 index 8c85dea..0000000 --- a/src/gameobjects/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './enemy' -export * from './player' diff --git a/src/gameobjects/player.ts b/src/gameobjects/player.ts deleted file mode 100644 index 960b611..0000000 --- a/src/gameobjects/player.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bean } from '../sprites' - -export function addPlayer(x = center().x, y = center().y) { - return add([bean, pos(x, y), rotate(0), anchor('center')]) -} diff --git a/src/helpers/index.ts b/src/helpers/index.ts new file mode 100644 index 0000000..1f68a07 --- /dev/null +++ b/src/helpers/index.ts @@ -0,0 +1,2 @@ +export * from './pipes' +export * from './solution' diff --git a/src/helpers/pipes.ts b/src/helpers/pipes.ts new file mode 100644 index 0000000..306ea5d --- /dev/null +++ b/src/helpers/pipes.ts @@ -0,0 +1,59 @@ +import type { GameObj } from 'kaboom' + +import { EmptyPipe } from '../constants' + +/** + * Rotates pipe 90 degrees. + * + * @param pipe - Pipe sprite. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function rotatePipe(pipe: GameObj) { + switch (pipe.type) { + case EmptyPipe['═']: + pipe.type = EmptyPipe['║'] + break + + case EmptyPipe['║']: + pipe.type = EmptyPipe['═'] + break + + case EmptyPipe['╔']: + pipe.type = EmptyPipe['╗'] + break + + case EmptyPipe['╗']: + pipe.type = EmptyPipe['╝'] + break + + case EmptyPipe['╚']: + pipe.type = EmptyPipe['╔'] + break + + case EmptyPipe['╝']: + pipe.type = EmptyPipe['╚'] + break + + case EmptyPipe['╠']: + pipe.type = EmptyPipe['╦'] + break + + case EmptyPipe['╣']: + pipe.type = EmptyPipe['╩'] + break + + case EmptyPipe['╦']: + pipe.type = EmptyPipe['╣'] + break + + case EmptyPipe['╩']: + pipe.type = EmptyPipe['╠'] + break + } + + pipe.angle += 90 + + if (pipe.angle >= 360) { + pipe.angle -= 360 + } +} diff --git a/src/helpers/solution.ts b/src/helpers/solution.ts new file mode 100644 index 0000000..305441f --- /dev/null +++ b/src/helpers/solution.ts @@ -0,0 +1,14 @@ +import type { GameObj } from 'kaboom' + +import { Tag } from '../constants' + +/** + * Checks if level has been solved. + * + * @returns - If all the pipes are in the correct position. + */ +export function checkSolution(level: GameObj): boolean { + return level.get(Tag.pipe).reduce((accumulator, pipe) => { + return accumulator && pipe.type === pipe.solution + }, true) +} diff --git a/src/index.ts b/src/index.ts index 23a668b..7cef882 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,6 @@ import { start } from './scenes' start() + +// press F1 +// debug.inspect = true; diff --git a/src/levels/index.ts b/src/levels/index.ts new file mode 100644 index 0000000..548d0c5 --- /dev/null +++ b/src/levels/index.ts @@ -0,0 +1,42 @@ +import { TILE_SIZE } from '../constants' +import { levels } from './levels' +import { getTiles } from './tiles' + +/** + * Gets level data. + * + * @param level - Level number. + * @returns - Level data. + */ +export function getLevel(level: number) { + const { map, scale } = levels[level] + + const tileWidth = TILE_SIZE * scale + const tileHeight = TILE_SIZE * scale + + const width = tileWidth * map[0].length + const height = tileHeight * map.length + + const options = { + tileWidth, + tileHeight, + tiles: getTiles(scale), + + pos: vec2( + center().x + tileWidth / 2 - width / 2, + center().y + tileHeight / 2 - height / 2, + ), + } + + return [map, options] as const +} + +/** + * Checks if level exists. + * + * @param level - Level number. + * @returns - Whether level exists. + */ +export function hasLevel(level: number): boolean { + return Boolean(levels[level]) +} diff --git a/src/levels/levels.ts b/src/levels/levels.ts new file mode 100644 index 0000000..6eef557 --- /dev/null +++ b/src/levels/levels.ts @@ -0,0 +1,42 @@ +// https://wikipedia.org/wiki/Box-drawing_characters +// ▲ ▼ ► ◄ ↑ ↓ → ← ⇦ ⇧ ⇨ ⇩ +// △ ▷ ▽ ◁ ⬤ ◉ ◎ +// ┓ ┗ ┏ ┛ ┣ ┫ ┳ ┻ ╋ ━ ┃ +// ╔ ╗ ╚ ╝ ╠ ╣ ╦ ╩ ╬ ═ ║ + +export const levels = [ + // 0 + { + // prettier-ignore + map: [ + '▷═╗ ', + ' ║ ', + ' ╚═◁', + ], + scale: 1, + }, + + // 1 + { + // prettier-ignore + map: [ + '╔═╦═◁', + '╚═╬═╗', + '▷═╩═╝', + ], + scale: 1, + }, + + // 2 + { + // prettier-ignore + map: [ + ' ╔══╦══╗ ', + ' ║╔═╬═╗║ ', + '▷╣╠═╬═╣╠◁', + ' ║╚═╬═╝║ ', + ' ╚══╩══╝ ', + ], + scale: 0.8, + }, +] diff --git a/src/levels/tiles.ts b/src/levels/tiles.ts new file mode 100644 index 0000000..5e07197 --- /dev/null +++ b/src/levels/tiles.ts @@ -0,0 +1,53 @@ +import { DirectionPipe, EmptyPipe, pipes, Tag } from '../constants' + +/** + * Gets level map tile object. + * + * @param tileScale - Tile scale. + * @returns - Tile object. + */ +export function getTiles(tileScale: number) { + const tileComps = [anchor('center'), scale(tileScale)] + + const staticComps = [...tileComps, color(135, 206, 235)] + + return pipes.reduce( + (accumulator: Record unknown[]>, value) => { + accumulator[value] = () => [ + ...tileComps, + sprite(value), + area(), + rotate(0), + { type: value, solution: value }, + Tag.pipe, + ] + + return accumulator + }, + { + [DirectionPipe['△']]: () => [ + ...staticComps, + sprite(EmptyPipe['║']), + { type: DirectionPipe['△'] }, + ], + + [DirectionPipe['▷']]: () => [ + ...staticComps, + sprite(EmptyPipe['═']), + { type: DirectionPipe['▷'] }, + ], + + [DirectionPipe['▽']]: () => [ + ...staticComps, + sprite(EmptyPipe['║']), + { type: DirectionPipe['▽'] }, + ], + + [DirectionPipe['◁']]: () => [ + ...staticComps, + sprite(EmptyPipe['═']), + { type: DirectionPipe['◁'] }, + ], + }, + ) +} diff --git a/src/scenes/game.ts b/src/scenes/game.ts index 87b15a2..c920b43 100644 --- a/src/scenes/game.ts +++ b/src/scenes/game.ts @@ -1,22 +1,25 @@ -import { addCursorKeys } from '../events' -import { addEnemy, addPlayer } from '../gameobjects' +import { Scene, Tag } from '../constants' +import { checkSolution, rotatePipe } from '../helpers' +import { getLevel, hasLevel } from '../levels' -scene('game', () => { - const player = addPlayer() - - player.onUpdate(() => { - player.angle += 120 * dt() - }) +scene(Scene.game, (levelNumber: number) => { + if (!hasLevel(levelNumber)) { + levelNumber = 0 + } - addCursorKeys(player) + const level = addLevel(...getLevel(levelNumber)) - onClick(() => addKaboom(mousePos())) + level.get(Tag.pipe).forEach((pipe) => { + Array(randi(4)) + .fill(undefined) + .forEach(() => rotatePipe(pipe)) + }) - add([text('Press arrow keys', { width: width() / 2 }), pos(12, 12)]) + onClick(Tag.pipe, (pipe) => { + rotatePipe(pipe) - for (let i = 0; i < 3; i++) { - const x = rand(0, width()) - const y = rand(0, height()) - addEnemy(x, y) - } + if (checkSolution(level)) { + go(Scene.game, levelNumber + 1) + } + }) }) diff --git a/src/scenes/index.ts b/src/scenes/index.ts index ba52303..bacd843 100644 --- a/src/scenes/index.ts +++ b/src/scenes/index.ts @@ -1,2 +1,8 @@ -export * from './game' -export * from './start' +import './game' +import './preload' + +import { Scene } from '../constants' + +export function start() { + go(Scene.preload) +} diff --git a/src/scenes/preload.ts b/src/scenes/preload.ts new file mode 100644 index 0000000..e93f23d --- /dev/null +++ b/src/scenes/preload.ts @@ -0,0 +1,11 @@ +import { pipes, Scene } from '../constants' + +scene(Scene.preload, async () => { + await Promise.all( + pipes.map((value) => { + loadSprite(value, `sprites/pipes/${value}.png`) + }), + ) + + go(Scene.game, new URLSearchParams(location.search).get('level') || 0) +}) diff --git a/src/scenes/start.ts b/src/scenes/start.ts deleted file mode 100644 index 15e4990..0000000 --- a/src/scenes/start.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Scene } from '../types' - -export function start() { - go(Scene.game) -} diff --git a/src/sounds/score.mp3 b/src/sounds/score.mp3 deleted file mode 100644 index e068db0..0000000 Binary files a/src/sounds/score.mp3 and /dev/null differ diff --git a/src/sprites/apple.png b/src/sprites/apple.png deleted file mode 100644 index a7d81ff..0000000 Binary files a/src/sprites/apple.png and /dev/null differ diff --git a/src/sprites/bag.png b/src/sprites/bag.png deleted file mode 100644 index 3b0ba4d..0000000 Binary files a/src/sprites/bag.png and /dev/null differ diff --git a/src/sprites/bean.png b/src/sprites/bean.png deleted file mode 100644 index 66637b6..0000000 Binary files a/src/sprites/bean.png and /dev/null differ diff --git a/src/sprites/bean.ts b/src/sprites/bean.ts deleted file mode 100644 index f8e0da3..0000000 --- a/src/sprites/bean.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Sprite } from '../types' -import image from './bean.png' - -loadSprite(Sprite.bean, image) - -export const bean = sprite(Sprite.bean) diff --git a/src/sprites/bobo.png b/src/sprites/bobo.png deleted file mode 100644 index a946bf8..0000000 Binary files a/src/sprites/bobo.png and /dev/null differ diff --git a/src/sprites/boom.png b/src/sprites/boom.png deleted file mode 100644 index 6289876..0000000 Binary files a/src/sprites/boom.png and /dev/null differ diff --git a/src/sprites/btfly.png b/src/sprites/btfly.png deleted file mode 100644 index d71338b..0000000 Binary files a/src/sprites/btfly.png and /dev/null differ diff --git a/src/sprites/cloud.png b/src/sprites/cloud.png deleted file mode 100644 index 05f93c9..0000000 Binary files a/src/sprites/cloud.png and /dev/null differ diff --git a/src/sprites/coin.png b/src/sprites/coin.png deleted file mode 100644 index 146a3d7..0000000 Binary files a/src/sprites/coin.png and /dev/null differ diff --git a/src/sprites/cursor_default.png b/src/sprites/cursor_default.png deleted file mode 100644 index 1a741a4..0000000 Binary files a/src/sprites/cursor_default.png and /dev/null differ diff --git a/src/sprites/cursor_pointer.png b/src/sprites/cursor_pointer.png deleted file mode 100644 index 4412581..0000000 Binary files a/src/sprites/cursor_pointer.png and /dev/null differ diff --git a/src/sprites/dino.png b/src/sprites/dino.png deleted file mode 100644 index edee654..0000000 Binary files a/src/sprites/dino.png and /dev/null differ diff --git a/src/sprites/door.png b/src/sprites/door.png deleted file mode 100644 index 87d020c..0000000 Binary files a/src/sprites/door.png and /dev/null differ diff --git a/src/sprites/egg.png b/src/sprites/egg.png deleted file mode 100644 index f37a364..0000000 Binary files a/src/sprites/egg.png and /dev/null differ diff --git a/src/sprites/egg_crack.png b/src/sprites/egg_crack.png deleted file mode 100644 index 7192a74..0000000 Binary files a/src/sprites/egg_crack.png and /dev/null differ diff --git a/src/sprites/ghosty.png b/src/sprites/ghosty.png deleted file mode 100644 index 4f2f3be..0000000 Binary files a/src/sprites/ghosty.png and /dev/null differ diff --git a/src/sprites/ghosty.ts b/src/sprites/ghosty.ts deleted file mode 100644 index e2b256c..0000000 --- a/src/sprites/ghosty.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Sprite } from '../types' -import image from './ghosty.png' - -loadSprite(Sprite.ghosty, image) - -export const ghosty = sprite(Sprite.ghosty) diff --git a/src/sprites/gigagantrum.png b/src/sprites/gigagantrum.png deleted file mode 100644 index 039dc9f..0000000 Binary files a/src/sprites/gigagantrum.png and /dev/null differ diff --git a/src/sprites/grape.png b/src/sprites/grape.png deleted file mode 100644 index 1427dd4..0000000 Binary files a/src/sprites/grape.png and /dev/null differ diff --git a/src/sprites/grass.png b/src/sprites/grass.png deleted file mode 100644 index 342993e..0000000 Binary files a/src/sprites/grass.png and /dev/null differ diff --git a/src/sprites/gun.png b/src/sprites/gun.png deleted file mode 100644 index f5d32bc..0000000 Binary files a/src/sprites/gun.png and /dev/null differ diff --git a/src/sprites/heart.png b/src/sprites/heart.png deleted file mode 100644 index a787a7f..0000000 Binary files a/src/sprites/heart.png and /dev/null differ diff --git a/src/sprites/index.ts b/src/sprites/index.ts deleted file mode 100644 index b174efe..0000000 --- a/src/sprites/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './bean' -export * from './ghosty' diff --git a/src/sprites/jumpy.png b/src/sprites/jumpy.png deleted file mode 100644 index 78ae7bb..0000000 Binary files a/src/sprites/jumpy.png and /dev/null differ diff --git a/src/sprites/k.png b/src/sprites/k.png deleted file mode 100644 index 20d23b2..0000000 Binary files a/src/sprites/k.png and /dev/null differ diff --git a/src/sprites/ka.png b/src/sprites/ka.png deleted file mode 100644 index 1bf2dd7..0000000 Binary files a/src/sprites/ka.png and /dev/null differ diff --git a/src/sprites/key.png b/src/sprites/key.png deleted file mode 100644 index 7552dfb..0000000 Binary files a/src/sprites/key.png and /dev/null differ diff --git a/src/sprites/lightening.png b/src/sprites/lightening.png deleted file mode 100644 index 8645c7b..0000000 Binary files a/src/sprites/lightening.png and /dev/null differ diff --git a/src/sprites/mark.png b/src/sprites/mark.png deleted file mode 100644 index 7c57042..0000000 Binary files a/src/sprites/mark.png and /dev/null differ diff --git a/src/sprites/meat.png b/src/sprites/meat.png deleted file mode 100644 index 292568d..0000000 Binary files a/src/sprites/meat.png and /dev/null differ diff --git a/src/sprites/moon.png b/src/sprites/moon.png deleted file mode 100644 index cd36c16..0000000 Binary files a/src/sprites/moon.png and /dev/null differ diff --git a/src/sprites/mushroom.png b/src/sprites/mushroom.png deleted file mode 100644 index 3ed177d..0000000 Binary files a/src/sprites/mushroom.png and /dev/null differ diff --git a/src/sprites/note.png b/src/sprites/note.png deleted file mode 100644 index 2bd770f..0000000 Binary files a/src/sprites/note.png and /dev/null differ diff --git a/src/sprites/pineapple.png b/src/sprites/pineapple.png deleted file mode 100644 index 894063b..0000000 Binary files a/src/sprites/pineapple.png and /dev/null differ diff --git a/src/sprites/portal.png b/src/sprites/portal.png deleted file mode 100644 index 49b52eb..0000000 Binary files a/src/sprites/portal.png and /dev/null differ diff --git a/src/sprites/spike.png b/src/sprites/spike.png deleted file mode 100644 index 94d814e..0000000 Binary files a/src/sprites/spike.png and /dev/null differ diff --git a/src/sprites/src b/src/sprites/src deleted file mode 100644 index 8f42b12..0000000 --- a/src/sprites/src +++ /dev/null @@ -1 +0,0 @@ -Error
404
\ No newline at end of file diff --git a/src/sprites/steel.png b/src/sprites/steel.png deleted file mode 100644 index ee896f1..0000000 Binary files a/src/sprites/steel.png and /dev/null differ diff --git a/src/sprites/sun.png b/src/sprites/sun.png deleted file mode 100644 index 3628ee7..0000000 Binary files a/src/sprites/sun.png and /dev/null differ diff --git a/src/sprites/sword.png b/src/sprites/sword.png deleted file mode 100644 index 99cf100..0000000 Binary files a/src/sprites/sword.png and /dev/null differ diff --git a/src/sprites/watermelon.png b/src/sprites/watermelon.png deleted file mode 100644 index 129ab67..0000000 Binary files a/src/sprites/watermelon.png and /dev/null differ diff --git a/src/types/gameobject.ts b/src/types/gameobject.ts deleted file mode 100644 index 4835fb3..0000000 --- a/src/types/gameobject.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { addPlayer } from '../gameobjects' - -export type Player = ReturnType diff --git a/src/types/index.ts b/src/types/index.ts deleted file mode 100644 index 87eac29..0000000 --- a/src/types/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './gameobject' -export * from './scene' -export * from './sprite' diff --git a/src/types/sprite.ts b/src/types/sprite.ts deleted file mode 100644 index c60dc0f..0000000 --- a/src/types/sprite.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Sprite { - bean = 'bean', - ghosty = 'ghosty', -}