added better documentation to Nodes folder
This commit is contained in:
		
							parent
							
								
									ea33e71619
								
							
						
					
					
						commit
						3661ee3ada
					
				|  | @ -13,6 +13,9 @@ export interface Unique { | |||
| export interface Positioned { | ||||
|     /** The center of this object. */ | ||||
|     position: Vec2; | ||||
| 
 | ||||
|     /** The center of this object relative to the viewport. */ | ||||
|     readonly relativePosition: Vec2; | ||||
| } | ||||
| 
 | ||||
| export interface Region { | ||||
|  | @ -22,6 +25,9 @@ export interface Region { | |||
|     /** The scale of this object. */ | ||||
|     scale: Vec2; | ||||
| 
 | ||||
|     /** The size of the object taking into account the zoom and scale */ | ||||
|     readonly sizeWithZoom: Vec2; | ||||
| 
 | ||||
|     /** The bounding box of this object. */ | ||||
|     boundary: AABB; | ||||
| } | ||||
|  | @ -95,13 +101,13 @@ export interface Physical { | |||
|      * Tells the physics engine to handle a move by this object. | ||||
|      * @param velocity The velocity with which to move the object. | ||||
|      */ | ||||
|     move: (velocity: Vec2) => void; | ||||
|     move(velocity: Vec2): void; | ||||
| 
 | ||||
|     /** | ||||
|      * The move actually done by the physics engine after collision checks are done. | ||||
|      * @param velocity The velocity with which the object will move. | ||||
|      */ | ||||
|     finishMove: () => void; | ||||
|     finishMove(): void; | ||||
|      | ||||
|     /** | ||||
|      * Adds physics to this object | ||||
|  | @ -109,20 +115,20 @@ export interface Physical { | |||
|      * @param isCollidable Whether this object will be able to collide with other objects | ||||
|      * @param isStatic Whether this object will be static or not | ||||
|      */ | ||||
|     addPhysics: (collisionShape?: Shape, colliderOffset?: Vec2, isCollidable?: boolean, isStatic?: boolean) => void; | ||||
|     addPhysics(collisionShape?: Shape, colliderOffset?: Vec2, isCollidable?: boolean, isStatic?: boolean): void; | ||||
| 
 | ||||
|     /** | ||||
|      * Adds a trigger to this object for a specific group | ||||
|      * @param group The name of the group that activates the trigger | ||||
|      * @param eventType The name of the event to send when this trigger is activated | ||||
|      */ | ||||
|     addTrigger: (group: string, eventType: string) => void; | ||||
|     addTrigger(group: string, eventType: string): void; | ||||
|      | ||||
|     /** | ||||
|      * Sets the physics layer of this node | ||||
|      * @param layer The name of the layer | ||||
|      */ | ||||
|     setPhysicsLayer: (layer: String) => void; | ||||
|     setPhysicsLayer(layer: string): void; | ||||
| 
 | ||||
|     /** | ||||
|      * If used before "move()", it will tell you the velocity of the node after its last movement | ||||
|  | @ -148,22 +154,41 @@ export interface Actor { | |||
|     /** The id of the actor according to the AIManager */ | ||||
|     actorId: number; | ||||
| 
 | ||||
|     /** The path that navigation will follow */ | ||||
|     path: NavigationPath; | ||||
| 
 | ||||
|     /** A flag representing whether or not the actor is currently pathfinding */ | ||||
|     pathfinding: boolean; | ||||
| 
 | ||||
|     addAI: <T extends AI>(ai: string | (new () => T), options: Record<string, any>) => void; | ||||
|     /** | ||||
|      * Adds an AI to this Actor. | ||||
|      * @param ai The name of the AI, or the actual AI, to add to the Actor. | ||||
|      * @param options The options to give to the AI for initialization. | ||||
|      */ | ||||
|     addAI<T extends AI>(ai: string | (new () => T), options: Record<string, any>): void; | ||||
| 
 | ||||
|     setAIActive: (active: boolean) => void; | ||||
|     /** | ||||
|      * Sets the AI to start/stop for this Actor. | ||||
|      * @param active The new active status of the AI. | ||||
|      */ | ||||
|     setAIActive(active: boolean): void; | ||||
| } | ||||
| 
 | ||||
| export interface Navigable { | ||||
|     getNavigationPath: (fromPosition: Vec2, toPosition: Vec2) => NavigationPath; | ||||
|     /** | ||||
|      * Gets a new navigation path based on this Navigable object. | ||||
|      * @param fromPosition The position to start navigation from. | ||||
|      * @param toPosition The position to navigate to. | ||||
|      */ | ||||
|     getNavigationPath(fromPosition: Vec2, toPosition: Vec2): NavigationPath; | ||||
| } | ||||
| 
 | ||||
| export interface Updateable { | ||||
|     /** Updates this object. */ | ||||
|     update: (deltaT: number) => void; | ||||
|     /** | ||||
|      * Updates this object. | ||||
|      * @param deltaT The timestep of the update. | ||||
|      */ | ||||
|     update(deltaT: number): void; | ||||
| } | ||||
| 
 | ||||
| export interface DebugRenderable { | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ import MathUtils from "../Utils/MathUtils"; | |||
| export default class Vec2 { | ||||
| 
 | ||||
| 	// Store x and y in an array
 | ||||
| 	/** The array that stores the actual vector values */ | ||||
| 	private vec: Float32Array; | ||||
| 
 | ||||
| 	/**	 | ||||
|  | @ -13,6 +14,11 @@ export default class Vec2 { | |||
| 	 */ | ||||
| 	private onChange: Function = () => {}; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Creates a new Vec2 | ||||
| 	 * @param x The x value of the vector | ||||
| 	 * @param y The y value of the vector | ||||
| 	 */ | ||||
| 	constructor(x: number = 0, y: number = 0) { | ||||
| 		this.vec = new Float32Array(2); | ||||
| 		this.vec[0] = x; | ||||
|  | @ -58,6 +64,18 @@ export default class Vec2 { | |||
| 		return new Vec2(0, -1); | ||||
| 	} | ||||
| 
 | ||||
| 	static get DOWN() { | ||||
| 		return new Vec2(0, 1); | ||||
| 	} | ||||
| 
 | ||||
| 	static get LEFT() { | ||||
| 		return new Vec2(-1, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	static get RIGHT() { | ||||
| 		return new Vec2(1, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * The squared magnitude of the vector | ||||
| 	 */ | ||||
|  | @ -86,7 +104,7 @@ export default class Vec2 { | |||
| 	/** | ||||
| 	 * Returns a new vector that is the normalized version of this one | ||||
| 	 */ | ||||
| 	normalized(){ | ||||
| 	normalized(): Vec2 { | ||||
| 		let mag = this.mag(); | ||||
| 		return new Vec2(this.x/mag, this.y/mag); | ||||
| 	} | ||||
|  | @ -94,7 +112,7 @@ export default class Vec2 { | |||
| 	/** | ||||
| 	 * Sets the x and y elements of this vector to zero | ||||
| 	 */ | ||||
| 	zero(){ | ||||
| 	zero(): Vec2 { | ||||
| 		return this.set(0, 0); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -335,10 +353,19 @@ export default class Vec2 { | |||
| 		this.onChange = f; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Gets the function that is called whenever this vector is changed | ||||
| 	 */ | ||||
| 	getOnChange(): string { | ||||
| 		return this.onChange.toString(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Performs linear interpolation between two vectors | ||||
| 	 * @param a The first vector | ||||
| 	 * @param b The second vector | ||||
| 	 * @param t The time of the lerp, with 0 being vector A, and 1 being vector B | ||||
| 	 */ | ||||
| 	static lerp(a: Vec2, b: Vec2, t: number): Vec2 { | ||||
| 		return new Vec2(MathUtils.lerp(a.x, b.x, t), MathUtils.lerp(a.y, b.y, t)); | ||||
| 	} | ||||
|  |  | |||
|  | @ -13,8 +13,9 @@ export default abstract class CanvasNode extends GameNode implements Region { | |||
| 	private _scale: Vec2; | ||||
| 	private _boundary: AABB; | ||||
| 
 | ||||
| 	visible = true; | ||||
| 
 | ||||
| 	/** A flag for whether or not the CanvasNode is visible */ | ||||
| 	visible: boolean = true; | ||||
| 	 | ||||
| 	constructor(){ | ||||
| 		super(); | ||||
| 		this._size = new Vec2(0, 0); | ||||
|  | @ -55,19 +56,24 @@ export default abstract class CanvasNode extends GameNode implements Region { | |||
| 		this.scale.y = value; | ||||
| 	} | ||||
| 
 | ||||
| 	// @override
 | ||||
| 	protected positionChanged(): void { | ||||
| 		super.positionChanged(); | ||||
| 		this.updateBoundary(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** Called if the size vector is changed or replaced. */ | ||||
| 	protected sizeChanged(): void { | ||||
| 		this.updateBoundary(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** Called if the scale vector is changed or replaced */ | ||||
| 	protected scaleChanged(): void { | ||||
| 		this.updateBoundary(); | ||||
| 	} | ||||
| 
 | ||||
| 	// @docIgnore
 | ||||
| 	/** Called if the position, size, or scale of the CanvasNode is changed. Updates the boundary. */ | ||||
| 	private updateBoundary(): void { | ||||
| 		this._boundary.center.set(this.position.x, this.position.y); | ||||
| 		this._boundary.halfSize.set(this.size.x*this.scale.x/2, this.size.y*this.scale.y/2); | ||||
|  | @ -85,13 +91,15 @@ export default abstract class CanvasNode extends GameNode implements Region { | |||
| 
 | ||||
| 	/** | ||||
| 	 * Returns true if the point (x, y) is inside of this canvas object | ||||
| 	 * @param x  | ||||
| 	 * @param y  | ||||
| 	 * @param x The x position of the point | ||||
| 	 * @param y The y position of the point | ||||
| 	 * @returns A flag representing whether or not this node contains the point. | ||||
| 	 */ | ||||
| 	contains(x: number, y: number): boolean { | ||||
| 		return this._boundary.containsPoint(new Vec2(x, y)); | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	debugRender(): void { | ||||
| 		super.debugRender(); | ||||
| 		let color = this.isColliding ? Color.RED : Color.GREEN; | ||||
|  |  | |||
|  | @ -14,7 +14,8 @@ 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. | ||||
|  * To construct GameNodes, see the @reference[Scene] documentation. | ||||
|  */ | ||||
| export default abstract class GameNode implements Positioned, Unique, Updateable, Physical, Actor, DebugRenderable { | ||||
| 	/*---------- POSITIONED ----------*/ | ||||
|  | @ -52,15 +53,24 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 	pathfinding: boolean = false; | ||||
| 
 | ||||
| 	/*---------- GENERAL ----------*/ | ||||
| 	/** An reference to the user input handler. This allows subclasses to easily access information about user input. */ | ||||
| 	protected input: InputReceiver; | ||||
| 	/** An event receiver. */ | ||||
| 	protected receiver: Receiver; | ||||
| 	/** An event emitter. */ | ||||
| 	protected emitter: Emitter; | ||||
| 	/** A reference to the scene this GameNode is a part of. */ | ||||
| 	protected scene: Scene; | ||||
| 	/** The visual layer this GameNode resides in. */ | ||||
| 	protected layer: Layer; | ||||
| 	/** A utility that allows the use of tweens on this GameNode */ | ||||
| 	tweens: TweenManager; | ||||
| 	/** A tweenable property for rotation. Does not affect the bounding box of this GameNode - Only rendering. */ | ||||
| 	rotation: number; | ||||
| 	/** The opacity value of this GameNode */ | ||||
| 	alpha: number; | ||||
| 
 | ||||
| 	// Constructor docs are ignored, as the user should NOT create new GameNodes with a raw constructor
 | ||||
| 	constructor(){ | ||||
| 		this.input = InputReceiver.getInstance(); | ||||
| 		this._position = new Vec2(0, 0); | ||||
|  | @ -105,18 +115,20 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 	} | ||||
| 
 | ||||
| 	/*---------- PHYSICAL ----------*/ | ||||
| 	// @implemented
 | ||||
| 	/** | ||||
|      * @param velocity The velocity with which to move the object. | ||||
|      */ | ||||
| 	move = (velocity: Vec2): void => { | ||||
| 	move(velocity: Vec2): void { | ||||
| 		this.moving = true; | ||||
| 		this._velocity = velocity; | ||||
| 	}; | ||||
| 
 | ||||
| 	// @implemented
 | ||||
|     /** | ||||
|      * @param velocity The velocity with which the object will move. | ||||
|      */ | ||||
| 	finishMove = (): void => { | ||||
| 	finishMove(): void { | ||||
| 		this.moving = false; | ||||
| 		this.position.add(this._velocity); | ||||
| 		if(this.pathfinding){ | ||||
|  | @ -124,13 +136,15 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	/** | ||||
| 	 * @param collisionShape The collider for this object. If this has a region (implements Region), | ||||
| 	 * it will be used when no collision shape is specified (or if collision shape is null). | ||||
| 	 * @param isCollidable Whether this is collidable or not. True by default. | ||||
| 	 * @param isStatic Whether this is static or not. False by default | ||||
| 	 */ | ||||
| 	addPhysics = (collisionShape?: Shape, colliderOffset?: Vec2, isCollidable: boolean = true, isStatic: boolean = false): void => { | ||||
| 	addPhysics(collisionShape?: Shape, colliderOffset?: Vec2, isCollidable: boolean = true, isStatic: boolean = false): void { | ||||
| 		// Initialize the physics variables
 | ||||
| 		this.hasPhysics = true; | ||||
| 		this.moving = false; | ||||
| 		this.onGround = false; | ||||
|  | @ -147,6 +161,7 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		this.collidedWithTilemap = false; | ||||
| 		this.physicsLayer = -1; | ||||
| 
 | ||||
| 		// Set the collision shape if provided, or simply use the the region if there is one.
 | ||||
| 		if(collisionShape){ | ||||
| 			this.collisionShape = collisionShape; | ||||
| 		} else if (isRegion(this)) { | ||||
|  | @ -156,29 +171,39 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 			throw "No collision shape specified for physics object." | ||||
| 		} | ||||
| 
 | ||||
| 		// If we were provided with a collider offset, set it. Otherwise there is no offset, so use the zero vector
 | ||||
| 		if(colliderOffset){ | ||||
| 			this.colliderOffset = colliderOffset; | ||||
| 		} else { | ||||
| 			this.colliderOffset = Vec2.ZERO; | ||||
| 		} | ||||
| 
 | ||||
| 		// Initialize the swept rect
 | ||||
| 		this.sweptRect = this.collisionShape.getBoundingRect(); | ||||
| 
 | ||||
| 		// Register the object with physics
 | ||||
| 		this.scene.getPhysicsManager().registerObject(this); | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	/** | ||||
| 	 * @param group The name of the group that will activate the trigger | ||||
| 	 * @param eventType The type of this event to send when this trigger is activated | ||||
| 	 */ | ||||
|     addTrigger = (group: string, eventType: string): void => { | ||||
|     addTrigger(group: string, eventType: string): void { | ||||
| 		this.isTrigger = true; | ||||
| 		this.triggers.add(group, eventType); | ||||
| 	}; | ||||
| 
 | ||||
| 	setPhysicsLayer = (layer: string): void => { | ||||
| 	// @implemented
 | ||||
| 	/** | ||||
| 	 * @param layer The physics layer this node should belong to | ||||
| 	 */ | ||||
| 	setPhysicsLayer(layer: string): void { | ||||
| 		this.scene.getPhysicsManager().setLayer(this, layer); | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemened
 | ||||
| 	getLastVelocity(): Vec2 { | ||||
| 		return this._velocity; | ||||
| 	} | ||||
|  | @ -198,6 +223,7 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		this.aiActive = true; | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	addAI<T extends AI>(ai: string | (new () => T), options?: Record<string, any>): void { | ||||
| 		if(!this._ai){ | ||||
| 			this.scene.getAIManager().registerActor(this); | ||||
|  | @ -214,6 +240,7 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		this.aiActive = true; | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	setAIActive(active: boolean): void { | ||||
| 		this.aiActive = active; | ||||
| 	} | ||||
|  | @ -240,7 +267,10 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		this.scene = scene; | ||||
| 	} | ||||
| 
 | ||||
| 	/** Gets the scene this object is in. */ | ||||
| 	/** | ||||
| 	 * Gets the scene this object is in.  | ||||
| 	 * @returns The scene this object belongs to | ||||
| 	*/ | ||||
| 	getScene(): Scene { | ||||
| 		return this.scene; | ||||
| 	} | ||||
|  | @ -253,24 +283,30 @@ export default abstract class GameNode implements Positioned, Unique, Updateable | |||
| 		this.layer = layer; | ||||
| 	} | ||||
| 
 | ||||
| 	/** Returns the layer this object is on. */ | ||||
| 	/** | ||||
| 	 * Returns the layer this object is on. | ||||
| 	 * @returns This layer this object is on. | ||||
| 	*/ | ||||
| 	getLayer(): Layer { | ||||
| 		return this.layer; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Called if the position vector is modified or replaced | ||||
| 	 */ | ||||
| 	/** Called if the position vector is modified or replaced */ | ||||
| 	protected positionChanged(): void { | ||||
| 		if(this.hasPhysics){ | ||||
| 			this.collisionShape.center = this.position.clone().add(this.colliderOffset); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Updates this GameNode | ||||
| 	 * @param deltaT The timestep of the update. | ||||
| 	 */ | ||||
| 	update(deltaT: number): void { | ||||
| 		this.tweens.update(deltaT); | ||||
| 	} | ||||
| 
 | ||||
| 	// @implemented
 | ||||
| 	debugRender(): void { | ||||
| 		let color = this.isColliding ? Color.RED : Color.GREEN; | ||||
| 		Debug.drawPoint(this.relativePosition, color); | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import Color from "../Utils/Color"; | |||
|  * The representation of a game object that doesn't rely on any resources to render - it is drawn to the screen by the canvas | ||||
|  */ | ||||
| export default abstract class Graphic extends CanvasNode { | ||||
| 
 | ||||
|     /** The color of the Graphic */ | ||||
|     color: Color; | ||||
| 
 | ||||
|     constructor(){ | ||||
|  | @ -13,6 +13,11 @@ export default abstract class Graphic extends CanvasNode { | |||
|         this.color = Color.RED; | ||||
|     } | ||||
| 
 | ||||
|     // @deprecated
 | ||||
|     /** | ||||
|      * Sets the color of the Graphic. DEPRECATED | ||||
|      * @param color The new color of the Graphic. | ||||
|      */ | ||||
|     setColor(color: Color){ | ||||
|         this.color = color; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import Graphic from "../Graphic"; | ||||
| import Vec2 from "../../DataTypes/Vec2"; | ||||
| 
 | ||||
| /** A basic point to be drawn on the screen. */ | ||||
| export default class Point extends Graphic { | ||||
| 
 | ||||
|     constructor(position: Vec2){ | ||||
|  |  | |||
|  | @ -2,10 +2,14 @@ import Graphic from "../Graphic"; | |||
| import Vec2 from "../../DataTypes/Vec2"; | ||||
| import Color from "../../Utils/Color"; | ||||
| 
 | ||||
| /** A basic rectangle to be drawn on the screen. */ | ||||
| export default class Rect extends Graphic { | ||||
| 
 | ||||
|     /** The border color of the Rect */ | ||||
|     borderColor: Color; | ||||
|     protected borderWidth: number; | ||||
| 
 | ||||
|     /** The width of the border */ | ||||
|     borderWidth: number; | ||||
| 
 | ||||
|     constructor(position: Vec2, size: Vec2){ | ||||
|         super(); | ||||
|  | @ -19,16 +23,17 @@ export default class Rect extends Graphic { | |||
|      * Sets the border color of this rectangle | ||||
|      * @param color The border color | ||||
|      */ | ||||
|     setBorderColor(color: Color){ | ||||
|     setBorderColor(color: Color): void { | ||||
|         this.borderColor = color; | ||||
|     } | ||||
| 
 | ||||
|     // @deprecated
 | ||||
|     getBorderColor(): Color { | ||||
|         return this.borderColor; | ||||
|     } | ||||
| 
 | ||||
|     /**Sets the border width of this rectangle | ||||
|      *  | ||||
|     /** | ||||
|      * Sets the border width of this rectangle | ||||
|      * @param width The width of the rectangle in pixels | ||||
|      */ | ||||
|     setBorderWidth(width: number){ | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ import AnimationManager from "../../Rendering/Animations/AnimationManager"; | |||
| import Spritesheet from "../../DataTypes/Spritesheet"; | ||||
| import Vec2 from "../../DataTypes/Vec2"; | ||||
| 
 | ||||
| /** An sprite with specified animation frames. */ | ||||
| export default class AnimatedSprite extends Sprite { | ||||
|     /** The number of columns in this sprite sheet */ | ||||
|     protected numCols: number; | ||||
|  | @ -29,6 +30,11 @@ export default class AnimatedSprite extends Sprite { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the image offset for the current index of animation | ||||
|      * @param index The index we're at in the animation | ||||
|      * @returns A Vec2 containing the image offset | ||||
|      */ | ||||
|     getAnimationOffset(index: number): Vec2 { | ||||
|         return new Vec2((index % this.numCols) * this.size.x, Math.floor(index / this.numCols) * this.size.y); | ||||
|     } | ||||
|  |  | |||
|  | @ -6,9 +6,13 @@ import Vec2 from "../../DataTypes/Vec2"; | |||
|  * The representation of a sprite - an in-game image | ||||
|  */ | ||||
| export default class Sprite extends CanvasNode { | ||||
|     /** The id of the image from the resourceManager */ | ||||
|     imageId: string; | ||||
|     /** The offset of the sprite in an atlas image */ | ||||
|     imageOffset: Vec2; | ||||
|     /** Whether or not the x-axis should be inverted on render */ | ||||
|     invertX: boolean; | ||||
|     /** Whether or not the y-axis should be inverted on render */ | ||||
|     invertY: boolean; | ||||
| 
 | ||||
|     constructor(imageId: string){ | ||||
|  | @ -23,7 +27,7 @@ export default class Sprite extends CanvasNode { | |||
| 
 | ||||
|     /** | ||||
|      * Sets the offset of the sprite from (0, 0) in the image's coordinates | ||||
|      * @param offset  | ||||
|      * @param offset The offset of the sprite from (0, 0) in image coordinates | ||||
|      */ | ||||
|     setImageOffset(offset: Vec2): void { | ||||
|         this.imageOffset = offset; | ||||
|  |  | |||
|  | @ -7,10 +7,19 @@ import CanvasNode from "./CanvasNode"; | |||
|  * The representation of a tilemap - this can consist of a combination of tilesets in one layer | ||||
|  */ | ||||
| export default abstract class Tilemap extends CanvasNode { | ||||
|     /** An array of the tilesets that this tilemap uses */ | ||||
|     protected tilesets: Array<Tileset>; | ||||
| 
 | ||||
|     /** The size of a tile in this tilemap */ | ||||
|     protected tileSize: Vec2; | ||||
| 
 | ||||
|     /** An array of tile data */ | ||||
|     protected data: Array<number>; | ||||
| 
 | ||||
|     /** An array of tile collision data */ | ||||
|     protected collisionMap: Array<boolean>; | ||||
| 
 | ||||
|     /** The name of the tilemap */ | ||||
|     name: string; | ||||
| 
 | ||||
|     // TODO: Make this no longer be specific to Tiled
 | ||||
|  | @ -37,6 +46,7 @@ export default abstract class Tilemap extends CanvasNode { | |||
| 
 | ||||
|     /** | ||||
|      * Returns an array of the tilesets associated with this tilemap | ||||
|      * @returns An array of all of the tilesets assocaited with this tilemap. | ||||
|      */ | ||||
|     getTilesets(): Tileset[] { | ||||
|         return this.tilesets; | ||||
|  | @ -44,18 +54,25 @@ export default abstract class Tilemap extends CanvasNode { | |||
| 
 | ||||
|     /** | ||||
|      * Returns the size of tiles in this tilemap as they appear in the game world after scaling | ||||
|      * @returns A vector containing the size of tiles in this tilemap as they appear in the game world after scaling. | ||||
|      */ | ||||
|     getTileSize(): Vec2 { | ||||
|         return this.tileSize.scaled(this.scale.x, this.scale.y); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the tile size taking zoom into account | ||||
|      * @returns The tile size with zoom | ||||
|     */ | ||||
|     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 => { | ||||
|         this.scene.getPhysicsManager().registerTilemap(this); | ||||
|     } | ||||
|  | @ -63,18 +80,21 @@ export default abstract class Tilemap extends CanvasNode { | |||
|     /** | ||||
|      * Returns the value of the tile at the specified position | ||||
|      * @param worldCoords The position in world coordinates | ||||
|      * @returns A number that represents the data value of the tile at the specified world position. | ||||
|      */ | ||||
|     abstract getTileAtWorldPosition(worldCoords: Vec2): number; | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the world position of the top left corner of the tile at the specified index | ||||
|      * @param index  | ||||
|      * @param index The index of the tile in the tileData array | ||||
|      * @returns The world position of the tile at the specified index | ||||
|      */ | ||||
|     abstract getTileWorldPosition(index: number): Vec2; | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the value of the tile at the specified index | ||||
|      * @param index | ||||
|      * @param index The index of the tile in the tileData array | ||||
|      * @returns The value of the tile in the tileData array | ||||
|      */ | ||||
|     abstract getTile(index: number): number; | ||||
| 
 | ||||
|  | @ -85,9 +105,11 @@ export default abstract class Tilemap extends CanvasNode { | |||
|      */ | ||||
|     abstract setTile(index: number, type: number): void; | ||||
| 
 | ||||
|     // TODO: This shouldn't use tiled data specifically - it should be more general
 | ||||
|     /** | ||||
|      * Sets up the tileset using the data loaded from file | ||||
|      * @param tilemapData The tilemap data from file | ||||
|      * @param layer The layer data from file | ||||
|      */ | ||||
|     // TODO: This shouldn't use tiled data specifically - it should be more general
 | ||||
|     protected abstract parseTilemapData(tilemapData: TiledTilemapData, layer: TiledLayerData): void; | ||||
| } | ||||
|  | @ -8,15 +8,12 @@ import Color from "../../Utils/Color"; | |||
|  * The representation of an orthogonal tilemap - i.e. a top down or platformer tilemap | ||||
|  */ | ||||
| export default class OrthogonalTilemap extends Tilemap { | ||||
| 
 | ||||
|     /** The number of columns in the tilemap */ | ||||
|     protected numCols: number; | ||||
|     /** The number of rows in the tilemap */ | ||||
|     protected numRows: number; | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the tilemap data loaded from the json file. DOES NOT process images automatically - the ResourceManager class does this while loading tilemaps | ||||
|      * @param tilemapData  | ||||
|      * @param layer  | ||||
|      */ | ||||
|     // @override
 | ||||
|     protected parseTilemapData(tilemapData: TiledTilemapData, layer: TiledLayerData): void { | ||||
|         // The size of the tilemap in local space
 | ||||
|         this.numCols = tilemapData.width; | ||||
|  | @ -47,10 +44,19 @@ export default class OrthogonalTilemap extends Tilemap { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the dimensions of the tilemap | ||||
|      * @returns A Vec2 containing the number of columns and the number of rows in the tilemap. | ||||
|      */ | ||||
|     getDimensions(): Vec2 { | ||||
|         return new Vec2(this.numCols, this.numRows); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the data value of the tile at the specified world position | ||||
|      * @param worldCoords The coordinates in world space | ||||
|      * @returns The data value of the tile | ||||
|      */ | ||||
|     getTileAtWorldPosition(worldCoords: Vec2): number { | ||||
|         let localCoords = this.getColRowAt(worldCoords); | ||||
|         return this.getTileAtRowCol(localCoords); | ||||
|  | @ -58,7 +64,8 @@ export default class OrthogonalTilemap extends Tilemap { | |||
| 
 | ||||
|     /** | ||||
|      * Get the tile at the specified row and column | ||||
|      * @param rowCol  | ||||
|      * @param rowCol The coordinates in tilemap space | ||||
|      * @returns The data value of the tile | ||||
|      */ | ||||
|     getTileAtRowCol(rowCol: Vec2): number { | ||||
|         if(rowCol.x < 0 || rowCol.x >= this.numCols || rowCol.y < 0 || rowCol.y >= this.numRows){ | ||||
|  | @ -68,6 +75,11 @@ export default class OrthogonalTilemap extends Tilemap { | |||
|         return this.data[rowCol.y * this.numCols + rowCol.x]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the world position of the tile at the specified index | ||||
|      * @param index The index of the tile | ||||
|      * @returns A Vec2 containing the world position of the tile | ||||
|      */ | ||||
|     getTileWorldPosition(index: number): Vec2 { | ||||
|         // Get the local position
 | ||||
|         let col = index % this.numCols; | ||||
|  | @ -80,14 +92,29 @@ export default class OrthogonalTilemap extends Tilemap { | |||
|         return new Vec2(x, y); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the data value of the tile at the specified index | ||||
|      * @param index The index of the tile | ||||
|      * @returns The data value of the tile | ||||
|      */ | ||||
|     getTile(index: number): number { | ||||
|         return this.data[index]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the tile at the specified index | ||||
|      * @param index The index of the tile | ||||
|      * @param type The new data value of the tile | ||||
|      */ | ||||
|     setTile(index: number, type: number): void { | ||||
|         this.data[index] = type; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the tile at the specified row and column | ||||
|      * @param rowCol The position of the tile in tilemap space | ||||
|      * @param type The new data value of the tile | ||||
|      */ | ||||
|     setTileAtRowCol(rowCol: Vec2, type: number): void { | ||||
|         let index = rowCol.y * this.numCols + rowCol.x; | ||||
|         this.setTile(index, type); | ||||
|  | @ -95,8 +122,9 @@ export default class OrthogonalTilemap extends Tilemap { | |||
| 
 | ||||
|     /** | ||||
|      * Returns true if the tile at the specified row and column of the tilemap is collidable | ||||
|      * @param indexOrCol  | ||||
|      * @param row  | ||||
|      * @param indexOrCol The index of the tile or the column it is in | ||||
|      * @param row The row the tile is in | ||||
|      * @returns A flag representing whether or not the tile is collidable. | ||||
|      */ | ||||
|     isTileCollidable(indexOrCol: number, row?: number): boolean { | ||||
|         // The value of the tile
 | ||||
|  | @ -123,7 +151,8 @@ export default class OrthogonalTilemap extends Tilemap { | |||
| 
 | ||||
|     /** | ||||
|      * Takes in world coordinates and returns the row and column of the tile at that position | ||||
|      * @param worldCoords  | ||||
|      * @param worldCoords The coordinates of the potential tile in world space | ||||
|      * @returns A Vec2 containing the coordinates of the potential tile in tilemap space | ||||
|      */ | ||||
|     getColRowAt(worldCoords: Vec2): Vec2 { | ||||
|         let col = Math.floor(worldCoords.x / this.tileSize.x / this.scale.x); | ||||
|  | @ -132,8 +161,10 @@ export default class OrthogonalTilemap extends Tilemap { | |||
|         return new Vec2(col, row); | ||||
|     } | ||||
| 
 | ||||
|     // @override
 | ||||
|     update(deltaT: number): void {} | ||||
| 
 | ||||
|     // @override
 | ||||
|     debugRender(){ | ||||
|         let tileSize = this.getTileSizeWithZoom(); | ||||
|         let origin = this.relativePosition.sub(this.sizeWithZoom); | ||||
|  |  | |||
|  | @ -6,24 +6,39 @@ import Vec2 from "../DataTypes/Vec2"; | |||
|  * The representation of a UIElement - the parent class of things like buttons | ||||
|  */ | ||||
| export default abstract class UIElement extends CanvasNode { | ||||
| 	// Style attributes
 | ||||
| 	// Style attributes - TODO - abstract this into a style object/interface
 | ||||
| 	/** The backgound color */ | ||||
| 	backgroundColor: Color; | ||||
| 	/** The border color */ | ||||
| 	borderColor: Color; | ||||
| 	/** The border radius */ | ||||
| 	borderRadius: number; | ||||
| 	/** The border width */ | ||||
| 	borderWidth: number; | ||||
| 	/** The padding */ | ||||
| 	padding: Vec2; | ||||
| 
 | ||||
| 	// EventAttributes
 | ||||
| 	/** The reaction of this UIElement on a click */ | ||||
| 	onClick: Function; | ||||
| 	/** The event propagated on click */ | ||||
| 	onClickEventId: string; | ||||
| 	/** The reaction to the release of a click */ | ||||
| 	onRelease: Function; | ||||
| 	/** The event propagated on the release of a click */ | ||||
| 	onReleaseEventId: string; | ||||
| 	/** The reaction when a mouse enters this UIElement */ | ||||
| 	onEnter: Function; | ||||
| 	/** The event propagated when a mouse enters this UIElement */ | ||||
| 	onEnterEventId: string; | ||||
| 	/** The reaction when a mouse leaves this UIElement */ | ||||
| 	onLeave: Function; | ||||
| 	/** The event propogated when a mouse leaves this UIElement */ | ||||
| 	onLeaveEventId: string; | ||||
| 
 | ||||
| 	/** Whether or not this UIElement is currently clicked on */ | ||||
| 	protected isClicked: boolean; | ||||
| 	/** Whether or not this UIElement is currently hovered over */ | ||||
| 	protected isEntered: boolean; | ||||
| 
 | ||||
| 	constructor(position: Vec2){ | ||||
|  | @ -50,10 +65,12 @@ export default abstract class UIElement extends CanvasNode { | |||
| 		this.isEntered = false; | ||||
| 	} | ||||
| 
 | ||||
| 	// @deprecated
 | ||||
| 	setBackgroundColor(color: Color): void { | ||||
| 		this.backgroundColor = color; | ||||
| 	} | ||||
| 
 | ||||
| 	// @deprecated
 | ||||
| 	setPadding(padding: Vec2): void { | ||||
| 		this.padding.copy(padding); | ||||
| 	} | ||||
|  | @ -116,6 +133,7 @@ export default abstract class UIElement extends CanvasNode { | |||
| 
 | ||||
| 	/** | ||||
| 	 * Overridable method for calculating background color - useful for elements that want to be colored on different after certain events | ||||
| 	 * @returns The background color of the UIElement | ||||
| 	 */ | ||||
| 	calculateBackgroundColor(): string { | ||||
| 		return this.backgroundColor.toStringRGBA(); | ||||
|  | @ -123,6 +141,7 @@ export default abstract class UIElement extends CanvasNode { | |||
| 
 | ||||
| 	/** | ||||
| 	 * Overridable method for calculating border color - useful for elements that want to be colored on different after certain events | ||||
| 	 * @returns The border color of the UIElement | ||||
| 	 */ | ||||
| 	calculateBorderColor(): string { | ||||
| 		return this.borderColor.toStringRGBA(); | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import Label from "./Label"; | |||
| import Color from "../../Utils/Color"; | ||||
| import Vec2 from "../../DataTypes/Vec2"; | ||||
| 
 | ||||
| /** A clickable button UIElement */ | ||||
| export default class Button extends Label { | ||||
| 
 | ||||
| 	constructor(position: Vec2, text: string){ | ||||
|  | @ -12,6 +13,7 @@ export default class Button extends Label { | |||
| 		this.textColor = new Color(255, 255, 255); | ||||
| 	} | ||||
| 
 | ||||
| 	// @override
 | ||||
| 	calculateBackgroundColor(): string { | ||||
| 		// Change the background color if clicked or hovered
 | ||||
| 		if(this.isEntered && !this.isClicked){ | ||||
|  |  | |||
|  | @ -2,12 +2,19 @@ import Vec2 from "../../DataTypes/Vec2"; | |||
| import Color from "../../Utils/Color"; | ||||
| import UIElement from "../UIElement"; | ||||
| 
 | ||||
| /** A basic text-containing label */ | ||||
| export default class Label extends UIElement{ | ||||
| 	/** The color of the text of this UIElement */ | ||||
| 	textColor: Color; | ||||
| 	/** The value of the text of this UIElement */ | ||||
| 	text: string; | ||||
| 	/** The name of the font */ | ||||
| 	protected font: string; | ||||
| 	/** The size of the font */ | ||||
| 	protected fontSize: number; | ||||
| 	/** The horizontal alignment of the text within the label */ | ||||
| 	protected hAlign: string; | ||||
| 	/** The vertical alignment of text within the label */ | ||||
| 	protected vAlign: string; | ||||
| 
 | ||||
| 	/** A flag for if the width of the text has been measured on the canvas for auto width assignment */ | ||||
|  | @ -25,32 +32,46 @@ export default class Label extends UIElement{ | |||
| 		this.sizeAssigned = false; | ||||
| 	} | ||||
| 
 | ||||
| 	// @deprecated
 | ||||
| 	setText(text: string): void { | ||||
| 		this.text = text; | ||||
| 	} | ||||
| 
 | ||||
| 	// @deprecated
 | ||||
| 	setTextColor(color: Color): void { | ||||
| 		this.textColor = color; | ||||
| 	} | ||||
| 
 | ||||
| 	getFontString(): string { | ||||
| 	/** | ||||
| 	 * Gets a string containg the font details for rendering | ||||
| 	 * @returns A string containing the font details | ||||
| 	 */ | ||||
| 	protected getFontString(): string { | ||||
| 		return this.fontSize + "px " + this.font; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Overridable method for calculating text color - useful for elements that want to be colored on different after certain events | ||||
| 	 * @returns a string containg the text color | ||||
| 	 */ | ||||
| 	calculateTextColor(): string { | ||||
| 		return this.textColor.toStringRGBA(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Uses the canvas to calculate the width of the text | ||||
| 	 * @param ctx The rendering context | ||||
| 	 * @returns A number representing the rendered text width | ||||
| 	 */ | ||||
| 	protected calculateTextWidth(ctx: CanvasRenderingContext2D): number { | ||||
| 		ctx.font = this.fontSize + "px " + this.font; | ||||
| 		return ctx.measureText(this.text).width; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Calculate the offset of the text - this is useful for rendering text with different alignments | ||||
| 	 * Calculate the offset of the text - this is used for rendering text with different alignments | ||||
| 	 * @param ctx The rendering context | ||||
| 	 * @returns The offset of the text in a Vec2 | ||||
| 	 */ | ||||
| 	calculateTextOffset(ctx: CanvasRenderingContext2D): Vec2 { | ||||
| 		let textWidth = this.calculateTextWidth(ctx); | ||||
|  | @ -83,6 +104,10 @@ export default class Label extends UIElement{ | |||
| 		this.sizeAssigned = true; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Automatically sizes the element to the text within it | ||||
| 	 * @param ctx The rendering context | ||||
| 	 */ | ||||
| 	protected autoSize(ctx: CanvasRenderingContext2D): void { | ||||
| 		let width = this.calculateTextWidth(ctx); | ||||
| 		let height = this.fontSize; | ||||
|  | @ -90,6 +115,10 @@ export default class Label extends UIElement{ | |||
| 		this.sizeAssigned = true; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Initially assigns a size to the UIElement if none is provided | ||||
| 	 * @param ctx The rendering context | ||||
| 	 */ | ||||
| 	handleInitialSizing(ctx: CanvasRenderingContext2D): void { | ||||
| 		if(!this.sizeAssigned){ | ||||
| 			this.autoSize(ctx); | ||||
|  |  | |||
|  | @ -3,12 +3,17 @@ import Color from "../../Utils/Color"; | |||
| import MathUtils from "../../Utils/MathUtils"; | ||||
| import UIElement from "../UIElement"; | ||||
| 
 | ||||
| /** A slider UIElement */ | ||||
| export default class Slider extends UIElement { | ||||
|     /** The value of the slider from [0, 1] */ | ||||
|     protected value: number; | ||||
|     /** The color of the slider nib */ | ||||
|     public nibColor: Color; | ||||
|     /** The color of the slider track */ | ||||
|     public sliderColor: Color; | ||||
|     /** The reaction of this UIElement to a value change */ | ||||
|     public onValueChange: (value: number) => void; | ||||
|     /** The event propagated by this UIElement when value changes */ | ||||
|     public onValueChangeEventId: string; | ||||
| 
 | ||||
|     constructor(position: Vec2){ | ||||
|  | @ -24,10 +29,15 @@ export default class Slider extends UIElement { | |||
|         this.size.set(200, 20); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieves the value of the slider | ||||
|      * @returns The value of the slider | ||||
|      */ | ||||
|     getValue(): number { | ||||
|         return this.value; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     /** A method called in response to the value changing */ | ||||
|     protected valueChanged(): void { | ||||
|         if(this.onValueChange){ | ||||
|             this.onValueChange(this.value); | ||||
|  |  | |||
|  | @ -2,8 +2,11 @@ import Vec2 from "../../DataTypes/Vec2"; | |||
| import Color from "../../Utils/Color"; | ||||
| import Label from "./Label"; | ||||
| 
 | ||||
| /** A text input UIElement */ | ||||
| export default class TextInput extends Label { | ||||
|     /** A flag the represents whether the user can type in this TextInput */ | ||||
|     focused: boolean; | ||||
|     /** The position of the cursor in this TextInput */ | ||||
|     cursorCounter: number; | ||||
| 
 | ||||
|     constructor(position: Vec2){ | ||||
|  | @ -39,7 +42,6 @@ export default class TextInput extends Label { | |||
|             let specialChars = "`~!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?"; | ||||
|             let letters = "qwertyuiopasdfghjklzxcvbnm"; | ||||
|             let mask = nums + specialChars + letters; | ||||
|             // THIS ISN'T ACTUALLY AN ERROR, DISREGARD
 | ||||
|             keys = keys.filter(key => mask.includes(key)); | ||||
|             let shiftPressed = this.input.isPressed("shift"); | ||||
|             let backspacePressed = this.input.isJustPressed("backspace"); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user