fixed archer AI, added lasergun for boss, added speed cheat, changed buff generator, fixed isplayervisible bug, added lastplayerposition to enemyAI
This commit is contained in:
parent
cf3c3cf860
commit
7dcf7f09dc
14
dist/shattered_sword_assets/data/weaponData.json
vendored
14
dist/shattered_sword_assets/data/weaponData.json
vendored
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"numWeapons": 2,
|
||||
"numWeapons": 3,
|
||||
"weapons": [
|
||||
{
|
||||
"weaponType": "slice",
|
||||
|
@ -16,10 +16,20 @@
|
|||
"name": "pistol",
|
||||
"displayName": "Pistol",
|
||||
"spriteKey": "pistol",
|
||||
"damage": 2,
|
||||
"damage": 15,
|
||||
"cooldown": 500,
|
||||
"useVolume": 320,
|
||||
"color": "#FFEEDD"
|
||||
},
|
||||
{
|
||||
"weaponType": "laserGun",
|
||||
"name": "laserGun",
|
||||
"displayName": "laserGun",
|
||||
"spriteKey": "laserGun",
|
||||
"damage": 30,
|
||||
"cooldown": 650,
|
||||
"useVolume": 320,
|
||||
"color": "#15E631"
|
||||
}
|
||||
]
|
||||
}
|
BIN
dist/shattered_sword_assets/sprites/laserGun.png
vendored
Normal file
BIN
dist/shattered_sword_assets/sprites/laserGun.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 249 B |
|
@ -2,8 +2,7 @@ import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|||
import EnemyAI, { EnemyStates } from "./EnemyAI";
|
||||
import ArcherAttack from "./EnemyStates/ArcherAttack";
|
||||
import Weapon from "../GameSystems/items/Weapon";
|
||||
|
||||
|
||||
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
||||
|
||||
|
||||
export default class ArcherAI extends EnemyAI {
|
||||
|
@ -16,4 +15,8 @@ export default class ArcherAI extends EnemyAI {
|
|||
this.addState(EnemyStates.ATTACK, new ArcherAttack(this, owner));
|
||||
this.weapon = options.weapon;
|
||||
}
|
||||
|
||||
canAttack(position: Vec2): boolean {
|
||||
return this.attackTimer.isStopped() && this.owner.position.distanceTo(position)<=96;
|
||||
}
|
||||
}
|
|
@ -70,6 +70,7 @@ export default class EnemyAI extends StateMachineAI implements BattlerAI {
|
|||
physicWidth: number;
|
||||
physicHeight: number;
|
||||
|
||||
lastPlayerPosition: Vec2;
|
||||
|
||||
initializeAI(owner: AnimatedSprite, options: Record<string, any>): void {
|
||||
this.owner = owner;
|
||||
|
@ -198,6 +199,7 @@ export default class EnemyAI extends StateMachineAI implements BattlerAI {
|
|||
}
|
||||
}
|
||||
}
|
||||
this.lastPlayerPosition = pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -206,7 +208,10 @@ export default class EnemyAI extends StateMachineAI implements BattlerAI {
|
|||
* @returns position of the player if visible, else null
|
||||
*/
|
||||
getPlayerPosition(): Vec2 {
|
||||
return this.isPlayerVisible(this.player.position);
|
||||
if(this.isPlayerVisible(this.player.position) == null){
|
||||
return this.lastPlayerPosition;
|
||||
}
|
||||
return this.isPlayerVisible(this.player.position) ;
|
||||
}
|
||||
|
||||
update(deltaT: number){
|
||||
|
|
|
@ -3,23 +3,31 @@ import AnimatedSprite from "../../../Wolfie2D/Nodes/Sprites/AnimatedSprite";
|
|||
import Attack from "./Attack";
|
||||
import ArcherAI from "../ArcherAI";
|
||||
import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||
import Timer from "../../../Wolfie2D/Timing/Timer";
|
||||
|
||||
//TODO - unfinished
|
||||
export default class ArcherAttack extends Attack {
|
||||
pauseTimer : Timer;
|
||||
onEnter(options: Record<string, any>): void {
|
||||
super.onEnter(options);
|
||||
this.pauseTimer = new Timer(1000);
|
||||
this.pauseTimer.start();
|
||||
}
|
||||
|
||||
update(deltaT: number): void {
|
||||
|
||||
|
||||
this.parent.direction = this.parent.getPlayerPosition().x - this.owner.position.x >= 0 ? 1 : 0;
|
||||
let dir = this.parent.getPlayerPosition().clone().sub(this.owner.position).normalize();
|
||||
(<ArcherAI>this.parent).weapon.use(this.owner, "enemy", dir.scale(1,0));
|
||||
|
||||
(<Sprite>this.owner).invertX = this.parent.direction === 1 ? true : false ;
|
||||
|
||||
this.finished(EnemyStates.ALERT);
|
||||
if(this.pauseTimer.isStopped()){
|
||||
this.parent.direction = this.parent.getPlayerPosition().x - this.owner.position.x >= 0 ? 1 : 0;
|
||||
let dir = this.parent.getPlayerPosition().clone().sub(this.owner.position).normalize();
|
||||
|
||||
(<ArcherAI>this.parent).weapon.use(this.owner, "enemy", dir.scale(1,0));
|
||||
(<Sprite>this.owner).invertX = this.parent.direction === 1 ? true : false ;
|
||||
this.finished(EnemyStates.ALERT);
|
||||
}
|
||||
super.update(deltaT);
|
||||
}
|
||||
onExit(): Record<string, any> {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -21,12 +21,9 @@ export default class AssassinAttack extends Attack {
|
|||
this.owner.alpha = 1; //unstealth to attack
|
||||
this.startPosition = this.owner.position;
|
||||
|
||||
|
||||
|
||||
if(this.parent.getPlayerPosition() !==null)
|
||||
this.owner.position = this.parent.getPlayerPosition().clone().add(new Vec2( (<Sprite>this.parent.player).invertX ? 64 : -64 ,0));
|
||||
|
||||
|
||||
this.pauseTimer.start();
|
||||
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ export default class Weapon extends Item {
|
|||
this.assets = this.type.createRequiredAssets(this.sprite.getScene());
|
||||
|
||||
// Do a type specific weapon animation
|
||||
this.type.doAnimation(user, direction, this.EXTRA_RANGE, ...this.assets);
|
||||
this.type.doAnimation(user, direction, ...this.assets, this.EXTRA_RANGE);
|
||||
|
||||
// Apply damage
|
||||
this.battleManager.handleInteraction(userType, this, user);
|
||||
|
|
103
src/shattered_sword/GameSystems/items/WeaponTypes/LaserGun.ts
Normal file
103
src/shattered_sword/GameSystems/items/WeaponTypes/LaserGun.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
import AABB from "../../../../Wolfie2D/DataTypes/Shapes/AABB";
|
||||
import Vec2 from "../../../../Wolfie2D/DataTypes/Vec2";
|
||||
import GameNode, { TweenableProperties } from "../../../../Wolfie2D/Nodes/GameNode";
|
||||
import { GraphicType } from "../../../../Wolfie2D/Nodes/Graphics/GraphicTypes";
|
||||
import Line from "../../../../Wolfie2D/Nodes/Graphics/Line";
|
||||
import OrthogonalTilemap from "../../../../Wolfie2D/Nodes/Tilemaps/OrthogonalTilemap";
|
||||
import Scene from "../../../../Wolfie2D/Scene/Scene";
|
||||
import Color from "../../../../Wolfie2D/Utils/Color";
|
||||
import { EaseFunctionType } from "../../../../Wolfie2D/Utils/EaseFunctions";
|
||||
import { Player_Events } from "../../../sword_enums";
|
||||
import WeaponType from "./WeaponType";
|
||||
|
||||
export default class laserGun extends WeaponType {
|
||||
|
||||
color: Color;
|
||||
private hexColor: string;
|
||||
|
||||
initialize(options: Record<string, any>): void {
|
||||
this.damage = options.damage;
|
||||
this.cooldown = options.cooldown;
|
||||
this.hexColor = options.color;
|
||||
this.color = Color.fromStringHex(options.color);
|
||||
this.displayName = options.displayName;
|
||||
this.spriteKey = options.spriteKey;
|
||||
this.useVolume = options.useVolume;
|
||||
}
|
||||
|
||||
doAnimation(shooter: GameNode, direction: Vec2, line: Line): void {
|
||||
let start = shooter.position.clone().add(shooter.colliderOffset);
|
||||
let end = shooter.position.clone().add(direction.scaled(900)).add(shooter.colliderOffset);
|
||||
let delta = end.clone().sub(start);
|
||||
|
||||
// Iterate through the tilemap region until we find a collision
|
||||
let minX = Math.min(start.x, end.x);
|
||||
let maxX = Math.max(start.x, end.x);
|
||||
let minY = Math.min(start.y, end.y);
|
||||
let maxY = Math.max(start.y, end.y);
|
||||
|
||||
// Get the wall tilemap
|
||||
let walls = <OrthogonalTilemap>shooter.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(end)){
|
||||
console.log("Found hit");
|
||||
end = hit.pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line.start = start;
|
||||
line.end = end;
|
||||
|
||||
line.tweens.play("fade");
|
||||
}
|
||||
|
||||
createRequiredAssets(scene: Scene): [Line] {
|
||||
let line = <Line>scene.add.graphic(GraphicType.LINE, "primary", {start: new Vec2(-1, 1), end: new Vec2(-1, -1)});
|
||||
line.color = this.color;
|
||||
line.thickness = 25;
|
||||
|
||||
line.tweens.add("fade", {
|
||||
startDelay: 0,
|
||||
duration: 800,
|
||||
effects: [
|
||||
{
|
||||
property: TweenableProperties.alpha,
|
||||
start: 1,
|
||||
end: 0,
|
||||
ease: EaseFunctionType.OUT_SINE
|
||||
}
|
||||
],
|
||||
onEnd: Player_Events.UNLOAD_ASSET
|
||||
});
|
||||
|
||||
return [line];
|
||||
}
|
||||
|
||||
hits(node: GameNode, line: Line): boolean {
|
||||
return node.collisionShape.getBoundingRect().intersectSegment(line.start, line.end.clone().sub(line.start)) !== null;
|
||||
}
|
||||
|
||||
clone(): WeaponType {
|
||||
let newType = new laserGun();
|
||||
newType.initialize({damage: this.damage, color: this.hexColor, cooldown: this.cooldown, displayName: this.displayName, spriteKey: this.spriteKey, useVolume: this.useVolume});
|
||||
return newType;
|
||||
}
|
||||
}
|
|
@ -26,8 +26,8 @@ export default class SemiAutoGun extends WeaponType {
|
|||
}
|
||||
|
||||
doAnimation(shooter: GameNode, direction: Vec2, line: Line): void {
|
||||
let start = shooter.position.clone();
|
||||
let end = shooter.position.clone().add(direction.scaled(900));
|
||||
let start = shooter.position.clone().add(shooter.colliderOffset);
|
||||
let end = shooter.position.clone().add(direction.scaled(900)).add(shooter.colliderOffset);
|
||||
let delta = end.clone().sub(start);
|
||||
|
||||
// Iterate through the tilemap region until we find a collision
|
||||
|
@ -72,10 +72,11 @@ export default class SemiAutoGun extends WeaponType {
|
|||
createRequiredAssets(scene: Scene): [Line] {
|
||||
let line = <Line>scene.add.graphic(GraphicType.LINE, "primary", {start: new Vec2(-1, 1), end: new Vec2(-1, -1)});
|
||||
line.color = this.color;
|
||||
line.thickness = 5;
|
||||
|
||||
line.tweens.add("fade", {
|
||||
startDelay: 0,
|
||||
duration: 300,
|
||||
duration: 600,
|
||||
effects: [
|
||||
{
|
||||
property: TweenableProperties.alpha,
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class Slice extends WeaponType {
|
|||
this.useVolume = options.useVolume;
|
||||
}
|
||||
|
||||
doAnimation(attacker: GameNode, direction: Vec2, extraRange:number,sliceSprite: AnimatedSprite): void {
|
||||
doAnimation(attacker: GameNode, direction: Vec2, sliceSprite: AnimatedSprite, extraRange:number): void {
|
||||
|
||||
// Rotate this with the game node
|
||||
// TODO - need to rotate the anim properly
|
||||
|
|
|
@ -391,7 +391,14 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
|||
PlayerController.buffPool.sort(() => 0.5 - Math.random());
|
||||
|
||||
// Get sub-array of first 3 elements after shuffled
|
||||
let shuffled = PlayerController.buffPool.slice(0, 3); //3 buff categories
|
||||
//let shuffled = PlayerController.buffPool.slice(0, 3); //3 buff categories
|
||||
|
||||
let shuffled = new Set<BuffCategory>();
|
||||
while(shuffled.size < 3){
|
||||
shuffled.add(PlayerController.buffPool.slice(0,1)[0]);
|
||||
PlayerController.buffPool.sort(() => 0.5 - Math.random());
|
||||
}
|
||||
|
||||
|
||||
//random number from 5 to 15 if no value given
|
||||
let num = Math.floor(Math.random() *10) +5;
|
||||
|
@ -459,8 +466,7 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
|||
|
||||
|
||||
let selected = new Array();
|
||||
while( shuffled.length != 0){
|
||||
let cat = shuffled.pop();
|
||||
for ( let cat of shuffled){
|
||||
switch(cat){
|
||||
case BuffCategory.ATTACK:
|
||||
attackBuffs.sort(() => 0.5 - Math.random());
|
||||
|
@ -532,7 +538,8 @@ export default class PlayerController extends StateMachineAI implements BattlerA
|
|||
}
|
||||
else if (!init){
|
||||
//increase weight of selected buff category
|
||||
PlayerController.buffPool.push(buff.category);
|
||||
if(buff.category != BuffCategory.EXTRA)
|
||||
PlayerController.buffPool.push(buff.category);
|
||||
PlayerController.appliedBuffs.push(buff);
|
||||
}
|
||||
// TODO
|
||||
|
|
|
@ -4,6 +4,7 @@ import ResourceManager from "../../Wolfie2D/ResourceManager/ResourceManager";
|
|||
import WeaponType from "../GameSystems/items/WeaponTypes/WeaponType";
|
||||
import Slice from "../GameSystems/items/WeaponTypes/Slice";
|
||||
import SemiAutoGun from "../GameSystems/items/WeaponTypes/SemiAutoGun";
|
||||
import laserGun from "../GameSystems/items/WeaponTypes/laserGun";
|
||||
export default class WeaponTemplateRegistry extends Registry<WeaponConstructor> {
|
||||
|
||||
public preload(): void {
|
||||
|
@ -14,6 +15,7 @@ export default class WeaponTemplateRegistry extends Registry<WeaponConstructor>
|
|||
//rm.image("something", "shattered_sword_assets/sprites/something.png");
|
||||
rm.image("knife", "shattered_sword_assets/sprites/knife.png");
|
||||
rm.image("pistol", "shattered_sword_assets/sprites/pistol.png");
|
||||
rm.image("laserGun", "shattered_sword_assets/sprites/laserGun.png");
|
||||
|
||||
// Load spritesheets
|
||||
//rm.spritesheet("weapon anim", "shattered_sword_assets/spritesheets/weapon anim.json");
|
||||
|
@ -23,6 +25,7 @@ export default class WeaponTemplateRegistry extends Registry<WeaponConstructor>
|
|||
//this.registerItem("itemtype", itemTypefile);
|
||||
this.registerItem("slice", Slice);
|
||||
this.registerItem("semiAutoGun", SemiAutoGun);
|
||||
this.registerItem("laserGun",laserGun);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ export default class GameLevel extends Scene {
|
|||
|
||||
this.load.image("knife", "shattered_sword_assets/sprites/knife.png");
|
||||
this.load.image("pistol","shattered_sword_assets/sprites/pistol.png");
|
||||
this.load.image("laserGun","shattered_sword_assets/sprites/laserGun.png")
|
||||
this.load.image("inventorySlot", "shattered_sword_assets/sprites/inventory.png");
|
||||
this.load.image("black", "shattered_sword_assets/images/black.png");
|
||||
this.load.image("poisoning", "shattered_sword_assets/images/poisoning.png");
|
||||
|
@ -555,7 +556,8 @@ export default class GameLevel extends Scene {
|
|||
Player_Events.LEVEL_END,
|
||||
Player_Events.PLAYER_KILLED,
|
||||
Player_Events.GIVE_REGULAR_BUFF,
|
||||
Player_Events.GIVE_SPECIAL_BUFF
|
||||
Player_Events.GIVE_SPECIAL_BUFF,
|
||||
Player_Events.UNLOAD_ASSET
|
||||
]);
|
||||
this.receiver.subscribe("buff1");
|
||||
this.receiver.subscribe("buff2");
|
||||
|
@ -860,10 +862,24 @@ export default class GameLevel extends Scene {
|
|||
//TODO - give each enemy unique weapon
|
||||
protected initializeEnemies( enemies: Enemy[]){
|
||||
|
||||
|
||||
let pistol = this.createWeapon("pistol");
|
||||
|
||||
for (let enemy of enemies) {
|
||||
switch (enemy.type) {
|
||||
|
||||
/*
|
||||
case "Snake":
|
||||
this.addEnemy("Archer", enemy.position.scale(32), ArcherAI, {
|
||||
player: this.player,
|
||||
health: 50,
|
||||
tilemap: "Main",
|
||||
size: new Vec2(14,10),
|
||||
offset : new Vec2(0, 22),
|
||||
exp: 50,
|
||||
weapon: pistol
|
||||
})
|
||||
break;
|
||||
*/
|
||||
case "Snake": //Snake enemies drop from sky("trees")? or could just be very abundant
|
||||
this.addEnemy("Snake", enemy.position.scale(32), SnakeAI, {
|
||||
player: this.player,
|
||||
|
@ -874,7 +890,7 @@ export default class GameLevel extends Scene {
|
|||
exp: 50,
|
||||
})
|
||||
break;
|
||||
|
||||
|
||||
case "Tiger": //Tiger can be miniboss for now?
|
||||
this.addEnemy("Tiger", enemy.position.scale(32), TigerAI, {
|
||||
player: this.player,
|
||||
|
@ -1148,6 +1164,10 @@ export default class GameLevel extends Scene {
|
|||
case "SLD":
|
||||
(<PlayerController>this.player._ai).CURRENT_SHIELD = parseInt(commands[2]);
|
||||
break;
|
||||
case "SPD":
|
||||
(<PlayerController>this.player._ai).speed = parseInt(commands[2]);
|
||||
(<PlayerController>this.player._ai).MIN_SPEED = parseInt(commands[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user