fixed tilemap physics

This commit is contained in:
Joe Weaver 2020-08-20 20:45:48 -04:00
parent 66ced08987
commit 2dd60b5197
14 changed files with 294 additions and 122 deletions

View File

@ -65,7 +65,7 @@ export default class Tileset {
return tileIndex >= this.startIndex && tileIndex <= this.endIndex; return tileIndex >= this.startIndex && tileIndex <= this.endIndex;
} }
renderTile(ctx: CanvasRenderingContext2D, tileIndex: number, dataIndex: number, worldSize: Vec2, origin: Vec2): void { renderTile(ctx: CanvasRenderingContext2D, tileIndex: number, dataIndex: number, worldSize: Vec2, origin: Vec2, scale: Vec2): void {
let index = tileIndex - this.startIndex; let index = tileIndex - this.startIndex;
let row = Math.floor(index / this.numCols); let row = Math.floor(index / this.numCols);
let col = index % this.numCols; let col = index % this.numCols;
@ -73,8 +73,8 @@ export default class Tileset {
let height = this.tileSize.y; let height = this.tileSize.y;
let left = col * width; let left = col * width;
let top = row * height; let top = row * height;
let x = (dataIndex % worldSize.x) * width * 4; let x = (dataIndex % worldSize.x) * width * scale.x;
let y = Math.floor(dataIndex / worldSize.x) * height * 4; let y = Math.floor(dataIndex / worldSize.x) * height * scale.y;
ctx.drawImage(this.image, left, top, width, height, x - origin.x, y - origin.y, width * 4, height * 4); ctx.drawImage(this.image, left, top, width, height, x - origin.x, y - origin.y, width * scale.x, height * scale.y);
} }
} }

View File

@ -80,4 +80,8 @@ export default class Vec2 {
toFixed(): string { toFixed(): string {
return "(" + this.x.toFixed(1) + ", " + this.y.toFixed(1) + ")"; return "(" + this.x.toFixed(1) + ", " + this.y.toFixed(1) + ")";
} }
clone(): Vec2 {
return new Vec2(this.x, this.y);
}
} }

View File

@ -2,6 +2,7 @@ import Scene from "../Scene";
import Viewport from "../../SceneGraph/Viewport"; import Viewport from "../../SceneGraph/Viewport";
import PhysicsNode from "../../Physics/PhysicsNode"; import PhysicsNode from "../../Physics/PhysicsNode";
import PhysicsManager from "../../Physics/PhysicsManager"; import PhysicsManager from "../../Physics/PhysicsManager";
import Tilemap from "../../Nodes/Tilemap";
export default class PhysicsNodeFactory { export default class PhysicsNodeFactory {
private scene: Scene; private scene: Scene;
@ -20,4 +21,8 @@ export default class PhysicsNodeFactory {
this.physicsManager.add(instance); this.physicsManager.add(instance);
return instance; return instance;
} }
addTilemap(tilemap: Tilemap): void {
this.physicsManager.addTilemap(tilemap);
}
} }

View File

