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