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