diff --git a/docs/todos.md b/docs/todos.md index f1bcd2d..d1af3fb 100644 --- a/docs/todos.md +++ b/docs/todos.md @@ -17,6 +17,7 @@ List of things to implement following the "release" of the minimum viable produc - [x] Tower info on click - [x] Animate projectiles - [x] Better mouseover tracking when placing tower and showing radius +- [ ] Sell tower button ## Gems @@ -25,8 +26,8 @@ List of things to implement following the "release" of the minimum viable produc ## Other -- [ ] Create mission authoring tool +- [ ] Disable player action during combat phase. - [ ] Add sound effects -- [ ] Tutorial image/mission +- [x] Tutorial image/mission - [ ] Pause menu - [x] Score screen when winning/losing map diff --git a/public/Mission011.tmx b/public/Mission011.tmx deleted file mode 100644 index df76b7d..0000000 --- a/public/Mission011.tmx +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, -15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, -15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, -4,4,4,4,4,4,4,4,4,4,4,4,4,5,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, -18,18,18,18,18,18,18,18,18,18,18,18,18,19,15,15,15,15,15,3,4,4,4,4,4,4,4,4,4,4, -32,32,32,32,32,32,32,32,32,32,32,7,18,19,15,15,15,15,15,17,18,18,18,18,18,18,18,18,18,18, -15,15,15,15,15,15,15,15,15,15,15,17,18,19,15,15,15,15,15,17,18,6,32,32,32,32,32,32,32,32, -15,15,15,15,15,15,15,15,15,15,15,17,18,19,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,15,15,15,15,15,15,15,15,15,17,18,19,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,3,4,4,4,4,4,4,4,4,21,18,19,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,17,18,18,18,18,18,18,18,18,18,18,19,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,17,18,6,32,32,32,32,32,32,32,32,33,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,17,18,19,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,18,19,15,15,15,15,15,15,15,15, -15,15,17,18,20,4,4,4,4,4,4,4,4,4,4,4,4,4,4,21,18,19,15,15,15,15,15,15,15,15, -15,15,17,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,19,15,15,15,15,15,15,15,15, -15,15,31,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,33,15,15,15,15,15,15,15,15, -15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 - - - diff --git a/public/assets/json/Gems.json b/public/assets/json/Gems.json index 23ef124..4a96e43 100644 --- a/public/assets/json/Gems.json +++ b/public/assets/json/Gems.json @@ -1,7 +1,7 @@ [ { "name": "Fire Gem", - "description": "Forged from molten lava, the Fire Gem imbues your tower's attacks and adds 50% extra fire damage. It can be merged with any gem and is common. This text shouldn't be long.", + "description": "Forged from molten lava, the Fire Gem imbues your tower's attacks and adds 50% extra fire damage. It can be merged with any gem and is common.", "color": "red", "type": "Fire", "totalLevels": 2, @@ -12,16 +12,16 @@ "genericImprovements": [ { "damageUp": 2, - "attackSpeedUp": 10, - "rangeUp": 0.5, + "attackSpeedUp": 0, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 0 }, { "damageUp": 2, - "attackSpeedUp": 10, - "rangeUp": 0.5, + "attackSpeedUp": 0, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 10 @@ -58,7 +58,7 @@ { "damageUp": 2, "attackSpeedUp": 10, - "rangeUp": 0.5, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 0 @@ -66,7 +66,7 @@ { "damageUp": 2, "attackSpeedUp": 10, - "rangeUp": 0.5, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 10 @@ -103,7 +103,7 @@ { "damageUp": 2, "attackSpeedUp": 10, - "rangeUp": 0.5, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 0 @@ -163,7 +163,7 @@ { "damageUp": 2, "attackSpeedUp": 10, - "rangeUp": 0.5, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 0 @@ -171,7 +171,7 @@ { "damageUp": 2, "attackSpeedUp": 10, - "rangeUp": 0.5, + "rangeUp": 0, "timeToLiveUp": 0, "pierceUp": 1, "gemValueUp": 10 diff --git a/public/assets/json/Towers.json b/public/assets/json/Towers.json index 34a088b..537746d 100644 --- a/public/assets/json/Towers.json +++ b/public/assets/json/Towers.json @@ -12,8 +12,8 @@ "cooldown": 120, "gemSlotsAmount": 2, "cost": 100, - "range": 3, - "timeToLive": 120, + "range": 4, + "timeToLive": 20, "pierce": 1 } }, @@ -30,8 +30,8 @@ "cooldown": 120, "gemSlotsAmount": 3, "cost": 125, - "range": 2, - "timeToLive": 8, + "range": 2.5, + "timeToLive": 12, "pierce": 30 } } diff --git a/public/assets/tutorial/tutorial01.jpg b/public/assets/tutorial/tutorial01.jpg new file mode 100644 index 0000000..e28af8a Binary files /dev/null and b/public/assets/tutorial/tutorial01.jpg differ diff --git a/public/assets/tutorial/tutorial02.jpg b/public/assets/tutorial/tutorial02.jpg new file mode 100644 index 0000000..7647be9 Binary files /dev/null and b/public/assets/tutorial/tutorial02.jpg differ diff --git a/public/assets/tutorial/tutorial03.jpg b/public/assets/tutorial/tutorial03.jpg new file mode 100644 index 0000000..4a3c32d Binary files /dev/null and b/public/assets/tutorial/tutorial03.jpg differ diff --git a/public/assets/tutorial/tutorial04.jpg b/public/assets/tutorial/tutorial04.jpg new file mode 100644 index 0000000..5c34d76 Binary files /dev/null and b/public/assets/tutorial/tutorial04.jpg differ diff --git a/public/assets/tutorial/tutorial05.jpg b/public/assets/tutorial/tutorial05.jpg new file mode 100644 index 0000000..f473c8d Binary files /dev/null and b/public/assets/tutorial/tutorial05.jpg differ diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/classes/Assets.ts b/src/classes/Assets.ts index 33ada65..2eb6350 100644 --- a/src/classes/Assets.ts +++ b/src/classes/Assets.ts @@ -26,6 +26,12 @@ export default class GameAssets { public static BannerGemsmith: PIXI.Texture; public static EndScreenDialog: PIXI.Texture; + public static Tutorial01: PIXI.Texture; + public static Tutorial02: PIXI.Texture; + public static Tutorial03: PIXI.Texture; + public static Tutorial04: PIXI.Texture; + public static Tutorial05: PIXI.Texture; + public static PlayIconTexture: PIXI.Texture; public static PauseIconTexture: PIXI.Texture; public static ExclamationIconTexture: PIXI.Texture; @@ -98,6 +104,13 @@ export default class GameAssets { this.Load('./assets/gui/frame_blue.png').then((texture) => (this.BlueBackground = texture)), this.Load('./assets/gui/banner_01.png').then((texture) => (this.BannerGemsmith = texture)), this.Load('./assets/gui/note.png').then((texture) => (this.EndScreenDialog = texture)), + + this.Load('./assets/tutorial/tutorial01.jpg').then((texture) => (this.Tutorial01 = texture)), + this.Load('./assets/tutorial/tutorial02.jpg').then((texture) => (this.Tutorial02 = texture)), + this.Load('./assets/tutorial/tutorial03.jpg').then((texture) => (this.Tutorial03 = texture)), + this.Load('./assets/tutorial/tutorial04.jpg').then((texture) => (this.Tutorial04 = texture)), + this.Load('./assets/tutorial/tutorial05.jpg').then((texture) => (this.Tutorial05 = texture)), + this.Load('./assets/gui/heart.png').then((texture) => (this.HealthTexture = texture)), this.Load('./assets/gui/money.png').then((texture) => (this.GoldTexture = texture)), this.Load('./assets/gui/wave.png').then((texture) => (this.WaveTexture = texture)), diff --git a/src/classes/game/TowerBehaviours.ts b/src/classes/game/TowerBehaviours.ts index b203ac4..719b8d2 100644 --- a/src/classes/game/TowerBehaviours.ts +++ b/src/classes/game/TowerBehaviours.ts @@ -16,6 +16,7 @@ function projectileCheck(tower: Tower, elapsedMS: number) { proj.collidedCreepIDs.forEach(() => { tower.damageDealt += tower.computedDamageToDeal; }); + proj.collidedCreepIDs = []; tower.projectiles.splice(tower.projectiles.indexOf(proj), 1); proj = null; } else proj.update(elapsedMS); diff --git a/src/classes/gui/Tooltip.ts b/src/classes/gui/Tooltip.ts index 7678ba2..ce49cc4 100644 --- a/src/classes/gui/Tooltip.ts +++ b/src/classes/gui/Tooltip.ts @@ -179,9 +179,14 @@ export default class Tooltip extends GuiObject { this.gemDescriptionText.alpha = 1; this.titleText.text = `Lv. ${gem.level} ` + gem.definition.name; + let costToLevelUp; + if (!gem.isMaxLevel()) + costToLevelUp = `Costs ${gem.definition.genericImprovements[gem.level].gemValueUp} gold to level up.`; + else costToLevelUp = 'Max level.'; this.gemDescriptionText.text = - `Valued at ${gem.definition.initialGemValue + gem.currentGemImprovement().gemValueUp} gold. ` + - gem.definition.description; + `${costToLevelUp} Valued at ${ + gem.definition.initialGemValue + gem.currentGemImprovement().gemValueUp + } gold. ` + gem.definition.description; } public Show(x, y) { this.container.alpha = 1; diff --git a/src/classes/gui/TowerPanel.ts b/src/classes/gui/TowerPanel.ts index 2eefd2b..f104c6d 100644 --- a/src/classes/gui/TowerPanel.ts +++ b/src/classes/gui/TowerPanel.ts @@ -73,7 +73,7 @@ export class VisualGemSlot extends GuiObject { this.container.addChild(this.background); this.container.addChild(this.iconSprite); this.container.addChild(this.frame); - let txt = gem ? gem.id : ''; + let txt = gem ? gem.level : ''; let dbgText = new PIXI.Text({ text: txt, zIndex: 11, @@ -156,6 +156,7 @@ export default class TowerPanel extends GuiObject { zIndex: 5, style: new PIXI.TextStyle({ fill: 0xffffff, + fontSize: 25, stroke: { color: 0x000000, width: 2, diff --git a/src/scenes/HowToPlay.ts b/src/scenes/HowToPlay.ts new file mode 100644 index 0000000..abf83e0 --- /dev/null +++ b/src/scenes/HowToPlay.ts @@ -0,0 +1,67 @@ +import GameAssets from '../classes/Assets'; +import Assets from '../classes/Assets'; +import { Engine } from '../classes/Bastion'; +import Button, { ButtonTexture } from '../classes/gui/Button'; +import { GameScene } from './Game'; +import { MainScene } from './Main'; +import Scene from './Scene'; +import * as PIXI from 'pixi.js'; + +export class HowToPlay extends Scene { + public currentImg = 1; + public sprite; + public init() { + let sprites = [ + null, + GameAssets.Tutorial01, + GameAssets.Tutorial02, + GameAssets.Tutorial03, + GameAssets.Tutorial04, + GameAssets.Tutorial05, + ]; + this.sprite = new PIXI.Sprite({ + texture: GameAssets.Tutorial01, + scale: 0.6, + x: 250, + y: 150, + }); + this.stage.addChild(this.sprite); + let leftButton = new Button( + new PIXI.Rectangle(250, this.sprite.height + 160, 120, 60), + 'Back', + ButtonTexture.Button01 + ); + leftButton.container.alpha = 0; + leftButton.onClick = () => { + if (leftButton.container.alpha == 0 || this.currentImg == 1) return; + this.currentImg--; + if (this.currentImg == 3) this.sprite.scale = 1.1; + else this.sprite.scale = 0.6; + this.sprite.texture = sprites[this.currentImg]; + if (this.currentImg == 1) leftButton.container.alpha = 0; + }; + + let right = new Button( + new PIXI.Rectangle(this.sprite.width + 130, this.sprite.height + 160, 120, 60), + 'Next', + ButtonTexture.Button01 + ); + right.onClick = () => { + if (right.container.alpha == 0) return; + this.currentImg++; + if (this.currentImg == 3) this.sprite.scale = 1.1; + else this.sprite.scale = 0.6; + if (this.currentImg != 1) leftButton.container.alpha = 1; + this.sprite.texture = sprites[this.currentImg]; + if (this.currentImg == 5) right.container.alpha = 0; + }; + const button = new Button( + new PIXI.Rectangle(this.sprite.width - 540, this.sprite.height + 160, 200, 60), + 'Main menu', + ButtonTexture.Button01 + ); + button.onClick = (e) => { + Engine.GameMaster.changeScene(new MainScene()); + }; + } +} diff --git a/src/scenes/Main.ts b/src/scenes/Main.ts index d1d6269..01c8e23 100644 --- a/src/scenes/Main.ts +++ b/src/scenes/Main.ts @@ -1,6 +1,7 @@ import { Engine } from '../classes/Bastion'; import { FadeInOut, Tween } from '../classes/game/AnimationManager'; import Button, { ButtonTexture } from '../classes/gui/Button'; +import { HowToPlay } from './HowToPlay'; import { MissionPickerScene } from './MissionPicker'; import Scene from './Scene'; import * as PIXI from 'pixi.js'; @@ -11,10 +12,11 @@ export class MainScene extends Scene { caption: 'New Game', rect: new PIXI.Rectangle( Engine.app.canvas.width / 2 - 300 / 2, - Engine.app.canvas.height / 5 + 3 * 80, + Engine.app.canvas.height / 5 + 2 * 80, 300, 60 ), + texture: ButtonTexture.Button02, }; @@ -28,9 +30,19 @@ export class MainScene extends Scene { ), texture: ButtonTexture.Button02, }; + const TutorialButton = { + caption: 'How to play', + rect: new PIXI.Rectangle( + Engine.app.canvas.width / 2 - 300 / 2, + Engine.app.canvas.height / 5 + 3 * 80, + 300, + 60 + ), + texture: ButtonTexture.Button02, + }; let text = new PIXI.Text({ x: Engine.app.canvas.width / 2 - 300 / 2, - y: Engine.app.canvas.height / 5 + 1 * 80, + y: Engine.app.canvas.height / 5 + 20, text: 'BASTION', style: { fill: 0xffaa00, @@ -62,5 +74,11 @@ export class MainScene extends Scene { b2.onClick = (e) => { Engine.NotificationManager.Notify('Not finished.', 'info'); }; + let b3 = new Button(TutorialButton.rect, TutorialButton.caption, TutorialButton.texture, true); + b3.onClick = (e) => { + Engine.GameMaster.currentScene.stage.removeChild(text); + Engine.GameMaster.currentScene.stage.removeChild(text2); + Engine.GameMaster.changeScene(new HowToPlay()); + }; } }