ShatteredSword/src/Nodes/CanvasNode.ts

102 lines
2.1 KiB
TypeScript

import GameNode from "./GameNode";
import Vec2 from "../DataTypes/Vec2";
import { Region } from "../DataTypes/Interfaces/Descriptors";
import AABB from "../DataTypes/AABB";
/**
* The representation of an object in the game world that can be drawn to the screen
*/
export default abstract class CanvasNode extends GameNode implements Region {
private _size: Vec2;
private _scale: Vec2;
private boundary: AABB;
constructor(){
super();
this._size = new Vec2(0, 0);
this._size.setOnChange(this.sizeChanged);
this._scale = new Vec2(1, 1);
this._scale.setOnChange(this.scaleChanged);
this.boundary = new AABB();
this.updateBoundary();
}
get size(): Vec2 {
return this._size;
}
set size(size: Vec2){
this._size = size;
this._size.setOnChange(this.sizeChanged);
this.sizeChanged();
}
get scale(): Vec2 {
return this._scale;
}
set scale(scale: Vec2){
this._scale = scale;
this._scale.setOnChange(this.sizeChanged);
this.scaleChanged();
}
getSize(): Vec2 {
return this.size.clone();
}
setSize(vecOrX: Vec2 | number, y: number = null): void {
if(vecOrX instanceof Vec2){
this.size.set(vecOrX.x, vecOrX.y);
} else {
this.size.set(vecOrX, y);
}
}
/**
* Returns the scale of the sprite
*/
getScale(): Vec2 {
return this.scale.clone();
}
/**
* Sets the scale of the sprite to the value provided
* @param scale
*/
setScale(scale: Vec2): void {
this.scale = scale;
}
positionChanged = (): void => {
this.updateBoundary();
}
sizeChanged = (): void => {
this.updateBoundary();
}
scaleChanged = (): void => {
this.updateBoundary();
}
private updateBoundary(): void {
this.boundary.setCenter(this.position.clone());
this.boundary.setHalfSize(this.size.clone().mult(this.scale).scale(1/2));
}
getBoundary(): AABB {
return this.boundary;
}
/**
* Returns true if the point (x, y) is inside of this canvas object
* @param x
* @param y
*/
contains(x: number, y: number): boolean {
return this.boundary.containsPoint(new Vec2(x, y));
}
abstract render(ctx: CanvasRenderingContext2D): void;
}