cleaned up typescript inconsistencies in code
This commit is contained in:
parent
2dd60b5197
commit
bd49258d30
|
@ -1,7 +1,7 @@
|
|||
import CanvasNode from "./CanvasNode";
|
||||
import Color from "../Utils/Color";
|
||||
import Vec2 from "../DataTypes/Vec2";
|
||||
import RandUtils from "../Utils/RandUtils";
|
||||
import CanvasNode from "./Nodes/CanvasNode";
|
||||
import Color from "./Utils/Color";
|
||||
import Vec2 from "./DataTypes/Vec2";
|
||||
import RandUtils from "./Utils/RandUtils";
|
||||
|
||||
export default class ColoredCircle extends CanvasNode{
|
||||
private color: Color;
|
|
@ -1,3 +1,3 @@
|
|||
export default interface Collection{
|
||||
export default interface Collection {
|
||||
forEach(func: Function): void;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import Collection from "./Collection";
|
||||
|
||||
export default class Queue<T> implements Collection{
|
||||
readonly MAX_ELEMENTS: number;
|
||||
private readonly MAX_ELEMENTS: number;
|
||||
private q: Array<T>;
|
||||
private head: number;
|
||||
private tail: number;
|
||||
|
|
|
@ -26,7 +26,7 @@ export default class Stack<T> implements Collection{
|
|||
/**
|
||||
* Removes an item from the top of the stack
|
||||
*/
|
||||
pop(): T{
|
||||
pop(): T {
|
||||
if(this.head === -1){
|
||||
throw "Stack empty - cannot remove element";
|
||||
}
|
||||
|
@ -34,13 +34,6 @@ export default class Stack<T> implements Collection{
|
|||
return this.stack[this.head + 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from the stack
|
||||
*/
|
||||
clear(): void{
|
||||
this.head = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element currently at the top of the stack
|
||||
*/
|
||||
|
@ -51,6 +44,13 @@ export default class Stack<T> implements Collection{
|
|||
return this.stack[this.head];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from the stack
|
||||
*/
|
||||
clear(): void{
|
||||
this.head = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items currently in the stack
|
||||
*/
|
||||
|
|
|
@ -4,8 +4,8 @@ export class TiledTilemapData {
|
|||
tileheight: number;
|
||||
tilewidth: number;
|
||||
orientation: string;
|
||||
layers: TiledLayerData[];
|
||||
tilesets: TiledTilesetData[];
|
||||
layers: Array<TiledLayerData>;
|
||||
tilesets: Array<TiledTilesetData>;
|
||||
}
|
||||
|
||||
export class TiledLayerProperty {
|
||||
|
|
|
@ -15,11 +15,12 @@ export default class Tileset {
|
|||
protected numRows: number;
|
||||
protected numCols: number;
|
||||
|
||||
// TODO: Change this to be more general and work with other tileset formats
|
||||
constructor(tilesetData: TiledTilesetData){
|
||||
this.initFromTiledData(tilesetData);
|
||||
}
|
||||
|
||||
initFromTiledData(tiledData: TiledTilesetData){
|
||||
initFromTiledData(tiledData: TiledTilesetData): void {
|
||||
this.numRows = tiledData.tilecount/tiledData.columns;
|
||||
this.numCols = tiledData.columns;
|
||||
this.startIndex = tiledData.firstgid;
|
||||
|
@ -57,6 +58,7 @@ export default class Tileset {
|
|||
return this.numCols;
|
||||
}
|
||||
|
||||
// TODO: This should probably be a thing that is tracked in the resource loader, not here
|
||||
isReady(): boolean {
|
||||
return this.image !== null;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class Vec2 {
|
|||
return this;
|
||||
}
|
||||
|
||||
rotate(angle: number): Vec2 {
|
||||
rotateCCW(angle: number): Vec2 {
|
||||
let cs = Math.cos(angle);
|
||||
let sn = Math.sin(angle);
|
||||
let tempX = this.x*cs - this.y*sn;
|
||||
|
@ -74,11 +74,11 @@ export default class Vec2 {
|
|||
}
|
||||
|
||||
toString(): string {
|
||||
return "(" + this.x + ", " + this.y + ")";
|
||||
return this.toFixed();
|
||||
}
|
||||
|
||||
toFixed(): string {
|
||||
return "(" + this.x.toFixed(1) + ", " + this.y.toFixed(1) + ")";
|
||||
toFixed(numDecimalPoints: number = 1): string {
|
||||
return "(" + this.x.toFixed(numDecimalPoints) + ", " + this.y.toFixed(numDecimalPoints) + ")";
|
||||
}
|
||||
|
||||
clone(): Vec2 {
|
||||
|
|
|
@ -7,14 +7,14 @@ export default class Vec4{
|
|||
public z : number;
|
||||
public w : number;
|
||||
|
||||
constructor(x : number = 0, y : number = 0, z : number = 0, w : number = 0){
|
||||
constructor(x : number = 0, y : number = 0, z : number = 0, w : number = 0) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
split() : [Vec2, Vec2]{
|
||||
split() : [Vec2, Vec2] {
|
||||
return [new Vec2(this.x, this.y), new Vec2(this.z, this.w)];
|
||||
}
|
||||
}
|
|
@ -1,30 +1,16 @@
|
|||
import Map from "../DataTypes/Map";
|
||||
|
||||
export default class Debug {
|
||||
private static instance: Debug = null;
|
||||
|
||||
logIds: number;
|
||||
logMessages: Map<string>;
|
||||
private static logMessages: Map<string> = new Map();
|
||||
|
||||
|
||||
constructor(){
|
||||
this.logIds = 0;
|
||||
this.logMessages = new Map();
|
||||
};
|
||||
|
||||
static getInstance(): Debug {
|
||||
if(this.instance === null){
|
||||
this.instance = new Debug();
|
||||
}
|
||||
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
log(id: string, message: string): void {
|
||||
static log(id: string, message: string): void {
|
||||
this.logMessages.add(id, message);
|
||||
}
|
||||
|
||||
render(ctx: CanvasRenderingContext2D): void {
|
||||
// TODO: Create a method that can delete messages from the log
|
||||
|
||||
static render(ctx: CanvasRenderingContext2D): void {
|
||||
let y = 20;
|
||||
ctx.font = "20px Arial";
|
||||
ctx.fillStyle = "#000000";
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import Scene from "../Scene";
|
||||
import Viewport from "../../SceneGraph/Viewport";
|
||||
import CanvasItem from "../../Nodes/CanvasNode"
|
||||
import PlayerSprite from "../../Nodes/PlayerSprite";
|
||||
|
||||
export default class CanvasNodeFactory {
|
||||
private scene: Scene;
|
||||
private viewport: Viewport;
|
||||
|
||||
constructor(scene: Scene, viewport: Viewport){
|
||||
constructor(scene: Scene){
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ import Vec2 from "../../DataTypes/Vec2";
|
|||
|
||||
export default class TilemapFactory {
|
||||
private scene: Scene;
|
||||
private viewport: Viewport;
|
||||
// TODO: get the resource manager OUT of here, it does not belong
|
||||
private resourceManager: ResourceManager;
|
||||
|
||||
constructor(scene: Scene, viewport: Viewport){
|
||||
constructor(scene: Scene){
|
||||
this.scene = scene;
|
||||
this.resourceManager = ResourceManager.getInstance();
|
||||
}
|
||||
|
@ -30,18 +30,6 @@ export default class TilemapFactory {
|
|||
if(tilemap.isCollidable()){
|
||||
// Register in physics as a tilemap
|
||||
this.scene.physics.addTilemap(tilemap);
|
||||
|
||||
// Create colliders
|
||||
// let worldSize = tilemap.getWorldSize();
|
||||
// let tileSize = tilemap.getTileSize();
|
||||
|
||||
// tilemap.forEachTile((tileIndex: number, i: number) => {
|
||||
// if(tileIndex !== 0){
|
||||
// let x = (i % worldSize.x) * tileSize.x * 4;
|
||||
// let y = Math.floor(i / worldSize.x) * tileSize.y * 4;
|
||||
// this.scene.physics.add(StaticBody, new Vec2(x, y), new Vec2(tileSize.x * 4, tileSize.y * 4));
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
// Load images for the tilesets
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class Scene {
|
|||
private gameState: GameState;
|
||||
private viewport: Viewport
|
||||
private parallax: Vec2;
|
||||
sceneGraph: SceneGraph;
|
||||
private sceneGraph: SceneGraph;
|
||||
private physicsManager: PhysicsManager;
|
||||
private tilemaps: Array<Tilemap>;
|
||||
private paused: boolean;
|
||||
|
@ -38,8 +38,8 @@ export default class Scene {
|
|||
this.physicsManager = new PhysicsManager();
|
||||
|
||||
// Factories
|
||||
this.canvasNode = new CanvasNodeFactory(this, this.viewport);
|
||||
this.tilemap = new TilemapFactory(this, this.viewport);
|
||||
this.canvasNode = new CanvasNodeFactory(this);
|
||||
this.tilemap = new TilemapFactory(this);
|
||||
this.physics = new PhysicsNodeFactory(this, this.physicsManager);
|
||||
}
|
||||
|
||||
|
@ -47,16 +47,16 @@ export default class Scene {
|
|||
this.paused = pauseValue;
|
||||
}
|
||||
|
||||
setAlpha(alpha: number): void {
|
||||
this.alpha = MathUtils.clamp(alpha, 0, 1);
|
||||
}
|
||||
|
||||
isPaused(): boolean {
|
||||
return this.paused;
|
||||
}
|
||||
|
||||
setHidden(hiddenValue: boolean): void {
|
||||
this.hidden = hiddenValue;
|
||||
setAlpha(alpha: number): void {
|
||||
this.alpha = MathUtils.clamp(alpha, 0, 1);
|
||||
}
|
||||
|
||||
setHidden(hidden: boolean): void {
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
isHidden(): boolean {
|
||||
|
@ -85,8 +85,8 @@ export default class Scene {
|
|||
return this.parallax;
|
||||
}
|
||||
|
||||
add(children: CanvasNode): void {
|
||||
this.sceneGraph.addNode(children);
|
||||
add(child: CanvasNode): void {
|
||||
this.sceneGraph.addNode(child);
|
||||
}
|
||||
|
||||
addTilemap(tilemap: Tilemap): void {
|
||||
|
|
|
@ -38,7 +38,6 @@ export default class GameLoop{
|
|||
private inputReceiver: InputReceiver;
|
||||
private recorder: Recorder;
|
||||
private gameState: GameState;
|
||||
private debug: Debug;
|
||||
private resourceManager: ResourceManager;
|
||||
|
||||
constructor(){
|
||||
|
@ -68,7 +67,6 @@ export default class GameLoop{
|
|||
this.inputReceiver.setViewport(this.viewport);
|
||||
this.recorder = new Recorder();
|
||||
this.gameState = new GameState(this.viewport);
|
||||
this.debug = Debug.getInstance();
|
||||
this.resourceManager = ResourceManager.getInstance();
|
||||
}
|
||||
|
||||
|
@ -99,7 +97,7 @@ export default class GameLoop{
|
|||
this.runningFrameSum = 0;
|
||||
}
|
||||
|
||||
this.debug.log("fps", "FPS: " + this.fps.toFixed(1));
|
||||
Debug.log("fps", "FPS: " + this.fps.toFixed(1));
|
||||
}
|
||||
|
||||
start(): void {
|
||||
|
@ -157,6 +155,6 @@ export default class GameLoop{
|
|||
render(): void {
|
||||
this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
|
||||
this.gameState.render(this.ctx);
|
||||
this.debug.render(this.ctx);
|
||||
Debug.render(this.ctx);
|
||||
}
|
||||
}
|
|
@ -39,11 +39,11 @@ export default abstract class GameNode{
|
|||
}
|
||||
}
|
||||
|
||||
subscribe(eventType: string){
|
||||
subscribe(eventType: string): void {
|
||||
this.eventQueue.subscribe(this.receiver, eventType);
|
||||
}
|
||||
|
||||
emit(eventType: string, data: Map<any> | Record<string, any> = null){
|
||||
emit(eventType: string, data: Map<any> | Record<string, any> = null): void {
|
||||
let event = new GameEvent(eventType, data);
|
||||
this.eventQueue.addEvent(event);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { TiledTilemapData, TiledLayerData } from "../DataTypes/Tilesets/TiledDat
|
|||
*/
|
||||
export default abstract class Tilemap extends GameNode {
|
||||
protected data: number[];
|
||||
protected collisionData: number [];
|
||||
protected collisionData: number[];
|
||||
protected tilesets: Tileset[];
|
||||
protected worldSize: Vec2;
|
||||
protected tileSize: Vec2;
|
||||
|
@ -16,7 +16,8 @@ export default abstract class Tilemap extends GameNode {
|
|||
protected collidable: boolean;
|
||||
protected scale: Vec2;
|
||||
|
||||
constructor(tilemapData: TiledTilemapData, layerData: TiledLayerData){
|
||||
// TODO: Make this no longer be specific to Tiled
|
||||
constructor(tilemapData: TiledTilemapData, layerData: TiledLayerData) {
|
||||
super();
|
||||
this.tilesets = new Array<Tileset>();
|
||||
this.worldSize = new Vec2(0, 0);
|
||||
|
@ -71,7 +72,8 @@ export default abstract class Tilemap extends GameNode {
|
|||
/**
|
||||
* Sets up the tileset using the data loaded from file
|
||||
*/
|
||||
abstract parseTilemapData(tilemapData: TiledTilemapData, layerData: TiledLayerData): void;
|
||||
// TODO: This shouldn't use tiled data specifically - it should be more general
|
||||
protected abstract parseTilemapData(tilemapData: TiledTilemapData, layerData: TiledLayerData): void;
|
||||
|
||||
abstract render(ctx: CanvasRenderingContext2D, origin: Vec2, viewportSize: Vec2): void;
|
||||
}
|
|
@ -6,7 +6,7 @@ import Tileset from "../../DataTypes/Tilesets/Tileset";
|
|||
|
||||
export default class OrthogonalTilemap extends Tilemap {
|
||||
|
||||
parseTilemapData(tilemapData: TiledTilemapData, layer: TiledLayerData): void {
|
||||
protected parseTilemapData(tilemapData: TiledTilemapData, layer: TiledLayerData): void {
|
||||
this.worldSize.set(tilemapData.width, tilemapData.height);
|
||||
this.tileSize.set(tilemapData.tilewidth, tilemapData.tileheight);
|
||||
this.data = layer.data;
|
||||
|
|
|
@ -4,16 +4,16 @@ import Vec2 from "../DataTypes/Vec2";
|
|||
|
||||
export default class UIElement extends CanvasNode{
|
||||
// Style attributes
|
||||
textColor: Color;
|
||||
backgroundColor: Color;
|
||||
borderColor: Color;
|
||||
text: string;
|
||||
font: string;
|
||||
fontSize: number;
|
||||
hAlign: string;
|
||||
vAlign: string;
|
||||
borderRadius: number;
|
||||
borderWidth: number;
|
||||
protected textColor: Color;
|
||||
protected backgroundColor: Color;
|
||||
protected borderColor: Color;
|
||||
protected text: string;
|
||||
protected font: string;
|
||||
protected fontSize: number;
|
||||
protected hAlign: string;
|
||||
protected vAlign: string;
|
||||
protected borderRadius: number;
|
||||
protected borderWidth: number;
|
||||
|
||||
// EventAttributes
|
||||
onClick: Function;
|
||||
|
|
|
@ -8,6 +8,7 @@ export default abstract class Collider extends GameNode {
|
|||
return this.size;
|
||||
}
|
||||
|
||||
// TODO: Make this accept vector arguments and number arguments
|
||||
setSize(size: Vec2): void {
|
||||
this.size = size;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import OrthogonalTilemap from "../Nodes/Tilemaps/OrthogonalTilemap";
|
|||
|
||||
export default class PhysicsManager {
|
||||
|
||||
physicsNodes: Array<PhysicsNode>;
|
||||
tilemaps: Array<Tilemap>;
|
||||
movements: Array<MovementData>;
|
||||
private physicsNodes: Array<PhysicsNode>;
|
||||
private tilemaps: Array<Tilemap>;
|
||||
private movements: Array<MovementData>;
|
||||
|
||||
constructor(){
|
||||
this.physicsNodes = new Array();
|
||||
|
@ -26,63 +26,17 @@ export default class PhysicsManager {
|
|||
this.tilemaps.push(tilemap);
|
||||
}
|
||||
|
||||
addMovement(node: PhysicsNode, velocity: Vec2){
|
||||
addMovement(node: PhysicsNode, velocity: Vec2): void {
|
||||
this.movements.push(new MovementData(node, velocity));
|
||||
}
|
||||
|
||||
update(deltaT: number): void {
|
||||
for(let node of this.physicsNodes){
|
||||
node.update(deltaT);
|
||||
}
|
||||
|
||||
let staticSet = new Array<PhysicsNode>();
|
||||
let dynamicSet = new Array<PhysicsNode>();
|
||||
|
||||
// TODO: REALLY bad, the physics system has to be improved, but that isn't the focus for now
|
||||
for(let node of this.physicsNodes){
|
||||
if(node.isMoving){
|
||||
dynamicSet.push(node);
|
||||
node.isMoving = false;
|
||||
} else {
|
||||
staticSet.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
// For now, we will only have the moving player, don't bother checking for collisions with other moving things
|
||||
for(let movingNode of dynamicSet){
|
||||
movingNode.setIsGrounded(false);
|
||||
// Get velocity of node
|
||||
let velocity = null;
|
||||
for(let data of this.movements){
|
||||
if(data.node === movingNode){
|
||||
velocity = new Vec2(data.velocity.x, data.velocity.y);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO handle collisions between dynamic nodes
|
||||
// We probably want to sort them by their left edges
|
||||
|
||||
// TODO: handle collisions between dynamic nodes and static nodes
|
||||
|
||||
// Handle Collisions with the tilemaps
|
||||
for(let tilemap of this.tilemaps){
|
||||
this.collideWithTilemap(movingNode, tilemap, velocity);
|
||||
}
|
||||
|
||||
movingNode.finishMove(velocity);
|
||||
}
|
||||
|
||||
// Reset movements
|
||||
this.movements = new Array();
|
||||
}
|
||||
|
||||
collideWithTilemap(node: PhysicsNode, tilemap: Tilemap, velocity: Vec2){
|
||||
private collideWithTilemap(node: PhysicsNode, tilemap: Tilemap, velocity: Vec2): void {
|
||||
if(tilemap instanceof OrthogonalTilemap){
|
||||
this.collideWithOrthogonalTilemap(node, tilemap, velocity);
|
||||
}
|
||||
}
|
||||
|
||||
collideWithOrthogonalTilemap(node: PhysicsNode, tilemap: OrthogonalTilemap, velocity: Vec2){
|
||||
private collideWithOrthogonalTilemap(node: PhysicsNode, tilemap: OrthogonalTilemap, velocity: Vec2): void {
|
||||
let startPos = node.getPosition();
|
||||
let endPos = startPos.clone().add(velocity);
|
||||
let size = node.getCollider().getSize();
|
||||
|
@ -95,12 +49,12 @@ export default class PhysicsManager {
|
|||
let tilemapCollisions = new Array<TileCollisionData>();
|
||||
let tileSize = tilemap.getTileSize();
|
||||
|
||||
Debug.getInstance().log("tilemapCollision", "");
|
||||
Debug.log("tilemapCollision", "");
|
||||
// Loop over all possible tiles
|
||||
for(let col = minIndex.x; col <= maxIndex.x; col++){
|
||||
for(let row = minIndex.y; row <= maxIndex.y; row++){
|
||||
if(tilemap.isTileCollidable(col, row)){
|
||||
Debug.getInstance().log("tilemapCollision", "Colliding with Tile");
|
||||
Debug.log("tilemapCollision", "Colliding with Tile");
|
||||
|
||||
// Tile position
|
||||
let tilePos = new Vec2(col * tileSize.x, row * tileSize.y);
|
||||
|
@ -124,7 +78,7 @@ export default class PhysicsManager {
|
|||
|
||||
// Resolve the collisions
|
||||
tilemapCollisions.forEach(collision => {
|
||||
let [firstContact, _, collidingX, collidingY] = this.getTimeOfCollision(startPos, size, velocity, collision.position, tileSize, new Vec2(0, 0));
|
||||
let [firstContact, _, collidingX, collidingY] = this.getTimeOfAABBCollision(startPos, size, velocity, collision.position, tileSize, new Vec2(0, 0));
|
||||
|
||||
// Handle collision
|
||||
if( (firstContact.x < 1 || collidingX) && (firstContact.y < 1 || collidingY)){
|
||||
|
@ -142,7 +96,7 @@ export default class PhysicsManager {
|
|||
}
|
||||
|
||||
if(yScale !== 1){
|
||||
node.setIsGrounded(true);
|
||||
node.setGrounded(true);
|
||||
}
|
||||
|
||||
velocity.scale(xScale, yScale);
|
||||
|
@ -151,7 +105,7 @@ export default class PhysicsManager {
|
|||
})
|
||||
}
|
||||
|
||||
handleCollision(movingNode: PhysicsNode, staticNode: PhysicsNode, velocity: Vec2, id: String){
|
||||
private handleCollision(movingNode: PhysicsNode, staticNode: PhysicsNode, velocity: Vec2, id: String){
|
||||
let sizeA = movingNode.getCollider().getSize();
|
||||
let posA = movingNode.getPosition();
|
||||
let velA = velocity;
|
||||
|
@ -159,7 +113,7 @@ export default class PhysicsManager {
|
|||
let posB = staticNode.getPosition();
|
||||
let velB = new Vec2(0, 0);
|
||||
|
||||
let [firstContact, _, collidingX, collidingY] = this.getTimeOfCollision(posA, sizeA, velA, posB, sizeB, velB);
|
||||
let [firstContact, _, collidingX, collidingY] = this.getTimeOfAABBCollision(posA, sizeA, velA, posB, sizeB, velB);
|
||||
|
||||
if( (firstContact.x < 1 || collidingX) && (firstContact.y < 1 || collidingY)){
|
||||
if(collidingX && collidingY){
|
||||
|
@ -170,7 +124,7 @@ export default class PhysicsManager {
|
|||
let xScale = MathUtils.clamp(firstContact.x, 0, 1);
|
||||
let yScale = MathUtils.clamp(firstContact.y, 0, 1);
|
||||
if(yScale !== 1){
|
||||
movingNode.setIsGrounded(true);
|
||||
movingNode.setGrounded(true);
|
||||
}
|
||||
velocity.scale(xScale, yScale);
|
||||
}
|
||||
|
@ -182,7 +136,7 @@ export default class PhysicsManager {
|
|||
* of the start and end of the collision and booleans for whether or not the objects are currently overlapping
|
||||
* (before they move).
|
||||
*/
|
||||
getTimeOfCollision(posA: Vec2, sizeA: Vec2, velA: Vec2, posB: Vec2, sizeB: Vec2, velB: Vec2): [Vec2, Vec2, boolean, boolean] {
|
||||
private getTimeOfAABBCollision(posA: Vec2, sizeA: Vec2, velA: Vec2, posB: Vec2, sizeB: Vec2, velB: Vec2): [Vec2, Vec2, boolean, boolean] {
|
||||
let firstContact = new Vec2(0, 0);
|
||||
let lastContact = new Vec2(0, 0);
|
||||
|
||||
|
@ -258,10 +212,57 @@ export default class PhysicsManager {
|
|||
|
||||
return [firstContact, lastContact, collidingX, collidingY];
|
||||
}
|
||||
|
||||
update(deltaT: number): void {
|
||||
for(let node of this.physicsNodes){
|
||||
node.update(deltaT);
|
||||
}
|
||||
|
||||
let staticSet = new Array<PhysicsNode>();
|
||||
let dynamicSet = new Array<PhysicsNode>();
|
||||
|
||||
// TODO: REALLY bad, the physics system has to be improved, but that isn't the focus for now
|
||||
for(let node of this.physicsNodes){
|
||||
if(node.isMoving()){
|
||||
dynamicSet.push(node);
|
||||
node.setMoving(false);
|
||||
} else {
|
||||
staticSet.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
// For now, we will only have the moving player, don't bother checking for collisions with other moving things
|
||||
for(let movingNode of dynamicSet){
|
||||
movingNode.setGrounded(false);
|
||||
// Get velocity of node
|
||||
let velocity = null;
|
||||
for(let data of this.movements){
|
||||
if(data.node === movingNode){
|
||||
velocity = new Vec2(data.velocity.x, data.velocity.y);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO handle collisions between dynamic nodes
|
||||
// We probably want to sort them by their left edges
|
||||
|
||||
// TODO: handle collisions between dynamic nodes and static nodes
|
||||
|
||||
// Handle Collisions with the tilemaps
|
||||
for(let tilemap of this.tilemaps){
|
||||
this.collideWithTilemap(movingNode, tilemap, velocity);
|
||||
}
|
||||
|
||||
movingNode.finishMove(velocity);
|
||||
}
|
||||
|
||||
// Reset movements
|
||||
this.movements = new Array();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper classes for internal data
|
||||
class MovementData{
|
||||
// TODO: Move these to data
|
||||
class MovementData {
|
||||
node: PhysicsNode;
|
||||
velocity: Vec2;
|
||||
constructor(node: PhysicsNode, velocity: Vec2){
|
||||
|
|
|
@ -8,17 +8,18 @@ export default abstract class PhysicsNode extends GameNode {
|
|||
protected collider: Collider = null;
|
||||
protected children: Array<GameNode>;
|
||||
private manager: PhysicsManager;
|
||||
isMoving: boolean;
|
||||
protected isGrounded: boolean;
|
||||
protected moving: boolean;
|
||||
protected grounded: boolean;
|
||||
|
||||
constructor(){
|
||||
super();
|
||||
this.children = new Array();
|
||||
this.isMoving = false;
|
||||
this.grounded = false;
|
||||
this.moving = false;
|
||||
}
|
||||
|
||||
setIsGrounded(isGrounded: boolean): void {
|
||||
this.isGrounded = isGrounded;
|
||||
setGrounded(grounded: boolean): void {
|
||||
this.grounded = grounded;
|
||||
}
|
||||
|
||||
addManager(manager: PhysicsManager): void {
|
||||
|
@ -33,8 +34,16 @@ export default abstract class PhysicsNode extends GameNode {
|
|||
return this.collider;
|
||||
}
|
||||
|
||||
move(velocity: Vec2): void {
|
||||
this.isMoving = true;
|
||||
setMoving(moving: boolean): void {
|
||||
this.moving = moving;
|
||||
}
|
||||
|
||||
isMoving(): boolean {
|
||||
return this.moving;
|
||||
}
|
||||
|
||||
protected move(velocity: Vec2): void {
|
||||
this.moving = true;
|
||||
this.manager.addMovement(this, velocity);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import PhysicsNode from "./Physics/PhysicsNode";
|
|||
import Vec2 from "./DataTypes/Vec2";
|
||||
import Debug from "./Debug/Debug";
|
||||
import AABB from "./Physics/Colliders/AABB";
|
||||
import PlayerSprite from "./Nodes/PlayerSprite";
|
||||
import PlayerSprite from "./PlayerSprite";
|
||||
|
||||
export default class Player extends PhysicsNode {
|
||||
velocity: Vec2;
|
||||
|
@ -24,7 +24,6 @@ export default class Player extends PhysicsNode {
|
|||
if(this.type === "topdown"){
|
||||
this.position = new Vec2(100, 100);
|
||||
}
|
||||
this.debug = Debug.getInstance();
|
||||
}
|
||||
|
||||
create(): void {
|
||||
|
@ -45,7 +44,7 @@ export default class Player extends PhysicsNode {
|
|||
|
||||
this.move(new Vec2(this.velocity.x * deltaT, this.velocity.y * deltaT));
|
||||
|
||||
this.debug.log("player", "Player Pos: " + this.position.toFixed() + ", Player Vel: " + this.velocity.toFixed());
|
||||
Debug.log("player", "Player Pos: " + this.position + ", Player Vel: " + this.velocity);
|
||||
}
|
||||
|
||||
topdown_computeDirection(): Vec2 {
|
||||
|
@ -70,7 +69,7 @@ export default class Player extends PhysicsNode {
|
|||
dir.x += this.input.isPressed('a') ? -1 : 0;
|
||||
dir.x += this.input.isPressed('d') ? 1 : 0;
|
||||
|
||||
if(this.isGrounded){
|
||||
if(this.grounded){
|
||||
dir.y += this.input.isJustPressed('w') ? -1 : 0;
|
||||
}
|
||||
|
||||
|
@ -80,7 +79,7 @@ export default class Player extends PhysicsNode {
|
|||
platformer_computeVelocity(dir: Vec2, deltaT: number): Vec2 {
|
||||
let vel = new Vec2(0, this.velocity.y);
|
||||
|
||||
if(this.isGrounded){
|
||||
if(this.grounded){
|
||||
vel.y = dir.y*1800;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import CanvasNode from "./CanvasNode";
|
||||
import Vec2 from "../DataTypes/Vec2";
|
||||
import Debug from "../Debug/Debug";
|
||||
import CanvasNode from "./Nodes/CanvasNode";
|
||||
import Vec2 from "./DataTypes/Vec2";
|
||||
import Debug from "./Debug/Debug";
|
||||
|
||||
export default class Player extends CanvasNode{
|
||||
debug: Debug;
|
|
@ -2,14 +2,17 @@ import Viewport from "./Viewport";
|
|||
import CanvasNode from "../Nodes/CanvasNode";
|
||||
import Map from "../DataTypes/Map";
|
||||
import Vec2 from "../DataTypes/Vec2";
|
||||
import Scene from "../GameState/Scene";
|
||||
|
||||
export default abstract class SceneGraph{
|
||||
protected viewport: Viewport;
|
||||
protected nodeMap: Map<CanvasNode>;
|
||||
protected idCounter: number;
|
||||
protected scene: Scene;
|
||||
|
||||
constructor(viewport: Viewport){
|
||||
constructor(viewport: Viewport, scene: Scene){
|
||||
this.viewport = viewport;
|
||||
this.scene = scene;
|
||||
this.nodeMap = new Map<CanvasNode>();
|
||||
this.idCounter = 0;
|
||||
}
|
||||
|
@ -39,7 +42,7 @@ export default abstract class SceneGraph{
|
|||
return this.nodeMap.get(id);
|
||||
};
|
||||
|
||||
getNodeAt(vecOrX: Vec2 | number, y: number = null): CanvasNode{
|
||||
getNodeAt(vecOrX: Vec2 | number, y: number = null): CanvasNode {
|
||||
if(vecOrX instanceof Vec2){
|
||||
return this.getNodeAtCoords(vecOrX.x, vecOrX.y);
|
||||
} else {
|
||||
|
|
|
@ -6,11 +6,9 @@ import Scene from "../GameState/Scene";
|
|||
export default class SceneGraphArray extends SceneGraph{
|
||||
private nodeList: Array<CanvasNode>;
|
||||
private turnOffViewportCulling_demoTool: boolean;
|
||||
private scene: Scene;
|
||||
|
||||
constructor(viewport: Viewport, scene: Scene){
|
||||
super(viewport);
|
||||
this.scene = scene;
|
||||
super(viewport, scene);
|
||||
|
||||
this.nodeList = new Array<CanvasNode>();
|
||||
this.turnOffViewportCulling_demoTool = false;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import MathUtils from "./MathUtils";
|
||||
|
||||
// TODO: This should be moved to the datatypes folder
|
||||
export default class Color{
|
||||
public r: number;
|
||||
public g: number;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
export default class MathUtils{
|
||||
static clamp(x: number, min: number, max: number): number{
|
||||
static clamp(x: number, min: number, max: number): number {
|
||||
if(x < min) return min;
|
||||
if(x > max) return max;
|
||||
return x;
|
||||
}
|
||||
|
||||
static toHex(num: number, minLength: number = null): string{
|
||||
static toHex(num: number, minLength: number = null): string {
|
||||
let factor = 1;
|
||||
while(factor*16 < num){
|
||||
factor *= 16;
|
||||
|
@ -27,7 +27,7 @@ export default class MathUtils{
|
|||
return hexStr;
|
||||
}
|
||||
|
||||
static toHexDigit(num: number): string{
|
||||
static toHexDigit(num: number): string {
|
||||
if(num < 10){
|
||||
return "" + num;
|
||||
} else {
|
||||
|
|
|
@ -2,15 +2,15 @@ import MathUtils from "./MathUtils";
|
|||
import Color from "./Color";
|
||||
|
||||
export default class RandUtils{
|
||||
static randInt(min: number, max: number): number{
|
||||
static randInt(min: number, max: number): number {
|
||||
return Math.floor(Math.random()*(max - min) + min);
|
||||
}
|
||||
|
||||
static randHex(min: number, max: number): string{
|
||||
static randHex(min: number, max: number): string {
|
||||
return MathUtils.toHex(RandUtils.randInt(min, max));
|
||||
}
|
||||
|
||||
static randColor(): Color{
|
||||
static randColor(): Color {
|
||||
let r = RandUtils.randInt(0, 256);
|
||||
let g = RandUtils.randInt(0, 256);
|
||||
let b = RandUtils.randInt(0, 256);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import GameLoop from "./Loop/GameLoop";
|
||||
import Player from "./Player";
|
||||
import UIElement from "./Nodes/UIElement";
|
||||
import ColoredCircle from "./Nodes/ColoredCircle";
|
||||
import Color from "./Utils/Color";
|
||||
import Button from "./Nodes/UIElements/Button";
|
||||
import {} from "./index";
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
"src/Nodes/UIElements/Button.ts",
|
||||
"src/Nodes/UIElements/Label.ts",
|
||||
"src/Nodes/CanvasNode.ts",
|
||||
"src/Nodes/ColoredCircle.ts",
|
||||
"src/ColoredCircle.ts",
|
||||
"src/Nodes/GameNode.ts",
|
||||
"src/Nodes/PlayerSprite.ts",
|
||||
"src/PlayerSprite.ts",
|
||||
"src/Nodes/Tilemap.ts",
|
||||
"src/Nodes/UIElement.ts",
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user