From a1ddce70bf32c0928b86bd5e299b8d39721fb505 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 28 Jan 2025 19:55:38 -0500 Subject: [PATCH] feat(scenes): add instructions to tutorial --- src/constants/layer.ts | 1 + src/gameobjects/text.ts | 4 ++ src/scenes/tutorial.ts | 137 ++++++++++++++++++++++++++++++++++------ 3 files changed, 123 insertions(+), 19 deletions(-) diff --git a/src/constants/layer.ts b/src/constants/layer.ts index 79dfe9a..d305c91 100644 --- a/src/constants/layer.ts +++ b/src/constants/layer.ts @@ -1,3 +1,4 @@ export enum Layer { + Background = -1, Foreground = 1, } diff --git a/src/gameobjects/text.ts b/src/gameobjects/text.ts index 80b23bf..c4b0c37 100644 --- a/src/gameobjects/text.ts +++ b/src/gameobjects/text.ts @@ -1,5 +1,7 @@ import type { GameObj } from 'kaplay' +import { Layer } from '../constants' + interface Props { width: number height: number @@ -16,6 +18,7 @@ export function addText(props: Props) { pos(props.x, props.y), anchor('center'), color(255, 255, 255), + z(Layer.Background), ] let box @@ -30,5 +33,6 @@ export function addText(props: Props) { text(props.text, { size: props.fontSize }), anchor('center'), color(0, 0, 0), + opacity(1), ]) } diff --git a/src/scenes/tutorial.ts b/src/scenes/tutorial.ts index 130557c..74c8d7b 100644 --- a/src/scenes/tutorial.ts +++ b/src/scenes/tutorial.ts @@ -1,40 +1,139 @@ -import { Scene, Sound } from '../constants' -import { addButton, addGame, addPlayer, addText } from '../gameobjects' +import { Scene, Sound, Sprite } from '../constants' +import { + addAvatar, + addButton, + addDrain, + addEnemy, + addGame, + addHealth, + addPause, + addPlayer, + addReward, + addScore, + addText, +} from '../gameobjects' +import { gameState } from '../helpers' + +const instructions = [ + { + start: 2, + text: 'WASD or arrow keys to move', + action() {}, + }, + + { + start: 4, + text: 'Left click to shoot', + action() {}, + }, + + { + start: 6, + text: 'Press P or ESC to pause', + action() { + addPause() + }, + }, + + { + start: 8, + text: 'Score is at the top left', + action() { + addScore() + }, + }, + + { + start: 10, + text: 'Health is at the bottom left', + action() { + addHealth() + addAvatar() + }, + }, + + { + start: 12, + text: 'Shoot bubbles at enemies', + action() { + gameState.enemy.sprites = [Sprite.Spiny] + addEnemy() + }, + }, + + { + start: 22, + text: 'Enemies in a bubble will fall down the drain', + action() { + gameState.enemy.sprites = [Sprite.Spiny] + addEnemy() + addDrain() + }, + }, + + { + start: 32, + text: 'Avoid enemies & projectiles', + action() { + gameState.enemy.sprites = [Sprite.Bubbie, Sprite.Pokey] + addEnemy() + }, + }, + + { + start: 42, + text: 'Upgrade when you reach a certain score', + action() { + addReward() + }, + }, + + { + start: 52, + text: 'Aim for a high score & have fun!', + action() {}, + }, +] scene(Scene.Tutorial, () => { addGame() + addPlayer() const { x } = center() + const margin = 100 addButton({ width: 220, height: 80, radius: 8, x, - y: height() - 80, + y: height() - margin, text: 'Play', onClick() { - play(Sound.Hit) + play(Sound.Shoot) go(Scene.Game) }, fixed: true, }) - addText({ - width: 600, - height: 60, - x, - y: 80, - text: 'WASD or arrow keys to move', - }) + instructions.forEach((instruction, index) => { + wait(instruction.start, () => { + play(Sound.Shoot, { detune: index * 100 }) + instruction.action() - addText({ - width: 600, - height: 60, - x, - y: 160, - text: 'Left click to shoot', + addText({ + ...getWidthAndHeight(instruction.text), + x, + y: margin * (index + 1), + text: instruction.text, + }).fadeIn(1) + }) }) - - addPlayer() }) + +function getWidthAndHeight(text: string) { + return { + width: 25 * text.length, + height: 60, + } +}