added enums for event type and added an emitter class
This commit is contained in:
parent
d452678344
commit
a67521ea26
20
src/Events/Emitter.ts
Normal file
20
src/Events/Emitter.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import Map from "../DataTypes/Map";
|
||||
import EventQueue from "./EventQueue";
|
||||
import GameEvent from "./GameEvent";
|
||||
|
||||
export default class Emitter {
|
||||
private eventQueue: EventQueue;
|
||||
|
||||
constructor(){
|
||||
this.eventQueue = EventQueue.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit and event of type eventType with the data packet data
|
||||
* @param eventType
|
||||
* @param data
|
||||
*/
|
||||
fireEvent(eventType: string, data: Map<any> | Record<string, any> = null): void {
|
||||
this.eventQueue.addEvent(new GameEvent(eventType, data));
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import Queue from "../DataTypes/Queue";
|
|||
import Map from "../DataTypes/Map";
|
||||
import GameEvent from "./GameEvent";
|
||||
import Receiver from "./Receiver";
|
||||
import { GameEventType } from "./GameEventType";
|
||||
|
||||
export default class EventQueue {
|
||||
private static instance: EventQueue = null;
|
||||
|
@ -65,8 +66,8 @@ export default class EventQueue {
|
|||
}
|
||||
|
||||
// If a receiver is subscribed to all events, send it the event
|
||||
if(this.receivers.has("all")){
|
||||
for(let receiver of this.receivers.get("all")){
|
||||
if(this.receivers.has(GameEventType.ALL)){
|
||||
for(let receiver of this.receivers.get(GameEventType.ALL)){
|
||||
receiver.receive(event);
|
||||
}
|
||||
}
|
||||
|
|
59
src/Events/GameEventType.ts
Normal file
59
src/Events/GameEventType.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
export enum GameEventType {
|
||||
/**
|
||||
* Mouse Down event. Has data: {position: Vec2 - Mouse Position}
|
||||
*/
|
||||
MOUSE_DOWN = "mouse_down",
|
||||
/**
|
||||
* Mouse Up event. Has data: {position: Vec2 - Mouse Position}
|
||||
*/
|
||||
MOUSE_UP = "mouse_up",
|
||||
/**
|
||||
* Mouse Move event. Has data: {position: Vec2 - Mouse Position}
|
||||
*/
|
||||
MOUSE_MOVE = "mouse_move",
|
||||
|
||||
/**
|
||||
* Key Down event. Has data: {key: string - The key that is down}
|
||||
*/
|
||||
KEY_DOWN = "key_down",
|
||||
|
||||
/**
|
||||
* Key Up event. Has data: {key: string - The key that is up}
|
||||
*/
|
||||
KEY_UP = "key_up",
|
||||
|
||||
/**
|
||||
* Canvas Blur event. Has data: {}
|
||||
*/
|
||||
CANVAS_BLUR = "canvas_blur",
|
||||
|
||||
/**
|
||||
* Start Recording event. Has data: {}
|
||||
*/
|
||||
START_RECORDING = "start_recording",
|
||||
|
||||
/**
|
||||
* Stop Recording event. Has data: {}
|
||||
*/
|
||||
STOP_RECORDING = "stop_recording",
|
||||
|
||||
/**
|
||||
* Play Recording event. Has data: {}
|
||||
*/
|
||||
PLAY_RECORDING = "play_recording",
|
||||
|
||||
/**
|
||||
* Play Sound event. Has data: {key: string, loop: boolean, holdReference: boolean }
|
||||
*/
|
||||
PLAY_SOUND = "play_sound",
|
||||
|
||||
/**
|
||||
* Play Sound event. Has data: {key: string}
|
||||
*/
|
||||
STOP_SOUND = "stop_sound",
|
||||
|
||||
/**
|
||||
* Encompasses all event types. Used for receivers only.
|
||||
*/
|
||||
ALL = "all",
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import EventQueue from "../Events/EventQueue";
|
||||
import Vec2 from "../DataTypes/Vec2";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import { GameEventType } from "../Events/GameEventType";
|
||||
|
||||
/**
|
||||
* Handles communication with the web browser to receive asynchronous events and send them to the event queue
|
||||
|
@ -23,36 +24,36 @@ export default class InputHandler{
|
|||
|
||||
private handleMouseDown = (event: MouseEvent, canvas: HTMLCanvasElement): void => {
|
||||
let pos = this.getMousePosition(event, canvas);
|
||||
let gameEvent = new GameEvent("mouse_down", {position: pos});
|
||||
let gameEvent = new GameEvent(GameEventType.MOUSE_DOWN, {position: pos});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
private handleMouseUp = (event: MouseEvent, canvas: HTMLCanvasElement): void => {
|
||||
let pos = this.getMousePosition(event, canvas);
|
||||
let gameEvent = new GameEvent("mouse_up", {position: pos});
|
||||
let gameEvent = new GameEvent(GameEventType.MOUSE_UP, {position: pos});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
private handleMouseMove = (event: MouseEvent, canvas: HTMLCanvasElement): void => {
|
||||
let pos = this.getMousePosition(event, canvas);
|
||||
let gameEvent = new GameEvent("mouse_move", {position: pos});
|
||||
let gameEvent = new GameEvent(GameEventType.MOUSE_MOVE, {position: pos});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
private handleKeyDown = (event: KeyboardEvent): void => {
|
||||
let key = this.getKey(event);
|
||||
let gameEvent = new GameEvent("key_down", {key: key});
|
||||
let gameEvent = new GameEvent(GameEventType.KEY_DOWN, {key: key});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
private handleKeyUp = (event: KeyboardEvent): void => {
|
||||
let key = this.getKey(event);
|
||||
let gameEvent = new GameEvent("key_up", {key: key});
|
||||
let gameEvent = new GameEvent(GameEventType.KEY_UP, {key: key});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
private handleBlur = (event: Event): void => {
|
||||
let gameEvent = new GameEvent("canvas_blur", {});
|
||||
let gameEvent = new GameEvent(GameEventType.CANVAS_BLUR, {});
|
||||
this.eventQueue.addEvent(gameEvent);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ import Map from "../DataTypes/Map";
|
|||
import Vec2 from "../DataTypes/Vec2";
|
||||
import EventQueue from "../Events/EventQueue";
|
||||
import Viewport from "../SceneGraph/Viewport";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import { GameEventType } from "../Events/GameEventType";
|
||||
|
||||
/**
|
||||
* Receives input events from the event queue and allows for easy access of information about input
|
||||
|
@ -31,7 +33,8 @@ export default class InputReceiver{
|
|||
|
||||
this.eventQueue = EventQueue.getInstance();
|
||||
// Subscribe to all input events
|
||||
this.eventQueue.subscribe(this.receiver, ["mouse_down", "mouse_up", "mouse_move", "key_down", "key_up", "canvas_blur"]);
|
||||
this.eventQueue.subscribe(this.receiver, [GameEventType.MOUSE_DOWN, GameEventType.MOUSE_UP, GameEventType.MOUSE_MOVE,
|
||||
GameEventType.KEY_DOWN, GameEventType.KEY_UP, GameEventType.CANVAS_BLUR]);
|
||||
}
|
||||
|
||||
static getInstance(): InputReceiver{
|
||||
|
@ -50,21 +53,21 @@ export default class InputReceiver{
|
|||
let event = this.receiver.getNextEvent();
|
||||
|
||||
// Handle each event type
|
||||
if(event.type === "mouse_down"){
|
||||
if(event.type === GameEventType.MOUSE_DOWN){
|
||||
this.mouseJustPressed = true;
|
||||
this.mousePressed = true;
|
||||
this.mousePressPosition = event.data.get("position");
|
||||
}
|
||||
|
||||
if(event.type === "mouse_up"){
|
||||
if(event.type === GameEventType.MOUSE_UP){
|
||||
this.mousePressed = false;
|
||||
}
|
||||
|
||||
if(event.type === "mouse_move"){
|
||||
if(event.type === GameEventType.MOUSE_MOVE){
|
||||
this.mousePosition = event.data.get("position");
|
||||
}
|
||||
|
||||
if(event.type === "key_down"){
|
||||
if(event.type === GameEventType.KEY_DOWN){
|
||||
let key = event.data.get("key")
|
||||
if(!this.keyPressed.get(key)){
|
||||
this.keyJustPressed.set(key, true);
|
||||
|
@ -72,12 +75,12 @@ export default class InputReceiver{
|
|||
}
|
||||
}
|
||||
|
||||
if(event.type === "key_up"){
|
||||
if(event.type === GameEventType.KEY_UP){
|
||||
let key = event.data.get("key")
|
||||
this.keyPressed.set(key, false);
|
||||
}
|
||||
|
||||
if(event.type === "canvas_blur"){
|
||||
if(event.type === GameEventType.CANVAS_BLUR){
|
||||
this.clearKeyPresses()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import UIElement from "./Nodes/UIElement";
|
|||
import Button from "./Nodes/UIElements/Button";
|
||||
import Layer from "./Scene/Layer";
|
||||
import SecondScene from "./SecondScene";
|
||||
import GameEvent from "./Events/GameEvent";
|
||||
import { GameEventType } from "./Events/GameEventType";
|
||||
|
||||
export default class MainScene extends Scene {
|
||||
|
||||
|
@ -42,7 +42,7 @@ export default class MainScene extends Scene {
|
|||
backgroundTilemap.getLayer().setAlpha(0.5);
|
||||
|
||||
// Add the music and start playing it on a loop
|
||||
this.emit("play_sound", {key: "level_music", loop: true, holdReference: true});
|
||||
this.emitter.fireEvent(GameEventType.PLAY_SOUND, {key: "level_music", loop: true, holdReference: true});
|
||||
|
||||
// Add the tilemap
|
||||
this.add.tilemap("platformer", OrthogonalTilemap);
|
||||
|
@ -65,19 +65,19 @@ export default class MainScene extends Scene {
|
|||
recordButton.setSize(100, 50);
|
||||
recordButton.setText("Record");
|
||||
recordButton.setPosition(400, 30);
|
||||
recordButton.onClickEventId = "record_button_press";
|
||||
recordButton.onClickEventId = GameEventType.START_RECORDING;
|
||||
|
||||
let stopButton = this.add.uiElement(Button, uiLayer);
|
||||
stopButton.setSize(100, 50);
|
||||
stopButton.setText("Stop");
|
||||
stopButton.setPosition(550, 30);
|
||||
stopButton.onClickEventId = "stop_button_press";
|
||||
stopButton.onClickEventId = GameEventType.STOP_RECORDING;
|
||||
|
||||
let playButton = this.add.uiElement(Button, uiLayer);
|
||||
playButton.setSize(100, 50);
|
||||
playButton.setText("Play");
|
||||
playButton.setPosition(700, 30);
|
||||
playButton.onClickEventId = "play_button_press";
|
||||
playButton.onClickEventId = GameEventType.PLAY_RECORDING;
|
||||
|
||||
let cycleFramerateButton = this.add.uiElement(Button, uiLayer);
|
||||
cycleFramerateButton.setSize(150, 50);
|
||||
|
@ -123,7 +123,7 @@ export default class MainScene extends Scene {
|
|||
switchButton.setText("Change Scene");
|
||||
switchButton.setPosition(340, 190);
|
||||
switchButton.onClick = () => {
|
||||
this.emit("stop_sound", {key: "level_music"});
|
||||
this.emitter.fireEvent(GameEventType.STOP_SOUND, {key: "level_music"});
|
||||
this.sceneManager.changeScene(SecondScene);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import EventQueue from "../Events/EventQueue";
|
||||
import InputReceiver from "../Input/InputReceiver";
|
||||
import Vec2 from "../DataTypes/Vec2";
|
||||
import Map from "../DataTypes/Map";
|
||||
import Receiver from "../Events/Receiver";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import Emitter from "../Events/Emitter";
|
||||
import Scene from "../Scene/Scene";
|
||||
import Layer from "../Scene/Layer";
|
||||
|
||||
/**
|
||||
* The representation of an object in the game world
|
||||
*/
|
||||
export default abstract class GameNode{
|
||||
private eventQueue: EventQueue;
|
||||
export default abstract class GameNode {
|
||||
protected input: InputReceiver;
|
||||
protected position: Vec2;
|
||||
private receiver: Receiver;
|
||||
protected receiver: Receiver;
|
||||
protected emitter: Emitter;
|
||||
protected scene: Scene;
|
||||
protected layer: Layer;
|
||||
|
||||
constructor(){
|
||||
this.eventQueue = EventQueue.getInstance();
|
||||
this.input = InputReceiver.getInstance();
|
||||
this.position = new Vec2(0, 0);
|
||||
this.receiver = new Receiver();
|
||||
this.emitter = new Emitter();
|
||||
}
|
||||
|
||||
setScene(scene: Scene): void {
|
||||
|
@ -52,24 +52,6 @@ export default abstract class GameNode{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe this object's receiver to the specified event type
|
||||
* @param eventType
|
||||
*/
|
||||
subscribe(eventType: string): void {
|
||||
this.eventQueue.subscribe(this.receiver, eventType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit and event of type eventType with the data packet data
|
||||
* @param eventType
|
||||
* @param data
|
||||
*/
|
||||
emit(eventType: string, data: Map<any> | Record<string, any> = null): void {
|
||||
let event = new GameEvent(eventType, data);
|
||||
this.eventQueue.addEvent(event);
|
||||
}
|
||||
|
||||
// TODO - This doesn't seem ideal. Is there a better way to do this?
|
||||
protected getViewportOriginWithParallax(): Vec2 {
|
||||
return this.scene.getViewport().getPosition().clone().mult(this.layer.getParallax());
|
||||
|
|
|
@ -82,7 +82,7 @@ export default class UIElement extends CanvasNode{
|
|||
}
|
||||
if(this.onClickEventId !== null){
|
||||
let data = {};
|
||||
this.emit(this.onClickEventId, data);
|
||||
this.emitter.fireEvent(this.onClickEventId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ export default class UIElement extends CanvasNode{
|
|||
}
|
||||
if(this.onEnterEventId !== null){
|
||||
let data = {};
|
||||
this.emit(this.onEnterEventId, data);
|
||||
this.emitter.fireEvent(this.onEnterEventId, data);
|
||||
}
|
||||
|
||||
} else if(this.isEntered) {
|
||||
|
@ -115,7 +115,7 @@ export default class UIElement extends CanvasNode{
|
|||
}
|
||||
if(this.onLeaveEventId !== null){
|
||||
let data = {};
|
||||
this.emit(this.onLeaveEventId, data);
|
||||
this.emitter.fireEvent(this.onLeaveEventId, data);
|
||||
}
|
||||
} else if(this.isClicked) {
|
||||
// If mouse is dragged off of element while down, it is not clicked anymore
|
||||
|
|
|
@ -2,6 +2,7 @@ import Queue from "../DataTypes/Queue";
|
|||
import Receiver from "../Events/Receiver";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import EventQueue from "../Events/EventQueue";
|
||||
import { GameEventType } from "../Events/GameEventType";
|
||||
|
||||
export default class Recorder{
|
||||
private receiver: Receiver;
|
||||
|
@ -53,7 +54,7 @@ export default class Recorder{
|
|||
while(this.receiver.hasNextEvent()){
|
||||
let event = this.receiver.getNextEvent();
|
||||
|
||||
if(event.type === "stop_button_press"){
|
||||
if(event.type === GameEventType.STOP_RECORDING){
|
||||
this.recording = false;
|
||||
}
|
||||
|
||||
|
@ -61,13 +62,13 @@ export default class Recorder{
|
|||
this.log.enqueue(new LogItem(this.frame, deltaT, event));
|
||||
}
|
||||
|
||||
if(event.type === "record_button_press"){
|
||||
if(event.type === GameEventType.START_RECORDING){
|
||||
this.log.clear();
|
||||
this.recording = true;
|
||||
this.frame = 0
|
||||
}
|
||||
|
||||
if(event.type === "play_button_press"){
|
||||
if(event.type === GameEventType.PLAY_RECORDING){
|
||||
this.frame = 0;
|
||||
this.recording = false;
|
||||
this.playing = true;
|
||||
|
|
|
@ -3,6 +3,7 @@ import Vec2 from "./DataTypes/Vec2";
|
|||
import Debug from "./Debug/Debug";
|
||||
import AABB from "./Physics/Colliders/AABB";
|
||||
import CanvasNode from "./Nodes/CanvasNode";
|
||||
import { GameEventType } from "./Events/GameEventType";
|
||||
|
||||
export default class Player extends PhysicsNode {
|
||||
velocity: Vec2;
|
||||
|
@ -83,7 +84,7 @@ export default class Player extends PhysicsNode {
|
|||
if(this.grounded){
|
||||
if(dir.y === -1){
|
||||
// Jumping
|
||||
this.emit("play_sound", {key: "player_jump"});
|
||||
this.emitter.fireEvent(GameEventType.PLAY_SOUND, {key: "player_jump"});
|
||||
}
|
||||
vel.y = dir.y*1800;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,8 @@ import Tilemap from "../Nodes/Tilemap";
|
|||
import ResourceManager from "../ResourceManager/ResourceManager";
|
||||
import GameLoop from "../Loop/GameLoop";
|
||||
import SceneManager from "./SceneManager";
|
||||
import EventQueue from "../Events/EventQueue";
|
||||
import GameEvent from "../Events/GameEvent";
|
||||
import Map from "../DataTypes/Map";
|
||||
import Receiver from "../Events/Receiver";
|
||||
import Emitter from "../Events/Emitter";
|
||||
|
||||
export default class Scene{
|
||||
protected layers: Stack<Layer>;
|
||||
|
@ -21,6 +20,8 @@ export default class Scene{
|
|||
protected running: boolean;
|
||||
protected game: GameLoop;
|
||||
protected sceneManager: SceneManager;
|
||||
protected receiver: Receiver;
|
||||
protected emitter: Emitter;
|
||||
|
||||
protected tilemaps: Array<Tilemap>;
|
||||
|
||||
|
@ -48,6 +49,8 @@ export default class Scene{
|
|||
this.running = false;
|
||||
this.game = game;
|
||||
this.sceneManager = sceneManager;
|
||||
this.receiver = new Receiver();
|
||||
this.emitter = new Emitter();
|
||||
|
||||
this.tilemaps = new Array();
|
||||
this.sceneGraph = new SceneGraphArray(this.viewport, this);
|
||||
|
@ -146,14 +149,4 @@ export default class Scene{
|
|||
getViewport(): Viewport {
|
||||
return this.viewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit and event of type eventType with the data packet data
|
||||
* @param eventType
|
||||
* @param data
|
||||
*/
|
||||
emit(eventType: string, data: Map<any> | Record<string, any> = null): void {
|
||||
let event = new GameEvent(eventType, data);
|
||||
EventQueue.getInstance().addEvent(event);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import Vec2 from "./DataTypes/Vec2";
|
|||
import UIElement from "./Nodes/UIElement";
|
||||
import Button from "./Nodes/UIElements/Button";
|
||||
import Layer from "./Scene/Layer";
|
||||
import { GameEventType } from "./Events/GameEventType";
|
||||
|
||||
export default class SecondScene extends Scene {
|
||||
|
||||
|
@ -40,7 +41,7 @@ export default class SecondScene extends Scene {
|
|||
backgroundTilemap.getLayer().setAlpha(0.2);
|
||||
|
||||
// Add the music and start playing it on a loop
|
||||
this.emit("play_sound", {key: "level_music", loop: true, holdReference: true});
|
||||
this.emitter.fireEvent(GameEventType.PLAY_SOUND, {key: "level_music", loop: true, holdReference: true});
|
||||
|
||||
// Add the tilemap
|
||||
this.add.tilemap("level2", OrthogonalTilemap);
|
||||
|
@ -63,19 +64,19 @@ export default class SecondScene extends Scene {
|
|||
recordButton.setSize(100, 50);
|
||||
recordButton.setText("Record");
|
||||
recordButton.setPosition(400, 30);
|
||||
recordButton.onClickEventId = "record_button_press";
|
||||
recordButton.onClickEventId = GameEventType.START_RECORDING;
|
||||
|
||||
let stopButton = this.add.uiElement(Button, uiLayer);
|
||||
stopButton.setSize(100, 50);
|
||||
stopButton.setText("Stop");
|
||||
stopButton.setPosition(550, 30);
|
||||
stopButton.onClickEventId = "stop_button_press";
|
||||
stopButton.onClickEventId = GameEventType.STOP_RECORDING;
|
||||
|
||||
let playButton = this.add.uiElement(Button, uiLayer);
|
||||
playButton.setSize(100, 50);
|
||||
playButton.setText("Play");
|
||||
playButton.setPosition(700, 30);
|
||||
playButton.onClickEventId = "play_button_press";
|
||||
playButton.onClickEventId = GameEventType.PLAY_RECORDING;
|
||||
|
||||
let cycleFramerateButton = this.add.uiElement(Button, uiLayer);
|
||||
cycleFramerateButton.setSize(150, 50);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Map from "../DataTypes/Map";
|
||||
import Receiver from "../Events/Receiver";
|
||||
import ResourceManager from "../ResourceManager/ResourceManager";
|
||||
import { GameEventType } from "../Events/GameEventType";
|
||||
|
||||
export default class AudioManager {
|
||||
private static instance: AudioManager;
|
||||
|
@ -12,7 +13,7 @@ export default class AudioManager {
|
|||
private constructor(){
|
||||
this.initAudio();
|
||||
this.receiver = new Receiver();
|
||||
this.receiver.subscribe(["play_sound", "stop_sound"]);
|
||||
this.receiver.subscribe([GameEventType.PLAY_SOUND, GameEventType.STOP_SOUND]);
|
||||
this.currentSounds = new Map();
|
||||
}
|
||||
|
||||
|
@ -117,14 +118,14 @@ export default class AudioManager {
|
|||
// TODO - Add logic to merge sounds if there are multiple of the same key
|
||||
while(this.receiver.hasNextEvent()){
|
||||
let event = this.receiver.getNextEvent();
|
||||
if(event.type === "play_sound"){
|
||||
if(event.type === GameEventType.PLAY_SOUND){
|
||||
let soundKey = event.data.get("key");
|
||||
let loop = event.data.get("loop");
|
||||
let holdReference = event.data.get("holdReference");
|
||||
this.playSound(soundKey, loop, holdReference);
|
||||
}
|
||||
|
||||
if(event.type === "stop_sound"){
|
||||
if(event.type === GameEventType.STOP_SOUND){
|
||||
let soundKey = event.data.get("key");
|
||||
this.stopSound(soundKey);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user