enemies can be killed and they give money upon death. towers shoot properly
This commit is contained in:
parent
95332a6dcc
commit
8ebb75fd1a
@ -6,7 +6,7 @@
|
|||||||
"description": "The building block of society, nothing more basic exists.",
|
"description": "The building block of society, nothing more basic exists.",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 2,
|
"damage": 2,
|
||||||
"cooldown": 120,
|
"cooldown": 60,
|
||||||
"gemSlotsAmount": 2,
|
"gemSlotsAmount": 2,
|
||||||
"cost": 100,
|
"cost": 100,
|
||||||
"range": 3
|
"range": 3
|
||||||
|
@ -23,5 +23,13 @@ export default abstract class GameObject {
|
|||||||
return this._events;
|
return this._events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public copyContainerToBB() {
|
||||||
|
this.bb.x = this.container.x;
|
||||||
|
this.bb.y = this.container.y;
|
||||||
|
this.bb.width = this.container.width;
|
||||||
|
this.bb.height = this.container.height;
|
||||||
|
return this.bb;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract update(elapsedMS): void;
|
public abstract update(elapsedMS): void;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ export enum CreepEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class Creep extends GameObject {
|
export default class Creep extends GameObject {
|
||||||
|
public id: number;
|
||||||
public creepType: CreepType;
|
public creepType: CreepType;
|
||||||
private sprite: PIXI.Sprite;
|
private sprite: PIXI.Sprite;
|
||||||
private path: PathDefinition;
|
private path: PathDefinition;
|
||||||
@ -25,14 +26,15 @@ export default class Creep extends GameObject {
|
|||||||
public died: boolean = false;
|
public died: boolean = false;
|
||||||
public x: number;
|
public x: number;
|
||||||
public y: number;
|
public y: number;
|
||||||
constructor(creepType: CreepType, path: PathDefinition) {
|
public dead: boolean = false;
|
||||||
|
constructor(creepType: CreepType, path: PathDefinition, id) {
|
||||||
super();
|
super();
|
||||||
this.creepType = creepType;
|
this.creepType = creepType;
|
||||||
this.stats = structuredClone(Assets.CreepStats[this.creepType]);
|
this.stats = structuredClone(Assets.CreepStats[this.creepType]);
|
||||||
this.sprite = new PIXI.Sprite({
|
this.sprite = new PIXI.Sprite({
|
||||||
texture: GameAssets.BasicCreepTexture,
|
texture: GameAssets.BasicCreepTexture,
|
||||||
});
|
});
|
||||||
this.container.label = 'creep-' + creepType.toString();
|
this.id = id;
|
||||||
// because wave manager spawns all instantly and i dont want
|
// because wave manager spawns all instantly and i dont want
|
||||||
// it to look like a shit game (they all spawn in top left corner)
|
// it to look like a shit game (they all spawn in top left corner)
|
||||||
// i want to hide minion - mario
|
// i want to hide minion - mario
|
||||||
@ -46,10 +48,21 @@ export default class Creep extends GameObject {
|
|||||||
this.path = path;
|
this.path = path;
|
||||||
this.x = path[0][1] * 64 + 32; // centered
|
this.x = path[0][1] * 64 + 32; // centered
|
||||||
this.y = path[0][0] * 64 + 32;
|
this.y = path[0][0] * 64 + 32;
|
||||||
|
Globals.GameScene.events.on(CreepEvents.TakenDamage, (creepID, damage) => {
|
||||||
|
if (creepID != this.id) return;
|
||||||
|
this.health -= damage;
|
||||||
|
});
|
||||||
Globals.Grid.container.addChild(this.container);
|
Globals.Grid.container.addChild(this.container);
|
||||||
this.container.addChild(this.sprite);
|
this.container.addChild(this.sprite);
|
||||||
}
|
}
|
||||||
public update(elapsedMS: number) {
|
public update(elapsedMS: number) {
|
||||||
|
if (this.dead) return;
|
||||||
|
if (this.health <= 0) {
|
||||||
|
Globals.GameScene.events.emit(CreepEvents.Died, this.maxHealth, this);
|
||||||
|
this.destroy();
|
||||||
|
this.dead = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.pathIndex + 1 == this.path.length) {
|
if (this.pathIndex + 1 == this.path.length) {
|
||||||
if (this.escaped) return;
|
if (this.escaped) return;
|
||||||
this.events.emit(CreepEvents.Escaped, this);
|
this.events.emit(CreepEvents.Escaped, this);
|
||||||
|
@ -141,7 +141,10 @@ export class Grid extends GameObject {
|
|||||||
}
|
}
|
||||||
public update(elapsedMS) {
|
public update(elapsedMS) {
|
||||||
this.creeps.forEach((creep) => {
|
this.creeps.forEach((creep) => {
|
||||||
creep.update(elapsedMS);
|
if (creep.dead) {
|
||||||
|
this.creeps.splice(this.creeps.indexOf(creep), 1);
|
||||||
|
creep = null;
|
||||||
|
} else creep.update(elapsedMS);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public getCellByRowAndCol(row, column) {
|
public getCellByRowAndCol(row, column) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import GameObject from '../GameObject';
|
import GameObject from '../GameObject';
|
||||||
import { Globals } from '../Bastion';
|
import { Globals } from '../Bastion';
|
||||||
|
import Creep, { CreepEvents } from './Creep';
|
||||||
|
|
||||||
export function calculateAngleToPoint(x, y, targetX, targetY) {
|
export function calculateAngleToPoint(x, y, targetX, targetY) {
|
||||||
const dx = targetX - x;
|
const dx = targetX - x;
|
||||||
@ -9,15 +10,20 @@ export function calculateAngleToPoint(x, y, targetX, targetY) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class Projectile extends GameObject {
|
export default class Projectile extends GameObject {
|
||||||
|
public deleteMe: boolean = false;
|
||||||
public sprite: PIXI.Sprite;
|
public sprite: PIXI.Sprite;
|
||||||
public x: number;
|
public x: number;
|
||||||
public y: number;
|
public y: number;
|
||||||
public angle: number;
|
public angle: number;
|
||||||
public speed: number;
|
public speed: number;
|
||||||
constructor(x, y, spriteTexture, angle) {
|
public damage: number;
|
||||||
|
public timeToLive: number = 1;
|
||||||
|
constructor(x, y, spriteTexture, angle, damage) {
|
||||||
super();
|
super();
|
||||||
|
console.log('I SHOOTTED!');
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
this.damage = damage;
|
||||||
|
|
||||||
this.sprite = new PIXI.Sprite({ texture: spriteTexture, scale: 0.5, rotation: angle });
|
this.sprite = new PIXI.Sprite({ texture: spriteTexture, scale: 0.5, rotation: angle });
|
||||||
this.sprite.anchor.set(0.5);
|
this.sprite.anchor.set(0.5);
|
||||||
@ -27,12 +33,24 @@ export default class Projectile extends GameObject {
|
|||||||
Globals.app.stage.addChild(this.container);
|
Globals.app.stage.addChild(this.container);
|
||||||
|
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
|
|
||||||
this.speed = 0.9;
|
this.speed = 0.9;
|
||||||
}
|
}
|
||||||
|
public destroy(): void {
|
||||||
|
super.destroy();
|
||||||
|
this.deleteMe = true;
|
||||||
|
}
|
||||||
|
|
||||||
public update(elapsedMS) {
|
public update(elapsedMS) {
|
||||||
if (this.x > 2000 || this.x < 0 || this.y > 2000 || this.y < 0) return this.destroy();
|
if (this.deleteMe) return;
|
||||||
|
if (this.x > 2000 || this.x < 0 || this.y > 2000 || this.y < 0 || this.timeToLive <= 0) return this.destroy();
|
||||||
|
Globals.Grid.creeps.forEach((creep) => {
|
||||||
|
if (this.timeToLive <= 0) return;
|
||||||
|
if (creep.container && this.checkCollision(creep)) {
|
||||||
|
this.timeToLive--;
|
||||||
|
this.onCollide(creep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
this.x += Math.cos(this.angle) * this.speed * elapsedMS;
|
this.x += Math.cos(this.angle) * this.speed * elapsedMS;
|
||||||
this.y += Math.sin(this.angle) * this.speed * elapsedMS;
|
this.y += Math.sin(this.angle) * this.speed * elapsedMS;
|
||||||
|
|
||||||
@ -40,18 +58,22 @@ export default class Projectile extends GameObject {
|
|||||||
this.container.y = this.y;
|
this.container.y = this.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCollide(otherSprite) {
|
public onCollide(creep) {
|
||||||
console.log(`Collision detected with`, otherSprite);
|
console.log('COLLIDED WITH' + creep);
|
||||||
|
Globals.GameScene.events.emit(CreepEvents.TakenDamage, creep.id, this.damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkCollision(otherSprite) {
|
public checkCollision(creep: Creep) {
|
||||||
const boundsA = this.sprite.getBounds();
|
if (creep == null) return;
|
||||||
const boundsB = otherSprite.getBounds();
|
let mybb = this.copyContainerToBB();
|
||||||
return (
|
let otherbb = creep.copyContainerToBB();
|
||||||
boundsA.x < boundsB.x + boundsB.width &&
|
return mybb.getBounds().intersects(otherbb.getBounds());
|
||||||
boundsA.x + boundsA.width > boundsB.x &&
|
// console.log(boundsA, boundsB);
|
||||||
boundsA.y < boundsB.y + boundsB.height &&
|
// return (
|
||||||
boundsA.y + boundsA.height > boundsB.y
|
// boundsA.x < boundsB.x + boundsB.width &&
|
||||||
);
|
// boundsA.x + boundsA.width > boundsB.x &&
|
||||||
|
// boundsA.y < boundsB.y + boundsB.height &&
|
||||||
|
// boundsA.y + boundsA.height > boundsB.y
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ export class Tower extends GameObject {
|
|||||||
private behaviour: string;
|
private behaviour: string;
|
||||||
private definition: TowerDefinition;
|
private definition: TowerDefinition;
|
||||||
private sprite: PIXI.Sprite;
|
private sprite: PIXI.Sprite;
|
||||||
|
private ticksUntilNextShot: number;
|
||||||
private graphics: PIXI.Graphics = new PIXI.Graphics();
|
private graphics: PIXI.Graphics = new PIXI.Graphics();
|
||||||
constructor(row, column, texture, definition, behaviour) {
|
constructor(row, column, texture, definition, behaviour) {
|
||||||
super();
|
super();
|
||||||
@ -45,6 +46,7 @@ export class Tower extends GameObject {
|
|||||||
this.column = column;
|
this.column = column;
|
||||||
this.behaviour = behaviour;
|
this.behaviour = behaviour;
|
||||||
this.definition = definition;
|
this.definition = definition;
|
||||||
|
this.ticksUntilNextShot = 0;
|
||||||
let parent: Cell = Globals.Grid.getCellByRowAndCol(row, column);
|
let parent: Cell = Globals.Grid.getCellByRowAndCol(row, column);
|
||||||
this.sprite = new PIXI.Sprite({
|
this.sprite = new PIXI.Sprite({
|
||||||
texture: texture,
|
texture: texture,
|
||||||
@ -79,17 +81,26 @@ export class Tower extends GameObject {
|
|||||||
let x = this.column * 64 + 32;
|
let x = this.column * 64 + 32;
|
||||||
let y = this.row * 64 + 32;
|
let y = this.row * 64 + 32;
|
||||||
let angle = calculateAngleToPoint(x, y, creep.x, creep.y);
|
let angle = calculateAngleToPoint(x, y, creep.x, creep.y);
|
||||||
this.projectiles.push(new Projectile(x, y, GameAssets.BasicProjectileTexture, angle));
|
this.projectiles.push(
|
||||||
|
new Projectile(x, y, GameAssets.BasicProjectileTexture, angle, this.definition.stats.damage)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
public update(elapsedMS: any): void {
|
public update(elapsedMS: any): void {
|
||||||
this.projectiles.forEach((proj) => {
|
this.projectiles.forEach((proj) => {
|
||||||
proj.update(elapsedMS);
|
if (proj.deleteMe) {
|
||||||
|
this.projectiles.splice(this.projectiles.indexOf(proj), 1);
|
||||||
|
proj = null;
|
||||||
|
} else proj.update(elapsedMS);
|
||||||
});
|
});
|
||||||
if (this.behaviour == TowerBehaviours.BasicTowerBehaviour) {
|
if (this.behaviour == TowerBehaviours.BasicTowerBehaviour) {
|
||||||
|
if (this.ticksUntilNextShot > 0) this.ticksUntilNextShot--;
|
||||||
let creepsInRange = this.GetCreepsInRange();
|
let creepsInRange = this.GetCreepsInRange();
|
||||||
if (creepsInRange.length > 0) {
|
if (creepsInRange.length > 0) {
|
||||||
let focus = creepsInRange[0];
|
let focus = creepsInRange[0];
|
||||||
this.Shoot(focus);
|
if (this.ticksUntilNextShot == 0) {
|
||||||
|
this.ticksUntilNextShot = this.definition.stats.cooldown;
|
||||||
|
this.Shoot(focus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ export default class WaveManager {
|
|||||||
private started: boolean = false;
|
private started: boolean = false;
|
||||||
public finished: boolean = false;
|
public finished: boolean = false;
|
||||||
public events = new PIXI.EventEmitter();
|
public events = new PIXI.EventEmitter();
|
||||||
|
private internalCreepId: number = 0;
|
||||||
constructor(rounds: MissionRoundDefinition[], paths: PathDefinition[]) {
|
constructor(rounds: MissionRoundDefinition[], paths: PathDefinition[]) {
|
||||||
Globals.WaveManager = this;
|
Globals.WaveManager = this;
|
||||||
this.rounds = rounds;
|
this.rounds = rounds;
|
||||||
@ -37,7 +38,8 @@ export default class WaveManager {
|
|||||||
this.rounds[roundIndex].waves.forEach((wave) => {
|
this.rounds[roundIndex].waves.forEach((wave) => {
|
||||||
tickToSpawnAt += wave.firstCreepSpawnTick;
|
tickToSpawnAt += wave.firstCreepSpawnTick;
|
||||||
wave.creeps.forEach((creep) => {
|
wave.creeps.forEach((creep) => {
|
||||||
const creepObj = new Creep(creep, this.paths[0]);
|
const creepObj = new Creep(creep, this.paths[0], this.internalCreepId);
|
||||||
|
this.internalCreepId++;
|
||||||
const creepInstance = {
|
const creepInstance = {
|
||||||
creep: creepObj,
|
creep: creepObj,
|
||||||
tickToSpawnAt,
|
tickToSpawnAt,
|
||||||
|
@ -58,6 +58,9 @@ export class GameScene extends Scene {
|
|||||||
this.onCreepEscaped(creep);
|
this.onCreepEscaped(creep);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
this.events.on(CreepEvents.Died, (playerAward, creepThatDied) => {
|
||||||
|
this.MissionStats.earnGold(playerAward);
|
||||||
|
});
|
||||||
this.sidebar = new Sidebar(SidebarRect);
|
this.sidebar = new Sidebar(SidebarRect);
|
||||||
this.changeRoundButton = new Button(changeRoundButtonRect, 'Start', ButtonTexture.Button01, true);
|
this.changeRoundButton = new Button(changeRoundButtonRect, 'Start', ButtonTexture.Button01, true);
|
||||||
this.changeRoundButton.container.removeFromParent();
|
this.changeRoundButton.container.removeFromParent();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user