more balance
This commit is contained in:
parent
a3e8be3c18
commit
185faa42e2
@ -26,8 +26,7 @@ List of things to implement following the "release" of the minimum viable produc
|
|||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
- [ ] Disable player action during combat phase.
|
|
||||||
- [ ] Add sound effects
|
- [ ] Add sound effects
|
||||||
- [x] Tutorial image/mission
|
- [x] Tutorial image/mission
|
||||||
- [ ] Pause menu
|
- [x] Pause menu
|
||||||
- [x] Score screen when winning/losing map
|
- [x] Score screen when winning/losing map
|
||||||
|
BIN
public/assets/creeps/green_spritesheet.png
Normal file
BIN
public/assets/creeps/green_spritesheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
BIN
public/assets/creeps/orange_spritesheet.png
Normal file
BIN
public/assets/creeps/orange_spritesheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
BIN
public/assets/creeps/phood_spritesheet.png
Normal file
BIN
public/assets/creeps/phood_spritesheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
@ -2,14 +2,15 @@
|
|||||||
{
|
{
|
||||||
"name": "basic",
|
"name": "basic",
|
||||||
"sprite": "wood",
|
"sprite": "wood",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 12,
|
"textureArrayLength": 12,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 5,
|
"health": 2,
|
||||||
"speed": 4,
|
"speed": 3,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
"physical": 0,
|
"physical": 0.05,
|
||||||
"divine": 0,
|
"divine": 0,
|
||||||
"fire": 0,
|
"fire": 0,
|
||||||
"ice": 0,
|
"ice": 0,
|
||||||
@ -20,11 +21,12 @@
|
|||||||
{
|
{
|
||||||
"name": "quick",
|
"name": "quick",
|
||||||
"sprite": "zombie",
|
"sprite": "zombie",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 8,
|
"textureArrayLength": 8,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 2,
|
"health": 1,
|
||||||
"speed": 6,
|
"speed": 5,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
"physical": 0,
|
"physical": 0,
|
||||||
@ -38,10 +40,11 @@
|
|||||||
{
|
{
|
||||||
"name": "tank",
|
"name": "tank",
|
||||||
"sprite": "skeleton",
|
"sprite": "skeleton",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 12,
|
"textureArrayLength": 12,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 12,
|
"health": 5,
|
||||||
"speed": 2,
|
"speed": 2,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
@ -56,29 +59,50 @@
|
|||||||
{
|
{
|
||||||
"name": "cloaker",
|
"name": "cloaker",
|
||||||
"sprite": "hood",
|
"sprite": "hood",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 12,
|
"textureArrayLength": 12,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 12,
|
"health": 7,
|
||||||
"speed": 2,
|
"speed": 3,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
"physical": 0,
|
"physical": 0,
|
||||||
"divine": 0,
|
"divine": 1,
|
||||||
"fire": 0,
|
"fire": 1,
|
||||||
"ice": 0,
|
"ice": 1,
|
||||||
"frostfire": 0
|
"frostfire": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "demon",
|
"name": "demon",
|
||||||
"sprite": "demon",
|
"sprite": "demon",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 8,
|
"textureArrayLength": 8,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 12,
|
"health": 5,
|
||||||
"speed": 2,
|
"speed": 3,
|
||||||
|
"special": null,
|
||||||
|
"resistance": {
|
||||||
|
"physical": 1,
|
||||||
|
"divine": -0.25,
|
||||||
|
"fire": 1,
|
||||||
|
"ice": 1,
|
||||||
|
"frostfire": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "maker",
|
||||||
|
"sprite": "pumpkin",
|
||||||
|
"tint": "0xffffff",
|
||||||
|
"textures": [],
|
||||||
|
"textureArrayLength": 11,
|
||||||
|
"stats": {
|
||||||
|
"health": 5,
|
||||||
|
"speed": 3,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
"physical": 0,
|
"physical": 0,
|
||||||
@ -89,17 +113,57 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "maker",
|
"name": "monster",
|
||||||
"sprite": "pumpkin",
|
"sprite": "green",
|
||||||
|
"tint": "0xffffff",
|
||||||
"textures": [],
|
"textures": [],
|
||||||
"textureArrayLength": 11,
|
"textureArrayLength": 12,
|
||||||
"stats": {
|
"stats": {
|
||||||
"health": 11,
|
"health": 30,
|
||||||
"speed": 2,
|
"speed": 1,
|
||||||
"special": null,
|
"special": null,
|
||||||
"resistance": {
|
"resistance": {
|
||||||
"physical": 0,
|
"physical": 0.05,
|
||||||
|
"divine": 0.05,
|
||||||
|
"fire": -0.25,
|
||||||
|
"ice": 0.05,
|
||||||
|
"frostfire": 0.05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "remaker",
|
||||||
|
"sprite": "orange",
|
||||||
|
"tint": "0xffffff",
|
||||||
|
"textures": [],
|
||||||
|
"textureArrayLength": 12,
|
||||||
|
"stats": {
|
||||||
|
"health": 2,
|
||||||
|
"speed": 3,
|
||||||
|
"special": null,
|
||||||
|
"resistance": {
|
||||||
|
"physical": 0.05,
|
||||||
|
"divine": 0,
|
||||||
|
"fire": 0,
|
||||||
|
"ice": 0,
|
||||||
|
"frostfire": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "elite",
|
||||||
|
"sprite": "phood",
|
||||||
|
"tint": "0xffffff",
|
||||||
|
"textures": [],
|
||||||
|
"textureArrayLength": 12,
|
||||||
|
"stats": {
|
||||||
|
"health": 2,
|
||||||
|
"speed": 3,
|
||||||
|
"special": null,
|
||||||
|
"resistance": {
|
||||||
|
"physical": 0.05,
|
||||||
"divine": 0,
|
"divine": 0,
|
||||||
"fire": 0,
|
"fire": 0,
|
||||||
"ice": 0,
|
"ice": 0,
|
||||||
|
@ -584,7 +584,7 @@
|
|||||||
"attackSpeedUp": 100,
|
"attackSpeedUp": 100,
|
||||||
"rangeUp": 2,
|
"rangeUp": 2,
|
||||||
"timeToLiveUp": 200,
|
"timeToLiveUp": 200,
|
||||||
"pierceUp": 20,
|
"pierceUp": 3,
|
||||||
"gemValueUp": 0
|
"gemValueUp": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -28,12 +28,12 @@
|
|||||||
"projectileTexturesArrayLength": 4,
|
"projectileTexturesArrayLength": 4,
|
||||||
"description": "Shoots 8 projectiles in a circle, they may miss.",
|
"description": "Shoots 8 projectiles in a circle, they may miss.",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 3,
|
"damage": 1,
|
||||||
"cooldown": 3000,
|
"cooldown": 2000,
|
||||||
"gemSlotsAmount": 2,
|
"gemSlotsAmount": 2,
|
||||||
"cost": 50,
|
"cost": 55,
|
||||||
"range": 3,
|
"range": 3,
|
||||||
"timeToLive": 20,
|
"timeToLive": 18,
|
||||||
"pierce": 5
|
"pierce": 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -47,10 +47,10 @@
|
|||||||
"projectileTexturesArrayLength": 4,
|
"projectileTexturesArrayLength": 4,
|
||||||
"description": "Zap zap zap! This towers shots connect to other enemies!",
|
"description": "Zap zap zap! This towers shots connect to other enemies!",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 3,
|
"damage": 2,
|
||||||
"cooldown": 3500,
|
"cooldown": 3500,
|
||||||
"gemSlotsAmount": 2,
|
"gemSlotsAmount": 2,
|
||||||
"cost": 100,
|
"cost": 110,
|
||||||
"range": 3,
|
"range": 3,
|
||||||
"timeToLive": 12,
|
"timeToLive": 12,
|
||||||
"pierce": 1
|
"pierce": 1
|
||||||
@ -66,7 +66,7 @@
|
|||||||
"projectileTexturesArrayLength": 4,
|
"projectileTexturesArrayLength": 4,
|
||||||
"description": "Doesn't shoot, instead buffs other towers with some of its power.",
|
"description": "Doesn't shoot, instead buffs other towers with some of its power.",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 4,
|
"damage": 3,
|
||||||
"cooldown": 1000,
|
"cooldown": 1000,
|
||||||
"gemSlotsAmount": 3,
|
"gemSlotsAmount": 3,
|
||||||
"cost": 200,
|
"cost": 200,
|
||||||
@ -86,12 +86,12 @@
|
|||||||
"description": "Behaves like the Basic Tower, only its shots stop creeps in their tracks!",
|
"description": "Behaves like the Basic Tower, only its shots stop creeps in their tracks!",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 2,
|
"damage": 2,
|
||||||
"cooldown": 2250,
|
"cooldown": 2200,
|
||||||
"gemSlotsAmount": 2,
|
"gemSlotsAmount": 2,
|
||||||
"cost": 75,
|
"cost": 80,
|
||||||
"range": 3.25,
|
"range": 3.25,
|
||||||
"timeToLive": 12,
|
"timeToLive": 12,
|
||||||
"pierce": 1
|
"pierce": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,13 +104,13 @@
|
|||||||
"projectileTexturesArrayLength": 4,
|
"projectileTexturesArrayLength": 4,
|
||||||
"description": "Shoots a quick, high pierce rail projectile at creeps.",
|
"description": "Shoots a quick, high pierce rail projectile at creeps.",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 4,
|
"damage": 5,
|
||||||
"cooldown": 3750,
|
"cooldown": 5020,
|
||||||
"gemSlotsAmount": 3,
|
"gemSlotsAmount": 3,
|
||||||
"cost": 125,
|
"cost": 134,
|
||||||
"range": 2.5,
|
"range": 2.5,
|
||||||
"timeToLive": 12,
|
"timeToLive": 12,
|
||||||
"pierce": 30
|
"pierce": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -62,15 +62,30 @@
|
|||||||
{
|
{
|
||||||
"firstCreepSpawnTick": 500,
|
"firstCreepSpawnTick": 500,
|
||||||
"spawnIntervalTicks": 1000,
|
"spawnIntervalTicks": 1000,
|
||||||
"creeps": [0, 0, 0]
|
"creeps": [0, 0, 0, 0, 0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"firstCreepSpawnTick": 4000,
|
"firstCreepSpawnTick": 4000,
|
||||||
"spawnIntervalTicks": 1000,
|
"spawnIntervalTicks": 1000,
|
||||||
"creeps": [0, 0, 0, 0]
|
"creeps": [0, 0, 0, 0, 0]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"offeredGems": [0, 1]
|
"offeredGems": [0, 1, 0, 1]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"waves": [
|
||||||
|
{
|
||||||
|
"firstCreepSpawnTick": 500,
|
||||||
|
"spawnIntervalTicks": 1000,
|
||||||
|
"creeps": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"firstCreepSpawnTick": 1000,
|
||||||
|
"spawnIntervalTicks": 1000,
|
||||||
|
"creeps": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"offeredGems": [0, 1, 0, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
{
|
{
|
||||||
"firstCreepSpawnTick": 500,
|
"firstCreepSpawnTick": 500,
|
||||||
"spawnIntervalTicks": 500,
|
"spawnIntervalTicks": 500,
|
||||||
"creeps": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 2]
|
"creeps": [0]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"offeredGems": [0, 0, 0, 0]
|
"offeredGems": [0, 0, 0, 0]
|
||||||
|
@ -49,7 +49,7 @@ export default class GameAssets {
|
|||||||
private static text;
|
private static text;
|
||||||
private static counter = 0;
|
private static counter = 0;
|
||||||
private static async Load(src) {
|
private static async Load(src) {
|
||||||
this.text.text = `Loading asset: ${src} (${this.counter}/99)`;
|
this.text.text = `Loading asset: ${src} (${this.counter}/102)`;
|
||||||
this.counter++;
|
this.counter++;
|
||||||
return await PIXI.Assets.load({
|
return await PIXI.Assets.load({
|
||||||
src: src,
|
src: src,
|
||||||
|
@ -32,6 +32,7 @@ export type WaveDefinition = {
|
|||||||
export type CreepDefinition = {
|
export type CreepDefinition = {
|
||||||
name: string;
|
name: string;
|
||||||
sprite: string;
|
sprite: string;
|
||||||
|
tint: PIXI.ColorSource;
|
||||||
textures: PIXI.Texture[];
|
textures: PIXI.Texture[];
|
||||||
textureArrayLength: number;
|
textureArrayLength: number;
|
||||||
stats: CreepStatsDefinition;
|
stats: CreepStatsDefinition;
|
||||||
@ -113,6 +114,9 @@ export enum CreepType {
|
|||||||
Cloaker = 3,
|
Cloaker = 3,
|
||||||
Demon = 4,
|
Demon = 4,
|
||||||
Maker = 5,
|
Maker = 5,
|
||||||
|
Monster = 6,
|
||||||
|
Remaker = 7,
|
||||||
|
Elite = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum GemType {
|
export enum GemType {
|
||||||
|
@ -49,6 +49,7 @@ export default class Creep extends GameObject {
|
|||||||
this.sprite.scale.x *= -1;
|
this.sprite.scale.x *= -1;
|
||||||
this.sprite.anchor.set(0.5, 0.5);
|
this.sprite.anchor.set(0.5, 0.5);
|
||||||
this.sprite.animationSpeed = 0.3;
|
this.sprite.animationSpeed = 0.3;
|
||||||
|
this.sprite.tint = Assets.Creeps[this.creepType].tint;
|
||||||
this.sprite.play();
|
this.sprite.play();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
// Explanation: WaveManager spawns all creeps instantly, and since I don't want
|
// Explanation: WaveManager spawns all creeps instantly, and since I don't want
|
||||||
@ -63,20 +64,20 @@ export default class Creep extends GameObject {
|
|||||||
this.health = this.stats.health;
|
this.health = this.stats.health;
|
||||||
this.maxHealth = this.stats.health;
|
this.maxHealth = this.stats.health;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
// Added + 32 to center them.
|
|
||||||
this.x = path[0][0] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
this.x = path[0][0] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
this.y = path[0][1] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
this.y = path[0][1] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
// TODO: Unsubscribe from events once the scene is destroyed
|
|
||||||
Engine.GameScene.events.on(
|
Engine.GameScene.events.on(
|
||||||
CreepEvents.TakenDamage,
|
CreepEvents.TakenDamage,
|
||||||
(creepID, damage, gemResistanceModifications: CreepResistancesDefinition) => {
|
(creepID, damage, gemResistanceModifications: CreepResistancesDefinition) => {
|
||||||
if (creepID != this.id) return;
|
if (creepID != this.id) return;
|
||||||
if (this.effects.find((e) => e.effectEnum == CreepEffects.DebuffTowerDebuff)) {
|
if (this.effects.find((e) => e.effectEnum == CreepEffects.DebuffTowerDebuff)) {
|
||||||
damage = damage * 1.5;
|
damage = damage * 1.5;
|
||||||
console.log('multiplying damage, ' + damage);
|
|
||||||
}
|
}
|
||||||
// Apply resistances.
|
// Apply resistances.
|
||||||
this.health -= damage + damage * (gemResistanceModifications.physical - this.stats.resistance.physical);
|
this.health -= Math.max(
|
||||||
|
damage + damage * (gemResistanceModifications.physical - this.stats.resistance.physical),
|
||||||
|
0
|
||||||
|
);
|
||||||
if (gemResistanceModifications.fire != 0)
|
if (gemResistanceModifications.fire != 0)
|
||||||
this.health -= Math.max(damage * (gemResistanceModifications.fire - this.stats.resistance.fire), 0);
|
this.health -= Math.max(damage * (gemResistanceModifications.fire - this.stats.resistance.fire), 0);
|
||||||
if (gemResistanceModifications.ice != 0)
|
if (gemResistanceModifications.ice != 0)
|
||||||
@ -98,7 +99,6 @@ export default class Creep extends GameObject {
|
|||||||
CreepEvents.GiveEffect,
|
CreepEvents.GiveEffect,
|
||||||
(creepID: number, effect: CreepEffects, durationInMS: number) => {
|
(creepID: number, effect: CreepEffects, durationInMS: number) => {
|
||||||
if (creepID != this.id) return;
|
if (creepID != this.id) return;
|
||||||
console.log(' I CAUGHT THE EVENT!');
|
|
||||||
if (this.effects.find((e) => e.effectEnum == effect) == undefined)
|
if (this.effects.find((e) => e.effectEnum == effect) == undefined)
|
||||||
this.effects.push(new Effect(effect, durationInMS));
|
this.effects.push(new Effect(effect, durationInMS));
|
||||||
}
|
}
|
||||||
@ -224,13 +224,13 @@ export default class Creep extends GameObject {
|
|||||||
this.container.y = this.y;
|
this.container.y = this.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public takeDamage(amount: number) {
|
// public takeDamage(amount: number) {
|
||||||
this.health -= amount;
|
// this.health -= amount;
|
||||||
if (this.health < 0 && !this.died) {
|
// if (this.health < 0 && !this.died) {
|
||||||
this.died = true;
|
// this.died = true;
|
||||||
this.events.emit(CreepEvents.Died, this);
|
// this.events.emit(CreepEvents.Died, this);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
|
@ -19,16 +19,15 @@ export default class GamePausedDialog extends ModalDialogBase {
|
|||||||
|
|
||||||
protected override createContent(): PIXI.Container {
|
protected override createContent(): PIXI.Container {
|
||||||
const container = new PIXI.Container();
|
const container = new PIXI.Container();
|
||||||
this.btnMainMenu = new Button(new PIXI.Rectangle(0, 0, 300, 60), 'Main Menu', ButtonTexture.Button01);
|
this.btnContinue = new Button(new PIXI.Rectangle(0, 0, 300, 60), 'Continue', ButtonTexture.Button01);
|
||||||
this.btnMainMenu.onClick = this.onMainMenuClick.bind(this);
|
this.btnContinue.onClick = this.onContinueClick.bind(this);
|
||||||
container.addChild(this.btnMainMenu.container);
|
container.addChild(this.btnContinue.container);
|
||||||
this.btnRetry = new Button(new PIXI.Rectangle(0, 70, 300, 60), 'Retry', ButtonTexture.Button01);
|
this.btnRetry = new Button(new PIXI.Rectangle(0, 70, 300, 60), 'Retry', ButtonTexture.Button01);
|
||||||
this.btnRetry.onClick = this.onRetryClick.bind(this);
|
this.btnRetry.onClick = this.onRetryClick.bind(this);
|
||||||
container.addChild(this.btnRetry.container);
|
container.addChild(this.btnRetry.container);
|
||||||
|
this.btnMainMenu = new Button(new PIXI.Rectangle(0, 140, 300, 60), 'Main Menu', ButtonTexture.Button01);
|
||||||
this.btnContinue = new Button(new PIXI.Rectangle(0, 140, 300, 60), 'Continue', ButtonTexture.Button01);
|
this.btnMainMenu.onClick = this.onMainMenuClick.bind(this);
|
||||||
this.btnContinue.onClick = this.onContinueClick.bind(this);
|
container.addChild(this.btnMainMenu.container);
|
||||||
container.addChild(this.btnContinue.container);
|
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,6 @@ export class GameScene extends Scene {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// offerText.x -= offerText.width;
|
|
||||||
Engine.GameMaster.currentScene.stage.addChildAt(offerText, 0);
|
Engine.GameMaster.currentScene.stage.addChildAt(offerText, 0);
|
||||||
gemsToOffer.forEach((gType, index) => {
|
gemsToOffer.forEach((gType, index) => {
|
||||||
let _Gem = new Gem(gType, true);
|
let _Gem = new Gem(gType, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user