diff --git a/src/shattered_sword/Player/PlayerController.ts b/src/shattered_sword/Player/PlayerController.ts index 76a9374..313430f 100644 --- a/src/shattered_sword/Player/PlayerController.ts +++ b/src/shattered_sword/Player/PlayerController.ts @@ -18,6 +18,7 @@ import Weapon from "../GameSystems/items/Weapon"; import AnimatedSprite from "../../Wolfie2D/Nodes/Sprites/AnimatedSprite"; import InputWrapper from "../Tools/InputWrapper"; import EnemyAI from "../AI/EnemyAI"; +import Timer from "../../Wolfie2D/Timing/Timer"; export enum PlayerType { @@ -91,6 +92,9 @@ export default class PlayerController extends StateMachineAI implements BattlerA // The inventory of the player inventory: InventoryManager; + static invincibilityTimer: Timer; + + CURRENT_BUFFS: { atk: number; //flat value to add to weapon hp: number; //flat value @@ -110,8 +114,17 @@ export default class PlayerController extends StateMachineAI implements BattlerA this.CURRENT_SHIELD = newshield; //update shield value } else{ - (this.owner).animation.play("HURT", false); + //i frame here + PlayerController.invincibilityTimer.start(); + this.invincible = true; + + (this.owner).animation.playIfNotAlready("HURT", false); this.CURRENT_HP -= damage; + if(this.CURRENT_HP <= 0){ + this.emitter.fireEvent(Player_Events.PLAYER_KILLED); + (this.owner).animation.playIfNotAlready("DYING", false); + (this.owner).animation.queue("DEAD", false); + } } } @@ -220,8 +233,10 @@ export default class PlayerController extends StateMachineAI implements BattlerA this.CURRENT_BUFFS = {hp:0, atk:0, def:0, speed:0, range:0}; //to test the buffs - this.addBuff( {type:BuffType.HEALTH, value:1} ); - //this.addBuff( {type:BuffType.RANGE, value:1, bonus:false} ); + //this.addBuff( {type:BuffType.HEALTH, value:1} ); + + //i frame timer + PlayerController.invincibilityTimer = new Timer(400); } initializePlatformer(): void { @@ -251,6 +266,9 @@ export default class PlayerController extends StateMachineAI implements BattlerA update(deltaT: number): void { super.update(deltaT); + if(PlayerController.invincibilityTimer.isStopped()){ + this.invincible = false; + } if(this.currentState instanceof Jump){ Debug.log("playerstate", "Player State: Jump"); diff --git a/src/shattered_sword/Player/PlayerStates/PlayerState.ts b/src/shattered_sword/Player/PlayerStates/PlayerState.ts index 0a5414c..6c5b5a8 100644 --- a/src/shattered_sword/Player/PlayerStates/PlayerState.ts +++ b/src/shattered_sword/Player/PlayerStates/PlayerState.ts @@ -25,6 +25,7 @@ export default abstract class PlayerState extends State { this.positionTimer.start(); PlayerState.dashTimer = new Timer(50); PlayerState.dashCoolDownTimer = new Timer(600); + } @@ -74,5 +75,7 @@ export default abstract class PlayerState extends State { this.parent.velocity.y += this.gravity*deltaT; this.owner.move(this.parent.velocity.scaled(deltaT)); } + + } } \ No newline at end of file diff --git a/src/shattered_sword/Scenes/GameLevel.ts b/src/shattered_sword/Scenes/GameLevel.ts index d6e1188..92048f3 100644 --- a/src/shattered_sword/Scenes/GameLevel.ts +++ b/src/shattered_sword/Scenes/GameLevel.ts @@ -33,6 +33,7 @@ import Stack from "../../Wolfie2D/DataTypes/Stack"; import InputWrapper from "../Tools/InputWrapper"; import Story from "../Tools/DataTypes/Story"; import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite"; +import Platformer from "../../demos/Platformer"; @@ -101,6 +102,8 @@ export default class GameLevel extends Scene { buffs: Array; randomSeed: number; + + startpos: Vec2; loadScene(): void { //can load player sprite here @@ -202,6 +205,19 @@ export default class GameLevel extends Scene { if (this.gameStateStack.peek() === GameState.GAMING) { switch(event.type){ + case Player_Events.PLAYER_COLLIDE: + let n = this.sceneGraph.getNode(event.data.get("node")); + let other = this.sceneGraph.getNode(event.data.get("other")); + + if(n === this.player){ + // Node is player, other is enemy + this.handlePlayerEnemyCollision(n, other); + } else { + // Other is player, node is balloon + this.handlePlayerEnemyCollision(other,n); + + } + break; case Player_Events.ENEMY_KILLED: let node = this.sceneGraph.getNode(event.data.get("owner"));//get enemy id @@ -225,6 +241,13 @@ export default class GameLevel extends Scene { this.setGameState(GameState.BUFF); this.buffLayer.enable(); break; + case Player_Events.PLAYER_KILLED: + //respawn player if he has lives, otherwise end game + console.log("player Died"); + (this.player).animation.play("DEAD", false); + InputWrapper.disableInput(); + this.respawnPlayer(); + break; } } @@ -349,6 +372,7 @@ export default class GameLevel extends Scene { */ protected subscribeToEvents(){ this.receiver.subscribe([ + Player_Events.PLAYER_COLLIDE, Player_Events.PLAYER_HIT_ENEMY, Player_Events.ENEMY_KILLED, Player_Events.LEVEL_START, @@ -542,6 +566,7 @@ export default class GameLevel extends Scene { console.warn("Player spawn was never set - setting spawn to (0, 0)"); this.playerSpawn = Vec2.ZERO; } + this.startpos = this.playerSpawn; this.player.position.copy(this.playerSpawn); this.player.addPhysics(new AABB(Vec2.ZERO, new Vec2(14, 16))); //sets the collision shape this.player.colliderOffset.set(0, 16); @@ -599,6 +624,7 @@ export default class GameLevel extends Scene { enemy.addAI(EnemyAI, aiOptions); //TODO - add individual enemy AI enemy.setGroup("Enemy"); + enemy.setTrigger("player", Player_Events.PLAYER_COLLIDE, null); //add enemy to the enemy array this.enemies.push(enemy); @@ -676,8 +702,28 @@ export default class GameLevel extends Scene { } + /** + * damages the player if they collide with an enemy + * @param player player sprite + * @param enemy enemy sprite + */ protected handlePlayerEnemyCollision(player: AnimatedSprite, enemy: AnimatedSprite) { - //collisions are handled by the battleManager - no need for this in gamelevel for now + if(enemy === undefined){ + console.log("undefined enemy"); + return; + } + if( player === undefined){ + console.log("undefined player"); + return; + } + if(typeof enemy != undefined && typeof player != undefined){ + //damage the player + console.log("player collision damage"); + (this.player._ai).damage(10); //10 collision dmg for now + } + + + } /** @@ -699,10 +745,10 @@ export default class GameLevel extends Scene { * Returns the player to spawn */ protected respawnPlayer(): void { - GameLevel.livesCount = 3; this.emitter.fireEvent(GameEventType.STOP_SOUND, {key: "level_music"}); - this.sceneManager.changeToScene(MainMenu, {}); InputWrapper.enableInput(); + this.player.position.copy(this.startpos); + (this.player._ai).CURRENT_HP = (this.player._ai).MAX_HP + (this.player._ai).CURRENT_BUFFS.hp; } diff --git a/src/shattered_sword/Scenes/Levels.ts b/src/shattered_sword/Scenes/Levels.ts index 81f5a09..6afa1e2 100644 --- a/src/shattered_sword/Scenes/Levels.ts +++ b/src/shattered_sword/Scenes/Levels.ts @@ -99,7 +99,18 @@ export default class Levels extends Scene { if(event.type === "tutorial"){ - this.sceneManager.changeToScene(Tutorial, {}); + let sceneOptions = { + physics: { + groupNames: ["ground", "player", "enemies"], + collisions: + [ + [0, 1, 1], + [1, 0, 0], + [1, 0, 0] + ] + } + } + this.sceneManager.changeToScene(Tutorial, {}, sceneOptions); } if(event.type === "level1"){ diff --git a/src/shattered_sword/Scenes/Tutorial.ts b/src/shattered_sword/Scenes/Tutorial.ts index d6e9a8e..763ab22 100644 --- a/src/shattered_sword/Scenes/Tutorial.ts +++ b/src/shattered_sword/Scenes/Tutorial.ts @@ -42,7 +42,8 @@ export default class Tutorial extends GameLevel { } startScene(): void { - + + this.startpos = this.rmg.getPlayer().scale(32); // Add the level 1 tilemap this.add.tilemap("forest1", new Vec2(2, 2)); diff --git a/src/shattered_sword/sword_enums.ts b/src/shattered_sword/sword_enums.ts index f183205..612b9c3 100644 --- a/src/shattered_sword/sword_enums.ts +++ b/src/shattered_sword/sword_enums.ts @@ -10,7 +10,8 @@ export enum Player_Events { ENEMY_KILLED = "EnemyKilled", PLAYER_HIT_ENEMY = "PlayerHitEnemy", BOSS_KILLED = "BossKilled", - GIVE_BUFF = "GiveBuff" + GIVE_BUFF = "GiveBuff", + PLAYER_COLLIDE = "PlayerCollide" } export enum Damage_Type { NORMAL_DAMAGE = "NormalDamage",