feat&fix: implement TigerAI and fix attack bugs

This commit is contained in:
Renge 2022-04-24 23:11:45 -04:00
parent b2adaaa1db
commit 17f4b00488
7 changed files with 85 additions and 26 deletions

View File

@ -8,7 +8,7 @@ import BattlerAI from "./BattlerAI";
import Patrol from "./EnemyStates/Patrol"; import Patrol from "./EnemyStates/Patrol";
import Alert from "./EnemyStates/Alert"; import Alert from "./EnemyStates/Alert";
import Attack from "./EnemyStates/Attack"; import SlimeAttack from "./EnemyStates/SlimeAttack";
import { GameState, Statuses } from "../sword_enums"; import { GameState, Statuses } from "../sword_enums";
import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite"; import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite";
@ -73,7 +73,7 @@ export default class EnemyAI extends StateMachineAI implements BattlerAI {
// Patrol mode // Patrol mode
this.addState(EnemyStates.PATROL, new Patrol(this, owner)); this.addState(EnemyStates.PATROL, new Patrol(this, owner));
this.addState(EnemyStates.ALERT, new Alert(this, owner)); this.addState(EnemyStates.ALERT, new Alert(this, owner));
this.addState(EnemyStates.ATTACK, new Attack(this, owner)); this.addState(EnemyStates.ATTACK, new SlimeAttack(this, owner));
this.maxHealth = options.health; this.maxHealth = options.health;
@ -142,6 +142,10 @@ export default class EnemyAI extends StateMachineAI implements BattlerAI {
player.damage(10); player.damage(10);
} }
canAttack(position: Vec2): boolean {
return this.attackTimer.isStopped() && this.owner.position.distanceTo(position)<=32;
}
//TODO - need to modify for side view //TODO - need to modify for side view
isPlayerVisible(pos: Vec2): Vec2{ isPlayerVisible(pos: Vec2): Vec2{
//Check ifplayer is visible, taking into account walls //Check ifplayer is visible, taking into account walls

View File

@ -13,7 +13,7 @@ export default class Alert extends EnemyState {
if (position) { if (position) {
this.parent.velocity.x = this.parent.maxSpeed * Math.sign(position.x - this.owner.position.x); this.parent.velocity.x = this.parent.maxSpeed * Math.sign(position.x - this.owner.position.x);
this.parent.direction = this.parent.velocity.x >= 0 ? 1 : -1; this.parent.direction = this.parent.velocity.x >= 0 ? 1 : -1;
if (this.parent.attackTimer.isStopped() && this.owner.position.distanceTo(position)<=32) { if (this.parent.canAttack(position)) {
this.finished(EnemyStates.ATTACK); this.finished(EnemyStates.ATTACK);
} }
} }

View File

@ -20,17 +20,6 @@ export default class Attack extends EnemyState {
} }
update(deltaT: number): void { update(deltaT: number): void {
while (this.receiver.hasNextEvent()) {
let event = this.receiver.getNextEvent().type;
switch (event) {
case this.charged:
(<AnimatedSprite>this.owner).animation.play("ATTACK", false, this.attacked);
break;
case this.attacked:
this.finished(EnemyStates.ALERT);
break;
}
}
super.update(deltaT); super.update(deltaT);
} }

View File

@ -0,0 +1,20 @@
import EnemyAI, { EnemyStates } from "../EnemyAI";
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
import Attack from "./Attack";
export default class SlimeAttack extends Attack {
update(deltaT: number): void {
while (this.receiver.hasNextEvent()) {
let event = this.receiver.getNextEvent().type;
switch (event) {
case this.charged:
(<AnimatedSprite>this.owner).animation.play("ATTACK", false, this.attacked);
break;
case this.attacked:
this.finished(EnemyStates.ALERT);
break;
}
}
super.update(deltaT);
}
}

View File

@ -5,13 +5,6 @@ import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
import Attack from "./Attack"; import Attack from "./Attack";
export default class SnakeAttack extends Attack { export default class SnakeAttack extends Attack {
protected charged: string;
protected attacked: string;
onEnter(options: Record<string, any>): void {
super.onEnter(options);
}
update(deltaT: number): void { update(deltaT: number): void {
while (this.receiver.hasNextEvent()) { while (this.receiver.hasNextEvent()) {
let event = this.receiver.getNextEvent().type; let event = this.receiver.getNextEvent().type;
@ -28,9 +21,4 @@ export default class SnakeAttack extends Attack {
} }
(<Sprite>this.owner).invertX = this.parent.direction === 1 ? true : false ; (<Sprite>this.owner).invertX = this.parent.direction === 1 ? true : false ;
} }
onExit(): Record<string, any> {
(<AnimatedSprite>this.owner).animation.stop();
return null;
}
} }

View File

@ -0,0 +1,39 @@
import EnemyAI, { EnemyStates } from "../EnemyAI";
import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
import AABB from "../../../Wolfie2D/DataTypes/Shapes/AABB";
import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
import Attack from "./Attack";
export default class TigerAttack extends Attack {
protected velocity: number;
protected distance: number;
protected attacking: boolean = false;
onEnter(options: Record<string, any>): void {
super.onEnter(options);
this.velocity = 0;
}
update(deltaT: number): void {
if (this.attacking && this.owner.onGround) {
this.emitter.fireEvent(this.attacked);
}
while (this.receiver.hasNextEvent()) {
let event = this.receiver.getNextEvent().type;
switch (event) {
case this.charged:
(<AnimatedSprite>this.owner).animation.play("ATTACK", true);
this.velocity = (this.parent.getPlayerPosition().x - this.owner.position.x)/2;
this.parent.direction = this.velocity >= 0 ? 1 : 0;
this.attacking = true;
break;
case this.attacked:
this.finished(EnemyStates.ALERT);
break;
}
}
this.parent.velocity.x = this.velocity;
(<Sprite>this.owner).invertX = this.parent.direction === 1 ? true : false ;
super.update(deltaT);
}
}

View File

@ -0,0 +1,19 @@
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
import EnemyAI, { EnemyStates } from "./EnemyAI";
import TigerAttack from "./EnemyStates/TigerAttack";
export default class TigerAI extends EnemyAI {
initializeAI(owner: AnimatedSprite, options: Record<string, any>): void {
super.initializeAI(owner, options);
this.addState(EnemyStates.ATTACK, new TigerAttack(this, owner));
}
canAttack(position: Vec2): boolean {
return this.attackTimer.isStopped();
}
getPlayerPosition(): Vec2 {
return this.player.position;
}
}