add gem slots for testing and user feedback
This commit is contained in:
commit
b3a36b1f35
24
docs/content.md
Normal file
24
docs/content.md
Normal file
@ -0,0 +1,24 @@
|
||||
# How to add new content to the game
|
||||
|
||||
A small guide so other people also understand how to add content.
|
||||
|
||||
## Tower
|
||||
|
||||
1. Update Towers.json by adding to the end of the array.
|
||||
2. Update TowerType in Defintions.ts
|
||||
3. Based of the Tower.sprite value, add projectile folder with appropriate projectiles as .png.
|
||||
4. Based of the Tower.sprite value, add the tower sprite into towers folder as a .png.
|
||||
5. Add appropriate behaviour in Tower.ts (if statement in update).
|
||||
6. Add way to spawn via TowerTab.ts button.
|
||||
|
||||
## Creep
|
||||
|
||||
1. Update Creeps.json by adding to the end of the array.
|
||||
2. Update CreepType in Defintions.ts
|
||||
3. Based of the Creep.name value, add creep's walking animations to the same named subfolder in creeps folder.
|
||||
4. When using creeps in waves, reference them by their index in the CreepType enum.
|
||||
|
||||
## Gem
|
||||
|
||||
1. Update Gems.json by adding to the end of the array.
|
||||
2. Update GemType in Defintions.ts and make sure Gem.type is CaSe sensitively the same.
|
@ -11,16 +11,16 @@ List of things to implement following the "release" of the minimum viable produc
|
||||
|
||||
## Towers
|
||||
|
||||
- [ ] Extend projectile into seperate defintion + json file
|
||||
- [x] Extend projectile into seperate defintion + json file
|
||||
- [ ] Make tower react with slotted gems
|
||||
- [ ] Alter damage based on attunement from slotted gems
|
||||
- [ ] Tower info on click
|
||||
- [x] Tower info on click
|
||||
- [x] Animate projectiles
|
||||
- [x] Better mouseover tracking when placing tower and showing radius
|
||||
|
||||
## Gems
|
||||
|
||||
- [ ] Create Gem definitions
|
||||
- [x] Create Gem definitions
|
||||
- [ ] Make gems affect towers
|
||||
|
||||
## Other
|
||||
|
@ -4,7 +4,7 @@
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev": "vite --host",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
|
BIN
public/assets/gems/Fire/1.png
Normal file
BIN
public/assets/gems/Fire/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
public/assets/gems/Fire/2.png
Normal file
BIN
public/assets/gems/Fire/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
BIN
public/assets/gui/frame_05.png
Executable file
BIN
public/assets/gui/frame_05.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
@ -5,7 +5,7 @@
|
||||
"textureArrayLength": 12,
|
||||
"stats": {
|
||||
"health": 5,
|
||||
"speed": 2.4,
|
||||
"speed": 6,
|
||||
"special": null,
|
||||
"resistance": {
|
||||
"physical": 0,
|
||||
|
43
public/assets/json/Gems.json
Normal file
43
public/assets/json/Gems.json
Normal file
@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"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.",
|
||||
"type": "Fire",
|
||||
"totalLevels": 2,
|
||||
"textures": [],
|
||||
"cantCombineWith": [],
|
||||
"specialCombine": [],
|
||||
"genericImprovements": [
|
||||
{
|
||||
"damageUp": 2,
|
||||
"attackSpeedUp": 100,
|
||||
"rangeUp": 0.5,
|
||||
"timeToLiveUp": 0,
|
||||
"pierceUp": 1
|
||||
},
|
||||
{
|
||||
"damageUp": 2,
|
||||
"attackSpeedUp": 100,
|
||||
"rangeUp": 0.5,
|
||||
"timeToLiveUp": 0,
|
||||
"pierceUp": 1
|
||||
}
|
||||
],
|
||||
"gemResistanceModifications": [
|
||||
{
|
||||
"physical": 0,
|
||||
"divine": 0,
|
||||
"fire": 0.5,
|
||||
"ice": 0,
|
||||
"frostfire": 0
|
||||
},
|
||||
{
|
||||
"physical": 0,
|
||||
"divine": 0,
|
||||
"fire": 0.5,
|
||||
"ice": 0,
|
||||
"frostfire": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -102,7 +102,7 @@
|
||||
"creeps": [0, 0, 0, 0, 0]
|
||||
}
|
||||
],
|
||||
"offeredGems": [0, 1, 2, 3]
|
||||
"offeredGems": [0, 0, 0, 0]
|
||||
},
|
||||
{
|
||||
"waves": [
|
||||
|
@ -36,7 +36,7 @@
|
||||
"scale": 0.5,
|
||||
"selectedLayer": 0,
|
||||
"viewCenter": {
|
||||
"x": 1070,
|
||||
"x": 570,
|
||||
"y": 448
|
||||
}
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import { CreepDefinition, MissionDefinition, TowerDefinition } from './Definitions';
|
||||
import { CreepDefinition, GemDefinition, MissionDefinition, TowerDefinition } from './Definitions';
|
||||
import { Engine } from './Bastion';
|
||||
|
||||
export default class GameAssets {
|
||||
@ -7,6 +7,7 @@ export default class GameAssets {
|
||||
public static Frame02Texture: PIXI.Texture;
|
||||
public static Frame03Texture: PIXI.Texture;
|
||||
public static Frame04Texture: PIXI.Texture;
|
||||
public static Frame05Texture: PIXI.Texture;
|
||||
public static FrameInventory: PIXI.Texture;
|
||||
public static FrameBackground: PIXI.Texture;
|
||||
public static FrameTowerTab: PIXI.Texture;
|
||||
@ -22,18 +23,22 @@ export default class GameAssets {
|
||||
public static WaveTexture: PIXI.Texture;
|
||||
public static SwordsTexture: PIXI.Texture;
|
||||
public static TitleTexture: PIXI.Texture;
|
||||
public static GemFrame: 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 XIconTexture: PIXI.Texture;
|
||||
public static PlusIconTexture: PIXI.Texture;
|
||||
public static GemAmountIcons: PIXI.Texture[] = [];
|
||||
|
||||
public static Missions: MissionDefinition[];
|
||||
public static MissionBackgrounds: PIXI.Texture[] = [];
|
||||
public static Towers: TowerDefinition[];
|
||||
public static Creeps: CreepDefinition[];
|
||||
public static Gems: GemDefinition[];
|
||||
|
||||
private static text;
|
||||
private static async Load(src) {
|
||||
@ -74,55 +79,70 @@ export default class GameAssets {
|
||||
Engine.app.stage.addChild(this.text);
|
||||
|
||||
await Promise.all([
|
||||
this.Load('/aclonica.woff2'),
|
||||
this.Load('/assets/gui/button_01.png').then((texture) => (this.Button01Texture = texture)),
|
||||
this.Load('/assets/gui/button_02.png').then((texture) => (this.Button02Texture = texture)),
|
||||
this.Load('/assets/gui/button_small.png').then((texture) => (this.ButtonSmallTexture = texture)),
|
||||
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)),
|
||||
this.Load('/assets/gui/frame_red.png').then((texture) => (this.RedBackground = texture)),
|
||||
this.Load('/assets/gui/frame_green.png').then((texture) => (this.GreenBackground = texture)),
|
||||
this.Load('/assets/gui/frame_blue.png').then((texture) => (this.BlueBackground = 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)),
|
||||
this.Load('/assets/gui/sword_02.png').then((texture) => (this.SwordsTexture = texture)),
|
||||
this.Load('/assets/gui/title01.png').then((texture) => (this.TitleTexture = 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)),
|
||||
this.Load('/assets/gui/icons/home.png').then((texture) => (this.HomeIconTexture = texture)),
|
||||
this.Load('/assets/gui/icons/hammer.png').then((texture) => (this.HammerIconTexture = texture)),
|
||||
this.Load('./aclonica.woff2'),
|
||||
this.Load('./assets/gui/button_01.png').then((texture) => (this.Button01Texture = texture)),
|
||||
this.Load('./assets/gui/button_02.png').then((texture) => (this.Button02Texture = texture)),
|
||||
this.Load('./assets/gui/button_small.png').then((texture) => (this.ButtonSmallTexture = texture)),
|
||||
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_05.png').then((texture) => (this.Frame05Texture = 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)),
|
||||
this.Load('./assets/gui/frame_red.png').then((texture) => (this.RedBackground = texture)),
|
||||
this.Load('./assets/gui/frame_green.png').then((texture) => (this.GreenBackground = texture)),
|
||||
this.Load('./assets/gui/frame_blue.png').then((texture) => (this.BlueBackground = texture)),
|
||||
this.Load('./assets/gui/gem_frame.png').then((texture) => (this.GemFrame = 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)),
|
||||
this.Load('./assets/gui/sword_02.png').then((texture) => (this.SwordsTexture = texture)),
|
||||
this.Load('./assets/gui/title01.png').then((texture) => (this.TitleTexture = 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)),
|
||||
this.Load('./assets/gui/icons/home.png').then((texture) => (this.HomeIconTexture = texture)),
|
||||
this.Load('./assets/gui/icons/hammer.png').then((texture) => (this.HammerIconTexture = texture)),
|
||||
this.Load('./assets/gui/icons/cross.png').then((texture) => (this.XIconTexture = texture)),
|
||||
this.Load('./assets/gui/icons/plus.png').then((texture) => (this.PlusIconTexture = texture)),
|
||||
this.LoadMissions(),
|
||||
this.LoadTowers(),
|
||||
this.LoadCreeps(),
|
||||
this.LoadGemIcons(),
|
||||
this.LoadGems(),
|
||||
]);
|
||||
t.destroy();
|
||||
this.text.destroy();
|
||||
// Set this.text = true to disallow calling GameAssets.LoadAssets() again
|
||||
this.text = true;
|
||||
}
|
||||
private static async LoadGemIcons() {
|
||||
private static async LoadGems() {
|
||||
const res = await fetch('./assets/json/Gems.json');
|
||||
const gems = await res.json();
|
||||
this.Gems = gems;
|
||||
|
||||
for (let idx = 0; idx < gems.length; idx++) {
|
||||
const gem = this.Gems[idx];
|
||||
for (let i = 1; i <= gem.totalLevels; i++) {
|
||||
const texture = await this.Load(`./assets/gems/${gem.type}/${i}.png`);
|
||||
gem.textures[i - 1] = texture;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < 7; i++) {
|
||||
this.GemAmountIcons[i] = await this.Load(`/assets/gui/gem_amount_${i}.png`);
|
||||
this.GemAmountIcons[i] = await this.Load(`./assets/gui/gem_amount_${i}.png`);
|
||||
}
|
||||
}
|
||||
|
||||
private static async LoadCreeps() {
|
||||
const res = await fetch('/assets/json/Creeps.json');
|
||||
const res = await fetch('./assets/json/Creeps.json');
|
||||
const creeps = await res.json();
|
||||
this.Creeps = creeps;
|
||||
for (let idx = 0; idx < this.Creeps.length; idx++) {
|
||||
const creep = this.Creeps[idx];
|
||||
for (let i = 0; i < creep.textureArrayLength; i++) {
|
||||
const texture = await this.Load(`/assets/creeps/${creep.name}/${i}.png`);
|
||||
const texture = await this.Load(`./assets/creeps/${creep.name}/${i}.png`);
|
||||
creep.textures[i] = texture;
|
||||
}
|
||||
}
|
||||
@ -130,20 +150,20 @@ export default class GameAssets {
|
||||
|
||||
private static async LoadMissions() {
|
||||
// When adding missions, make sure to keep order.
|
||||
GameAssets.Missions = [await this.LoadMission('/assets/missions/mission_01.json')];
|
||||
GameAssets.Missions = [await this.LoadMission('./assets/missions/mission_01.json')];
|
||||
}
|
||||
|
||||
private static async LoadTowers() {
|
||||
const res = await fetch('/assets/json/Towers.json');
|
||||
const res = await fetch('./assets/json/Towers.json');
|
||||
const towers = await res.json();
|
||||
this.Towers = towers;
|
||||
for (let idx = 0; idx < this.Towers.length; idx++) {
|
||||
const tower = this.Towers[idx];
|
||||
for (let i = 0; i < tower.projectileTexturesArrayLength; i++) {
|
||||
const projTexture = await this.Load(`/assets/projectiles/${tower.sprite}/${i}.png`);
|
||||
const projTexture = await this.Load(`./assets/projectiles/${tower.sprite}/${i}.png`);
|
||||
tower.projectileTextures[i] = projTexture;
|
||||
}
|
||||
tower.texture = await this.Load(`/assets/towers/${tower.sprite}.png`);
|
||||
tower.texture = await this.Load(`./assets/towers/${tower.sprite}.png`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@ import TowerManager from './game/TowerManager';
|
||||
import { GameScene } from '../scenes/Game';
|
||||
import { AnimationManager } from './game/AnimationManager';
|
||||
import NotificationManager from './game/NotificationManager';
|
||||
import Gem from './game/Gem';
|
||||
import GameAssets from './Assets';
|
||||
import { GemType } from './Definitions';
|
||||
|
||||
export class Engine {
|
||||
public static app: PIXI.Application;
|
||||
@ -25,6 +28,15 @@ export class Engine {
|
||||
public static GridRows: number = 17;
|
||||
public static MouseX: number = 0;
|
||||
public static MouseY: number = 0;
|
||||
|
||||
public static TestSuite() {
|
||||
Engine.NotificationManager.Notify('Loaded testing suite.', 'danger');
|
||||
Engine.TowerManager.ToggleChoosingTowerLocation('RESET');
|
||||
Engine.TowerManager.PlaceTower(GameAssets.Towers[1], 10, 15, GameAssets.Towers[0].behaviour, true);
|
||||
for (let i = 0; i < 16; i++) {
|
||||
this.GameScene.MissionStats.giveGem(new Gem(GemType.Fire), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class GameMaster {
|
||||
|
@ -70,13 +70,27 @@ export type TowerStatsDefinition = {
|
||||
range: number;
|
||||
};
|
||||
|
||||
export type PathDefinition = [[row: number, column: number]];
|
||||
export type GemDefinition = {
|
||||
name: string;
|
||||
description: string;
|
||||
type: GemType;
|
||||
totalLevels: number;
|
||||
textures: PIXI.Texture[];
|
||||
cantCombineWith: GemType[];
|
||||
specialCombine: GemType[];
|
||||
genericImprovements: GenericGemImprovement[];
|
||||
gemResistanceModifications: CreepResistancesDefinition[];
|
||||
};
|
||||
|
||||
export enum CreepType {
|
||||
Basic = 0,
|
||||
Quick = 1,
|
||||
Tank = 2,
|
||||
}
|
||||
export type GenericGemImprovement = {
|
||||
damageUp: number;
|
||||
attackSpeedUp: number;
|
||||
rangeUp: number;
|
||||
timeToLiveUp: number;
|
||||
pierceUp: number;
|
||||
};
|
||||
|
||||
export type PathDefinition = [[row: number, column: number]];
|
||||
|
||||
export enum TerrainType {
|
||||
Restricted = 0,
|
||||
@ -84,6 +98,13 @@ export enum TerrainType {
|
||||
Path = 9,
|
||||
}
|
||||
|
||||
// Make sure to sync these with the respective JSON files.
|
||||
export enum CreepType {
|
||||
Basic = 0,
|
||||
Quick = 1,
|
||||
Tank = 2,
|
||||
}
|
||||
|
||||
export enum GemType {
|
||||
Fire = 0,
|
||||
Yeti = 1,
|
||||
|
30
src/classes/Events.ts
Normal file
30
src/classes/Events.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export enum WaveManagerEvents {
|
||||
CreepSpawned = 'creepSpawned',
|
||||
Finished = 'finished',
|
||||
NewWave = 'newwave',
|
||||
}
|
||||
|
||||
export enum CreepEvents {
|
||||
Died = 'died',
|
||||
TakenDamage = 'takenDamage',
|
||||
Escaped = 'escaped',
|
||||
Moved = 'moved',
|
||||
}
|
||||
|
||||
export enum GridEvents {
|
||||
CellMouseOver = 'cellmouseover',
|
||||
CellMouseLeave = 'cellmouseleave',
|
||||
}
|
||||
|
||||
export enum TowerEvents {
|
||||
TowerPlacedEvent = 'towerPlacedEvent',
|
||||
TowerSoldEvent = 'towerSoldEvent',
|
||||
}
|
||||
|
||||
export enum StatsEvents {
|
||||
GemGivenEvent = 'gemGivenEvent',
|
||||
}
|
||||
|
||||
export enum GemEvents {
|
||||
TowerPanelSelectGem = 'towerTabSelectGem',
|
||||
}
|
@ -4,13 +4,7 @@ import { Engine } from '../Bastion';
|
||||
import { CreepStatsDefinition, CreepType, PathDefinition } from '../Definitions';
|
||||
import GameObject from '../GameObject';
|
||||
import * as PIXI from 'pixi.js';
|
||||
|
||||
export enum CreepEvents {
|
||||
Died = 'died',
|
||||
TakenDamage = 'takenDamage',
|
||||
Escaped = 'escaped',
|
||||
Moved = 'moved',
|
||||
}
|
||||
import { CreepEvents } from '../Events';
|
||||
|
||||
export default class Creep extends GameObject {
|
||||
public id: number;
|
||||
|
18
src/classes/game/Gem.ts
Normal file
18
src/classes/game/Gem.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import { GemType, GemDefinition } from '../Definitions';
|
||||
import GameAssets from '../Assets';
|
||||
|
||||
let latestGemId = 0;
|
||||
|
||||
export default class Gem {
|
||||
public texture: PIXI.Texture;
|
||||
public level: number = 1;
|
||||
public definition: GemDefinition;
|
||||
public id;
|
||||
constructor(gemType: GemType) {
|
||||
this.definition = GameAssets.Gems[gemType];
|
||||
this.texture = this.definition.textures[0];
|
||||
this.id = latestGemId + 1;
|
||||
latestGemId++;
|
||||
}
|
||||
}
|
@ -3,13 +3,8 @@ import GameObject from '../GameObject';
|
||||
import { GameMapDefinition, TerrainType } from '../Definitions';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import Creep, { CreepEvents } from './Creep';
|
||||
import { TowerEvents } from './Tower';
|
||||
|
||||
export enum GridEvents {
|
||||
CellMouseOver = 'cellmouseover',
|
||||
CellMouseLeave = 'cellmouseleave',
|
||||
}
|
||||
import Creep from './Creep';
|
||||
import { CreepEvents, TowerEvents, GridEvents } from '../Events';
|
||||
|
||||
export class Cell extends GameObject {
|
||||
public type: TerrainType;
|
||||
@ -38,7 +33,6 @@ export class Cell extends GameObject {
|
||||
zIndex: 99,
|
||||
interactive: true,
|
||||
});
|
||||
// ? TODO: make range preview 1 global graphics obj, child. fix
|
||||
|
||||
this.g = new PIXI.Graphics({
|
||||
zIndex: 5,
|
||||
@ -48,13 +42,16 @@ export class Cell extends GameObject {
|
||||
this.container.addChild(this.clickDetector);
|
||||
this.container.addChild(this.g);
|
||||
this.clickDetector.on('pointerup', (e) => {
|
||||
if (!Engine.Grid.gridInteractionEnabled) return;
|
||||
if (Engine.TowerManager.isPlacingTower) Engine.Grid.onGridCellClicked(row, column);
|
||||
else this.OpenSelectedTowerPanel();
|
||||
});
|
||||
this.clickDetector.on('pointerenter', (e) => {
|
||||
if (!Engine.Grid.gridInteractionEnabled) return;
|
||||
Engine.GameScene.events.emit(GridEvents.CellMouseOver, this);
|
||||
});
|
||||
this.clickDetector.on('pointerleave', (e) => {
|
||||
if (!Engine.Grid.gridInteractionEnabled) return;
|
||||
Engine.GameScene.events.emit(GridEvents.CellMouseLeave, this);
|
||||
Engine.Grid.rangePreview.clear();
|
||||
});
|
||||
@ -83,6 +80,8 @@ export class Cell extends GameObject {
|
||||
}
|
||||
public OpenSelectedTowerPanel() {
|
||||
if (this.hasTowerPlaced) {
|
||||
const tower = Engine.TowerManager.GetTowerByRowAndCol(this.row, this.column);
|
||||
Engine.GameScene.towerPanel.Show(tower);
|
||||
}
|
||||
}
|
||||
public checkIfCantPlace() {
|
||||
@ -114,6 +113,7 @@ export class Grid extends GameObject {
|
||||
public rangePreview: PIXI.Graphics;
|
||||
public creeps: Creep[] = [];
|
||||
public gridShown: boolean = false;
|
||||
public gridInteractionEnabled = true;
|
||||
|
||||
constructor(map: GameMapDefinition, missionIndex) {
|
||||
super();
|
||||
|
@ -2,7 +2,8 @@ import Assets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import GameObject from '../GameObject';
|
||||
import * as PIXI from 'pixi.js';
|
||||
import { WaveManagerEvents } from './WaveManager';
|
||||
import { WaveManagerEvents, StatsEvents } from '../Events';
|
||||
import Gem from './Gem';
|
||||
|
||||
export default class MissionStats extends GameObject {
|
||||
private hp: number = 100;
|
||||
@ -10,6 +11,10 @@ export default class MissionStats extends GameObject {
|
||||
private goldText: PIXI.Text;
|
||||
private healthText: PIXI.Text;
|
||||
private waveText: PIXI.Text;
|
||||
private inventory: Gem[] = [];
|
||||
|
||||
// TODO: implement score keeping for leaderboards.
|
||||
private score: number = 0;
|
||||
|
||||
public getHP() {
|
||||
return this.hp;
|
||||
@ -44,6 +49,33 @@ export default class MissionStats extends GameObject {
|
||||
this.goldText.text = this.gold;
|
||||
}
|
||||
|
||||
public giveGem(gem: Gem, noNotify?) {
|
||||
if (this.inventory.length >= 48)
|
||||
return Engine.NotificationManager.Notify(
|
||||
"Can't hold more than 48 Gems. Extra Gem was thrown away.",
|
||||
'danger'
|
||||
);
|
||||
this.inventory.push(gem);
|
||||
if (!noNotify)
|
||||
Engine.NotificationManager.Notify(
|
||||
`Lv. ${gem.level} ${gem.definition.name}` + ' added to your inventory.',
|
||||
'gemaward'
|
||||
);
|
||||
Engine.GameScene.events.emit(StatsEvents.GemGivenEvent, gem);
|
||||
}
|
||||
|
||||
public takeGem(gem) {
|
||||
return this.inventory.splice(this.inventory.indexOf(gem), 1)[0];
|
||||
}
|
||||
|
||||
public getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
public checkIfPlayerHasAnyGems() {
|
||||
return this.inventory.length > 0;
|
||||
}
|
||||
|
||||
constructor(initialHP: number, initialGold: number) {
|
||||
super();
|
||||
this.hp = initialHP;
|
||||
|
@ -3,7 +3,7 @@ import GameObject from '../GameObject';
|
||||
import * as PIXI from 'pixi.js';
|
||||
import { FadeInOut } from './AnimationManager';
|
||||
|
||||
export type NotificationType = 'info' | 'warn' | 'danger' | 'reward';
|
||||
export type NotificationType = 'info' | 'warn' | 'danger' | 'reward' | 'gemaward';
|
||||
|
||||
class Notification {
|
||||
public textObj: PIXI.Text;
|
||||
@ -20,6 +20,8 @@ class Notification {
|
||||
fill = 0xfc0a0a;
|
||||
} else if (type == 'reward') {
|
||||
fill = 0xd65afc;
|
||||
} else if (type == 'gemaward') {
|
||||
fill = 0xffffff;
|
||||
}
|
||||
this.ticksToFadeAway = ticksToFadeAway;
|
||||
this.textObj = new PIXI.Text({
|
||||
@ -53,7 +55,7 @@ export default class NotificationManager extends GameObject {
|
||||
this.bb.x = Engine.app.canvas.width / 2;
|
||||
this.bb.y = 40;
|
||||
this.copyBBToContainer();
|
||||
this.container.zIndex = 100;
|
||||
this.container.zIndex = 200;
|
||||
Engine.app.stage.addChild(this.container);
|
||||
}
|
||||
public Notify(text, type: NotificationType) {
|
||||
@ -72,7 +74,7 @@ export default class NotificationManager extends GameObject {
|
||||
if (this.ticks >= notif.ticksToFadeAway && !notif.animating) {
|
||||
notif.animating = true;
|
||||
Engine.AnimationManager.Animate(
|
||||
new FadeInOut('out', 240, notif.textObj, () => {
|
||||
new FadeInOut('out', 300, notif.textObj, () => {
|
||||
notif.destroy();
|
||||
})
|
||||
);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import GameObject from '../GameObject';
|
||||
import { Engine } from '../Bastion';
|
||||
import Creep, { CreepEvents } from './Creep';
|
||||
import Creep from './Creep';
|
||||
import { CreepEvents } from '../Events';
|
||||
|
||||
export function calculateAngleToPoint(x, y, targetX, targetY) {
|
||||
const dx = targetX - x;
|
||||
|
@ -5,39 +5,21 @@ import { TowerDefinition } from '../Definitions';
|
||||
import { Cell } from './Grid';
|
||||
import { TowerBehaviours } from './TowerManager';
|
||||
import Projectile, { calculateAngleToPoint } from './Projectile';
|
||||
import GameAssets from '../Assets';
|
||||
import Creep from './Creep';
|
||||
import Gem from './Gem';
|
||||
|
||||
function distance(x1, y1, x2, y2) {
|
||||
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
|
||||
}
|
||||
|
||||
export type TowerInstance = {
|
||||
row: number;
|
||||
column: number;
|
||||
sprite: PIXI.Sprite;
|
||||
projectiles: Array<any>;
|
||||
baseDamage: number;
|
||||
damage: number;
|
||||
cooldown: number;
|
||||
ticksToFireAt: number;
|
||||
slottedGems: Array<any>;
|
||||
cost: number;
|
||||
baseRange: number;
|
||||
range: number;
|
||||
};
|
||||
|
||||
export enum TowerEvents {
|
||||
TowerPlacedEvent = 'towerPlacedEvent',
|
||||
TowerSoldEvent = 'towerSoldEvent',
|
||||
}
|
||||
|
||||
export class Tower extends GameObject {
|
||||
public row: number;
|
||||
public column: number;
|
||||
public definition: TowerDefinition;
|
||||
public slottedGems: Array<Gem> = [];
|
||||
public damageDealt: number = 0;
|
||||
private projectiles: Projectile[] = [];
|
||||
private behaviour: string;
|
||||
private definition: TowerDefinition;
|
||||
private sprite: PIXI.Sprite;
|
||||
private ticksUntilNextShot: number;
|
||||
private graphics: PIXI.Graphics = new PIXI.Graphics();
|
||||
@ -51,12 +33,11 @@ export class Tower extends GameObject {
|
||||
this.definition = definition;
|
||||
this.ticksUntilNextShot = 0;
|
||||
this.parent = Engine.Grid.getCellByRowAndCol(row, column);
|
||||
console.log(texture);
|
||||
this.sprite = new PIXI.Sprite({
|
||||
texture: texture,
|
||||
height: Engine.GridCellSize,
|
||||
width: Engine.GridCellSize,
|
||||
zIndex: 10,
|
||||
zIndex: 130,
|
||||
});
|
||||
this.container.addChild(this.sprite);
|
||||
this.parent.container.addChild(this.container);
|
||||
@ -67,12 +48,34 @@ export class Tower extends GameObject {
|
||||
}
|
||||
|
||||
private onParentCellEnter = (e) => {
|
||||
if (!Engine.TowerManager.isPlacingTower) this.parent.showRangePreview(false, this.definition.stats.range);
|
||||
if (!Engine.TowerManager.isPlacingTower && Engine.Grid.gridInteractionEnabled)
|
||||
this.parent.showRangePreview(false, this.definition.stats.range);
|
||||
};
|
||||
|
||||
private onParentCellLeave = (e) => {
|
||||
this.graphics.clear();
|
||||
};
|
||||
public SlotGem(gem: Gem, index: number) {
|
||||
console.log('ATTEMPTING TO SLOT ', gem, index);
|
||||
this.slottedGems[index] = gem;
|
||||
Engine.GameScene.towerPanel.Hide();
|
||||
Engine.GameScene.towerPanel.Show(this);
|
||||
}
|
||||
public UnslotGem(index) {
|
||||
const gem = this.slottedGems.splice(index, 1)[0];
|
||||
Engine.GameScene.MissionStats.giveGem(gem, true);
|
||||
for (let i = index; i < this.slottedGems.length - 1; i++) {
|
||||
if (this.slottedGems[i] == null) {
|
||||
this.slottedGems[i] = this.slottedGems[i + 1];
|
||||
this.slottedGems[i + 1] = null;
|
||||
}
|
||||
}
|
||||
this.slottedGems = this.slottedGems.filter((gem) => gem != null);
|
||||
Engine.NotificationManager.Notify(
|
||||
`Lv. ${gem.level} ${gem.definition.name} unslotted and placed back in your inventory.`,
|
||||
'info'
|
||||
);
|
||||
}
|
||||
|
||||
public GetCreepsInRange() {
|
||||
let creeps = Engine.Grid.creeps;
|
||||
@ -97,6 +100,7 @@ export class Tower extends GameObject {
|
||||
public update(elapsedMS: any): void {
|
||||
this.projectiles.forEach((proj) => {
|
||||
if (proj.deleteMe) {
|
||||
this.damageDealt += this.definition.stats.damage;
|
||||
this.projectiles.splice(this.projectiles.indexOf(proj), 1);
|
||||
proj = null;
|
||||
} else proj.update(elapsedMS);
|
||||
@ -114,7 +118,7 @@ export class Tower extends GameObject {
|
||||
}
|
||||
}
|
||||
|
||||
override destroy(): void {
|
||||
public destroy(): void {
|
||||
super.destroy();
|
||||
this.parent.clickDetector.off('pointerenter', this.onParentCellEnter);
|
||||
this.parent.clickDetector.off('pointerleave', this.onParentCellLeave);
|
||||
|
@ -2,8 +2,9 @@ import * as PIXI from 'pixi.js';
|
||||
import { Engine } from '../Bastion';
|
||||
import { TerrainType, TowerDefinition } from '../Definitions';
|
||||
import GameAssets from '../Assets';
|
||||
import { Tower, TowerEvents } from './Tower';
|
||||
import { Cell, GridEvents } from './Grid';
|
||||
import { Tower } from './Tower';
|
||||
import { Cell } from './Grid';
|
||||
import { GridEvents, TowerEvents } from '../Events';
|
||||
|
||||
export enum TowerBehaviours {
|
||||
BasicTowerBehaviour = 'BasicTowerBehaviour',
|
||||
@ -71,7 +72,7 @@ export default class TowerManager {
|
||||
'TowerManager.selectedTower is null when trying to place tower.',
|
||||
'danger'
|
||||
);
|
||||
throw console.warn('TowerManager.selectedTower is null when trying to place tower.');
|
||||
return console.warn('TowerManager.selectedTower is null when trying to place tower.');
|
||||
}
|
||||
this.PlaceTower(this.selectedTower, row, column, this.selectedTower.behaviour);
|
||||
}
|
||||
@ -87,7 +88,7 @@ export default class TowerManager {
|
||||
return returnTower;
|
||||
}
|
||||
public PlaceTower(definition: TowerDefinition, row, column, behaviour: string, ignoreCost?) {
|
||||
const sprite = this.selectedTower.texture;
|
||||
const sprite = definition.texture;
|
||||
if (!Engine.GameScene.MissionStats.hasEnoughGold(definition.stats.cost) && !ignoreCost)
|
||||
return Engine.NotificationManager.Notify('Not enough gold.', 'warn');
|
||||
if (
|
||||
@ -95,7 +96,7 @@ export default class TowerManager {
|
||||
Engine.Grid.getCellByRowAndCol(row, column).type != TerrainType.Path &&
|
||||
Engine.Grid.getCellByRowAndCol(row, column).type != TerrainType.Restricted
|
||||
) {
|
||||
Engine.GameScene.MissionStats.spendGold(definition.stats.cost);
|
||||
if (!ignoreCost) Engine.GameScene.MissionStats.spendGold(definition.stats.cost);
|
||||
let tower = new Tower(row, column, sprite, definition, behaviour);
|
||||
this.towers.push(tower);
|
||||
this.ToggleChoosingTowerLocation('RESET');
|
||||
|
@ -1,15 +1,9 @@
|
||||
import { CreepType, MissionRoundDefinition, PathDefinition } from '../Definitions';
|
||||
import * as PIXI from 'pixi.js';
|
||||
import Creep, { CreepEvents } from './Creep';
|
||||
import Creep from './Creep';
|
||||
import { Engine } from '../Bastion';
|
||||
import { WaveManagerEvents } from '../Events';
|
||||
import GameObject from '../GameObject';
|
||||
|
||||
export enum WaveManagerEvents {
|
||||
CreepSpawned = 'creepSpawned',
|
||||
Finished = 'finished',
|
||||
NewWave = 'newwave',
|
||||
}
|
||||
|
||||
type CreepInstance = {
|
||||
creep: Creep;
|
||||
tickToSpawnAt: number;
|
||||
|
@ -1,10 +1,19 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import GuiObject from '../GuiObject';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import { StatsEvents } from '../Events';
|
||||
import Gem from '../game/Gem';
|
||||
import { VisualGemSlot } from './TowerPanel';
|
||||
import { Tower } from '../game/Tower';
|
||||
|
||||
export default class GemTab extends GuiObject {
|
||||
private bounds: PIXI.Rectangle;
|
||||
private gemTabSprite: PIXI.NineSliceSprite;
|
||||
private vGems: VisualGemSlot[] = [];
|
||||
public isSelectingGem: boolean = false;
|
||||
public selectingGemSlotIndex: number = -1;
|
||||
public selectingGemTowerObject: Tower = null;
|
||||
|
||||
constructor(bounds: PIXI.Rectangle) {
|
||||
super(false);
|
||||
@ -22,7 +31,79 @@ export default class GemTab extends GuiObject {
|
||||
this.gemTabSprite.y = 0;
|
||||
this.gemTabSprite.width = this.bounds.width;
|
||||
this.gemTabSprite.height = this.bounds.height;
|
||||
|
||||
this.container.addChild(this.gemTabSprite);
|
||||
|
||||
Engine.GameScene.events.on(StatsEvents.GemGivenEvent, () => {
|
||||
this.RebuildInventoryVisual();
|
||||
});
|
||||
}
|
||||
// TODO: add more visual clarity
|
||||
public TowerPanelSelectingGem(gem: Gem, index: number, tower: Tower) {
|
||||
console.log('TOWER PANEL SELECTING GEM ' + index);
|
||||
if (index < 0) console.error('TOWER PANEL SELECTING GEM INDEX IS LESS THAN 0, ', index);
|
||||
// index = Engine.GameScene.towerPanel.vGems.indexOf(gem);
|
||||
if (!this.isSelectingGem) {
|
||||
this.isSelectingGem = true;
|
||||
if (gem == null) {
|
||||
// Want to select gem to slot in, already checked if player has a Gem.
|
||||
Engine.NotificationManager.Notify(
|
||||
'Click on any Gem in your inventory to slot it into this Gem slot.',
|
||||
'info'
|
||||
);
|
||||
this.selectingGemSlotIndex = index;
|
||||
this.selectingGemTowerObject = tower;
|
||||
} else {
|
||||
// Already have a gem selected
|
||||
tower.UnslotGem(index);
|
||||
this.RebuildInventoryVisual();
|
||||
Engine.GameScene.towerPanel.Hide();
|
||||
Engine.GameScene.towerPanel.Show(tower);
|
||||
this.isSelectingGem = false;
|
||||
this.selectingGemSlotIndex = -1;
|
||||
this.selectingGemTowerObject = null;
|
||||
}
|
||||
} else {
|
||||
if (gem == null) {
|
||||
this.isSelectingGem = false;
|
||||
this.selectingGemSlotIndex = -1;
|
||||
this.selectingGemTowerObject = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
public RebuildInventoryVisual() {
|
||||
this.vGems.forEach((vGem) => vGem.destroy());
|
||||
this.vGems = [];
|
||||
Engine.GameScene.MissionStats.getInventory().forEach((gem, index) => {
|
||||
let vGem = new VisualGemSlot(0, this.container, gem);
|
||||
|
||||
let vGemYCoord = 10;
|
||||
let vGemXCoord = (index % 4) * 70 + 10;
|
||||
let vGemYIdx = index;
|
||||
while (true) {
|
||||
if (vGemYIdx <= 3) break;
|
||||
vGemYCoord += 66;
|
||||
vGemYIdx -= 4;
|
||||
}
|
||||
vGem.container.x = vGemXCoord;
|
||||
vGem.container.y = vGemYCoord;
|
||||
vGem.container.onpointermove = () => {
|
||||
if (gem == null) return;
|
||||
Engine.GameScene.tooltip.SetContentGem(gem);
|
||||
Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY);
|
||||
};
|
||||
vGem.container.onpointerleave = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
};
|
||||
vGem.onClick = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
if (this.isSelectingGem) {
|
||||
this.isSelectingGem = false;
|
||||
let takenGem = Engine.GameScene.MissionStats.takeGem(gem);
|
||||
this.selectingGemTowerObject.SlotGem(takenGem, this.selectingGemSlotIndex);
|
||||
this.RebuildInventoryVisual();
|
||||
}
|
||||
};
|
||||
this.vGems.push(vGem);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import GuiObject from '../GuiObject';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
|
||||
// ! TODO NEXT!
|
||||
|
||||
export default class SelectedTowerPanel extends GuiObject {
|
||||
private bounds: PIXI.Rectangle;
|
||||
private towerPanel: PIXI.NineSliceSprite;
|
||||
|
||||
constructor(bounds: PIXI.Rectangle) {
|
||||
super(false);
|
||||
this.bounds = bounds;
|
||||
this.container.x = this.bounds.x;
|
||||
this.container.y = this.bounds.y;
|
||||
this.towerPanel = new PIXI.NineSliceSprite({
|
||||
texture: GameAssets.FrameTowerTab,
|
||||
leftWidth: 1000,
|
||||
topHeight: 1000,
|
||||
rightWidth: 1000,
|
||||
bottomHeight: 1000,
|
||||
});
|
||||
this.towerPanel.x = -300;
|
||||
this.towerPanel.y = -300;
|
||||
this.towerPanel.width = this.bounds.width;
|
||||
this.towerPanel.height = this.bounds.height;
|
||||
|
||||
this.container.addChild(this.towerPanel);
|
||||
Engine.GameMaster.currentScene.stage.addChild(this.container);
|
||||
}
|
||||
}
|
@ -6,9 +6,9 @@ import GemTab from './GemTab';
|
||||
|
||||
export default class Sidebar extends GuiObject {
|
||||
public towerTab: TowerTab;
|
||||
public gemTab: GemTab;
|
||||
private bounds: PIXI.Rectangle;
|
||||
private sidebarSprite: PIXI.NineSliceSprite;
|
||||
private gemTab: GemTab;
|
||||
|
||||
constructor(bounds: PIXI.Rectangle) {
|
||||
super(false);
|
||||
|
@ -2,6 +2,7 @@ import * as PIXI from 'pixi.js';
|
||||
import GuiObject from '../GuiObject';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import Gem from '../game/Gem';
|
||||
|
||||
// ! TODO NEXT!
|
||||
|
||||
@ -14,12 +15,17 @@ export default class Tooltip extends GuiObject {
|
||||
private damageText: PIXI.Text;
|
||||
private gemAmount: PIXI.Text;
|
||||
private gemAmountSprite: PIXI.Sprite;
|
||||
private title: PIXI.Sprite;
|
||||
private costSprite: PIXI.Sprite;
|
||||
private damageSprite: PIXI.Sprite;
|
||||
private gemDescriptionText: PIXI.Text;
|
||||
|
||||
constructor(bounds: PIXI.Rectangle) {
|
||||
super(false);
|
||||
this.bounds = bounds;
|
||||
this.container.x = -500;
|
||||
this.container.y = -500;
|
||||
this.container.zIndex = 150;
|
||||
this.tooltipSprite = new PIXI.NineSliceSprite({
|
||||
texture: GameAssets.Frame04Texture,
|
||||
leftWidth: 200,
|
||||
@ -43,16 +49,16 @@ export default class Tooltip extends GuiObject {
|
||||
}),
|
||||
});
|
||||
this.titleText.anchor.set(0.5, 0);
|
||||
let title = new PIXI.Sprite({
|
||||
this.title = new PIXI.Sprite({
|
||||
x: this.tooltipSprite.width / 2,
|
||||
y: -20,
|
||||
width: 250,
|
||||
height: 40,
|
||||
texture: GameAssets.TitleTexture,
|
||||
});
|
||||
title.anchor.set(0.5, 0);
|
||||
this.title.anchor.set(0.5, 0);
|
||||
|
||||
const costSprite = new PIXI.Sprite({
|
||||
this.costSprite = new PIXI.Sprite({
|
||||
texture: GameAssets.GoldTexture,
|
||||
x: 10,
|
||||
y: 20,
|
||||
@ -88,7 +94,7 @@ export default class Tooltip extends GuiObject {
|
||||
},
|
||||
},
|
||||
});
|
||||
const damageSprite = new PIXI.Sprite({
|
||||
this.damageSprite = new PIXI.Sprite({
|
||||
texture: GameAssets.SwordsTexture,
|
||||
x: 22,
|
||||
y: 70,
|
||||
@ -105,7 +111,7 @@ export default class Tooltip extends GuiObject {
|
||||
});
|
||||
this.gemAmount = new PIXI.Text({
|
||||
x: 54,
|
||||
y: 108,
|
||||
y: 105,
|
||||
zIndex: 5,
|
||||
text: 'Something went wrong if you see this.',
|
||||
style: {
|
||||
@ -117,26 +123,64 @@ export default class Tooltip extends GuiObject {
|
||||
},
|
||||
},
|
||||
});
|
||||
this.gemDescriptionText = new PIXI.Text({
|
||||
x: 10,
|
||||
y: 20,
|
||||
text: '',
|
||||
style: {
|
||||
fontSize: 18,
|
||||
wordWrap: true,
|
||||
wordWrapWidth: this.tooltipSprite.width - 30,
|
||||
fill: 'white',
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'italic',
|
||||
stroke: {
|
||||
color: 0x000000,
|
||||
width: 5,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.container.addChild(this.tooltipSprite);
|
||||
this.container.addChild(title);
|
||||
this.container.addChild(costSprite);
|
||||
this.container.addChild(damageSprite);
|
||||
this.container.addChild(this.title);
|
||||
this.container.addChild(this.costSprite);
|
||||
this.container.addChild(this.damageSprite);
|
||||
this.container.addChild(this.gemAmountSprite);
|
||||
this.container.addChild(this.costText);
|
||||
this.container.addChild(this.titleText);
|
||||
this.container.addChild(this.damageText);
|
||||
this.container.addChild(this.gemAmount);
|
||||
|
||||
Engine.GameMaster.currentScene.stage.addChild(this.container);
|
||||
this.container.addChild(this.gemDescriptionText);
|
||||
Engine.app.stage.addChildAt(this.container, 0);
|
||||
}
|
||||
public SetContent(title, damage: number, cost: number, gemSlotsAmount: number) {
|
||||
public SetContentTower(title, damage: number, cost: number, gemSlotsAmount: number) {
|
||||
this.costSprite.alpha = 1;
|
||||
this.damageSprite.alpha = 1;
|
||||
this.gemAmountSprite.alpha = 1;
|
||||
this.costText.alpha = 1;
|
||||
this.damageText.alpha = 1;
|
||||
this.gemAmount.alpha = 1;
|
||||
this.gemDescriptionText.alpha = 0;
|
||||
|
||||
this.titleText.text = title;
|
||||
this.gemAmount.text = `Has ${gemSlotsAmount} Gem slots.`;
|
||||
this.gemAmountSprite.texture = GameAssets.GemAmountIcons[gemSlotsAmount];
|
||||
this.costText.text = `Costs ${cost} gold.`;
|
||||
this.damageText.text = `Deals ${damage} base damage.`;
|
||||
}
|
||||
public SetContentGem(gem: Gem) {
|
||||
this.costSprite.alpha = 0;
|
||||
this.damageSprite.alpha = 0;
|
||||
this.gemAmountSprite.alpha = 0;
|
||||
this.costText.alpha = 0;
|
||||
this.damageText.alpha = 0;
|
||||
this.gemAmount.alpha = 0;
|
||||
this.gemDescriptionText.alpha = 1;
|
||||
|
||||
this.titleText.text = `Lv. ${gem.level} ` + gem.definition.name;
|
||||
this.gemDescriptionText.text = gem.definition.description;
|
||||
}
|
||||
public Show(x, y) {
|
||||
this.container.alpha = 1;
|
||||
if (x + this.container.width > Engine.app.canvas.width) {
|
||||
|
205
src/classes/gui/TowerPanel.ts
Normal file
205
src/classes/gui/TowerPanel.ts
Normal file
@ -0,0 +1,205 @@
|
||||
import * as PIXI from 'pixi.js';
|
||||
import GuiObject from '../GuiObject';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import GameUIConstants from '../GameUIConstants';
|
||||
import Button, { ButtonTexture } from './Button';
|
||||
import { Tower } from '../game/Tower';
|
||||
import Gem from '../game/Gem';
|
||||
import { GemEvents } from '../Events';
|
||||
|
||||
export class VisualGemSlot extends GuiObject {
|
||||
public iconSprite: PIXI.Sprite;
|
||||
private background: PIXI.Sprite;
|
||||
private frame: PIXI.Sprite;
|
||||
public i: number = 0;
|
||||
constructor(index: number, parent: PIXI.Container, gem: Gem | null) {
|
||||
super(true);
|
||||
let gtexture;
|
||||
this.i = index;
|
||||
this.container.x = 10;
|
||||
this.container.y = index * (Engine.GridCellSize + 6) + 300;
|
||||
this.background = new PIXI.Sprite({
|
||||
texture: GameAssets.Frame01Texture,
|
||||
});
|
||||
if (gem == null) {
|
||||
gtexture = GameAssets.PlusIconTexture;
|
||||
} else {
|
||||
gtexture = gem.texture;
|
||||
}
|
||||
this.iconSprite = new PIXI.Sprite({
|
||||
texture: gtexture,
|
||||
zIndex: 10,
|
||||
});
|
||||
this.background.width = Engine.GridCellSize;
|
||||
this.background.height = Engine.GridCellSize;
|
||||
if (gem == null) {
|
||||
this.iconSprite.x = Engine.GridCellSize / 2;
|
||||
this.iconSprite.y = Engine.GridCellSize / 2;
|
||||
this.iconSprite.width = Engine.GridCellSize / 2;
|
||||
this.iconSprite.height = Engine.GridCellSize / 2;
|
||||
this.iconSprite.anchor.set(0.5, 0.5);
|
||||
} else {
|
||||
this.iconSprite.x = 4;
|
||||
this.iconSprite.y = 4;
|
||||
this.iconSprite.width = Engine.GridCellSize - 8;
|
||||
this.iconSprite.height = Engine.GridCellSize - 8;
|
||||
}
|
||||
this.frame = new PIXI.Sprite({
|
||||
texture: GameAssets.Frame05Texture,
|
||||
width: 64,
|
||||
height: 64,
|
||||
});
|
||||
|
||||
this.container.addChild(this.background);
|
||||
this.container.addChild(this.iconSprite);
|
||||
this.container.addChild(this.frame);
|
||||
if (Engine.latestCommit == 'DEVELOPMENT') {
|
||||
let txt = gem ? gem.id : '';
|
||||
let dbgText = new PIXI.Text({
|
||||
text: txt,
|
||||
zIndex: 11,
|
||||
style: {
|
||||
fill: 'white',
|
||||
stroke: {
|
||||
color: 0x000000,
|
||||
width: 5,
|
||||
},
|
||||
},
|
||||
});
|
||||
this.container.addChild(dbgText);
|
||||
}
|
||||
parent.addChild(this.container);
|
||||
}
|
||||
|
||||
public setTint(color) {
|
||||
this.frame.tint = color;
|
||||
}
|
||||
|
||||
public resetTint() {
|
||||
this.frame.tint = 0xffffff;
|
||||
}
|
||||
}
|
||||
|
||||
export default class TowerPanel extends GuiObject {
|
||||
private bounds: PIXI.Rectangle;
|
||||
private towerPanel: PIXI.NineSliceSprite;
|
||||
private closeBtn: Button;
|
||||
public vGems: VisualGemSlot[] = [];
|
||||
public isShown: boolean = false;
|
||||
public titleText: PIXI.Text;
|
||||
|
||||
constructor(bounds: PIXI.Rectangle) {
|
||||
super(false);
|
||||
this.bounds = bounds;
|
||||
this.towerPanel = new PIXI.NineSliceSprite({
|
||||
texture: GameAssets.Frame03Texture,
|
||||
leftWidth: 100,
|
||||
topHeight: 100,
|
||||
rightWidth: 100,
|
||||
bottomHeight: 100,
|
||||
});
|
||||
this.towerPanel.width = this.bounds.width;
|
||||
this.towerPanel.height = this.bounds.height - this.bounds.height / 3.5;
|
||||
this.closeBtn = new Button(new PIXI.Rectangle(-20, -20, 60, 60), '', ButtonTexture.Button01, true);
|
||||
this.closeBtn.container.removeFromParent();
|
||||
// Added custom button logic to still keep all the regular events for the button, just have an icon instead of text.
|
||||
// TODO: maybe make this better? add like a seperate class for icon buttons or smth
|
||||
this.closeBtn.CustomButtonLogic = () => {
|
||||
this.closeBtn.buttonIcon = new PIXI.Sprite({
|
||||
texture: GameAssets.XIconTexture,
|
||||
x: this.closeBtn.container.width / 2,
|
||||
y: this.closeBtn.container.height / 2,
|
||||
scale: 0.2,
|
||||
});
|
||||
this.closeBtn.buttonIcon.anchor.set(0.5, 0.5);
|
||||
this.closeBtn.container.addChild(this.closeBtn.buttonIcon);
|
||||
};
|
||||
this.closeBtn.onClick = () => {
|
||||
this.Hide();
|
||||
};
|
||||
this.Hide();
|
||||
this.closeBtn.CustomButtonLogic();
|
||||
this.container.y = Engine.app.canvas.height / 2 - Engine.app.canvas.height / 2.7;
|
||||
this.container.addChild(this.towerPanel);
|
||||
this.container.addChild(this.closeBtn.container);
|
||||
Engine.GameMaster.currentScene.stage.addChild(this.container);
|
||||
|
||||
this.titleText = new PIXI.Text({
|
||||
x: this.bounds.width / 3,
|
||||
y: 50,
|
||||
zIndex: 5,
|
||||
style: new PIXI.TextStyle({
|
||||
fill: 0xffffff,
|
||||
stroke: {
|
||||
color: 0x000000,
|
||||
width: 2,
|
||||
},
|
||||
}),
|
||||
});
|
||||
this.titleText.anchor.set(0.5, 0);
|
||||
this.container.addChild(this.titleText);
|
||||
}
|
||||
private MakeSlots(tower: Tower) {
|
||||
this.vGems.forEach((vGem) => {
|
||||
vGem.destroy();
|
||||
});
|
||||
this.vGems = [];
|
||||
let amount = tower.definition.stats.gemSlotsAmount;
|
||||
// amount = 6;
|
||||
for (let i = 0; i < amount; i++) {
|
||||
console.log('BUILDING TOWER PANEL ' + i);
|
||||
let gem = tower.slottedGems[i];
|
||||
if (!gem) gem = null;
|
||||
const vGem = new VisualGemSlot(i, this.container, gem);
|
||||
vGem.resetTint();
|
||||
this.vGems.push(vGem);
|
||||
vGem.container.onpointermove = () => {
|
||||
if (!gem) return;
|
||||
Engine.GameScene.tooltip.SetContentGem(gem);
|
||||
Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY);
|
||||
};
|
||||
vGem.container.onpointerleave = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
};
|
||||
vGem.onClick = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
console.warn('EMITTING TOWER PANEL SELECT GEM', gem, vGem.i, i, tower);
|
||||
Engine.GameScene.events.emit(GemEvents.TowerPanelSelectGem, gem, vGem.i, tower);
|
||||
if (!gem && Engine.GameScene.sidebar.gemTab.isSelectingGem) vGem.setTint(0x00ffff);
|
||||
else vGem.resetTint();
|
||||
};
|
||||
}
|
||||
}
|
||||
public Show(tower: Tower) {
|
||||
let mouseX = Engine.MouseX;
|
||||
this.isShown = true;
|
||||
this.SetContent(tower);
|
||||
this.MakeSlots(tower);
|
||||
if (tower.container.x < 900) {
|
||||
this.ShowRight();
|
||||
} else {
|
||||
this.ShowLeft();
|
||||
}
|
||||
}
|
||||
private SetContent(tower: Tower) {
|
||||
this.titleText.text = tower.definition.name;
|
||||
}
|
||||
private ShowLeft() {
|
||||
this.towerPanel.x = -100;
|
||||
this.container.x = 0;
|
||||
this.container.alpha = 1;
|
||||
this.closeBtn.container.x = this.bounds.width - 150;
|
||||
}
|
||||
private ShowRight() {
|
||||
this.towerPanel.x = -10;
|
||||
this.container.x = GameUIConstants.SidebarRect.x - 210;
|
||||
this.closeBtn.container.x = -20;
|
||||
this.container.alpha = 1;
|
||||
}
|
||||
public Hide() {
|
||||
this.isShown = false;
|
||||
this.container.alpha = 0;
|
||||
this.container.x = GameUIConstants.SidebarRect.x + 10;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import * as PIXI from 'pixi.js';
|
||||
import GuiObject from '../GuiObject';
|
||||
import GameAssets from '../Assets';
|
||||
import { Engine } from '../Bastion';
|
||||
import { TowerEvents } from '../game/Tower';
|
||||
import { TowerEvents } from '../Events';
|
||||
import { TowerDefinition } from '../Definitions';
|
||||
|
||||
class TowerButton extends GuiObject {
|
||||
@ -47,7 +47,8 @@ class TowerButton extends GuiObject {
|
||||
Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (name) => {
|
||||
this.resetTint();
|
||||
});
|
||||
this.container.onmousemove = (e) => {
|
||||
this.container.onpointermove = (e) => {
|
||||
if (Engine.Grid.gridInteractionEnabled == false) return;
|
||||
if (Engine.TowerManager.isPlacingTower) return;
|
||||
this.ShowTooltip();
|
||||
};
|
||||
@ -63,7 +64,7 @@ class TowerButton extends GuiObject {
|
||||
definition = item;
|
||||
}
|
||||
});
|
||||
Engine.GameScene.tooltip.SetContent(
|
||||
Engine.GameScene.tooltip.SetContentTower(
|
||||
this.towerName,
|
||||
definition.stats.damage,
|
||||
definition.stats.cost,
|
||||
@ -72,10 +73,12 @@ class TowerButton extends GuiObject {
|
||||
Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY);
|
||||
}
|
||||
public onClick(e: PIXI.FederatedPointerEvent): void {
|
||||
if (Engine.Grid.gridInteractionEnabled == false) return;
|
||||
if (Engine.TowerManager.isPlacingTower && Engine.TowerManager.selectedTower.name != this.towerName) {
|
||||
Engine.GameScene.sidebar.towerTab.resetTint();
|
||||
Engine.TowerManager.ResetChooseTower();
|
||||
}
|
||||
Engine.GameScene.towerPanel.Hide();
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
if (this.frameSprite.tint == 0x00ff00) {
|
||||
this.frameSprite.tint = 0xffffff;
|
||||
|
@ -67,4 +67,5 @@ import GameUIConstants from './classes/GameUIConstants';
|
||||
window.onbeforeunload = () => {
|
||||
return 'You are about to leave.';
|
||||
};
|
||||
else Engine.TestSuite();
|
||||
})();
|
||||
|
@ -1,9 +1,10 @@
|
||||
import GameAssets from '../classes/Assets';
|
||||
import { Engine } from '../classes/Bastion';
|
||||
import { MissionDefinition } from '../classes/Definitions';
|
||||
import Creep, { CreepEvents } from '../classes/game/Creep';
|
||||
import Creep from '../classes/game/Creep';
|
||||
import { Grid } from '../classes/game/Grid';
|
||||
import WaveManager, { WaveManagerEvents } from '../classes/game/WaveManager';
|
||||
import WaveManager from '../classes/game/WaveManager';
|
||||
import { WaveManagerEvents, CreepEvents, GemEvents } from '../classes/Events';
|
||||
import Sidebar from '../classes/gui/Sidebar';
|
||||
import Button, { ButtonTexture } from '../classes/gui/Button';
|
||||
import Scene from './Scene';
|
||||
@ -13,10 +14,13 @@ import TowerManager from '../classes/game/TowerManager';
|
||||
import { MissionPickerScene } from './MissionPicker';
|
||||
import GameUIConstants from '../classes/GameUIConstants';
|
||||
import Tooltip from '../classes/gui/Tooltip';
|
||||
import TowerPanel, { VisualGemSlot } from '../classes/gui/TowerPanel';
|
||||
import Gem from '../classes/game/Gem';
|
||||
|
||||
enum RoundMode {
|
||||
Purchase = 0,
|
||||
Combat = 1,
|
||||
OfferingGems = 2,
|
||||
}
|
||||
|
||||
export class GameScene extends Scene {
|
||||
@ -29,10 +33,18 @@ export class GameScene extends Scene {
|
||||
public changeRoundButton: Button;
|
||||
public sidebar: Sidebar;
|
||||
public tooltip: Tooltip;
|
||||
public towerPanel: TowerPanel;
|
||||
private visualGems: VisualGemSlot[] = [];
|
||||
private currentRound: number = 0;
|
||||
private isWaveManagerFinished: boolean = false;
|
||||
private playerWon: boolean = false;
|
||||
private destroyTicker: boolean = false;
|
||||
private offerGemsSprite: PIXI.NineSliceSprite;
|
||||
private dimGraphics: PIXI.Graphics = new PIXI.Graphics({
|
||||
x: 0,
|
||||
y: 0,
|
||||
zIndex: 120,
|
||||
});
|
||||
|
||||
constructor(name: string) {
|
||||
super();
|
||||
@ -45,13 +57,6 @@ export class GameScene extends Scene {
|
||||
});
|
||||
}
|
||||
public init() {
|
||||
this.ticker = new PIXI.Ticker();
|
||||
this.ticker.maxFPS = 60;
|
||||
this.ticker.minFPS = 30;
|
||||
this.ticker.add(() => {
|
||||
if (this.update) this.update(this.ticker.elapsedMS);
|
||||
});
|
||||
this.ticker.start();
|
||||
new Grid(this.mission.gameMap, this.missionIndex);
|
||||
new TowerManager();
|
||||
new WaveManager(this.mission.rounds, this.mission.gameMap.paths);
|
||||
@ -72,13 +77,14 @@ export class GameScene extends Scene {
|
||||
this.events.on(CreepEvents.Died, (playerAward, creepThatDied) => {
|
||||
this.MissionStats.earnGold(playerAward);
|
||||
});
|
||||
this.towerPanel = new TowerPanel(GameUIConstants.SidebarRect);
|
||||
this.sidebar = new Sidebar(GameUIConstants.SidebarRect);
|
||||
this.tooltip = new Tooltip(new PIXI.Rectangle(0, 0, 350, 160));
|
||||
this.changeRoundButton = new Button(GameUIConstants.ChangeRoundButtonRect, '', ButtonTexture.Button01, true);
|
||||
this.changeRoundButton.container.removeFromParent();
|
||||
this.sidebar.container.addChild(this.changeRoundButton.container);
|
||||
Engine.GameMaster.currentScene.stage.addChildAt(this.dimGraphics, 0);
|
||||
this.tooltip = new Tooltip(new PIXI.Rectangle(0, 0, 350, 160));
|
||||
// Added custom button logic to still keep all the regular events for the button, just have an icon instead of text.
|
||||
// TODO: maybe make this better? add like a seperate class for icon buttons or smth
|
||||
this.changeRoundButton.CustomButtonLogic = () => {
|
||||
this.changeRoundButton.buttonIcon = new PIXI.Sprite({
|
||||
texture: GameAssets.PlayIconTexture,
|
||||
@ -95,12 +101,34 @@ export class GameScene extends Scene {
|
||||
if (this.roundMode == RoundMode.Combat)
|
||||
return Engine.NotificationManager.Notify('Wave is already in progress.', 'warn');
|
||||
if (this.isGameOver) return Engine.NotificationManager.Notify('No more waves.', 'danger');
|
||||
if (this.roundMode == RoundMode.OfferingGems) return;
|
||||
this.setRoundMode(RoundMode.Combat);
|
||||
this.changeRoundButton.buttonIcon.texture = GameAssets.ExclamationIconTexture;
|
||||
this.events.emit(WaveManagerEvents.NewWave, `${this.currentRound + 1}`);
|
||||
};
|
||||
|
||||
this.MissionStats = new MissionStats(100, 200);
|
||||
this.events.on(GemEvents.TowerPanelSelectGem, (gem, index, tower) => {
|
||||
if (gem == null) {
|
||||
if (!this.MissionStats.checkIfPlayerHasAnyGems())
|
||||
return Engine.NotificationManager.Notify(
|
||||
'You require atleast 1 Gem in your inventory to slot it in a Gem slot.',
|
||||
'warn'
|
||||
);
|
||||
}
|
||||
this.sidebar.gemTab.TowerPanelSelectingGem(gem, index, tower);
|
||||
});
|
||||
this.ticker = new PIXI.Ticker();
|
||||
this.ticker.maxFPS = 60;
|
||||
this.ticker.minFPS = 30;
|
||||
// fix tooltip behaving weirdly for some reason
|
||||
this.tooltip.SetContentTower(0, 0, 0, 0);
|
||||
this.tooltip.Show(Engine.MouseX, Engine.MouseY);
|
||||
this.tooltip.Hide();
|
||||
|
||||
this.ticker.add(() => {
|
||||
if (this.update) this.update(this.ticker.elapsedMS);
|
||||
});
|
||||
this.ticker.start();
|
||||
}
|
||||
public update(elapsedMS) {
|
||||
if (this.isGameOver) {
|
||||
@ -113,6 +141,7 @@ export class GameScene extends Scene {
|
||||
Engine.WaveManager.update(elapsedMS);
|
||||
Engine.Grid.update(elapsedMS);
|
||||
Engine.TowerManager.update(elapsedMS);
|
||||
// Means the round is finished.
|
||||
if (this.isWaveManagerFinished && Engine.Grid.creeps.length == 0) {
|
||||
this.isWaveManagerFinished = false;
|
||||
this.setRoundMode(RoundMode.Purchase);
|
||||
@ -121,14 +150,14 @@ export class GameScene extends Scene {
|
||||
`Round ${this.currentRound + 1}/${this.mission.rounds.length} completed.`,
|
||||
'info'
|
||||
);
|
||||
if (this.currentRound == this.mission.rounds.length) {
|
||||
Engine.NotificationManager.Notify(`Final round.`, 'danger');
|
||||
}
|
||||
if (this.currentRound + 1 == this.mission.rounds.length) {
|
||||
Engine.NotificationManager.Notify(`Mission victory!!`, 'reward');
|
||||
this.changeRoundButton.buttonIcon.texture = GameAssets.HomeIconTexture;
|
||||
this.playerWon = true;
|
||||
} else this.currentRound++;
|
||||
} else {
|
||||
this.OfferPlayerGems();
|
||||
this.currentRound++;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.MissionStats.getHP() <= 0) {
|
||||
@ -139,9 +168,80 @@ export class GameScene extends Scene {
|
||||
this.ShowScoreScreen(false);
|
||||
}
|
||||
}
|
||||
public DarkenScreen() {
|
||||
this.dimGraphics.rect(0, 0, Engine.app.canvas.width, Engine.app.canvas.height);
|
||||
this.dimGraphics.fill({ color: 0x000000, alpha: 0.5 });
|
||||
}
|
||||
public UndarkenScreen() {
|
||||
this.dimGraphics.clear();
|
||||
}
|
||||
private OfferPlayerGems() {
|
||||
Engine.Grid.gridInteractionEnabled = false;
|
||||
Engine.GameScene.sidebar.towerTab.resetTint();
|
||||
Engine.TowerManager.ResetChooseTower();
|
||||
this.setRoundMode(RoundMode.OfferingGems);
|
||||
let gemsToOffer = this.mission.rounds[this.currentRound].offeredGems;
|
||||
this.DarkenScreen();
|
||||
this.offerGemsSprite = new PIXI.NineSliceSprite({
|
||||
width: 380,
|
||||
height: 150,
|
||||
texture: GameAssets.Frame01Texture,
|
||||
leftWidth: 100,
|
||||
topHeight: 100,
|
||||
rightWidth: 100,
|
||||
bottomHeight: 100,
|
||||
zIndex: this.dimGraphics.zIndex + 1,
|
||||
x: Engine.app.canvas.width / 2 - 190,
|
||||
y: Engine.app.canvas.height / 2 - 75,
|
||||
});
|
||||
Engine.GameMaster.currentScene.stage.addChildAt(this.offerGemsSprite, 0);
|
||||
let offerText = new PIXI.Text({
|
||||
x: Engine.app.canvas.width / 4,
|
||||
y: Engine.app.canvas.height / 4,
|
||||
zIndex: this.dimGraphics.zIndex + 1,
|
||||
text: 'Choose a Gem as your reward for beating this round!',
|
||||
style: {
|
||||
fontSize: 40,
|
||||
fill: 'orange',
|
||||
fontWeight: 'bold',
|
||||
stroke: {
|
||||
color: 0x000000,
|
||||
width: 5,
|
||||
},
|
||||
},
|
||||
});
|
||||
// offerText.x -= offerText.width;
|
||||
Engine.GameMaster.currentScene.stage.addChildAt(offerText, 0);
|
||||
gemsToOffer.forEach((gType, index) => {
|
||||
let _Gem = new Gem(gType);
|
||||
let vGem = new VisualGemSlot(0, Engine.app.stage, _Gem);
|
||||
this.visualGems.push(vGem);
|
||||
vGem.container.x = this.offerGemsSprite.x - 15 + 69 * (index + 1);
|
||||
vGem.container.y = this.offerGemsSprite.y + 40;
|
||||
vGem.container.onpointermove = () => {
|
||||
Engine.GameScene.tooltip.SetContentGem(_Gem);
|
||||
Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY);
|
||||
};
|
||||
vGem.container.onpointerleave = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
};
|
||||
vGem.onClick = () => {
|
||||
Engine.GameScene.tooltip.Hide();
|
||||
offerText.destroy();
|
||||
this.PlayerPickedGem(_Gem);
|
||||
};
|
||||
});
|
||||
}
|
||||
private PlayerPickedGem(gem: Gem) {
|
||||
this.offerGemsSprite.destroy();
|
||||
this.UndarkenScreen();
|
||||
this.visualGems.forEach((item) => item.destroy());
|
||||
Engine.Grid.gridInteractionEnabled = true;
|
||||
this.MissionStats.giveGem(gem);
|
||||
}
|
||||
|
||||
private ShowScoreScreen(lost) {
|
||||
// TODO: show to player for real
|
||||
// TODO: show to player for real (see how this.OfferPlayerGems() does it)
|
||||
if (lost) {
|
||||
console.log('LOSE!');
|
||||
} else {
|
||||
@ -174,5 +274,4 @@ export class GameScene extends Scene {
|
||||
Engine.GameMaster.currentScene.stage.removeChildren();
|
||||
Engine.GameMaster.changeScene(new MissionPickerScene());
|
||||
}
|
||||
public onTowerPlaced() {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user