diff --git a/docs/assets.md b/docs/assets.md index 8050bb1..3af6d02 100644 --- a/docs/assets.md +++ b/docs/assets.md @@ -1,4 +1,5 @@ # Assets List of assets used in the project, all purchased. -https://assetstore.unity.com/packages/2d/gui/icons/gui-megapack-101517 +https://assetstore.unity.com/packages/2d/gui/icons/gui-megapack-101517 +https://magory.itch.io/ultimate-gem-collections diff --git a/public/assets/gui/frame_04.png b/public/assets/gui/frame_04.png new file mode 100755 index 0000000..7828160 Binary files /dev/null and b/public/assets/gui/frame_04.png differ diff --git a/public/assets/gui/slot_02.PNG b/public/assets/gui/frame_inv.png similarity index 100% rename from public/assets/gui/slot_02.PNG rename to public/assets/gui/frame_inv.png diff --git a/public/assets/gui/gem_amount.png b/public/assets/gui/gem_amount.png new file mode 100644 index 0000000..ba83d43 Binary files /dev/null and b/public/assets/gui/gem_amount.png differ diff --git a/public/assets/gui/gem_amount_0.png b/public/assets/gui/gem_amount_0.png new file mode 100644 index 0000000..b173ce8 Binary files /dev/null and b/public/assets/gui/gem_amount_0.png differ diff --git a/public/assets/gui/gem_amount_1.png b/public/assets/gui/gem_amount_1.png new file mode 100644 index 0000000..936deb9 Binary files /dev/null and b/public/assets/gui/gem_amount_1.png differ diff --git a/public/assets/gui/gem_amount_2.png b/public/assets/gui/gem_amount_2.png new file mode 100644 index 0000000..a98bb3e Binary files /dev/null and b/public/assets/gui/gem_amount_2.png differ diff --git a/public/assets/gui/gem_amount_3.png b/public/assets/gui/gem_amount_3.png new file mode 100644 index 0000000..d1cbf01 Binary files /dev/null and b/public/assets/gui/gem_amount_3.png differ diff --git a/public/assets/gui/gem_amount_4.png b/public/assets/gui/gem_amount_4.png new file mode 100644 index 0000000..96363d5 Binary files /dev/null and b/public/assets/gui/gem_amount_4.png differ diff --git a/public/assets/gui/gem_amount_5.png b/public/assets/gui/gem_amount_5.png new file mode 100644 index 0000000..a6c3d81 Binary files /dev/null and b/public/assets/gui/gem_amount_5.png differ diff --git a/public/assets/gui/gem_amount_6.png b/public/assets/gui/gem_amount_6.png new file mode 100644 index 0000000..de65e05 Binary files /dev/null and b/public/assets/gui/gem_amount_6.png differ diff --git a/src/classes/Assets.ts b/src/classes/Assets.ts index 9d25712..a31d9c8 100644 --- a/src/classes/Assets.ts +++ b/src/classes/Assets.ts @@ -6,6 +6,8 @@ export default class GameAssets { public static Frame01Texture: PIXI.Texture; public static Frame02Texture: PIXI.Texture; public static Frame03Texture: PIXI.Texture; + public static Frame04Texture: PIXI.Texture; + public static FrameInventory: PIXI.Texture; public static FrameBackground: PIXI.Texture; public static FrameTowerTab: PIXI.Texture; public static VioletBackground: PIXI.Texture; @@ -17,12 +19,14 @@ export default class GameAssets { public static HealthTexture: PIXI.Texture; public static GoldTexture: PIXI.Texture; public static WaveTexture: PIXI.Texture; + public static SwordsTexture: PIXI.Texture; public static PlayIconTexture: PIXI.Texture; public static PauseIconTexture: PIXI.Texture; public static ExclamationIconTexture: PIXI.Texture; public static HomeIconTexture: PIXI.Texture; public static HammerIconTexture: PIXI.Texture; + public static GemAmountIcons: PIXI.Texture[] = []; public static Missions: MissionDefinition[]; public static MissionBackgrounds: PIXI.Texture[] = []; @@ -75,6 +79,8 @@ export default class GameAssets { this.Load('/assets/gui/frame_01.png').then((texture) => (this.Frame01Texture = texture)), this.Load('/assets/gui/frame_02.png').then((texture) => (this.Frame02Texture = texture)), this.Load('/assets/gui/frame_03.png').then((texture) => (this.Frame03Texture = texture)), + this.Load('/assets/gui/frame_04.png').then((texture) => (this.Frame04Texture = texture)), + this.Load('/assets/gui/frame_inv.png').then((texture) => (this.FrameInventory = texture)), this.Load('/assets/gui/background_01.png').then((texture) => (this.FrameBackground = texture)), this.Load('/assets/gui/background_02.png').then((texture) => (this.FrameTowerTab = texture)), this.Load('/assets/gui/frame_violet.png').then((texture) => (this.VioletBackground = texture)), @@ -83,6 +89,7 @@ export default class GameAssets { 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)), + this.Load('/assets/gui/sword_02.png').then((texture) => (this.SwordsTexture = texture)), this.Load('/assets/gui/icons/play.png').then((texture) => (this.PlayIconTexture = texture)), this.Load('/assets/gui/icons/pause.png').then((texture) => (this.PauseIconTexture = texture)), this.Load('/assets/gui/icons/exclamation.png').then((texture) => (this.ExclamationIconTexture = texture)), @@ -91,13 +98,18 @@ export default class GameAssets { this.LoadMissions(), this.LoadTowers(), this.LoadCreeps(), + this.LoadGemIcons(), ]); - t.destroy(); this.text.destroy(); // Set this.text = true to disallow calling GameAssets.LoadAssets() again this.text = true; } + private static async LoadGemIcons() { + for (let i = 0; i < 7; i++) { + this.GemAmountIcons[i] = await this.Load(`/assets/gui/gem_amount_${i}.png`); + } + } private static async LoadCreeps() { const res = await fetch('/assets/json/Creeps.json'); diff --git a/src/classes/Bastion.ts b/src/classes/Bastion.ts index bfad197..508e463 100644 --- a/src/classes/Bastion.ts +++ b/src/classes/Bastion.ts @@ -23,6 +23,8 @@ export class Engine { public static GridCellSize: number = 64; public static GridColumns: number = 25; public static GridRows: number = 17; + public static MouseX: number = 0; + public static MouseY: number = 0; } export default class GameMaster { diff --git a/src/classes/game/Grid.ts b/src/classes/game/Grid.ts index 377988e..81a09d9 100644 --- a/src/classes/game/Grid.ts +++ b/src/classes/game/Grid.ts @@ -8,6 +8,7 @@ import { TowerEvents } from './Tower'; export enum GridEvents { CellMouseOver = 'cellmouseover', + CellMouseLeave = 'cellmouseleave', } export class Cell extends GameObject { @@ -47,12 +48,14 @@ export class Cell extends GameObject { this.container.addChild(this.clickDetector); this.container.addChild(this.g); this.clickDetector.on('pointerup', (e) => { - Engine.Grid.onGridCellClicked(row, column); + if (Engine.TowerManager.isPlacingTower) Engine.Grid.onGridCellClicked(row, column); + else this.OpenSelectedTowerPanel(); }); this.clickDetector.on('pointerenter', (e) => { Engine.GameScene.events.emit(GridEvents.CellMouseOver, this); }); this.clickDetector.on('pointerleave', (e) => { + Engine.GameScene.events.emit(GridEvents.CellMouseLeave, this); Engine.Grid.rangePreview.clear(); }); Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (_, row, col) => { @@ -78,6 +81,10 @@ export class Cell extends GameObject { ); Engine.Grid.rangePreview.fill({ color: color, alpha: 0.3 }); } + public OpenSelectedTowerPanel() { + if (this.hasTowerPlaced) { + } + } public checkIfCantPlace() { return ( this.hasTowerPlaced || this.isPath || this.type == TerrainType.Path || this.type == TerrainType.Restricted diff --git a/src/classes/game/TowerManager.ts b/src/classes/game/TowerManager.ts index c5f2d29..7267015 100644 --- a/src/classes/game/TowerManager.ts +++ b/src/classes/game/TowerManager.ts @@ -38,6 +38,9 @@ export default class TowerManager { this.previewSprite.texture = this.selectedTower.texture; } }); + Engine.GameScene.events.on(GridEvents.CellMouseLeave, (cell: Cell) => { + this.previewSprite.texture = null; + }); } public ResetChooseTower() { this.selectedTower = null; diff --git a/src/classes/gui/Tooltip.ts b/src/classes/gui/Tooltip.ts index 28cdb15..29c4c06 100644 --- a/src/classes/gui/Tooltip.ts +++ b/src/classes/gui/Tooltip.ts @@ -1,6 +1,7 @@ import * as PIXI from 'pixi.js'; import GuiObject from '../GuiObject'; import GameAssets from '../Assets'; +import { Engine } from '../Bastion'; // ! TODO NEXT! @@ -8,23 +9,112 @@ export default class Tooltip extends GuiObject { private bounds: PIXI.Rectangle; private tooltipSprite: PIXI.NineSliceSprite; + public titleText: PIXI.Text; + public costText: PIXI.Text; + public previewSprite: PIXI.Sprite; + private gemAmountSprite: PIXI.Sprite; + constructor(bounds: PIXI.Rectangle) { super(false); this.bounds = bounds; - this.container.x = this.bounds.x; - this.container.y = this.bounds.y; + this.container.x = -500; + this.container.y = -500; this.tooltipSprite = new PIXI.NineSliceSprite({ - texture: GameAssets.FrameTowerTab, - leftWidth: 1000, - topHeight: 1000, - rightWidth: 1000, - bottomHeight: 1000, + texture: GameAssets.Frame04Texture, + leftWidth: 200, + topHeight: 200, + rightWidth: 200, + bottomHeight: 200, }); - this.tooltipSprite.x = 0; - this.tooltipSprite.y = 0; this.tooltipSprite.width = this.bounds.width; this.tooltipSprite.height = this.bounds.height; - this.container.addChild(this.tooltipSprite); + + this.titleText = new PIXI.Text({ + x: 87, + y: 34, + text: 'Something went wrong if you see this.', + style: { + fill: 0xffffff, + dropShadow: true, + }, + }); + this.titleText.anchor.set(0, 0.5); + this.container.addChild(this.titleText); + + this.previewSprite = new PIXI.Sprite({ + x: 27, + y: 30, + width: 50, + height: 50, + }); + + this.container.addChild(this.previewSprite); + let frameSprite = new PIXI.NineSliceSprite({ + texture: GameAssets.Frame02Texture, + leftWidth: 150, + topHeight: 150, + rightWidth: 150, + bottomHeight: 150, + roundPixels: true, + height: 64, + width: 64, + x: 20, + y: 20, + }); + this.container.addChild(frameSprite); + + this.costText = new PIXI.Text({ + x: 113, + y: 40, + text: 'Something went wrong if you see this.', + style: { + fill: 'gold', + fontWeight: 'bold', + dropShadow: true, + }, + }); + this.container.addChild(this.costText); + const goldSprite = new PIXI.Sprite({ + texture: GameAssets.GoldTexture, + x: 82, + y: 40, + width: 36, + height: 34, + }); + + this.container.addChild(goldSprite); + + this.gemAmountSprite = new PIXI.Sprite({ + texture: GameAssets.GemAmountIcons[0], + x: 300, + y: 20, + width: 64, + height: 64, + }); + + this.container.addChild(this.gemAmountSprite); + + Engine.GameMaster.currentScene.stage.addChild(this.container); + } + public SetContent(title, spriteTexture, damage: number, cost: number, gemSlotsAmount: number) { + this.titleText.text = title; + this.previewSprite.texture = spriteTexture; + this.gemAmountSprite.texture = GameAssets.GemAmountIcons[gemSlotsAmount]; + this.costText.text = cost; + } + public Show(x, y) { + this.container.alpha = 1; + if (x + this.container.width > Engine.app.canvas.width) { + this.container.x = x - this.container.width; + } else { + this.container.x = x; + } + this.container.y = y; + } + public Hide() { + this.container.alpha = 0; + this.container.x = -500; + this.container.y = -500; } } diff --git a/src/classes/gui/TowerTab.ts b/src/classes/gui/TowerTab.ts index e412796..6df83ca 100644 --- a/src/classes/gui/TowerTab.ts +++ b/src/classes/gui/TowerTab.ts @@ -3,6 +3,7 @@ import GuiObject from '../GuiObject'; import GameAssets from '../Assets'; import { Engine } from '../Bastion'; import { TowerEvents } from '../game/Tower'; +import { TowerDefinition } from '../Definitions'; class TowerButton extends GuiObject { private frameSprite: PIXI.NineSliceSprite; @@ -46,11 +47,27 @@ class TowerButton extends GuiObject { Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (name) => { this.resetTint(); }); - this.container.onpointerenter = (e) => { - // add on mouse over info (banner next to sidebar) + this.container.onmousemove = (e) => { + if (Engine.TowerManager.isPlacingTower) return; + let definition: TowerDefinition; + GameAssets.Towers.forEach((item) => { + if (item.name == towerName) { + definition = item; + } + }); + Engine.GameScene.tooltip.SetContent( + this.towerName, + definition.texture, + definition.stats.damage, + definition.stats.cost, + definition.stats.gemSlotsAmount + ); + Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY); }; - this.container.onpointerleave = (e) => {}; + this.container.onpointerleave = (e) => { + Engine.GameScene.tooltip.Hide(); + }; } public onClick(e: PIXI.FederatedPointerEvent): void { if (Engine.TowerManager.isPlacingTower && Engine.TowerManager.selectedTower.name != this.towerName) { @@ -59,6 +76,7 @@ class TowerButton extends GuiObject { } if (this.frameSprite.tint == 0x00ff00) this.frameSprite.tint = 0xffffff; else this.frameSprite.tint = 0x00ff00; + Engine.GameScene.tooltip.Hide(); Engine.TowerManager.ToggleChoosingTowerLocation(this.towerName); } public resetTint() { @@ -102,7 +120,7 @@ export default class TowerTab extends GuiObject { ); this.towerButtons.push( new TowerButton( - 0, + 3, 1, 70, 70, diff --git a/src/main.ts b/src/main.ts index 3b70666..fac0057 100644 --- a/src/main.ts +++ b/src/main.ts @@ -55,6 +55,10 @@ import GameUIConstants from './classes/GameUIConstants'; Engine.NotificationManager.update(ticker.elapsedMS); Engine.AnimationManager.update(ticker.elapsedMS); }); + app.canvas.addEventListener('pointermove', function (event) { + Engine.MouseX = ((event.clientX - app.canvas.offsetLeft) / app.canvas.offsetWidth) * 1920; + Engine.MouseY = ((event.clientY - app.canvas.offsetTop) / app.canvas.offsetHeight) * 1080; + }); Engine.GameMaster.changeScene(new MainScene()); let params = new URLSearchParams(location.href); if (params.entries().next().value[1] == 'game') Engine.GameMaster.changeScene(new GameScene('Mission 1')); diff --git a/src/scenes/Game.ts b/src/scenes/Game.ts index be16af2..65cdda4 100644 --- a/src/scenes/Game.ts +++ b/src/scenes/Game.ts @@ -12,6 +12,7 @@ import MissionStats from '../classes/game/MissionStats'; import TowerManager from '../classes/game/TowerManager'; import { MissionPickerScene } from './MissionPicker'; import GameUIConstants from '../classes/GameUIConstants'; +import Tooltip from '../classes/gui/Tooltip'; enum RoundMode { Purchase = 0, @@ -27,6 +28,7 @@ export class GameScene extends Scene { public ticker: PIXI.Ticker; public changeRoundButton: Button; public sidebar: Sidebar; + public tooltip: Tooltip; private currentRound: number = 0; private isWaveManagerFinished: boolean = false; private playerWon: boolean = false; @@ -71,6 +73,7 @@ export class GameScene extends Scene { this.MissionStats.earnGold(playerAward); }); this.sidebar = new Sidebar(GameUIConstants.SidebarRect); + this.tooltip = new Tooltip(new PIXI.Rectangle(0, 0, 400, 200)); this.changeRoundButton = new Button(GameUIConstants.ChangeRoundButtonRect, '', ButtonTexture.Button01, true); this.changeRoundButton.container.removeFromParent(); this.sidebar.container.addChild(this.changeRoundButton.container);