@ -28,17 +28,20 @@ export default class TilemapFactory {
this.scene.addTilemap(tilemap); this.scene.addTilemap(tilemap);
if(tilemap.isCollidable()){ if(tilemap.isCollidable()){
// Create colliders // Register in physics as a tilemap
let worldSize = tilemap.getWorldSize(); this.scene.physics.addTilemap(tilemap);
let tileSize = tilemap.getTileSize();
tilemap.forEachTile((tileIndex: number, i: number) => { // Create colliders
if(tileIndex !== 0){ // let worldSize = tilemap.getWorldSize();
let x = (i % worldSize.x) * tileSize.x * 4; // let tileSize = tilemap.getTileSize();
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)); // 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 // Load images for the tilesets

View File

@ -8,11 +8,10 @@ export default class GameState{
private worldSize: Vec2; private worldSize: Vec2;
private viewport: Viewport; private viewport: Viewport;
constructor(){ constructor(viewport: Viewport){
this.sceneStack = new Stack(10); this.sceneStack = new Stack(10);
this.worldSize = new Vec2(1600, 1000); this.worldSize = new Vec2(1600, 1000);
this.viewport = new Viewport(); this.viewport = viewport;
this.viewport.setSize(800, 500);
this.viewport.setBounds(0, 0, 2560, 1280); this.viewport.setBounds(0, 0, 2560, 1280);
} }

View File

@ -98,6 +98,7 @@ export default class Scene {
this.viewport.update(deltaT); this.viewport.update(deltaT);
this.physicsManager.update(deltaT); this.physicsManager.update(deltaT);
this.sceneGraph.update(deltaT); this.sceneGraph.update(deltaT);
this.tilemaps.forEach((tilemap: Tilemap) => tilemap.update(deltaT));
} }
} }

View File

@ -2,6 +2,7 @@ import Receiver from "../Events/Receiver";
import Map from "../DataTypes/Map"; import Map from "../DataTypes/Map";
import Vec2 from "../DataTypes/Vec2"; import Vec2 from "../DataTypes/Vec2";
import EventQueue from "../Events/EventQueue"; import EventQueue from "../Events/EventQueue";
import Viewport from "../SceneGraph/Viewport";
export default class InputReceiver{ export default class InputReceiver{
private static instance: InputReceiver = null; private static instance: InputReceiver = null;
@ -14,6 +15,7 @@ export default class InputReceiver{
private mousePressPosition: Vec2; private mousePressPosition: Vec2;
private eventQueue: EventQueue; private eventQueue: EventQueue;
private receiver: Receiver; private receiver: Receiver;
private viewport: Viewport;
private constructor(){ private constructor(){
this.mousePressed = false; this.mousePressed = false;
@ -108,7 +110,19 @@ export default class InputReceiver{
return this.mousePosition; return this.mousePosition;
} }
getGlobalMousePosition(): Vec2 {
return this.mousePosition.clone().add(this.viewport.getPosition());
}
getMousePressPosition(): Vec2 { getMousePressPosition(): Vec2 {
return this.mousePressPosition; return this.mousePressPosition;
} }
getGlobalMousePressPosition(): Vec2 {
return this.mousePressPosition.clone().add(this.viewport.getPosition());
}
setViewport(viewport: Viewport): void {
this.viewport = viewport;
}
} }

View File

@ -5,6 +5,7 @@ import Recorder from "../Playback/Recorder";
import GameState from "../GameState/GameState"; import GameState from "../GameState/GameState";
import Debug from "../Debug/Debug"; import Debug from "../Debug/Debug";
import ResourceManager from "../ResourceManager/ResourceManager"; import ResourceManager from "../ResourceManager/ResourceManager";
import Viewport from "../SceneGraph/Viewport";
export default class GameLoop{ export default class GameLoop{
// The amount of time to spend on a physics step // The amount of time to spend on a physics step
@ -30,6 +31,7 @@ export default class GameLoop{
readonly GAME_CANVAS: HTMLCanvasElement; readonly GAME_CANVAS: HTMLCanvasElement;
readonly WIDTH: number; readonly WIDTH: number;
readonly HEIGHT: number; readonly HEIGHT: number;
private viewport: Viewport;
private ctx: CanvasRenderingContext2D; private ctx: CanvasRenderingContext2D;
private eventQueue: EventQueue; private eventQueue: EventQueue;
private inputHandler: InputHandler; private inputHandler: InputHandler;
@ -57,12 +59,15 @@ export default class GameLoop{
this.WIDTH = 800; this.WIDTH = 800;
this.HEIGHT = 500; this.HEIGHT = 500;
this.ctx = this.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT); this.ctx = this.initializeCanvas(this.GAME_CANVAS, this.WIDTH, this.HEIGHT);
this.viewport = new Viewport();
this.viewport.setSize(this.WIDTH, this.HEIGHT);
this.eventQueue = EventQueue.getInstance(); this.eventQueue = EventQueue.getInstance();
this.inputHandler = new InputHandler(this.GAME_CANVAS); this.inputHandler = new InputHandler(this.GAME_CANVAS);
this.inputReceiver = InputReceiver.getInstance(); this.inputReceiver = InputReceiver.getInstance();
this.inputReceiver.setViewport(this.viewport);
this.recorder = new Recorder(); this.recorder = new Recorder();
this.gameState = new GameState(); this.gameState = new GameState(this.viewport);
this.debug = Debug.getInstance(); this.debug = Debug.getInstance();
this.resourceManager = ResourceManager.getInstance(); this.resourceManager = ResourceManager.getInstance();
} }

View File

@ -8,11 +8,13 @@ import { TiledTilemapData, TiledLayerData } from "../DataTypes/Tilesets/TiledDat
*/ */
export default abstract class Tilemap extends GameNode { export default abstract class Tilemap extends GameNode {
protected data: number[]; protected data: number[];
protected collisionData: number [];
protected tilesets: Tileset[]; protected tilesets: Tileset[];
protected worldSize: Vec2; protected worldSize: Vec2;
protected tileSize: Vec2; protected tileSize: Vec2;
protected visible: boolean; protected visible: boolean;
protected collidable: boolean; protected collidable: boolean;
protected scale: Vec2;
constructor(tilemapData: TiledTilemapData, layerData: TiledLayerData){ constructor(tilemapData: TiledTilemapData, layerData: TiledLayerData){
super(); super();
@ -20,6 +22,7 @@ export default abstract class Tilemap extends GameNode {
this.worldSize = new Vec2(0, 0); this.worldSize = new Vec2(0, 0);
this.tileSize = new Vec2(0, 0); this.tileSize = new Vec2(0, 0);
this.parseTilemapData(tilemapData, layerData); this.parseTilemapData(tilemapData, layerData);
this.scale = new Vec2(4, 4);
} }
isCollidable(): boolean { isCollidable(): boolean {
@ -39,9 +42,19 @@ export default abstract class Tilemap extends GameNode {
} }
getTileSize(): Vec2 { getTileSize(): Vec2 {
return this.tileSize; return this.tileSize.clone().scale(this.scale.x, this.scale.y);
} }
getScale(): Vec2 {
return this.scale;
}
setScale(scale: Vec2): void {
this.scale = scale;
}
abstract getTileAt(worldCoords: Vec2): number;
isReady(): boolean { isReady(): boolean {
if(this.tilesets.length !== 0){ if(this.tilesets.length !== 0){
for(let tileset of this.tilesets){ for(let tileset of this.tilesets){

View File

@ -10,6 +10,7 @@ export default class OrthogonalTilemap extends Tilemap {
this.worldSize.set(tilemapData.width, tilemapData.height); this.worldSize.set(tilemapData.width, tilemapData.height);
this.tileSize.set(tilemapData.tilewidth, tilemapData.tileheight); this.tileSize.set(tilemapData.tilewidth, tilemapData.tileheight);
this.data = layer.data; this.data = layer.data;
this.collisionData = this.data.map(tile => tile !== 0 ? 1 : 0);
this.visible = layer.visible; this.visible = layer.visible;
this.collidable = false; this.collidable = false;
if(layer.properties){ if(layer.properties){
@ -22,7 +23,40 @@ export default class OrthogonalTilemap extends Tilemap {
tilemapData.tilesets.forEach(tilesetData => this.tilesets.push(new Tileset(tilesetData))); tilemapData.tilesets.forEach(tilesetData => this.tilesets.push(new Tileset(tilesetData)));
} }
forEachTile(func: Function){ getTileAt(worldCoords: Vec2): number {
let localCoords = this.getColRowAt(worldCoords);
if(localCoords.x < 0 || localCoords.x >= this.worldSize.x || localCoords.y < 0 || localCoords.y >= this.worldSize.y){
// There are no tiles in negative positions or out of bounds positions
return 0;
}
return this.data[localCoords.y * this.worldSize.x + localCoords.x];
}
isTileCollidable(indexOrCol: number, row?: number): boolean {
if(row){
if(indexOrCol < 0 || indexOrCol >= this.worldSize.x || row < 0 || row >= this.worldSize.y){
// There are no tiles in negative positions or out of bounds positions
return false;
}
return this.collisionData[row * this.worldSize.x + indexOrCol] === 1 && this.collidable;
} else {
if(indexOrCol < 0 || indexOrCol >= this.collisionData.length){
// Tiles that don't exist aren't collidable
return false;
}
return this.collisionData[indexOrCol] === 1 && this.collidable;
}
}
// TODO: Should this throw an error if someone tries to access an out of bounds value?
getColRowAt(worldCoords: Vec2): Vec2 {
let col = Math.floor(worldCoords.x / this.tileSize.x / this.scale.x);
let row = Math.floor(worldCoords.y / this.tileSize.y / this.scale.y);
return new Vec2(col, row);
}
forEachTile(func: Function): void {
for(let i = 0; i < this.data.length; i++){ for(let i = 0; i < this.data.length; i++){
func(this.data[i], i); func(this.data[i], i);
} }
@ -37,7 +71,7 @@ export default class OrthogonalTilemap extends Tilemap {
for(let tileset of this.tilesets){ for(let tileset of this.tilesets){
if(tileset.hasTile(tileIndex)){ if(tileset.hasTile(tileIndex)){
tileset.renderTile(ctx, tileIndex, i, this.worldSize, origin); tileset.renderTile(ctx, tileIndex, i, this.worldSize, origin, this.scale);
} }
} }
} }

View File

@ -3,14 +3,18 @@ import Vec2 from "../DataTypes/Vec2";
import StaticBody from "./StaticBody"; import StaticBody from "./StaticBody";
import Debug from "../Debug/Debug"; import Debug from "../Debug/Debug";
import MathUtils from "../Utils/MathUtils"; import MathUtils from "../Utils/MathUtils";
import Tilemap from "../Nodes/Tilemap";
import OrthogonalTilemap from "../Nodes/Tilemaps/OrthogonalTilemap";
export default class PhysicsManager { export default class PhysicsManager {
physicsNodes: Array<PhysicsNode>; physicsNodes: Array<PhysicsNode>;
tilemaps: Array<Tilemap>;
movements: Array<MovementData>; movements: Array<MovementData>;
constructor(){ constructor(){
this.physicsNodes = new Array(); this.physicsNodes = new Array();
this.tilemaps = new Array();
this.movements = new Array(); this.movements = new Array();
} }
@ -18,6 +22,10 @@ export default class PhysicsManager {
this.physicsNodes.push(node); this.physicsNodes.push(node);
} }
addTilemap(tilemap: Tilemap): void {
this.tilemaps.push(tilemap);
}
addMovement(node: PhysicsNode, velocity: Vec2){ addMovement(node: PhysicsNode, velocity: Vec2){
this.movements.push(new MovementData(node, velocity)); this.movements.push(new MovementData(node, velocity));
} }
@ -51,8 +59,14 @@ export default class PhysicsManager {
} }
} }
for(let staticNode of staticSet){ // TODO handle collisions between dynamic nodes
this.handleCollision(movingNode, staticNode, velocity, (<StaticBody>staticNode).id); // 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); movingNode.finishMove(velocity);
@ -62,102 +76,90 @@ export default class PhysicsManager {
this.movements = new Array(); this.movements = new Array();
} }
collideWithTilemap(node: PhysicsNode, tilemap: Tilemap, velocity: Vec2){
if(tilemap instanceof OrthogonalTilemap){
this.collideWithOrthogonalTilemap(node, tilemap, velocity);
}
}
collideWithOrthogonalTilemap(node: PhysicsNode, tilemap: OrthogonalTilemap, velocity: Vec2){
let startPos = node.getPosition();
let endPos = startPos.clone().add(velocity);
let size = node.getCollider().getSize();
let min = new Vec2(Math.min(startPos.x, endPos.x), Math.min(startPos.y, endPos.y));
let max = new Vec2(Math.max(startPos.x + size.x, endPos.x + size.x), Math.max(startPos.y + size.y, endPos.y + size.y));
let minIndex = tilemap.getColRowAt(min);
let maxIndex = tilemap.getColRowAt(max);
let tilemapCollisions = new Array<TileCollisionData>();
let tileSize = tilemap.getTileSize();
Debug.getInstance().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");
// Tile position
let tilePos = new Vec2(col * tileSize.x, row * tileSize.y);
// Calculate collision area
let dx = Math.min(startPos.x, tilePos.x) - Math.max(startPos.x + size.x, tilePos.x + size.x);
let dy = Math.min(startPos.y, tilePos.y) - Math.max(startPos.y + size.y, tilePos.y + size.y);
let overlap = 0;
if(dx * dy > 0){
overlap = dx * dy;
}
tilemapCollisions.push(new TileCollisionData(tilePos, overlap));
}
}
}
// Now that we have all collisions, sort by collision area
tilemapCollisions = tilemapCollisions.sort((a, b) => a.overlapArea - b.overlapArea);
// Resolve the collisions
tilemapCollisions.forEach(collision => {
let [firstContact, _, collidingX, collidingY] = this.getTimeOfCollision(startPos, size, velocity, collision.position, tileSize, new Vec2(0, 0));
// Handle collision
if( (firstContact.x < 1 || collidingX) && (firstContact.y < 1 || collidingY)){
if(collidingX && collidingY){
// If we're already intersecting, freak out I guess?
} else {
// let contactTime = Math.min(firstContact.x, firstContact.y);
// velocity.scale(contactTime);
let xScale = MathUtils.clamp(firstContact.x, 0, 1);
let yScale = MathUtils.clamp(firstContact.y, 0, 1);
// Handle special case of stickiness on corner to corner collisions
if(xScale === yScale){
xScale = 1;
}
if(yScale !== 1){
node.setIsGrounded(true);
}
velocity.scale(xScale, yScale);
}
}
})
}
handleCollision(movingNode: PhysicsNode, staticNode: PhysicsNode, velocity: Vec2, id: String){ handleCollision(movingNode: PhysicsNode, staticNode: PhysicsNode, velocity: Vec2, id: String){
let sizeA = movingNode.getCollider().getSize(); let sizeA = movingNode.getCollider().getSize();
let A = movingNode.getPosition(); let posA = movingNode.getPosition();
let velA = velocity; let velA = velocity;
let sizeB = staticNode.getCollider().getSize(); let sizeB = staticNode.getCollider().getSize();
let B = staticNode.getPosition(); let posB = staticNode.getPosition();
let velB = new Vec2(0, 0); let velB = new Vec2(0, 0);
let firstContact = new Vec2(0, 0); let [firstContact, _, collidingX, collidingY] = this.getTimeOfCollision(posA, sizeA, velA, posB, sizeB, velB);
let lastContact = new Vec2(0, 0);
let collidingX = false;
let collidingY = false;
// Sort by position
if(B.x < A.x){
// Swap, because B is to the left of A
let temp: Vec2;
temp = sizeA;
sizeA = sizeB;
sizeB = temp;
temp = A;
A = B;
B = temp;
temp = velA;
velA = velB;
velB = temp;
}
// A is left, B is right
firstContact.x = Infinity;
lastContact.x = Infinity;
if (B.x >= A.x + sizeA.x){
// If we aren't currently colliding
let relVel = velA.x - velB.x;
if(relVel > 0){
// If they are moving towards each other
firstContact.x = (B.x - (A.x + (sizeA.x)))/(relVel);
lastContact.x = ((B.x + sizeB.x) - A.x)/(relVel);
}
} else {
collidingX = true;
}
if(B.y < A.y){
// Swap, because B is above A
let temp: Vec2;
temp = sizeA;
sizeA = sizeB;
sizeB = temp;
temp = A;
A = B;
B = temp;
temp = velA;
velA = velB;
velB = temp;
}
// A is top, B is bottom
firstContact.y = Infinity;
lastContact.y = Infinity;
if (B.y >= A.y + sizeA.y){
// If we aren't currently colliding
let relVel = velA.y - velB.y;
if(relVel > 0){
// If they are moving towards each other
firstContact.y = (B.y - (A.y + (sizeA.y)))/(relVel);
lastContact.y = ((B.y + sizeB.y) - A.y)/(relVel);
}
} else {
collidingY = true;
}
if(B.x < A.x){
// Swap, because B is to the left of A
let temp: Vec2;
temp = sizeA;
sizeA = sizeB;
sizeB = temp;
temp = A;
A = B;
B = temp;
temp = velA;
velA = velB;
velB = temp;
}
if( (firstContact.x < 1 || collidingX) && (firstContact.y < 1 || collidingY)){ if( (firstContact.x < 1 || collidingX) && (firstContact.y < 1 || collidingY)){
if(collidingX && collidingY){ if(collidingX && collidingY){
@ -174,8 +176,91 @@ export default class PhysicsManager {
} }
} }
} }
/**
* Gets the collision time of two AABBs using continuous collision checking. Returns vectors representing the time
* 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] {
let firstContact = new Vec2(0, 0);
let lastContact = new Vec2(0, 0);
let collidingX = false;
let collidingY = false;
// Sort by position
if(posB.x < posA.x){
// Swap, because B is to the left of A
let temp: Vec2;
temp = sizeA;
sizeA = sizeB;
sizeB = temp;
temp = posA;
posA = posB;
posB = temp;
temp = velA;
velA = velB;
velB = temp;
} }
// A is left, B is right
firstContact.x = Infinity;
lastContact.x = Infinity;
if (posB.x >= posA.x + sizeA.x){
// If we aren't currently colliding
let relVel = velA.x - velB.x;
if(relVel > 0){
// If they are moving towards each other
firstContact.x = (posB.x - (posA.x + (sizeA.x)))/(relVel);
lastContact.x = ((posB.x + sizeB.x) - posA.x)/(relVel);
}
} else {
collidingX = true;
}
if(posB.y < posA.y){
// Swap, because B is above A
let temp: Vec2;
temp = sizeA;
sizeA = sizeB;
sizeB = temp;
temp = posA;
posA = posB;
posB = temp;
temp = velA;
velA = velB;
velB = temp;
}
// A is top, B is bottom
firstContact.y = Infinity;
lastContact.y = Infinity;
if (posB.y >= posA.y + sizeA.y){
// If we aren't currently colliding
let relVel = velA.y - velB.y;
if(relVel > 0){
// If they are moving towards each other
firstContact.y = (posB.y - (posA.y + (sizeA.y)))/(relVel);
lastContact.y = ((posB.y + sizeB.y) - posA.y)/(relVel);
}
} else {
collidingY = true;
}
return [firstContact, lastContact, collidingX, collidingY];
}
}
// Helper classes for internal data
class MovementData{ class MovementData{
node: PhysicsNode; node: PhysicsNode;
velocity: Vec2; velocity: Vec2;
@ -184,3 +269,12 @@ class MovementData{
this.velocity = velocity; this.velocity = velocity;
} }
} }
class TileCollisionData {
position: Vec2;
overlapArea: number;
constructor(position: Vec2, overlapArea: number){
this.position = position;
this.overlapArea = overlapArea;
}
}

View File

@ -16,7 +16,7 @@ export default class Player extends PhysicsNode {
super(); super();
this.type = type; this.type = type;
this.velocity = new Vec2(0, 0); this.velocity = new Vec2(0, 0);
this.speed = 500; this.speed = 600;
this.size = new Vec2(50, 50); this.size = new Vec2(50, 50);
this.collider = new AABB(); this.collider = new AABB();
this.collider.setSize(this.size); this.collider.setSize(this.size);

View File

@ -74,12 +74,12 @@ function main(){
pauseMenu.disable(); pauseMenu.disable();
} }
// backgroundScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/Background.json"); backgroundScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/Background.json");
// mainScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/Platformer.json"); mainScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/Platformer.json");
// let player = mainScene.physics.add(Player, "platformer"); let player = mainScene.physics.add(Player, "platformer");
mainScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/TopDown.json"); // mainScene.tilemap.add(OrthogonalTilemap, "assets/tilemaps/TopDown.json");
let player = mainScene.physics.add(Player, "topdown"); // let player = mainScene.physics.add(Player, "topdown");
mainScene.getViewport().follow(player); mainScene.getViewport().follow(player);

View File

@ -29,7 +29,7 @@
"src/Loop/GameLoop.ts", "src/Loop/GameLoop.ts",
"src/Nodes/Tilemaps/OrgthogonalTilemap.ts", "src/Nodes/Tilemaps/OrthogonalTilemap.ts",
"src/Nodes/UIElements/Button.ts", "src/Nodes/UIElements/Button.ts",
"src/Nodes/UIElements/Label.ts", "src/Nodes/UIElements/Label.ts",
"src/Nodes/CanvasNode.ts", "src/Nodes/CanvasNode.ts",