diff --git a/front/src/Phaser/Entity/PlayableCaracter.ts b/front/src/Phaser/Entity/PlayableCaracter.ts index 789b2475..0c9db376 100644 --- a/front/src/Phaser/Entity/PlayableCaracter.ts +++ b/front/src/Phaser/Entity/PlayableCaracter.ts @@ -1,7 +1,9 @@ import {getPlayerAnimations, playAnimation, PlayerAnimationNames} from "../Player/Animation"; import {ActiveEventList, UserInputEvent} from "../UserInput/UserInputManager"; +import {SpeechBubble} from "./SpeechBubble"; export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite { + private bubble: SpeechBubble; constructor(scene: Phaser.Scene, x: number, y: number, texture: string, frame?: string | number) { super(scene, x, y, texture, frame); @@ -29,4 +31,14 @@ export class PlayableCaracter extends Phaser.Physics.Arcade.Sprite { this.play(PlayerAnimationNames.WalkDown, true); } } + + say(text: string) { + if (this.bubble) return; + this.bubble = new SpeechBubble(this.scene, this, text) + //todo make the buble destroy on player movement? + setTimeout(() => { + this.bubble.destroy(); + this.bubble = null; + }, 3000) + } } \ No newline at end of file diff --git a/front/src/Phaser/Entity/SpeechBubble.ts b/front/src/Phaser/Entity/SpeechBubble.ts new file mode 100644 index 00000000..e3a055b2 --- /dev/null +++ b/front/src/Phaser/Entity/SpeechBubble.ts @@ -0,0 +1,62 @@ +import Scene = Phaser.Scene; +import {PlayableCaracter} from "./PlayableCaracter"; + +export class SpeechBubble { + private bubble: Phaser.GameObjects.Graphics; + private content: Phaser.GameObjects.Text; + + constructor(scene: Scene, player: PlayableCaracter, text: string) { + + let bubbleHeight = 50; + let bubblePadding = 10; + let bubbleWidth = bubblePadding * 2 + text.length * 10; + let arrowHeight = bubbleHeight / 4; + + this.bubble = scene.add.graphics({ x: player.x + 16, y: player.y - 80 }); + + // Bubble shadow + this.bubble.fillStyle(0x222222, 0.5); + this.bubble.fillRoundedRect(6, 6, bubbleWidth, bubbleHeight, 16); + + // this.bubble color + this.bubble.fillStyle(0xffffff, 1); + + // this.bubble outline line style + this.bubble.lineStyle(4, 0x565656, 1); + + // this.bubble shape and outline + this.bubble.strokeRoundedRect(0, 0, bubbleWidth, bubbleHeight, 16); + this.bubble.fillRoundedRect(0, 0, bubbleWidth, bubbleHeight, 16); + + // Calculate arrow coordinates + let point1X = Math.floor(bubbleWidth / 7); + let point1Y = bubbleHeight; + let point2X = Math.floor((bubbleWidth / 7) * 2); + let point2Y = bubbleHeight; + let point3X = Math.floor(bubbleWidth / 7); + let point3Y = Math.floor(bubbleHeight + arrowHeight); + + // bubble arrow shadow + this.bubble.lineStyle(4, 0x222222, 0.5); + this.bubble.lineBetween(point2X - 1, point2Y + 6, point3X + 2, point3Y); + + // bubble arrow fill + this.bubble.fillTriangle(point1X, point1Y, point2X, point2Y, point3X, point3Y); + this.bubble.lineStyle(2, 0x565656, 1); + this.bubble.lineBetween(point2X, point2Y, point3X, point3Y); + this.bubble.lineBetween(point1X, point1Y, point3X, point3Y); + + this.content = scene.add.text(0, 0, text, { fontFamily: 'Arial', fontSize: 20, color: '#000000', align: 'center', wordWrap: { width: bubbleWidth - (bubblePadding * 2) } }); + + let bounds = this.content.getBounds(); + + this.content.setPosition(this.bubble.x + (bubbleWidth / 2) - (bounds.width / 2), this.bubble.y + (bubbleHeight / 2) - (bounds.height / 2)); + + } + + destroy(): void { + this.bubble.setVisible(false) //todo find a better way + this.content.destroy() + } + +} \ No newline at end of file diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 112e452c..eab3df65 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1,6 +1,6 @@ import {GameManagerInterface} from "./GameManager"; import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager"; -import {getPlayerAnimations, PlayerAnimationNames} from "../Player/Animation"; +import {getPlayerAnimations} from "../Player/Animation"; import {Player} from "../Player/Player"; import {NonPlayer} from "../NonPlayer/NonPlayer"; @@ -65,7 +65,6 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{ this.otherPlayers.add(new NonPlayer(this, 400, 600)); this.physics.add.collider(this.player, this.otherPlayers, (player: Player, otherPlayer: NonPlayer) => { - console.log("Don't touch me!"); otherPlayer.fleeFrom(player) }); @@ -120,6 +119,10 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface{ this.player.move(0, 0) } + if(activeEvents.get(UserInputEvent.Shout)) { + this.player.say('HEHO!'); + } + //updates other players this.otherPlayers.getChildren().forEach((otherPlayer: NonPlayer) => { diff --git a/front/src/Phaser/NonPlayer/NonPlayer.ts b/front/src/Phaser/NonPlayer/NonPlayer.ts index 91b83ba3..f2d748ab 100644 --- a/front/src/Phaser/NonPlayer/NonPlayer.ts +++ b/front/src/Phaser/NonPlayer/NonPlayer.ts @@ -15,10 +15,11 @@ export class NonPlayer extends PlayableCaracter { fleeFrom(player:Player) { if (this.isFleeing) return; + this.say("Don't touch me!"); this.isFleeing = true; setTimeout(() => { - console.log("I escaped"); + this.say("Feww, I escaped."); this.isFleeing = false this.fleeingDirection = null }, 3000); diff --git a/front/src/Phaser/UserInput/UserInputManager.ts b/front/src/Phaser/UserInput/UserInputManager.ts index e05eccb2..1e5e6e13 100644 --- a/front/src/Phaser/UserInput/UserInputManager.ts +++ b/front/src/Phaser/UserInput/UserInputManager.ts @@ -14,6 +14,7 @@ export enum UserInputEvent { MoveDown, SpeedUp, Interact, + Shout, } //we cannot the map structure so we have to create a replacment @@ -46,6 +47,7 @@ export class UserInputManager { {keyCode: Phaser.Input.Keyboard.KeyCodes.SHIFT, event: UserInputEvent.SpeedUp, keyInstance: null}, {keyCode: Phaser.Input.Keyboard.KeyCodes.E, event: UserInputEvent.Interact, keyInstance: null}, + {keyCode: Phaser.Input.Keyboard.KeyCodes.F, event: UserInputEvent.Shout, keyInstance: null}, ]; constructor(Scene : GameSceneInterface) {