improved visual debugging
This commit is contained in:
		
							parent
							
								
									b8849b4c84
								
							
						
					
					
						commit
						4b8ebf360d
					
				| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
import Graph, { MAX_V } from "./Graph";
 | 
					import Graph, { MAX_V } from "./Graph";
 | 
				
			||||||
import Vec2 from "../Vec2";
 | 
					import Vec2 from "../Vec2";
 | 
				
			||||||
import { Debug_Renderable } from "../Interfaces/Descriptors";
 | 
					import { DebugRenderable } from "../Interfaces/Descriptors";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class PositionGraph extends Graph implements Debug_Renderable{
 | 
					export default class PositionGraph extends Graph implements DebugRenderable{
 | 
				
			||||||
	positions: Array<Vec2>;
 | 
						positions: Array<Vec2>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(directed: boolean = false){
 | 
						constructor(directed: boolean = false){
 | 
				
			||||||
| 
						 | 
					@ -38,9 +38,9 @@ export default class PositionGraph extends Graph implements Debug_Renderable{
 | 
				
			||||||
		return "Node " + index + " - " + this.positions[index].toString();
 | 
							return "Node " + index + " - " + this.positions[index].toString();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	debug_render(ctx: CanvasRenderingContext2D, origin: Vec2, zoom: number): void {
 | 
						debugRender = (): void => {
 | 
				
			||||||
		for(let point of this.positions){
 | 
							// for(let point of this.positions){
 | 
				
			||||||
			ctx.fillRect((point.x - origin.x - 4)*zoom, (point.y - origin.y - 4)*zoom, 8, 8);
 | 
							// 	ctx.fillRect((point.x - origin.x - 4)*zoom, (point.y - origin.y - 4)*zoom, 8, 8);
 | 
				
			||||||
		}
 | 
							// }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -156,12 +156,7 @@ export interface Updateable {
 | 
				
			||||||
    update: (deltaT: number) => void;
 | 
					    update: (deltaT: number) => void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Renderable {
 | 
					export interface DebugRenderable {
 | 
				
			||||||
    /** Renders this object. */
 | 
					 | 
				
			||||||
    render: (ctx: CanvasRenderingContext2D) => void;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface Debug_Renderable {
 | 
					 | 
				
			||||||
    /** Renders the debugging infor for this object. */
 | 
					    /** Renders the debugging infor for this object. */
 | 
				
			||||||
    debug_render: (ctx: CanvasRenderingContext2D, origin: Vec2, zoom: number) => void;
 | 
					    debugRender(): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,17 +307,24 @@ export default class Vec2 {
 | 
				
			||||||
	 * @param other The vector to check against
 | 
						 * @param other The vector to check against
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	equals(other: Vec2): boolean {
 | 
						equals(other: Vec2): boolean {
 | 
				
			||||||
		let xEq = Math.abs(this.x - other.x) < 0.00000001;
 | 
							let xEq = Math.abs(this.x - other.x) < 0.0000001;
 | 
				
			||||||
		let yEq = Math.abs(this.y - other.y) < 0.00000001;
 | 
							let yEq = Math.abs(this.y - other.y) < 0.0000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return xEq && yEq;
 | 
							return xEq && yEq;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Returns true if this vector is the zero vector
 | 
						 * Returns true if this vector is the zero vector exactly (not assured to be safe for floats).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						strictIsZero(): boolean {
 | 
				
			||||||
 | 
							return this.x === 0 && this.y === 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Returns true if this x and y for this vector are both zero.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	isZero(): boolean {
 | 
						isZero(): boolean {
 | 
				
			||||||
		return this.x === 0 && this.y === 0;
 | 
							return Math.abs(this.x) < 0.0000001 && Math.abs(this.y) < 0.0000001;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,27 +1,135 @@
 | 
				
			||||||
import Map from "../DataTypes/Map";
 | 
					import Map from "../DataTypes/Map";
 | 
				
			||||||
 | 
					import Vec2 from "../DataTypes/Vec2";
 | 
				
			||||||
 | 
					import InputHandler from "../Input/InputHandler";
 | 
				
			||||||
 | 
					import GameNode from "../Nodes/GameNode";
 | 
				
			||||||
 | 
					import Color from "../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DebugRenderFunction = (ctx: CanvasRenderingContext2D) => void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Debug {
 | 
					export default class Debug {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// A map of log messages to display on the screen
 | 
						/** A map of log messages to display on the screen */ 
 | 
				
			||||||
	private static logMessages: Map<string> = new Map();
 | 
						private static logMessages: Map<string> = new Map();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** An array of game nodes to render debug info for */
 | 
				
			||||||
 | 
						private static nodes: Array<GameNode>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** The rendering context for any debug messages */
 | 
				
			||||||
 | 
						private static debugRenderingContext: CanvasRenderingContext2D;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**	The size of the debug canvas */
 | 
				
			||||||
 | 
						private static debugCanvasSize: Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** The rendering color for text */
 | 
				
			||||||
 | 
						private static defaultTextColor: Color = Color.WHITE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Add a message to display on the debug screen
 | 
				
			||||||
 | 
						 * @param id A unique ID for this message
 | 
				
			||||||
 | 
						 * @param messages The messages to print to the debug screen
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	static log(id: string, ...messages: any): void {
 | 
						static log(id: string, ...messages: any): void {
 | 
				
			||||||
		let message = "";
 | 
							// let message = "";
 | 
				
			||||||
		for(let i = 0; i < messages.length; i++){
 | 
							// for(let i = 0; i < messages.length; i++){
 | 
				
			||||||
			message += messages[i].toString();
 | 
							// 	message += messages[i].toString();
 | 
				
			||||||
		}
 | 
							// }
 | 
				
			||||||
 | 
							// Join all messages with spaces
 | 
				
			||||||
 | 
							let message = messages.map((m: any) => m.toString()).join(" ");
 | 
				
			||||||
		this.logMessages.add(id, message);
 | 
							this.logMessages.add(id, message);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: Create a method that can delete messages from the log
 | 
						/**
 | 
				
			||||||
 | 
						 * Deletes a a key from the log and stops it from keeping up space on the screen
 | 
				
			||||||
 | 
						 * @param id 
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						static clearLogItem(id: string): void {
 | 
				
			||||||
 | 
							this.logMessages.delete(id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static render(ctx: CanvasRenderingContext2D): void {
 | 
						/**
 | 
				
			||||||
 | 
						 * Sets the list of nodes to render with the debugger
 | 
				
			||||||
 | 
						 * @param nodes The new list of nodes
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						static setNodes(nodes: Array<GameNode>): void {
 | 
				
			||||||
 | 
							this.nodes = nodes;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Draws a box at the specified position
 | 
				
			||||||
 | 
						 * @param center The center of the box
 | 
				
			||||||
 | 
						 * @param halfSize The dimensions of the box
 | 
				
			||||||
 | 
						 * @param filled A boolean for whether or not the box is filled
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						static drawBox(center: Vec2, halfSize: Vec2, filled: boolean, color: Color): void {
 | 
				
			||||||
 | 
							if(filled){
 | 
				
			||||||
 | 
								this.debugRenderingContext.fillStyle = color.toString();
 | 
				
			||||||
 | 
								this.debugRenderingContext.fillRect(center.x - halfSize.x, center.y - halfSize.y, halfSize.x*2, halfSize.y*2);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								let lineWidth = 2;
 | 
				
			||||||
 | 
								this.debugRenderingContext.lineWidth = lineWidth;
 | 
				
			||||||
 | 
								this.debugRenderingContext.strokeStyle = color.toString();
 | 
				
			||||||
 | 
								this.debugRenderingContext.strokeRect(center.x - halfSize.x, center.y - halfSize.y, halfSize.x*2, halfSize.y*2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static drawRay(from: Vec2, to: Vec2, color: Color): void {
 | 
				
			||||||
 | 
							this.debugRenderingContext.lineWidth = 2;
 | 
				
			||||||
 | 
							this.debugRenderingContext.strokeStyle = color.toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.debugRenderingContext.beginPath();
 | 
				
			||||||
 | 
							this.debugRenderingContext.moveTo(from.x, from.y);
 | 
				
			||||||
 | 
							this.debugRenderingContext.lineTo(to.x, to.y);
 | 
				
			||||||
 | 
							this.debugRenderingContext.closePath();
 | 
				
			||||||
 | 
							this.debugRenderingContext.stroke();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static drawPoint(pos: Vec2, color: Color): void {
 | 
				
			||||||
 | 
							let pointSize = 6;
 | 
				
			||||||
 | 
							this.debugRenderingContext.fillStyle = color.toString();
 | 
				
			||||||
 | 
							this.debugRenderingContext.fillRect(pos.x - pointSize/2, pos.y - pointSize/2, pointSize, pointSize);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static setDefaultTextColor(color: Color): void {
 | 
				
			||||||
 | 
							this.defaultTextColor = color;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static initializeDebugCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {
 | 
				
			||||||
 | 
					        canvas.width = width;
 | 
				
			||||||
 | 
							canvas.height = height;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							this.debugCanvasSize = new Vec2(width, height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.debugRenderingContext = canvas.getContext("2d");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.debugRenderingContext;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static clearCanvas(): void {
 | 
				
			||||||
 | 
							this.debugRenderingContext.clearRect(0, 0, this.debugCanvasSize.x, this.debugCanvasSize.y);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static render(): void {
 | 
				
			||||||
 | 
							this.renderText();
 | 
				
			||||||
 | 
							this.renderNodes();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static renderText(): void {
 | 
				
			||||||
		let y = 20;
 | 
							let y = 20;
 | 
				
			||||||
		ctx.font = "20px Arial";
 | 
							this.debugRenderingContext.font = "20px Arial";
 | 
				
			||||||
		ctx.fillStyle = "#000000";
 | 
							this.debugRenderingContext.fillStyle = this.defaultTextColor.toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Draw all of the text
 | 
				
			||||||
		this.logMessages.forEach((key: string) => {
 | 
							this.logMessages.forEach((key: string) => {
 | 
				
			||||||
			ctx.fillText(this.logMessages.get(key), 10, y)
 | 
								this.debugRenderingContext.fillText(this.logMessages.get(key), 10, y)
 | 
				
			||||||
			y += 30;	
 | 
								y += 30;	
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static renderNodes(): void {
 | 
				
			||||||
 | 
							if(this.nodes){
 | 
				
			||||||
 | 
								this.nodes.forEach(node => {
 | 
				
			||||||
 | 
									node.debugRender();
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,7 @@ export default class GameLoop {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Game canvas and its width and height
 | 
					    // Game canvas and its width and height
 | 
				
			||||||
    readonly GAME_CANVAS: HTMLCanvasElement;
 | 
					    readonly GAME_CANVAS: HTMLCanvasElement;
 | 
				
			||||||
 | 
					    readonly DEBUG_CANVAS: HTMLCanvasElement;
 | 
				
			||||||
	readonly WIDTH: number;
 | 
						readonly WIDTH: number;
 | 
				
			||||||
    readonly HEIGHT: number;
 | 
					    readonly HEIGHT: number;
 | 
				
			||||||
    private viewport: Viewport;
 | 
					    private viewport: Viewport;
 | 
				
			||||||
| 
						 | 
					@ -100,7 +101,7 @@ export default class GameLoop {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Get the game canvas and give it a background color
 | 
					        // Get the game canvas and give it a background color
 | 
				
			||||||
        this.GAME_CANVAS = <HTMLCanvasElement>document.getElementById("game-canvas");
 | 
					        this.GAME_CANVAS = <HTMLCanvasElement>document.getElementById("game-canvas");
 | 
				
			||||||
        this.GAME_CANVAS.style.setProperty("background-color", "whitesmoke");
 | 
					        this.DEBUG_CANVAS = <HTMLCanvasElement>document.getElementById("debug-canvas");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        // Give the canvas a size and get the rendering context
 | 
					        // Give the canvas a size and get the rendering context
 | 
				
			||||||
        this.WIDTH = this.gameOptions.viewportSize.x;
 | 
					        this.WIDTH = this.gameOptions.viewportSize.x;
 | 
				
			||||||
| 
						 | 
					@ -108,9 +109,14 @@ export default class GameLoop {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // For now, just hard code a canvas renderer. We can do this with options later
 | 
					        // For now, just hard code a canvas renderer. We can do this with options later
 | 
				
			||||||
        this.renderingManager = new CanvasRenderer();
 | 
					        this.renderingManager = new CanvasRenderer();
 | 
				
			||||||
 | 
					        this.initializeGameWindow();
 | 
				
			||||||
        this.ctx = this.renderingManager.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT);
 | 
					        this.ctx = this.renderingManager.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT);
 | 
				
			||||||
        this.clearColor = new Color(this.gameOptions.clearColor.r, this.gameOptions.clearColor.g, this.gameOptions.clearColor.b);
 | 
					        this.clearColor = new Color(this.gameOptions.clearColor.r, this.gameOptions.clearColor.g, this.gameOptions.clearColor.b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Initialize debug canvas
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Debug.initializeDebugCanvas(this.DEBUG_CANVAS, this.WIDTH, this.HEIGHT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Size the viewport to the game canvas
 | 
					        // Size the viewport to the game canvas
 | 
				
			||||||
        this.viewport = new Viewport();
 | 
					        this.viewport = new Viewport();
 | 
				
			||||||
        this.viewport.setCanvasSize(this.WIDTH, this.HEIGHT);
 | 
					        this.viewport.setCanvasSize(this.WIDTH, this.HEIGHT);
 | 
				
			||||||
| 
						 | 
					@ -129,6 +135,17 @@ export default class GameLoop {
 | 
				
			||||||
        Stats.initStats();
 | 
					        Stats.initStats();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set up the game window that holds the canvases
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private initializeGameWindow(): void {
 | 
				
			||||||
 | 
					        const gameWindow = document.getElementById("game-window");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Set the height of the game window
 | 
				
			||||||
 | 
					        gameWindow.style.width = this.WIDTH + "px";
 | 
				
			||||||
 | 
					        gameWindow.style.height = this.HEIGHT + "px";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Changes the maximum allowed physics framerate of the game
 | 
					     * Changes the maximum allowed physics framerate of the game
 | 
				
			||||||
     * @param initMax 
 | 
					     * @param initMax 
 | 
				
			||||||
| 
						 | 
					@ -274,11 +291,17 @@ export default class GameLoop {
 | 
				
			||||||
     * Clears the canvas and defers scene rendering to the sceneManager. Renders the debug
 | 
					     * Clears the canvas and defers scene rendering to the sceneManager. Renders the debug
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    render(): void {
 | 
					    render(): void {
 | 
				
			||||||
 | 
					        // Clear the canvases
 | 
				
			||||||
        this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
 | 
					        this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
 | 
				
			||||||
 | 
					        Debug.clearCanvas();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Game Canvas
 | 
				
			||||||
        this.ctx.fillStyle = this.clearColor.toString();
 | 
					        this.ctx.fillStyle = this.clearColor.toString();
 | 
				
			||||||
        this.ctx.fillRect(0, 0, this.WIDTH, this.HEIGHT);
 | 
					        this.ctx.fillRect(0, 0, this.WIDTH, this.HEIGHT);
 | 
				
			||||||
        this.sceneManager.render();
 | 
					        this.sceneManager.render();
 | 
				
			||||||
        Debug.render(this.ctx);
 | 
					
 | 
				
			||||||
 | 
					        // Debug render
 | 
				
			||||||
 | 
					        Debug.render();
 | 
				
			||||||
        Stats.render();
 | 
					        Stats.render();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,9 @@
 | 
				
			||||||
import GameNode from "./GameNode";
 | 
					import GameNode from "./GameNode";
 | 
				
			||||||
import Vec2 from "../DataTypes/Vec2";
 | 
					import Vec2 from "../DataTypes/Vec2";
 | 
				
			||||||
import { Region, Renderable } from "../DataTypes/Interfaces/Descriptors";
 | 
					import { Region } from "../DataTypes/Interfaces/Descriptors";
 | 
				
			||||||
import AABB from "../DataTypes/Shapes/AABB";
 | 
					import AABB from "../DataTypes/Shapes/AABB";
 | 
				
			||||||
 | 
					import Debug from "../Debug/Debug";
 | 
				
			||||||
 | 
					import Color from "../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The representation of an object in the game world that can be drawn to the screen
 | 
					 * The representation of an object in the game world that can be drawn to the screen
 | 
				
			||||||
| 
						 | 
					@ -75,6 +77,12 @@ export default abstract class CanvasNode extends GameNode implements Region {
 | 
				
			||||||
		return this._boundary;
 | 
							return this._boundary;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get sizeWithZoom(): Vec2 {
 | 
				
			||||||
 | 
							let zoom = this.scene.getViewScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return this.boundary.halfSize.clone().scaled(zoom, zoom);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Returns true if the point (x, y) is inside of this canvas object
 | 
						 * Returns true if the point (x, y) is inside of this canvas object
 | 
				
			||||||
	 * @param x 
 | 
						 * @param x 
 | 
				
			||||||
| 
						 | 
					@ -83,4 +91,9 @@ export default abstract class CanvasNode extends GameNode implements Region {
 | 
				
			||||||
	contains(x: number, y: number): boolean {
 | 
						contains(x: number, y: number): boolean {
 | 
				
			||||||
		return this._boundary.containsPoint(new Vec2(x, y));
 | 
							return this._boundary.containsPoint(new Vec2(x, y));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						debugRender(): void {
 | 
				
			||||||
 | 
							super.debugRender();
 | 
				
			||||||
 | 
							Debug.drawBox(this.relativePosition, this.sizeWithZoom, false, Color.GREEN);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,17 +4,19 @@ import Receiver from "../Events/Receiver";
 | 
				
			||||||
import Emitter from "../Events/Emitter";
 | 
					import Emitter from "../Events/Emitter";
 | 
				
			||||||
import Scene from "../Scene/Scene";
 | 
					import Scene from "../Scene/Scene";
 | 
				
			||||||
import Layer from "../Scene/Layer";
 | 
					import Layer from "../Scene/Layer";
 | 
				
			||||||
import { Physical, Positioned, isRegion, Unique, Updateable, Actor, AI, Debug_Renderable } from "../DataTypes/Interfaces/Descriptors"
 | 
					import { Physical, Positioned, isRegion, Unique, Updateable, Actor, AI, DebugRenderable } from "../DataTypes/Interfaces/Descriptors"
 | 
				
			||||||
import Shape from "../DataTypes/Shapes/Shape";
 | 
					import Shape from "../DataTypes/Shapes/Shape";
 | 
				
			||||||
import Map from "../DataTypes/Map";
 | 
					import Map from "../DataTypes/Map";
 | 
				
			||||||
import AABB from "../DataTypes/Shapes/AABB";
 | 
					import AABB from "../DataTypes/Shapes/AABB";
 | 
				
			||||||
import NavigationPath from "../Pathfinding/NavigationPath";
 | 
					import NavigationPath from "../Pathfinding/NavigationPath";
 | 
				
			||||||
import TweenManager from "../Rendering/Animations/TweenManager";
 | 
					import TweenManager from "../Rendering/Animations/TweenManager";
 | 
				
			||||||
 | 
					import Debug from "../Debug/Debug";
 | 
				
			||||||
 | 
					import Color from "../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The representation of an object in the game world
 | 
					 * The representation of an object in the game world
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export default abstract class GameNode implements Positioned, Unique, Updateable, Physical, Actor {
 | 
					export default abstract class GameNode implements Positioned, Unique, Updateable, Physical, Actor, DebugRenderable {
 | 
				
			||||||
	/*---------- POSITIONED ----------*/
 | 
						/*---------- POSITIONED ----------*/
 | 
				
			||||||
	private _position: Vec2;
 | 
						private _position: Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +81,13 @@ export default abstract class GameNode implements Positioned, Unique, Updateable
 | 
				
			||||||
		this.positionChanged();
 | 
							this.positionChanged();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get relativePosition(): Vec2 {
 | 
				
			||||||
 | 
							let origin = this.scene.getViewTranslation(this);
 | 
				
			||||||
 | 
							let zoom = this.scene.getViewScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return this.position.clone().sub(origin).scale(zoom);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*---------- UNIQUE ----------*/
 | 
						/*---------- UNIQUE ----------*/
 | 
				
			||||||
	get id(): number {
 | 
						get id(): number {
 | 
				
			||||||
		return this._id;
 | 
							return this._id;
 | 
				
			||||||
| 
						 | 
					@ -249,6 +258,15 @@ export default abstract class GameNode implements Positioned, Unique, Updateable
 | 
				
			||||||
	update(deltaT: number): void {
 | 
						update(deltaT: number): void {
 | 
				
			||||||
		this.tweens.update(deltaT);
 | 
							this.tweens.update(deltaT);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						debugRender(): void {
 | 
				
			||||||
 | 
							Debug.drawPoint(this.relativePosition, Color.GREEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If velocity is not zero, draw a vector for it
 | 
				
			||||||
 | 
							if(this._velocity && !this._velocity.isZero()){
 | 
				
			||||||
 | 
								Debug.drawRay(this.relativePosition, this._velocity.clone().scaleTo(20).add(this.relativePosition), Color.GREEN);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum TweenableProperties{
 | 
					export enum TweenableProperties{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,14 +4,14 @@ import Color from "../../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Rect extends Graphic {
 | 
					export default class Rect extends Graphic {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected borderColor: Color;
 | 
					    borderColor: Color;
 | 
				
			||||||
    protected borderWidth: number;
 | 
					    protected borderWidth: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(position: Vec2, size: Vec2){
 | 
					    constructor(position: Vec2, size: Vec2){
 | 
				
			||||||
        super();
 | 
					        super();
 | 
				
			||||||
        this.position = position;
 | 
					        this.position = position;
 | 
				
			||||||
        this.size = size;
 | 
					        this.size = size;
 | 
				
			||||||
        this.borderColor = this.color;
 | 
					        this.borderColor = Color.TRANSPARENT;
 | 
				
			||||||
        this.borderWidth = 0;
 | 
					        this.borderWidth = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,12 @@ export default abstract class Tilemap extends CanvasNode {
 | 
				
			||||||
        return this.tileSize.scaled(this.scale.x, this.scale.y);
 | 
					        return this.tileSize.scaled(this.scale.x, this.scale.y);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getTileSizeWithZoom(): Vec2 {
 | 
				
			||||||
 | 
					        let zoom = this.scene.getViewScale();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return this.getTileSize().scale(zoom);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Adds this tilemap to the physics system */
 | 
					    /** Adds this tilemap to the physics system */
 | 
				
			||||||
    addPhysics = (): void => {
 | 
					    addPhysics = (): void => {
 | 
				
			||||||
        this.scene.getPhysicsManager().registerTilemap(this);
 | 
					        this.scene.getPhysicsManager().registerTilemap(this);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
import Tilemap from "../Tilemap";
 | 
					import Tilemap from "../Tilemap";
 | 
				
			||||||
import Vec2 from "../../DataTypes/Vec2";
 | 
					import Vec2 from "../../DataTypes/Vec2";
 | 
				
			||||||
import { TiledTilemapData, TiledLayerData } from "../../DataTypes/Tilesets/TiledData";
 | 
					import { TiledTilemapData, TiledLayerData } from "../../DataTypes/Tilesets/TiledData";
 | 
				
			||||||
import Tileset from "../../DataTypes/Tilesets/Tileset";
 | 
					import Debug from "../../Debug/Debug";
 | 
				
			||||||
 | 
					import Color from "../../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * The representation of an orthogonal tilemap - i.e. a top down or platformer tilemap
 | 
					 * The representation of an orthogonal tilemap - i.e. a top down or platformer tilemap
 | 
				
			||||||
| 
						 | 
					@ -46,6 +47,10 @@ export default class OrthogonalTilemap extends Tilemap {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getDimensions(): Vec2 {
 | 
				
			||||||
 | 
					        return new Vec2(this.numCols, this.numRows);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getTileAtWorldPosition(worldCoords: Vec2): number {
 | 
					    getTileAtWorldPosition(worldCoords: Vec2): number {
 | 
				
			||||||
        let localCoords = this.getColRowAt(worldCoords);
 | 
					        let localCoords = this.getColRowAt(worldCoords);
 | 
				
			||||||
        return this.getTileAtRowCol(localCoords);
 | 
					        return this.getTileAtRowCol(localCoords);
 | 
				
			||||||
| 
						 | 
					@ -128,4 +133,20 @@ export default class OrthogonalTilemap extends Tilemap {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    update(deltaT: number): void {}
 | 
					    update(deltaT: number): void {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    debugRender(){
 | 
				
			||||||
 | 
					        let tileSize = this.getTileSizeWithZoom();
 | 
				
			||||||
 | 
					        let origin = this.relativePosition.sub(this.sizeWithZoom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(let col = 0; col < this.numCols; col++){
 | 
				
			||||||
 | 
					            for(let row = 0; row < this.numRows; row++){
 | 
				
			||||||
 | 
					                if(this.isCollidable && this.isTileCollidable(col, row)){
 | 
				
			||||||
 | 
					                    // Draw a box for this tile
 | 
				
			||||||
 | 
					                    let center = new Vec2(origin.x + (col + 0.5)*tileSize.x, origin.y + (row + 0.5)*tileSize.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Debug.drawBox(center, tileSize.scaled(0.5), false, Color.BLUE);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -100,13 +100,4 @@ export default class Label extends UIElement{
 | 
				
			||||||
	sizeToText(): void {
 | 
						sizeToText(): void {
 | 
				
			||||||
		this.sizeAssigned = false;
 | 
							this.sizeAssigned = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	debug_render = (ctx: CanvasRenderingContext2D): void => {
 | 
					 | 
				
			||||||
		let origin = this.scene.getViewTranslation(this);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		ctx.lineWidth = 4;
 | 
					 | 
				
			||||||
        ctx.strokeStyle = "#00FF00"
 | 
					 | 
				
			||||||
        let b = this.boundary;
 | 
					 | 
				
			||||||
        ctx.strokeRect(b.x - b.hw - origin.x, b.y - b.hh - origin.y, b.hw*2, b.hh*2);
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -326,10 +326,6 @@ export default class BasicPhysicsManager extends PhysicsManager {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	debug_render(ctx: CanvasRenderingContext2D): void {
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Collision data objects for tilemaps
 | 
					// Collision data objects for tilemaps
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
import GameNode from "../Nodes/GameNode";
 | 
					import GameNode from "../Nodes/GameNode";
 | 
				
			||||||
import Vec2 from "../DataTypes/Vec2";
 | 
					import Vec2 from "../DataTypes/Vec2";
 | 
				
			||||||
import { Debug_Renderable, Updateable } from "../DataTypes/Interfaces/Descriptors";
 | 
					import { Updateable } from "../DataTypes/Interfaces/Descriptors";
 | 
				
			||||||
import Tilemap from "../Nodes/Tilemap";
 | 
					import Tilemap from "../Nodes/Tilemap";
 | 
				
			||||||
import Receiver from "../Events/Receiver";
 | 
					import Receiver from "../Events/Receiver";
 | 
				
			||||||
import Emitter from "../Events/Emitter";
 | 
					import Emitter from "../Events/Emitter";
 | 
				
			||||||
import Map from "../DataTypes/Map";
 | 
					import Map from "../DataTypes/Map";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default abstract class PhysicsManager implements Updateable, Debug_Renderable {
 | 
					export default abstract class PhysicsManager implements Updateable {
 | 
				
			||||||
	protected receiver: Receiver;
 | 
						protected receiver: Receiver;
 | 
				
			||||||
	protected emitter: Emitter;
 | 
						protected emitter: Emitter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,12 +43,6 @@ export default abstract class PhysicsManager implements Updateable, Debug_Render
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	abstract update(deltaT: number): void;
 | 
						abstract update(deltaT: number): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Renders any debug shapes or graphics
 | 
					 | 
				
			||||||
	 * @param ctx 
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	abstract debug_render(ctx: CanvasRenderingContext2D): void;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	setLayer(node: GameNode, layer: string): void {
 | 
						setLayer(node: GameNode, layer: string): void {
 | 
				
			||||||
		node.physicsLayer = this.layerMap.get(layer);
 | 
							node.physicsLayer = this.layerMap.get(layer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,9 +199,9 @@ export default class CanvasRenderer extends RenderingManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected renderGraphic(graphic: Graphic): void {
 | 
					    protected renderGraphic(graphic: Graphic): void {
 | 
				
			||||||
        if(graphic instanceof Point){
 | 
					        if(graphic instanceof Point){
 | 
				
			||||||
            this.graphicRenderer.renderPoint(<Point>graphic, this.origin, this.zoom);
 | 
					            this.graphicRenderer.renderPoint(<Point>graphic, this.zoom);
 | 
				
			||||||
        } else if(graphic instanceof Rect){
 | 
					        } else if(graphic instanceof Rect){
 | 
				
			||||||
            this.graphicRenderer.renderRect(<Rect>graphic, this.origin, this.zoom);
 | 
					            this.graphicRenderer.renderRect(<Rect>graphic, this.zoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -213,13 +213,13 @@ export default class CanvasRenderer extends RenderingManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected renderUIElement(uiElement: UIElement): void {
 | 
					    protected renderUIElement(uiElement: UIElement): void {
 | 
				
			||||||
        if(uiElement instanceof Label){
 | 
					        if(uiElement instanceof Label){
 | 
				
			||||||
            this.uiElementRenderer.renderLabel(uiElement, this.origin, this.zoom);
 | 
					            this.uiElementRenderer.renderLabel(uiElement);
 | 
				
			||||||
        } else if(uiElement instanceof Button){
 | 
					        } else if(uiElement instanceof Button){
 | 
				
			||||||
            this.uiElementRenderer.renderButton(uiElement, this.origin, this.zoom);
 | 
					            this.uiElementRenderer.renderButton(uiElement);
 | 
				
			||||||
        } else if(uiElement instanceof Slider){
 | 
					        } else if(uiElement instanceof Slider){
 | 
				
			||||||
            this.uiElementRenderer.renderSlider(uiElement, this.origin, this.zoom);
 | 
					            this.uiElementRenderer.renderSlider(uiElement);
 | 
				
			||||||
        } else if(uiElement instanceof TextInput){
 | 
					        } else if(uiElement instanceof TextInput){
 | 
				
			||||||
            this.uiElementRenderer.renderTextInput(uiElement, this.origin, this.zoom);
 | 
					            this.uiElementRenderer.renderTextInput(uiElement);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -18,22 +18,24 @@ export default class GraphicRenderer {
 | 
				
			||||||
        this.scene = scene;
 | 
					        this.scene = scene;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderPoint(point: Point, origin: Vec2, zoom: number): void {
 | 
					    renderPoint(point: Point, zoom: number): void {
 | 
				
			||||||
		this.ctx.fillStyle = point.color.toStringRGBA();
 | 
							this.ctx.fillStyle = point.color.toStringRGBA();
 | 
				
			||||||
        this.ctx.fillRect((-point.size.x/2)*zoom, (-point.size.y/2)*zoom,
 | 
					        this.ctx.fillRect((-point.size.x/2)*zoom, (-point.size.y/2)*zoom,
 | 
				
			||||||
        point.size.x*zoom, point.size.y*zoom);
 | 
					        point.size.x*zoom, point.size.y*zoom);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderRect(rect: Rect, origin: Vec2, zoom: number): void {
 | 
					    renderRect(rect: Rect, zoom: number): void {
 | 
				
			||||||
        // Draw the interior of the rect
 | 
					        // Draw the interior of the rect
 | 
				
			||||||
        if(rect.color.a !== 0){
 | 
					        if(rect.color.a !== 0){
 | 
				
			||||||
            this.ctx.fillStyle = rect.color.toStringRGB();
 | 
					            this.ctx.fillStyle = rect.color.toStringRGB();
 | 
				
			||||||
            this.ctx.fillRect((-rect.size.x/2)*zoom, (-rect.size.y/2)*zoom, rect.size.x*zoom, rect.size.y*zoom);
 | 
					            this.ctx.fillRect((-rect.size.x/2)*zoom, (-rect.size.y/2)*zoom, rect.size.x*zoom, rect.size.y*zoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Draw the border of the rect
 | 
					        // Draw the border of the rect if it isn't transparent
 | 
				
			||||||
 | 
					        if(rect.borderColor.a !== 0){
 | 
				
			||||||
            this.ctx.strokeStyle = rect.getBorderColor().toStringRGB();
 | 
					            this.ctx.strokeStyle = rect.getBorderColor().toStringRGB();
 | 
				
			||||||
            this.ctx.lineWidth = rect.getBorderWidth();
 | 
					            this.ctx.lineWidth = rect.getBorderWidth();
 | 
				
			||||||
            this.ctx.strokeRect((-rect.size.x/2)*zoom, (-rect.size.y/2)*zoom, rect.size.x*zoom, rect.size.y*zoom);
 | 
					            this.ctx.strokeRect((-rect.size.x/2)*zoom, (-rect.size.y/2)*zoom, rect.size.x*zoom, rect.size.y*zoom);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ export default class UIElementRenderer {
 | 
				
			||||||
        this.scene = scene;
 | 
					        this.scene = scene;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderLabel(label: Label, origin: Vec2, zoom: number): void {
 | 
					    renderLabel(label: Label): void {
 | 
				
			||||||
        // If the size is unassigned (by the user or automatically) assign it
 | 
					        // If the size is unassigned (by the user or automatically) assign it
 | 
				
			||||||
        label.handleInitialSizing(this.ctx);
 | 
					        label.handleInitialSizing(this.ctx);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
| 
						 | 
					@ -51,11 +51,11 @@ export default class UIElementRenderer {
 | 
				
			||||||
		this.ctx.globalAlpha = previousAlpha;
 | 
							this.ctx.globalAlpha = previousAlpha;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderButton(button: Button, origin: Vec2, zoom: number): void {
 | 
					    renderButton(button: Button): void {
 | 
				
			||||||
        this.renderLabel(button, origin, zoom);
 | 
					        this.renderLabel(button);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderSlider(slider: Slider, origin: Vec2, zoom: number): void {
 | 
					    renderSlider(slider: Slider): void {
 | 
				
			||||||
		// Grab the global alpha so we can adjust it for this render
 | 
							// Grab the global alpha so we can adjust it for this render
 | 
				
			||||||
		let previousAlpha = this.ctx.globalAlpha;
 | 
							let previousAlpha = this.ctx.globalAlpha;
 | 
				
			||||||
		this.ctx.globalAlpha = slider.getLayer().getAlpha();
 | 
							this.ctx.globalAlpha = slider.getLayer().getAlpha();
 | 
				
			||||||
| 
						 | 
					@ -82,13 +82,13 @@ export default class UIElementRenderer {
 | 
				
			||||||
        this.ctx.globalAlpha = previousAlpha;
 | 
					        this.ctx.globalAlpha = previousAlpha;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    renderTextInput(textInput: TextInput, origin: Vec2, zoom: number): void {
 | 
					    renderTextInput(textInput: TextInput): void {
 | 
				
			||||||
        // Show a cursor sometimes
 | 
					        // Show a cursor sometimes
 | 
				
			||||||
        if(textInput.focused && textInput.cursorCounter % 60 > 30){
 | 
					        if(textInput.focused && textInput.cursorCounter % 60 > 30){
 | 
				
			||||||
            textInput.text += "|";
 | 
					            textInput.text += "|";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.renderLabel(textInput, origin, zoom);
 | 
					        this.renderLabel(textInput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(textInput.focused){
 | 
					        if(textInput.focused){
 | 
				
			||||||
            if(textInput.cursorCounter % 60 > 30){
 | 
					            if(textInput.cursorCounter % 60 > 30){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ import GameLoop from "../Loop/GameLoop";
 | 
				
			||||||
import SceneManager from "./SceneManager";
 | 
					import SceneManager from "./SceneManager";
 | 
				
			||||||
import Receiver from "../Events/Receiver";
 | 
					import Receiver from "../Events/Receiver";
 | 
				
			||||||
import Emitter from "../Events/Emitter";
 | 
					import Emitter from "../Events/Emitter";
 | 
				
			||||||
import { Renderable, Updateable } from "../DataTypes/Interfaces/Descriptors";
 | 
					import { Updateable } from "../DataTypes/Interfaces/Descriptors";
 | 
				
			||||||
import NavigationManager from "../Pathfinding/NavigationManager";
 | 
					import NavigationManager from "../Pathfinding/NavigationManager";
 | 
				
			||||||
import AIManager from "../AI/AIManager";
 | 
					import AIManager from "../AI/AIManager";
 | 
				
			||||||
import Map from "../DataTypes/Map";
 | 
					import Map from "../DataTypes/Map";
 | 
				
			||||||
| 
						 | 
					@ -22,8 +22,9 @@ import CanvasNode from "../Nodes/CanvasNode";
 | 
				
			||||||
import GameNode from "../Nodes/GameNode";
 | 
					import GameNode from "../Nodes/GameNode";
 | 
				
			||||||
import ArrayUtils from "../Utils/ArrayUtils";
 | 
					import ArrayUtils from "../Utils/ArrayUtils";
 | 
				
			||||||
import RenderingManager from "../Rendering/RenderingManager";
 | 
					import RenderingManager from "../Rendering/RenderingManager";
 | 
				
			||||||
 | 
					import Debug from "../Debug/Debug";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Scene implements Updateable, Renderable {
 | 
					export default class Scene implements Updateable {
 | 
				
			||||||
    /** The size of the game world. */
 | 
					    /** The size of the game world. */
 | 
				
			||||||
    protected worldSize: Vec2;
 | 
					    protected worldSize: Vec2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,6 +165,10 @@ export default class Scene implements Updateable, Renderable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Send the visible set, tilemaps, and uiLayers to the renderer
 | 
					        // Send the visible set, tilemaps, and uiLayers to the renderer
 | 
				
			||||||
        this.renderingManager.render(visibleSet, this.tilemaps, this.uiLayers);
 | 
					        this.renderingManager.render(visibleSet, this.tilemaps, this.uiLayers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let nodes = this.sceneGraph.getAllNodes();
 | 
				
			||||||
 | 
					        this.tilemaps.forEach(tilemap => tilemap.visible && tilemap.debugRender());
 | 
				
			||||||
 | 
					        Debug.setNodes(nodes);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setRunning(running: boolean): void {
 | 
					    setRunning(running: boolean): void {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,6 +83,12 @@ export default abstract class SceneGraph {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	abstract getNodesInRegion(boundary: AABB): Array<CanvasNode>;
 | 
						abstract getNodesInRegion(boundary: AABB): Array<CanvasNode>;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						getAllNodes(): Array<CanvasNode> {
 | 
				
			||||||
 | 
							let arr = new Array<CanvasNode>();
 | 
				
			||||||
 | 
							this.nodeMap.forEach(key => arr.push(this.nodeMap.get(key)));
 | 
				
			||||||
 | 
							return arr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The specific implementation of getting a node at certain coordinates
 | 
						 * The specific implementation of getting a node at certain coordinates
 | 
				
			||||||
	 * @param x 
 | 
						 * @param x 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,6 @@ export default class Walk extends OnGround {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(this.parent.jumpy && (Date.now() - this.time > 500)){
 | 
							if(this.parent.jumpy && (Date.now() - this.time > 500)){
 | 
				
			||||||
			console.log("Jump");
 | 
					 | 
				
			||||||
			this.finished(GoombaStates.JUMP);
 | 
								this.finished(GoombaStates.JUMP);
 | 
				
			||||||
			this.parent.velocity.y = -300;
 | 
								this.parent.velocity.y = -300;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										55
									
								
								src/_DemoClasses/PhysicsTesting/TestScene.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/_DemoClasses/PhysicsTesting/TestScene.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					import Vec2 from "../../DataTypes/Vec2";
 | 
				
			||||||
 | 
					import InputHandler from "../../Input/InputHandler";
 | 
				
			||||||
 | 
					import InputReceiver from "../../Input/InputReceiver";
 | 
				
			||||||
 | 
					import { GraphicType } from "../../Nodes/Graphics/GraphicTypes";
 | 
				
			||||||
 | 
					import BasicPhysicsManager from "../../Physics/BasicPhysicsManager";
 | 
				
			||||||
 | 
					import Scene from "../../Scene/Scene";
 | 
				
			||||||
 | 
					import Color from "../../Utils/Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class TestScene extends Scene {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						startScene(){
 | 
				
			||||||
 | 
							// Opt into a custom physics manager
 | 
				
			||||||
 | 
							this.physicsManager = new BasicPhysicsManager(this.sceneOptions.physics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.addLayer("main");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let player = this.add.graphic(GraphicType.RECT, "main", {position: new Vec2(100, 100), size: new Vec2(100, 100)});
 | 
				
			||||||
 | 
							player.addPhysics();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							player.update = (deltaT: number) => {
 | 
				
			||||||
 | 
								const input = InputReceiver.getInstance()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let xDir = (input.isPressed("a") ? -1 : 0) + (input.isPressed("d") ? 1 : 0);
 | 
				
			||||||
 | 
								let yDir = (input.isPressed("w") ? -1 : 0) + (input.isPressed("s") ? 1 : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let dir = new Vec2(xDir, yDir);
 | 
				
			||||||
 | 
								dir.normalize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if(!dir.isZero()){
 | 
				
			||||||
 | 
									player.move(dir.scale(deltaT * 300));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let block = this.add.graphic(GraphicType.RECT, "main", {position: new Vec2(300, 500), size: new Vec2(100, 100)});
 | 
				
			||||||
 | 
							block.color = Color.CYAN;
 | 
				
			||||||
 | 
							block.addPhysics(block.boundary, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let movingBlock = this.add.graphic(GraphicType.RECT, "main", {position: new Vec2(500, 200), size: new Vec2(100, 100)});
 | 
				
			||||||
 | 
							movingBlock.color = Color.CYAN;
 | 
				
			||||||
 | 
							movingBlock.addPhysics();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let timer = 0;
 | 
				
			||||||
 | 
							let dir = new Vec2(1, 0);
 | 
				
			||||||
 | 
							movingBlock.update = (deltaT: number) => {
 | 
				
			||||||
 | 
								if(timer > 0.5){
 | 
				
			||||||
 | 
									timer = 0;
 | 
				
			||||||
 | 
									dir.scale(-1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								movingBlock.move(dir.scaled(200*deltaT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								timer += deltaT;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -26,16 +26,45 @@ export default class Jump extends PlayerState {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Go up plus some extra
 | 
								// Go up plus some extra
 | 
				
			||||||
			pos.y -= (this.owner.collisionShape.halfSize.y + 10);
 | 
								pos.y -= (this.owner.collisionShape.halfSize.y + 10);
 | 
				
			||||||
			pos = this.parent.tilemap.getColRowAt(pos);
 | 
								pos.x -= 16;
 | 
				
			||||||
			let tile = this.parent.tilemap.getTileAtRowCol(pos);
 | 
								let rowCol = this.parent.tilemap.getColRowAt(pos);
 | 
				
			||||||
 | 
								let tile1 = this.parent.tilemap.getTileAtRowCol(rowCol);
 | 
				
			||||||
 | 
								pos.x += 16;
 | 
				
			||||||
 | 
								rowCol = this.parent.tilemap.getColRowAt(pos);
 | 
				
			||||||
 | 
								let tile2 = this.parent.tilemap.getTileAtRowCol(rowCol);
 | 
				
			||||||
 | 
								pos.x += 16;
 | 
				
			||||||
 | 
								rowCol = this.parent.tilemap.getColRowAt(pos);
 | 
				
			||||||
 | 
								let tile3 = this.parent.tilemap.getTileAtRowCol(rowCol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								let t1 = tile1 === 17;
 | 
				
			||||||
 | 
								let t2 = tile2 === 17;
 | 
				
			||||||
 | 
								let t3 = tile3 === 17;
 | 
				
			||||||
 | 
								let air1 = tile1 === 0;
 | 
				
			||||||
 | 
								let air2 = tile2 === 0;
 | 
				
			||||||
 | 
								let air3 = tile3 === 0;
 | 
				
			||||||
 | 
								let majority = (t1 && t2) || (t1 && t3) || (t2 && t3) || (t1 && t2 && t3);
 | 
				
			||||||
 | 
								let minorityButAir = (t1 && air2 && air3) || (air1 && t2 && air3) || (air1 && air2 && t3);
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// If coin block, change to empty coin block
 | 
								// If coin block, change to empty coin block
 | 
				
			||||||
			if(tile === 17){
 | 
								if(majority || minorityButAir){
 | 
				
			||||||
				this.parent.tilemap.setTileAtRowCol(pos, 18);
 | 
									if(minorityButAir){
 | 
				
			||||||
 | 
										// Get the correct position
 | 
				
			||||||
 | 
										if(t1){
 | 
				
			||||||
 | 
											pos.x -= 32;
 | 
				
			||||||
 | 
										} else if(t2){
 | 
				
			||||||
 | 
											pos.x -= 16;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										rowCol = this.parent.tilemap.getColRowAt(pos);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										pos.x -= 16;
 | 
				
			||||||
 | 
										rowCol = this.parent.tilemap.getColRowAt(pos);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this.parent.tilemap.setTileAtRowCol(rowCol, 18);
 | 
				
			||||||
				this.emitter.fireEvent(MarioEvents.PLAYER_HIT_COIN_BLOCK);
 | 
									this.emitter.fireEvent(MarioEvents.PLAYER_HIT_COIN_BLOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				let tileSize = this.parent.tilemap.getTileSize();
 | 
									let tileSize = this.parent.tilemap.getTileSize();
 | 
				
			||||||
				this.parent.coin.position.copy(pos.scale(tileSize.x, tileSize.y).add(tileSize.scaled(0.5)));
 | 
									this.parent.coin.position.copy(rowCol.scale(tileSize.x, tileSize.y).add(tileSize.scaled(0.5)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Animate collision
 | 
									// Animate collision
 | 
				
			||||||
				this.parent.coin.tweens.add("coin", {
 | 
									this.parent.coin.tweens.add("coin", {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,40 @@
 | 
				
			||||||
  <head>
 | 
					  <head>
 | 
				
			||||||
    <meta charset="UTF-8" />
 | 
					    <meta charset="UTF-8" />
 | 
				
			||||||
    <title>Game</title>
 | 
					    <title>Game</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					      #game-window {
 | 
				
			||||||
 | 
					        position: relative;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      #game-canvas {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        position: absolute;
 | 
				
			||||||
 | 
					        top: 0px;
 | 
				
			||||||
 | 
					        left: 0px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      #debug-canvas {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        position: absolute;
 | 
				
			||||||
 | 
					        top: 0px;
 | 
				
			||||||
 | 
					        left: 0px;
 | 
				
			||||||
 | 
					        pointer-events: none;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
  </head>
 | 
					  </head>
 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <div style="display: flex; flex-direction: row;">
 | 
					    <div style="display: flex; flex-direction: row;">
 | 
				
			||||||
 | 
					      <!-- The main window of the game. This contains the rendered game and any debug text -->
 | 
				
			||||||
 | 
					      <div id="game-window">
 | 
				
			||||||
 | 
					        <!-- This is the canvas where the actual game is rendered -->
 | 
				
			||||||
        <canvas id="game-canvas"></canvas>
 | 
					        <canvas id="game-canvas"></canvas>
 | 
				
			||||||
 | 
					        <!-- This is the canvas where the debug text and graphics are rendered -->
 | 
				
			||||||
 | 
					        <canvas id="debug-canvas"></canvas>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <!-- This contains stats about the game for development purposes, such as the average update time -->
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
        <canvas id="stats-canvas"></canvas>
 | 
					        <canvas id="stats-canvas"></canvas>
 | 
				
			||||||
        <select name="Display" id="chart-option">
 | 
					        <select name="Display" id="chart-option">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ import GameLoop from "./Loop/GameLoop";
 | 
				
			||||||
import {} from "./index";
 | 
					import {} from "./index";
 | 
				
			||||||
import MainMenu from "./_DemoClasses/Mario/MainMenu";
 | 
					import MainMenu from "./_DemoClasses/Mario/MainMenu";
 | 
				
			||||||
import Level1 from "./_DemoClasses/Mario/Level1";
 | 
					import Level1 from "./_DemoClasses/Mario/Level1";
 | 
				
			||||||
 | 
					import TestScene from "./_DemoClasses/PhysicsTesting/TestScene";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function main(){
 | 
					function main(){
 | 
				
			||||||
    // Create the game object
 | 
					    // Create the game object
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user