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