added super simple ai
no GOAP yet
This commit is contained in:
parent
d8223358d8
commit
417315cf08
196
src/shattered_sword/AI/EnemyAI.ts
Normal file
196
src/shattered_sword/AI/EnemyAI.ts
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
import GoapActionPlanner from "../../Wolfie2D/AI/GoapActionPlanner";
|
||||||
|
import StateMachineAI from "../../Wolfie2D/AI/StateMachineAI";
|
||||||
|
import StateMachineGoapAI from "../../Wolfie2D/AI/StateMachineGoapAI";
|
||||||
|
import GoapAction from "../../Wolfie2D/DataTypes/Interfaces/GoapAction";
|
||||||
|
import AABB from "../../Wolfie2D/DataTypes/Shapes/AABB";
|
||||||
|
import Stack from "../../Wolfie2D/DataTypes/Stack";
|
||||||
|
import State from "../../Wolfie2D/DataTypes/State/State";
|
||||||
|
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
||||||
|
import GameEvent from "../../Wolfie2D/Events/GameEvent";
|
||||||
|
import GameNode from "../../Wolfie2D/Nodes/GameNode";
|
||||||
|
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
||||||
|
import OrthogonalTilemap from "../../Wolfie2D/Nodes/Tilemaps/OrthogonalTilemap";
|
||||||
|
import NavigationPath from "../../Wolfie2D/Pathfinding/NavigationPath";
|
||||||
|
import Weapon from "../GameSystems/items/Weapon";
|
||||||
|
import BattlerAI from "./BattlerAI";
|
||||||
|
|
||||||
|
import Patrol from "./EnemyStates/Patrol";
|
||||||
|
import { Statuses } from "../sword_enums";
|
||||||
|
|
||||||
|
import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||||
|
|
||||||
|
import MathUtils from "../../Wolfie2D/Utils/MathUtils";
|
||||||
|
export default class EnemyAI extends StateMachineGoapAI implements BattlerAI {
|
||||||
|
/** The owner of this AI */
|
||||||
|
owner: AnimatedSprite;
|
||||||
|
|
||||||
|
/** The total possible amount of health this entity has */
|
||||||
|
maxHealth: number;
|
||||||
|
|
||||||
|
/** The current amount of health this entity has */
|
||||||
|
CURRENT_HP: number;
|
||||||
|
|
||||||
|
/** The default movement speed of this AI */
|
||||||
|
speed: number = 20;
|
||||||
|
|
||||||
|
/** The weapon this AI has */
|
||||||
|
weapon: Weapon;
|
||||||
|
|
||||||
|
/** A reference to the player object */
|
||||||
|
player: GameNode;
|
||||||
|
|
||||||
|
// The current known position of the player
|
||||||
|
playerPos: Vec2;
|
||||||
|
|
||||||
|
// The last known position of the player
|
||||||
|
lastPlayerPos: Vec2;
|
||||||
|
|
||||||
|
// Attack range
|
||||||
|
inRange: number;
|
||||||
|
|
||||||
|
// Path to player
|
||||||
|
//path: NavigationPath;
|
||||||
|
|
||||||
|
// Path away from player
|
||||||
|
retreatPath: NavigationPath;
|
||||||
|
|
||||||
|
tilemap: OrthogonalTilemap;
|
||||||
|
|
||||||
|
velocity: Vec2 = Vec2.ZERO;
|
||||||
|
|
||||||
|
direction: number; //1 for right, -1 for left
|
||||||
|
|
||||||
|
initializeAI(owner: AnimatedSprite, options: Record<string, any>): void {
|
||||||
|
this.owner = owner;
|
||||||
|
|
||||||
|
//add states
|
||||||
|
// Patrol mode
|
||||||
|
this.addState(EnemyStates.DEFAULT, new Patrol(this, owner));
|
||||||
|
|
||||||
|
this.maxHealth = options.health;
|
||||||
|
|
||||||
|
this.CURRENT_HP = options.health;
|
||||||
|
|
||||||
|
this.weapon = options.weapon;
|
||||||
|
|
||||||
|
this.player = options.player;
|
||||||
|
|
||||||
|
this.inRange = options.inRange;
|
||||||
|
|
||||||
|
this.goal = options.goal;
|
||||||
|
|
||||||
|
this.currentStatus = options.status;
|
||||||
|
|
||||||
|
this.possibleActions = options.actions;
|
||||||
|
|
||||||
|
this.plan = new Stack<GoapAction>();
|
||||||
|
|
||||||
|
this.planner = new GoapActionPlanner();
|
||||||
|
|
||||||
|
//TODO - get correct tilemap
|
||||||
|
//this.tilemap = this.owner.getScene().getTilemap(options.tilemap) as OrthogonalTilemap;
|
||||||
|
this.tilemap = <OrthogonalTilemap>this.owner.getScene().getLayer("Wall").getItems()[0];
|
||||||
|
//this.tilemap = <OrthogonalTilemap>this.owner.getScene().getTilemap("Main");
|
||||||
|
|
||||||
|
// Initialize to the default state
|
||||||
|
this.initialize(EnemyStates.DEFAULT);
|
||||||
|
|
||||||
|
//this.getPlayerPosition();
|
||||||
|
|
||||||
|
this.direction = 1; //default moving to the right
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
activate(options: Record<string, any>): void { }
|
||||||
|
|
||||||
|
damage(damage: number): void {
|
||||||
|
this.CURRENT_HP -= damage;
|
||||||
|
|
||||||
|
// If we're low enough, add Low Health status to enemy
|
||||||
|
if (this.CURRENT_HP <= Math.floor(this.maxHealth/2)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If health goes below 0, disable AI and fire enemyDied event
|
||||||
|
if (this.CURRENT_HP <= 0) {
|
||||||
|
this.owner.setAIActive(false, {});
|
||||||
|
this.owner.isCollidable = false;
|
||||||
|
this.owner.visible = false;
|
||||||
|
|
||||||
|
this.emitter.fireEvent("enemyDied", {enemy: this.owner})
|
||||||
|
|
||||||
|
|
||||||
|
if (Math.random() < 0.05) {
|
||||||
|
// give buff maybe
|
||||||
|
//this.emitter.fireEvent("giveBuff", { position: this.owner.position });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO - need to modify for side view
|
||||||
|
/*
|
||||||
|
isPlayerVisible(pos: Vec2): Vec2{
|
||||||
|
//Check if one player is visible, taking into account walls
|
||||||
|
|
||||||
|
// Get the new player location
|
||||||
|
let start = this.owner.position.clone();
|
||||||
|
let delta = pos.clone().sub(start);
|
||||||
|
|
||||||
|
// Iterate through the tilemap region until we find a collision
|
||||||
|
let minX = Math.min(start.x, pos.x);
|
||||||
|
let maxX = Math.max(start.x, pos.x);
|
||||||
|
let minY = Math.min(start.y, pos.y);
|
||||||
|
let maxY = Math.max(start.y, pos.y);
|
||||||
|
|
||||||
|
// Get the wall tilemap
|
||||||
|
let walls = <OrthogonalTilemap>this.owner.getScene().getLayer("Wall").getItems()[0];
|
||||||
|
|
||||||
|
let minIndex = walls.getColRowAt(new Vec2(minX, minY));
|
||||||
|
let maxIndex = walls.getColRowAt(new Vec2(maxX, maxY));
|
||||||
|
|
||||||
|
let tileSize = walls.getTileSize();
|
||||||
|
|
||||||
|
for (let col = minIndex.x; col <= maxIndex.x; col++) {
|
||||||
|
for (let row = minIndex.y; row <= maxIndex.y; row++) {
|
||||||
|
if (walls.isTileCollidable(col, row)) {
|
||||||
|
// Get the position of this tile
|
||||||
|
let tilePos = new Vec2(col * tileSize.x + tileSize.x / 2, row * tileSize.y + tileSize.y / 2);
|
||||||
|
|
||||||
|
// Create a collider for this tile
|
||||||
|
let collider = new AABB(tilePos, tileSize.scaled(1 / 2));
|
||||||
|
|
||||||
|
let hit = collider.intersectSegment(start, delta, Vec2.ZERO);
|
||||||
|
|
||||||
|
if (hit !== null && start.distanceSqTo(hit.pos) < start.distanceSqTo(pos)) {
|
||||||
|
// We hit a wall, we can't see the player
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
update(deltaT: number){
|
||||||
|
super.update(deltaT);
|
||||||
|
|
||||||
|
// This is the plan that is executed in the Active state, so whenever we don't have a plan, acquire a new one given the current statuses the enemy has
|
||||||
|
/*
|
||||||
|
if (this.plan.isEmpty()) {
|
||||||
|
//get a new plan
|
||||||
|
this.plan = this.planner.plan(Statuses.REACHED_GOAL, this.possibleActions, this.currentStatus, null);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EnemyStates {
|
||||||
|
DEFAULT = "default",
|
||||||
|
ALERT = "alert",
|
||||||
|
PREVIOUS = "previous"
|
||||||
|
}
|
23
src/shattered_sword/AI/EnemyStates/EnemyState.ts
Normal file
23
src/shattered_sword/AI/EnemyStates/EnemyState.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import State from "../../../Wolfie2D/DataTypes/State/State";
|
||||||
|
import GameNode from "../../../Wolfie2D/Nodes/GameNode";
|
||||||
|
import EnemyAI from "../EnemyAI";
|
||||||
|
|
||||||
|
export default abstract class EnemyState extends State {
|
||||||
|
protected parent: EnemyAI;
|
||||||
|
protected owner: GameNode;
|
||||||
|
gravity: number = 1500; //TODO - can change later
|
||||||
|
|
||||||
|
constructor(parent: EnemyAI, owner: GameNode){
|
||||||
|
super(parent);
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
update(deltaT: number): void {
|
||||||
|
// Do gravity
|
||||||
|
this.parent.velocity.y += this.gravity*deltaT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
27
src/shattered_sword/AI/EnemyStates/OnGround.ts
Normal file
27
src/shattered_sword/AI/EnemyStates/OnGround.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
||||||
|
import Input from "../../../Wolfie2D/Input/Input";
|
||||||
|
import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||||
|
import MathUtils from "../../../Wolfie2D/Utils/MathUtils";
|
||||||
|
import EnemyState from "./EnemyState";
|
||||||
|
|
||||||
|
export default class OnGround extends EnemyState {
|
||||||
|
onEnter(options: Record<string, any>): void {}
|
||||||
|
|
||||||
|
update(deltaT: number): void {
|
||||||
|
if(this.parent.velocity.y > 0){
|
||||||
|
this.parent.velocity.y = 0;
|
||||||
|
}
|
||||||
|
super.update(deltaT);
|
||||||
|
|
||||||
|
|
||||||
|
this.finished("fall");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInput(event: GameEvent): void { }
|
||||||
|
|
||||||
|
onExit(): Record<string, any> {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
71
src/shattered_sword/AI/EnemyStates/Patrol.ts
Normal file
71
src/shattered_sword/AI/EnemyStates/Patrol.ts
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import Vec2 from "../../../Wolfie2D/DataTypes/Vec2";
|
||||||
|
import GameEvent from "../../../Wolfie2D/Events/GameEvent";
|
||||||
|
import GameNode from "../../../Wolfie2D/Nodes/GameNode";
|
||||||
|
import NavigationPath from "../../../Wolfie2D/Pathfinding/NavigationPath";
|
||||||
|
|
||||||
|
import EnemyAI, { EnemyStates } from "../EnemyAI";
|
||||||
|
import EnemyState from "./EnemyState";
|
||||||
|
import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||||
|
import MathUtils from "../../../Wolfie2D/Utils/MathUtils";
|
||||||
|
import OnGround from "./OnGround";
|
||||||
|
|
||||||
|
export default class Patrol extends EnemyState {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A return object for exiting this state
|
||||||
|
protected retObj: Record<string, any>;
|
||||||
|
|
||||||
|
constructor(parent: EnemyAI, owner: GameNode){
|
||||||
|
super(parent, owner);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnter(options: Record<string, any>): void {
|
||||||
|
//this.currentPath = this.getNextPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInput(event: GameEvent): void { }
|
||||||
|
|
||||||
|
update(deltaT: number): void {
|
||||||
|
super.update(deltaT);
|
||||||
|
|
||||||
|
//no goap rn, just adding some moving
|
||||||
|
let colrow = this.parent.tilemap.getColRowAt(this.owner.position.clone());
|
||||||
|
|
||||||
|
//check if next tile on walking path is collidable
|
||||||
|
if(this.parent.tilemap.isTileCollidable(colrow.x+this.parent.direction,colrow.y)){
|
||||||
|
//turn around
|
||||||
|
console.log(this.parent.tilemap.getTileAtRowCol(colrow));
|
||||||
|
this.parent.direction *= -1;
|
||||||
|
(<Sprite>this.owner).invertX = MathUtils.sign(1) < 0;
|
||||||
|
console.log("turn around cus wall in front");
|
||||||
|
}
|
||||||
|
//check if next ground tile is collidable
|
||||||
|
else if(this.parent.tilemap.isTileCollidable(colrow.x+this.parent.direction,colrow.y+1)){
|
||||||
|
//keep moving
|
||||||
|
//this.velocity.x = this.speed;
|
||||||
|
console.log("there is floor ahead");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//turn around
|
||||||
|
this.parent.direction *=-1;
|
||||||
|
(<Sprite>this.owner).invertX = MathUtils.sign(1) < 0;
|
||||||
|
console.log("turn around cus no floor in front");
|
||||||
|
|
||||||
|
}
|
||||||
|
//move
|
||||||
|
this.parent.velocity.x = this.parent.direction * this.parent.speed;
|
||||||
|
|
||||||
|
//move this elsewhere later
|
||||||
|
this.owner.move(this.parent.velocity.scaled(deltaT));
|
||||||
|
//console.log("enemy moving");
|
||||||
|
}
|
||||||
|
|
||||||
|
onExit(): Record<string, any> {
|
||||||
|
return this.retObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -11,12 +11,13 @@ export default class BattleManager {
|
||||||
handleInteraction(attackerType: string, weapon: Weapon) {
|
handleInteraction(attackerType: string, weapon: Weapon) {
|
||||||
//may be unneeded since we are controlling the player -
|
//may be unneeded since we are controlling the player -
|
||||||
//we determine enemy collision there
|
//we determine enemy collision there
|
||||||
/*
|
|
||||||
if (attackerType === "player") {
|
if (attackerType === "player") {
|
||||||
// Check for collisions with enemies
|
// Check for collisions with enemies
|
||||||
for (let enemy of this.enemies) {
|
for (let enemy of this.enemies) {
|
||||||
if (weapon.hits(enemy.owner)) {
|
if (weapon.hits(enemy.owner)) {
|
||||||
enemy.damage(weapon.type.damage);
|
enemy.damage(weapon.type.damage);
|
||||||
|
console.log("enemy took dmg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,14 +28,8 @@ export default class BattleManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Check for collision with player
|
|
||||||
for (let player of this.players) {
|
|
||||||
if (weapon.hits(player.owner)) {
|
|
||||||
player.damage(weapon.type.damage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setPlayers(player: Array<BattlerAI>): void {
|
setPlayers(player: Array<BattlerAI>): void {
|
||||||
|
@ -44,4 +39,8 @@ export default class BattleManager {
|
||||||
setEnemies(enemies: Array<BattlerAI>): void {
|
setEnemies(enemies: Array<BattlerAI>): void {
|
||||||
this.enemies = enemies;
|
this.enemies = enemies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addEnemy(enemy : BattlerAI){
|
||||||
|
this.enemies.push(enemy);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -32,9 +32,13 @@ export enum PlayerStates {
|
||||||
|
|
||||||
export enum BuffType {
|
export enum BuffType {
|
||||||
ATK = "attack",
|
ATK = "attack",
|
||||||
DEF = "defence"
|
DEF = "defence",
|
||||||
|
HEALTH = "health",
|
||||||
|
SPEED = "speed",
|
||||||
|
RANGE = "range"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Buff = {
|
type Buff = {
|
||||||
"type": BuffType,
|
"type": BuffType,
|
||||||
"value": number,
|
"value": number,
|
||||||
|
@ -45,10 +49,11 @@ type Buffs = [
|
||||||
Buff, Buff, Buff
|
Buff, Buff, Buff
|
||||||
]
|
]
|
||||||
|
|
||||||
|
//TODO - discuss max stats during refinement, unused for now
|
||||||
export default class PlayerController extends StateMachineAI implements BattlerAI{
|
export default class PlayerController extends StateMachineAI implements BattlerAI{
|
||||||
owner: GameNode;
|
owner: GameNode;
|
||||||
velocity: Vec2 = Vec2.ZERO;
|
velocity: Vec2 = Vec2.ZERO;
|
||||||
|
//will need to discuss redundant stats
|
||||||
speed: number = 200;
|
speed: number = 200;
|
||||||
MIN_SPEED: number = 200;
|
MIN_SPEED: number = 200;
|
||||||
MAX_SPEED: number = 300;
|
MAX_SPEED: number = 300;
|
||||||
|
@ -78,10 +83,11 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
||||||
inventory: InventoryManager;
|
inventory: InventoryManager;
|
||||||
|
|
||||||
CURRENT_BUFFS: {
|
CURRENT_BUFFS: {
|
||||||
atk: 0;
|
atk: number; //flat value to add to weapon
|
||||||
hp: 0;
|
hp: number; //flat value
|
||||||
def: 0;
|
def: number; //falt value
|
||||||
speed: 0;
|
speed: number;
|
||||||
|
range:number; //range will be a multiplier value: 1.5 = 150% range
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,9 +105,35 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
||||||
* Add given buff to the player
|
* Add given buff to the player
|
||||||
* @param buff Given buff
|
* @param buff Given buff
|
||||||
*/
|
*/
|
||||||
setBuff(buff: Buff): void {
|
addBuff(buff: Buff): void {
|
||||||
// TODO
|
// TODO
|
||||||
|
let item = this.inventory.getItem();
|
||||||
|
|
||||||
|
switch(buff.type){
|
||||||
|
case BuffType.HEALTH:
|
||||||
|
this.CURRENT_BUFFS.hp += buff.value;
|
||||||
|
this.CURRENT_HP += buff.value;
|
||||||
|
break;
|
||||||
|
case BuffType.ATK:
|
||||||
|
//TODO - may have to modify the weapon dmg value here instead
|
||||||
|
this.CURRENT_BUFFS.atk += buff.value;
|
||||||
|
break;
|
||||||
|
case BuffType.SPEED:
|
||||||
|
this.CURRENT_BUFFS.speed += buff.value;
|
||||||
|
break;
|
||||||
|
case BuffType.DEF:
|
||||||
|
this.CURRENT_BUFFS.def += buff.value;
|
||||||
|
break;
|
||||||
|
case BuffType.RANGE:
|
||||||
|
this.CURRENT_BUFFS.range += buff.value;
|
||||||
|
if (item) {
|
||||||
|
//item.sprite.
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO - get the correct tilemap
|
//TODO - get the correct tilemap
|
||||||
initializeAI(owner: GameNode, options: Record<string, any>){
|
initializeAI(owner: GameNode, options: Record<string, any>){
|
||||||
|
@ -114,6 +146,10 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
||||||
this.inventory = options.inventory;
|
this.inventory = options.inventory;
|
||||||
|
|
||||||
this.lookDirection = new Vec2();
|
this.lookDirection = new Vec2();
|
||||||
|
|
||||||
|
this.CURRENT_BUFFS = {hp:0, atk:0, def:0, speed:0, range:0};
|
||||||
|
|
||||||
|
this.addBuff( {type:BuffType.HEALTH, value:1, bonus:false} );
|
||||||
}
|
}
|
||||||
|
|
||||||
initializePlatformer(): void {
|
initializePlatformer(): void {
|
||||||
|
|
|
@ -16,12 +16,12 @@ import Color from "../../Wolfie2D/Utils/Color";
|
||||||
import { EaseFunctionType } from "../../Wolfie2D/Utils/EaseFunctions";
|
import { EaseFunctionType } from "../../Wolfie2D/Utils/EaseFunctions";
|
||||||
import PlayerController from "../Player/PlayerController";
|
import PlayerController from "../Player/PlayerController";
|
||||||
import MainMenu from "./MainMenu";
|
import MainMenu from "./MainMenu";
|
||||||
import { Player_Events } from "../sword_enums";
|
import { Player_Events, Statuses } from "../sword_enums";
|
||||||
import RegistryManager from "../../Wolfie2D/Registry/RegistryManager";
|
import RegistryManager from "../../Wolfie2D/Registry/RegistryManager";
|
||||||
import WeaponType from "../GameSystems/items/WeaponTypes/WeaponType";
|
import WeaponType from "../GameSystems/items/WeaponTypes/WeaponType";
|
||||||
import Weapon from "../GameSystems/items/Weapon";
|
import Weapon from "../GameSystems/items/Weapon";
|
||||||
import BattleManager from "../GameSystems/BattleManager";
|
import BattleManager from "../GameSystems/BattleManager";
|
||||||
//import EnemyAI from "../AI/EnemyAI";
|
import EnemyAI from "../AI/EnemyAI";
|
||||||
import BattlerAI from "../AI/BattlerAI";
|
import BattlerAI from "../AI/BattlerAI";
|
||||||
import InventoryManager from "../GameSystems/InventoryManager";
|
import InventoryManager from "../GameSystems/InventoryManager";
|
||||||
import Item from "../GameSystems/items/Item";
|
import Item from "../GameSystems/items/Item";
|
||||||
|
@ -64,6 +64,9 @@ export default class GameLevel extends Scene {
|
||||||
// A list of items in the scene
|
// A list of items in the scene
|
||||||
private items: Array<Item>;
|
private items: Array<Item>;
|
||||||
|
|
||||||
|
// A list of enemies
|
||||||
|
private enemies: Array<AnimatedSprite>;
|
||||||
|
|
||||||
loadScene(): void {
|
loadScene(): void {
|
||||||
//can load player sprite here
|
//can load player sprite here
|
||||||
|
|
||||||
|
@ -82,6 +85,8 @@ export default class GameLevel extends Scene {
|
||||||
this.load.image("knife", "shattered_sword_assets/sprites/knife.png");
|
this.load.image("knife", "shattered_sword_assets/sprites/knife.png");
|
||||||
this.load.spritesheet("slice", "shattered_sword_assets/spritesheets/slice.json");
|
this.load.spritesheet("slice", "shattered_sword_assets/spritesheets/slice.json");
|
||||||
this.load.image("inventorySlot", "shattered_sword_assets/sprites/inventory.png");
|
this.load.image("inventorySlot", "shattered_sword_assets/sprites/inventory.png");
|
||||||
|
|
||||||
|
this.load.spritesheet("test_dummy","shattered_sword_assets/spritesheets/test_dummy.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
startScene(): void {
|
startScene(): void {
|
||||||
|
@ -100,6 +105,9 @@ export default class GameLevel extends Scene {
|
||||||
// Initialize the items array - this represents items that are in the game world
|
// Initialize the items array - this represents items that are in the game world
|
||||||
this.items = new Array();
|
this.items = new Array();
|
||||||
|
|
||||||
|
// Create an enemies array
|
||||||
|
this.enemies = new Array();
|
||||||
|
|
||||||
this.initPlayer();
|
this.initPlayer();
|
||||||
this.subscribeToEvents();
|
this.subscribeToEvents();
|
||||||
this.addUI();
|
this.addUI();
|
||||||
|
@ -148,7 +156,7 @@ export default class GameLevel extends Scene {
|
||||||
|
|
||||||
//update health UI
|
//update health UI
|
||||||
let playerAI = (<PlayerController>this.player.ai);
|
let playerAI = (<PlayerController>this.player.ai);
|
||||||
this.healthLabel.text = "Player Health: "+ playerAI.CURRENT_HP +'/' + (playerAI.MAX_HP );
|
this.healthLabel.text = "Player Health: "+ playerAI.CURRENT_HP +'/' + (playerAI.MAX_HP +playerAI.CURRENT_BUFFS.hp );
|
||||||
|
|
||||||
//handle collisions - may be in battle manager instead
|
//handle collisions - may be in battle manager instead
|
||||||
|
|
||||||
|
@ -163,7 +171,17 @@ export default class GameLevel extends Scene {
|
||||||
this.playerFalloff(viewportCenter, baseViewportSize);
|
this.playerFalloff(viewportCenter, baseViewportSize);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO - this is for testing
|
||||||
|
if(Input.isJustPressed("spawn")){
|
||||||
|
console.log("trying to spawn enemy");
|
||||||
|
this.addEnemy("test_dummy",this.player.position,{player: this.player,
|
||||||
|
health :100,
|
||||||
|
tilemap: "Main",
|
||||||
|
//actions:actions,
|
||||||
|
goal: Statuses.REACHED_GOAL,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +222,7 @@ export default class GameLevel extends Scene {
|
||||||
*/
|
*/
|
||||||
protected addUI(){
|
protected addUI(){
|
||||||
// In-game labels
|
// In-game labels
|
||||||
this.healthLabel = <Label> this.add.uiElement(UIElementType.LABEL, "UI",{position: new Vec2(80, 30), text: "Player Health: "+ (<PlayerController>this.player.ai).CURRENT_HP });
|
this.healthLabel = <Label> this.add.uiElement(UIElementType.LABEL, "UI",{position: new Vec2(100, 30), text: "Player Health: "+ (<PlayerController>this.player.ai).CURRENT_HP });
|
||||||
this.healthLabel.textColor = Color.WHITE;
|
this.healthLabel.textColor = Color.WHITE;
|
||||||
this.healthLabel.font = "PixelSimple";
|
this.healthLabel.font = "PixelSimple";
|
||||||
|
|
||||||
|
@ -339,7 +357,7 @@ export default class GameLevel extends Scene {
|
||||||
}
|
}
|
||||||
this.player.position.copy(this.playerSpawn);
|
this.player.position.copy(this.playerSpawn);
|
||||||
this.player.addPhysics(new AABB(Vec2.ZERO, new Vec2(32, 32))); //sets the collision shape
|
this.player.addPhysics(new AABB(Vec2.ZERO, new Vec2(32, 32))); //sets the collision shape
|
||||||
this.player.colliderOffset.set(0, 2);
|
this.player.colliderOffset.set(0, 0);
|
||||||
this.player.addAI(PlayerController, {
|
this.player.addAI(PlayerController, {
|
||||||
playerType: "platformer",
|
playerType: "platformer",
|
||||||
tilemap: "Main",
|
tilemap: "Main",
|
||||||
|
@ -367,14 +385,17 @@ export default class GameLevel extends Scene {
|
||||||
|
|
||||||
protected addEnemy(spriteKey: string, tilePos: Vec2, aiOptions: Record<string, any>): void {
|
protected addEnemy(spriteKey: string, tilePos: Vec2, aiOptions: Record<string, any>): void {
|
||||||
let enemy = this.add.animatedSprite(spriteKey, "primary");
|
let enemy = this.add.animatedSprite(spriteKey, "primary");
|
||||||
enemy.position.set(tilePos.x*32, tilePos.y*32);
|
//enemy.position.set(tilePos.x*32, tilePos.y*32);
|
||||||
|
enemy.position.copy(tilePos);
|
||||||
enemy.scale.set(2, 2);
|
enemy.scale.set(2, 2);
|
||||||
enemy.addPhysics();
|
enemy.addPhysics(new AABB(Vec2.ZERO, new Vec2(16, 25)));
|
||||||
//enemy.addAI(EnemyAI, aiOptions); //TODO - add individual enemy AI
|
enemy.colliderOffset.set(0, 6);
|
||||||
|
enemy.addAI(EnemyAI, aiOptions); //TODO - add individual enemy AI
|
||||||
enemy.setGroup("Enemy");
|
enemy.setGroup("Enemy");
|
||||||
|
|
||||||
enemy.setTrigger("player",Player_Events.PLAYER_HIT_ENEMY, null);
|
//add enemy to the enemy array
|
||||||
|
this.enemies.push(enemy);
|
||||||
|
this.battleManager.setEnemies(this.enemies.map(enemy => <BattlerAI>enemy._ai));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,10 @@ export enum Damage_Type {
|
||||||
ENVIRONMENT_DAMAGE = "EnvironmentDamage",
|
ENVIRONMENT_DAMAGE = "EnvironmentDamage",
|
||||||
DOT_DAMAGE = "DOTDamage",
|
DOT_DAMAGE = "DOTDamage",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum Statuses {
|
||||||
|
IN_RANGE = "IN_RANGE",
|
||||||
|
LOW_HEALTH = "LOW_HEALTH",
|
||||||
|
CAN_RETREAT = "CAN_RETREAT",
|
||||||
|
REACHED_GOAL = "GOAL"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user