added resource loader
This commit is contained in:
parent
bd49258d30
commit
214eba6e71
|
@ -4,13 +4,15 @@ export default class Queue<T> implements Collection{
|
||||||
private readonly MAX_ELEMENTS: number;
|
private readonly MAX_ELEMENTS: number;
|
||||||
private q: Array<T>;
|
private q: Array<T>;
|
||||||
private head: number;
|
private head: number;
|
||||||
private tail: number;
|
private tail: number;
|
||||||
|
private size: number;
|
||||||
|
|
||||||
constructor(maxElements: number = 100){
|
constructor(maxElements: number = 100){
|
||||||
this.MAX_ELEMENTS = maxElements;
|
this.MAX_ELEMENTS = maxElements;
|
||||||
this.q = new Array(this.MAX_ELEMENTS);
|
this.q = new Array(this.MAX_ELEMENTS);
|
||||||
this.head = 0;
|
this.head = 0;
|
||||||
this.tail = 0;
|
this.tail = 0;
|
||||||
|
this.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enqueue(item: T): void{
|
enqueue(item: T): void{
|
||||||
|
@ -18,6 +20,7 @@ export default class Queue<T> implements Collection{
|
||||||
throw "Queue full - cannot add element"
|
throw "Queue full - cannot add element"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.size += 1;
|
||||||
this.q[this.tail] = item;
|
this.q[this.tail] = item;
|
||||||
this.tail = (this.tail + 1) % this.MAX_ELEMENTS;
|
this.tail = (this.tail + 1) % this.MAX_ELEMENTS;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +30,8 @@ export default class Queue<T> implements Collection{
|
||||||
throw "Queue empty - cannot remove element"
|
throw "Queue empty - cannot remove element"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.size -= 1;
|
||||||
let item = this.q[this.head];
|
let item = this.q[this.head];
|
||||||
this.head = (this.head + 1) % this.MAX_ELEMENTS;
|
this.head = (this.head + 1) % this.MAX_ELEMENTS;
|
||||||
|
|
||||||
|
@ -47,7 +52,13 @@ export default class Queue<T> implements Collection{
|
||||||
return this.head !== this.tail;
|
return this.head !== this.tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSize(): number {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This should actually delete the items in the queue instead of leaving them here
|
||||||
clear(): void {
|
clear(): void {
|
||||||
|
this.size = 0;
|
||||||
this.head = this.tail;
|
this.head = this.tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
src/DataTypes/Tilesets/TileLayer.ts
Normal file
5
src/DataTypes/Tilesets/TileLayer.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export default class TileLayer {
|
||||||
|
public data: Array<number>;
|
||||||
|
public collidable: boolean;
|
||||||
|
public visible: boolean;
|
||||||
|
}
|
|
@ -1,45 +0,0 @@
|
||||||
import Scene from "../Scene";
|
|
||||||
import Viewport from "../../SceneGraph/Viewport";
|
|
||||||
import Tilemap from "../../Nodes/Tilemap"
|
|
||||||
import ResourceManager from "../../ResourceManager/ResourceManager";
|
|
||||||
import { TiledTilemapData } from "../../DataTypes/Tilesets/TiledData";
|
|
||||||
import StringUtils from "../../Utils/StringUtils";
|
|
||||||
import StaticBody from "../../Physics/StaticBody";
|
|
||||||
import Vec2 from "../../DataTypes/Vec2";
|
|
||||||
|
|
||||||
export default class TilemapFactory {
|
|
||||||
private scene: Scene;
|
|
||||||
// TODO: get the resource manager OUT of here, it does not belong
|
|
||||||
private resourceManager: ResourceManager;
|
|
||||||
|
|
||||||
constructor(scene: Scene){
|
|
||||||
this.scene = scene;
|
|
||||||
this.resourceManager = ResourceManager.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
add<T extends Tilemap>(constr: new (...a: any) => T, path: string, ...args: any): void {
|
|
||||||
this.resourceManager.loadTilemap(path, (tilemapData: TiledTilemapData) => {
|
|
||||||
// For each of the layers in the tilemap, create a tilemap
|
|
||||||
for(let layer of tilemapData.layers){
|
|
||||||
let tilemap = new constr(tilemapData, layer);
|
|
||||||
tilemap.init(this.scene);
|
|
||||||
|
|
||||||
// Add to scene
|
|
||||||
this.scene.addTilemap(tilemap);
|
|
||||||
|
|
||||||
if(tilemap.isCollidable()){
|
|
||||||
// Register in physics as a tilemap
|
|
||||||
this.scene.physics.addTilemap(tilemap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load images for the tilesets
|
|
||||||
tilemap.getTilesets().forEach(tileset => {
|
|
||||||
let imagePath = StringUtils.getPathFromFilePath(path) + tileset.getImageUrl();
|
|
||||||
this.resourceManager.loadImage(imagePath, (path: string, image: HTMLImageElement) => {
|
|
||||||
tileset.setImage(image);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
import Stack from "../DataTypes/Stack";
|
|
||||||
import Scene from "./Scene";
|
|
||||||
import Viewport from "../SceneGraph/Viewport";
|
|
||||||
import Vec2 from "../DataTypes/Vec2";
|
|
||||||
|
|
||||||
export default class GameState{
|
|
||||||
private sceneStack: Stack<Scene>;
|
|
||||||
private worldSize: Vec2;
|
|
||||||
private viewport: Viewport;
|
|
||||||
|
|
||||||
constructor(viewport: Viewport){
|
|
||||||
this.sceneStack = new Stack(10);
|
|
||||||
this.worldSize = new Vec2(1600, 1000);
|
|
||||||
this.viewport = viewport;
|
|
||||||
this.viewport.setBounds(0, 0, 2560, 1280);
|
|
||||||
}
|
|
||||||
|
|
||||||
createScene(): Scene{
|
|
||||||
let scene = new Scene(this.viewport, this);
|
|
||||||
this.addScene(scene);
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
addScene(scene: Scene): void {
|
|
||||||
this.sceneStack.push(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeScene(startNewTopScene: boolean = true): void {
|
|
||||||
this.sceneStack.pop();
|
|
||||||
this.sceneStack.peek().setPaused(!startNewTopScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeScene(scene: Scene): void {
|
|
||||||
this.sceneStack.clear();
|
|
||||||
this.sceneStack.push(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {
|
|
||||||
this.sceneStack.forEach((scene: Scene) => scene.update(deltaT));
|
|
||||||
}
|
|
||||||
|
|
||||||
render(ctx: CanvasRenderingContext2D): void {
|
|
||||||
this.sceneStack.forEach((scene: Scene) => scene.render(ctx));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,10 +2,10 @@ import EventQueue from "../Events/EventQueue";
|
||||||
import InputReceiver from "../Input/InputReceiver";
|
import InputReceiver from "../Input/InputReceiver";
|
||||||
import InputHandler from "../Input/InputHandler";
|
import InputHandler from "../Input/InputHandler";
|
||||||
import Recorder from "../Playback/Recorder";
|
import Recorder from "../Playback/Recorder";
|
||||||
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";
|
import Viewport from "../SceneGraph/Viewport";
|
||||||
|
import SceneManager from "../Scene/SceneManager";
|
||||||
|
|
||||||
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
|
||||||
|
@ -37,8 +37,8 @@ export default class GameLoop{
|
||||||
private inputHandler: InputHandler;
|
private inputHandler: InputHandler;
|
||||||
private inputReceiver: InputReceiver;
|
private inputReceiver: InputReceiver;
|
||||||
private recorder: Recorder;
|
private recorder: Recorder;
|
||||||
private gameState: GameState;
|
|
||||||
private resourceManager: ResourceManager;
|
private resourceManager: ResourceManager;
|
||||||
|
private sceneManager: SceneManager;
|
||||||
|
|
||||||
constructor(){
|
constructor(){
|
||||||
this.maxFPS = 60;
|
this.maxFPS = 60;
|
||||||
|
@ -66,8 +66,8 @@ export default class GameLoop{
|
||||||
this.inputReceiver = InputReceiver.getInstance();
|
this.inputReceiver = InputReceiver.getInstance();
|
||||||
this.inputReceiver.setViewport(this.viewport);
|
this.inputReceiver.setViewport(this.viewport);
|
||||||
this.recorder = new Recorder();
|
this.recorder = new Recorder();
|
||||||
this.gameState = new GameState(this.viewport);
|
|
||||||
this.resourceManager = ResourceManager.getInstance();
|
this.resourceManager = ResourceManager.getInstance();
|
||||||
|
this.sceneManager = new SceneManager(this.viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
private initializeCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {
|
private initializeCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {
|
||||||
|
@ -83,8 +83,8 @@ export default class GameLoop{
|
||||||
this.simulationTimestep = Math.floor(1000/this.maxFPS);
|
this.simulationTimestep = Math.floor(1000/this.maxFPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGameState(): GameState {
|
getSceneManager(): SceneManager {
|
||||||
return this.gameState;
|
return this.sceneManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateFrameCount(timestep: number): void {
|
private updateFrameCount(timestep: number): void {
|
||||||
|
@ -149,12 +149,12 @@ export default class GameLoop{
|
||||||
this.eventQueue.update(deltaT);
|
this.eventQueue.update(deltaT);
|
||||||
this.inputReceiver.update(deltaT);
|
this.inputReceiver.update(deltaT);
|
||||||
this.recorder.update(deltaT);
|
this.recorder.update(deltaT);
|
||||||
this.gameState.update(deltaT);
|
this.sceneManager.update(deltaT);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): void {
|
render(): void {
|
||||||
this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
|
this.ctx.clearRect(0, 0, this.WIDTH, this.HEIGHT);
|
||||||
this.gameState.render(this.ctx);
|
this.sceneManager.render(this.ctx);
|
||||||
Debug.render(this.ctx);
|
Debug.render(this.ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import GameNode from "./GameNode";
|
import GameNode from "./GameNode";
|
||||||
import Vec2 from "../DataTypes/Vec2";
|
import Vec2 from "../DataTypes/Vec2";
|
||||||
import Scene from "../GameState/Scene";
|
import Layer from "../Scene/Layer";
|
||||||
|
|
||||||
export default abstract class CanvasNode extends GameNode{
|
export default abstract class CanvasNode extends GameNode{
|
||||||
protected size: Vec2;
|
protected size: Vec2;
|
||||||
|
|
|
@ -4,14 +4,14 @@ import Vec2 from "../DataTypes/Vec2";
|
||||||
import Map from "../DataTypes/Map";
|
import Map from "../DataTypes/Map";
|
||||||
import Receiver from "../Events/Receiver";
|
import Receiver from "../Events/Receiver";
|
||||||
import GameEvent from "../Events/GameEvent";
|
import GameEvent from "../Events/GameEvent";
|
||||||
import Scene from "../GameState/Scene";
|
import Layer from "../Scene/Layer";
|
||||||
|
|
||||||
export default abstract class GameNode{
|
export default abstract class GameNode{
|
||||||
private eventQueue: EventQueue;
|
private eventQueue: EventQueue;
|
||||||
protected input: InputReceiver;
|
protected input: InputReceiver;
|
||||||
protected position: Vec2;
|
protected position: Vec2;
|
||||||
private receiver: Receiver;
|
private receiver: Receiver;
|
||||||
protected scene: Scene;
|
protected scene: Layer;
|
||||||
|
|
||||||
constructor(){
|
constructor(){
|
||||||
this.eventQueue = EventQueue.getInstance();
|
this.eventQueue = EventQueue.getInstance();
|
||||||
|
@ -19,11 +19,11 @@ export default abstract class GameNode{
|
||||||
this.position = new Vec2(0, 0);
|
this.position = new Vec2(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
init(scene: Scene){
|
init(scene: Layer){
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
getScene(): Scene {
|
getScene(): Layer {
|
||||||
return this.scene;
|
return this.scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,38 +2,28 @@ import Vec2 from "../DataTypes/Vec2";
|
||||||
import GameNode from "./GameNode";
|
import GameNode from "./GameNode";
|
||||||
import Tileset from "../DataTypes/Tilesets/Tileset";
|
import Tileset from "../DataTypes/Tilesets/Tileset";
|
||||||
import { TiledTilemapData, TiledLayerData } from "../DataTypes/Tilesets/TiledData"
|
import { TiledTilemapData, TiledLayerData } from "../DataTypes/Tilesets/TiledData"
|
||||||
|
import TileLayer from "../DataTypes/Tilesets/TileLayer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents one layer of tiles
|
* Represents one layer of tiles
|
||||||
*/
|
*/
|
||||||
export default abstract class Tilemap extends GameNode {
|
export default abstract class Tilemap extends GameNode {
|
||||||
protected data: number[];
|
protected tilesets: Array<Tileset>;
|
||||||
protected collisionData: number[];
|
|
||||||
protected tilesets: Tileset[];
|
|
||||||
protected worldSize: Vec2;
|
protected worldSize: Vec2;
|
||||||
protected tileSize: Vec2;
|
protected tileSize: Vec2;
|
||||||
protected visible: boolean;
|
|
||||||
protected collidable: boolean;
|
|
||||||
protected scale: Vec2;
|
protected scale: Vec2;
|
||||||
|
protected layers: Array<TileLayer>;
|
||||||
|
|
||||||
// TODO: Make this no longer be specific to Tiled
|
// TODO: Make this no longer be specific to Tiled
|
||||||
constructor(tilemapData: TiledTilemapData, layerData: TiledLayerData) {
|
constructor(tilemapData: TiledTilemapData) {
|
||||||
super();
|
super();
|
||||||
this.tilesets = new Array<Tileset>();
|
this.tilesets = new Array<Tileset>();
|
||||||
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);
|
||||||
this.scale = new Vec2(4, 4);
|
this.scale = new Vec2(4, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
isCollidable(): boolean {
|
|
||||||
return this.collidable;
|
|
||||||
}
|
|
||||||
|
|
||||||
isVisible(): boolean {
|
|
||||||
return this.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTilesets(): Tileset[] {
|
getTilesets(): Tileset[] {
|
||||||
return this.tilesets;
|
return this.tilesets;
|
||||||
}
|
}
|
||||||
|
@ -56,24 +46,11 @@ export default abstract class Tilemap extends GameNode {
|
||||||
|
|
||||||
abstract getTileAt(worldCoords: Vec2): number;
|
abstract getTileAt(worldCoords: Vec2): number;
|
||||||
|
|
||||||
isReady(): boolean {
|
|
||||||
if(this.tilesets.length !== 0){
|
|
||||||
for(let tileset of this.tilesets){
|
|
||||||
if(!tileset.isReady()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract forEachTile(func: Function): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up the tileset using the data loaded from file
|
* Sets up the tileset using the data loaded from file
|
||||||
*/
|
*/
|
||||||
// TODO: This shouldn't use tiled data specifically - it should be more general
|
// TODO: This shouldn't use tiled data specifically - it should be more general
|
||||||
protected abstract parseTilemapData(tilemapData: TiledTilemapData, layerData: TiledLayerData): void;
|
protected abstract parseTilemapData(tilemapData: TiledTilemapData): void;
|
||||||
|
|
||||||
abstract render(ctx: CanvasRenderingContext2D, origin: Vec2, viewportSize: Vec2): void;
|
abstract render(ctx: CanvasRenderingContext2D, origin: Vec2, viewportSize: Vec2): void;
|
||||||
}
|
}
|
|
@ -2,27 +2,33 @@ import Tilemap from "../Tilemap";
|
||||||
import Vec2 from "../../DataTypes/Vec2";
|
import Vec2 from "../../DataTypes/Vec2";
|
||||||
import { TiledTilemapData, TiledLayerData } from "../../DataTypes/Tilesets/TiledData";
|
import { TiledTilemapData, TiledLayerData } from "../../DataTypes/Tilesets/TiledData";
|
||||||
import Tileset from "../../DataTypes/Tilesets/Tileset";
|
import Tileset from "../../DataTypes/Tilesets/Tileset";
|
||||||
|
import TileLayer from "../../DataTypes/Tilesets/TileLayer";
|
||||||
|
|
||||||
|
|
||||||
export default class OrthogonalTilemap extends Tilemap {
|
export default class OrthogonalTilemap extends Tilemap {
|
||||||
|
|
||||||
protected parseTilemapData(tilemapData: TiledTilemapData, layer: TiledLayerData): void {
|
protected parseTilemapData(tilemapData: TiledTilemapData): void {
|
||||||
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;
|
for(let layerData of tilemapData.layers){
|
||||||
this.collisionData = this.data.map(tile => tile !== 0 ? 1 : 0);
|
let layer = new TileLayer();
|
||||||
this.visible = layer.visible;
|
layer.data = layer.data;
|
||||||
this.collidable = false;
|
layer.visible = layer.visible;
|
||||||
if(layer.properties){
|
layer.collidable = false;
|
||||||
for(let item of layer.properties){
|
if(layerData.properties){
|
||||||
if(item.name === "Collidable"){
|
for(let item of layerData.properties){
|
||||||
this.collidable = item.value;
|
if(item.name === "Collidable"){
|
||||||
|
layer.collidable = item.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.layers.push(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
tilemapData.tilesets.forEach(tilesetData => this.tilesets.push(new Tileset(tilesetData)));
|
tilemapData.tilesets.forEach(tilesetData => this.tilesets.push(new Tileset(tilesetData)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO - Should this even work as it currently does? The layers make things more complicated
|
||||||
getTileAt(worldCoords: Vec2): number {
|
getTileAt(worldCoords: Vec2): number {
|
||||||
let localCoords = this.getColRowAt(worldCoords);
|
let localCoords = this.getColRowAt(worldCoords);
|
||||||
if(localCoords.x < 0 || localCoords.x >= this.worldSize.x || localCoords.y < 0 || localCoords.y >= this.worldSize.y){
|
if(localCoords.x < 0 || localCoords.x >= this.worldSize.x || localCoords.y < 0 || localCoords.y >= this.worldSize.y){
|
||||||
|
@ -30,23 +36,39 @@ export default class OrthogonalTilemap extends Tilemap {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.data[localCoords.y * this.worldSize.x + localCoords.x];
|
// Return the top nonzero tile
|
||||||
|
let tile = 0;
|
||||||
|
for(let layer of this.layers){
|
||||||
|
if(layer.data[localCoords.y * this.worldSize.x + localCoords.x] !== 0){
|
||||||
|
tile = layer.data[localCoords.y * this.worldSize.x + localCoords.x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
isTileCollidable(indexOrCol: number, row?: number): boolean {
|
isTileCollidable(indexOrCol: number, row?: number): boolean {
|
||||||
|
let index = 0;
|
||||||
if(row){
|
if(row){
|
||||||
if(indexOrCol < 0 || indexOrCol >= this.worldSize.x || row < 0 || row >= this.worldSize.y){
|
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
|
// There are no tiles in negative positions or out of bounds positions
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.collisionData[row * this.worldSize.x + indexOrCol] === 1 && this.collidable;
|
index = row * this.worldSize.x + indexOrCol;
|
||||||
} else {
|
} else {
|
||||||
if(indexOrCol < 0 || indexOrCol >= this.collisionData.length){
|
if(indexOrCol < 0 || indexOrCol >= this.layers[0].data.length){
|
||||||
// Tiles that don't exist aren't collidable
|
// Tiles that don't exist aren't collidable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.collisionData[indexOrCol] === 1 && this.collidable;
|
index = indexOrCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(let layer of this.layers){
|
||||||
|
if(layer.data[index] !== 0 && layer.collidable){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Should this throw an error if someone tries to access an out of bounds value?
|
// TODO: Should this throw an error if someone tries to access an out of bounds value?
|
||||||
|
@ -56,22 +78,20 @@ export default class OrthogonalTilemap extends Tilemap {
|
||||||
return new Vec2(col, row);
|
return new Vec2(col, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachTile(func: Function): void {
|
|
||||||
for(let i = 0; i < this.data.length; i++){
|
|
||||||
func(this.data[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update(deltaT: number): void {}
|
update(deltaT: number): void {}
|
||||||
|
|
||||||
// TODO: Don't render tiles that aren't on screen
|
// TODO: Don't render tiles that aren't on screen
|
||||||
render(ctx: CanvasRenderingContext2D, origin: Vec2, viewportSize: Vec2) {
|
render(ctx: CanvasRenderingContext2D, origin: Vec2, viewportSize: Vec2) {
|
||||||
for(let i = 0; i < this.data.length; i++){
|
for(let layer of this.layers){
|
||||||
let tileIndex = this.data[i];
|
if(layer.visible){
|
||||||
|
for(let i = 0; i < layer.data.length; i++){
|
||||||
|
let tileIndex = layer.data[i];
|
||||||
|
|
||||||
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, this.scale);
|
tileset.renderTile(ctx, tileIndex, i, this.worldSize, origin, this.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,37 @@
|
||||||
|
import Map from "../DataTypes/Map";
|
||||||
|
import Tilemap from "../Nodes/Tilemap";
|
||||||
|
import Queue from "../DataTypes/Queue";
|
||||||
|
import { TiledTilemapData } from "../DataTypes/Tilesets/TiledData";
|
||||||
|
import StringUtils from "../Utils/StringUtils";
|
||||||
|
|
||||||
export default class ResourceManager {
|
export default class ResourceManager {
|
||||||
private static instance: ResourceManager;
|
private static instance: ResourceManager;
|
||||||
|
|
||||||
|
private loading: boolean;
|
||||||
|
|
||||||
private constructor(){};
|
private imagesLoaded: number;
|
||||||
|
private imagesToLoad: number;
|
||||||
|
private imageLoadingQueue: Queue<{key: string, path: string}>;
|
||||||
|
private images: Map<HTMLImageElement>;
|
||||||
|
|
||||||
|
private tilemapsLoaded: number;
|
||||||
|
private tilemapsToLoad: number;
|
||||||
|
private tilemapLoadingQueue: Queue<{key: string, path: string}>;
|
||||||
|
private tilemaps: Map<TiledTilemapData>;
|
||||||
|
|
||||||
|
private constructor(){
|
||||||
|
this.loading = false;
|
||||||
|
|
||||||
|
this.imagesLoaded = 0;
|
||||||
|
this.imagesToLoad = 0;
|
||||||
|
this.imageLoadingQueue = new Queue();
|
||||||
|
this.images = new Map();
|
||||||
|
|
||||||
|
this.tilemapsLoaded = 0;
|
||||||
|
this.tilemapsToLoad = 0;
|
||||||
|
this.tilemapLoadingQueue = new Queue();
|
||||||
|
this.tilemaps = new Map();
|
||||||
|
};
|
||||||
|
|
||||||
static getInstance(): ResourceManager {
|
static getInstance(): ResourceManager {
|
||||||
if(!this.instance){
|
if(!this.instance){
|
||||||
|
@ -11,11 +41,128 @@ export default class ResourceManager {
|
||||||
return this.instance;
|
return this.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadTilemap(pathToTilemapJSON: string, callback: Function): void {
|
public image(key: string, path: string): void {
|
||||||
this.loadTextFile(pathToTilemapJSON, (fileText: string) => {
|
this.imageLoadingQueue.enqueue({key: key, path: path});
|
||||||
let tilemapObject = JSON.parse(fileText);
|
}
|
||||||
callback(tilemapObject);
|
|
||||||
|
public spritesheet(key: string, path: string, frames: {hFrames: number, vFrames: number}): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public audio(key: string, path: string): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This one is trickier than the others because we first have to load the json file, then we have to load the images
|
||||||
|
public tilemap(key: string, path: string): void {
|
||||||
|
// Add a function that loads the tilemap to the queue
|
||||||
|
this.tilemapLoadingQueue.enqueue({key: key, path: path});
|
||||||
|
|
||||||
|
// this.tilemapLoadingQueue.enqueue((callback: Function) => {
|
||||||
|
// this.loadTilemap(path, (tilemapData: TiledTilemapData) => {
|
||||||
|
// // When the tilemap file loads, first construct the tilemap
|
||||||
|
// // TODO: Ignore multiple layers for now, but this will have to be elegantly dealt with sometime in the future
|
||||||
|
|
||||||
|
// // Count the total number of images that need to be loaded
|
||||||
|
|
||||||
|
// let tilemap = new constr(tilemapData);
|
||||||
|
// // For each of the tilesets in the tilemap, load the image
|
||||||
|
// tilemap.getTilesets().forEach(tileset => {
|
||||||
|
// let imagePath = StringUtils.getPathFromFilePath(path) + tileset.getImageUrl();
|
||||||
|
// this.loadImage(imagePath, (image: HTMLImageElement) => {
|
||||||
|
// tileset.setImage(image);
|
||||||
|
// })
|
||||||
|
// });
|
||||||
|
|
||||||
|
// this.tilemaps.add(key, tilemap);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
loadResourcesFromQueue(callback: Function): void {
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
|
// Load everything in the queues. Tilemaps have to come before images because they will add new images to the queue
|
||||||
|
this.loadTilemapsFromQueue(() => {
|
||||||
|
this.loadImagesFromQueue(() => {
|
||||||
|
// Done loading
|
||||||
|
this.loading = false;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadTilemapsFromQueue(onFinishLoading: Function){
|
||||||
|
this.tilemapsToLoad = this.tilemapLoadingQueue.getSize();
|
||||||
|
this.tilemapsLoaded = 0;
|
||||||
|
|
||||||
|
while(this.tilemapLoadingQueue.hasItems()){
|
||||||
|
let tilemap = this.tilemapLoadingQueue.dequeue();
|
||||||
|
this.loadTilemap(tilemap.key, tilemap.path, onFinishLoading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadTilemap(key: string, pathToTilemapJSON: string, callbackIfLast: Function): void {
|
||||||
|
this.loadTextFile(pathToTilemapJSON, (fileText: string) => {
|
||||||
|
let tilemapObject = <TiledTilemapData>JSON.parse(fileText);
|
||||||
|
|
||||||
|
// We can parse the object later - it's much faster than loading
|
||||||
|
this.tilemaps.add(key, tilemapObject);
|
||||||
|
|
||||||
|
// Grab the tileset images we need to load and add them to the imageloading queue
|
||||||
|
for(let tileset of tilemapObject.tilesets){
|
||||||
|
let key = tileset.image;
|
||||||
|
let path = StringUtils.getPathFromFilePath(pathToTilemapJSON) + key;
|
||||||
|
this.imageLoadingQueue.enqueue({key: key, path: path});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish loading
|
||||||
|
this.finishLoadingTilemap(callbackIfLast);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private finishLoadingTilemap(callback: Function){
|
||||||
|
this.tilemapsLoaded += 1;
|
||||||
|
|
||||||
|
if(this.tilemapsLoaded === this.tilemapsToLoad){
|
||||||
|
// We're done loading tilemaps
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadImagesFromQueue(onFinishLoading: Function): void {
|
||||||
|
this.imagesToLoad = this.imageLoadingQueue.getSize();
|
||||||
|
this.tilemapsLoaded = 0;
|
||||||
|
|
||||||
|
while(this.imageLoadingQueue.hasItems()){
|
||||||
|
let image = this.imageLoadingQueue.dequeue();
|
||||||
|
this.loadImage(image.key, image.path, onFinishLoading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: When you switch to WebGL, make sure to make this private and make a "loadTexture" function
|
||||||
|
public loadImage(key: string, path: string, callbackIfLast: Function): void {
|
||||||
|
var image = new Image();
|
||||||
|
|
||||||
|
image.onload = () => {
|
||||||
|
// Add to loaded images
|
||||||
|
this.images.add(key, image);
|
||||||
|
|
||||||
|
// Finish image load
|
||||||
|
this.finishLoadingImage(callbackIfLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.src = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private finishLoadingImage(callback: Function): void {
|
||||||
|
this.imagesLoaded += 1;
|
||||||
|
|
||||||
|
if(this.imagesLoaded === this.imagesToLoad ){
|
||||||
|
// We're done loading tilemaps
|
||||||
|
callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadTextFile(textFilePath: string, callback: Function): void {
|
private loadTextFile(textFilePath: string, callback: Function): void {
|
||||||
|
@ -29,15 +176,4 @@ export default class ResourceManager {
|
||||||
};
|
};
|
||||||
xobj.send(null);
|
xobj.send(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: When you switch to WebGL, make sure to make this private and make a "loadTexture" function
|
|
||||||
public loadImage(path: string, callback: Function): void {
|
|
||||||
var image = new Image();
|
|
||||||
|
|
||||||
image.onload = function () {
|
|
||||||
callback(path, image);
|
|
||||||
}
|
|
||||||
|
|
||||||
image.src = path;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
import Scene from "../Scene";
|
import Layer from "../Layer";
|
||||||
import Viewport from "../../SceneGraph/Viewport";
|
import Viewport from "../../SceneGraph/Viewport";
|
||||||
import CanvasItem from "../../Nodes/CanvasNode"
|
import CanvasItem from "../../Nodes/CanvasNode"
|
||||||
|
|
||||||
export default class CanvasNodeFactory {
|
export default class CanvasNodeFactory {
|
||||||
private scene: Scene;
|
private scene: Layer;
|
||||||
|
|
||||||
constructor(scene: Scene){
|
constructor(scene: Layer){
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import Scene from "../Scene";
|
import Layer from "../Layer";
|
||||||
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";
|
import Tilemap from "../../Nodes/Tilemap";
|
||||||
|
|
||||||
export default class PhysicsNodeFactory {
|
export default class PhysicsNodeFactory {
|
||||||
private scene: Scene;
|
private scene: Layer;
|
||||||
private physicsManager: PhysicsManager;
|
private physicsManager: PhysicsManager;
|
||||||
|
|
||||||
constructor(scene: Scene, physicsManager: PhysicsManager){
|
constructor(scene: Layer, physicsManager: PhysicsManager){
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.physicsManager = physicsManager;
|
this.physicsManager = physicsManager;
|
||||||
}
|
}
|
45
src/Scene/Factories/TilemapFactory.ts
Normal file
45
src/Scene/Factories/TilemapFactory.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import Layer from "../Layer";
|
||||||
|
import Viewport from "../../SceneGraph/Viewport";
|
||||||
|
import Tilemap from "../../Nodes/Tilemap";
|
||||||
|
import ResourceManager from "../../ResourceManager/ResourceManager";
|
||||||
|
import { TiledTilemapData } from "../../DataTypes/Tilesets/TiledData";
|
||||||
|
import StringUtils from "../../Utils/StringUtils";
|
||||||
|
import StaticBody from "../../Physics/StaticBody";
|
||||||
|
import Vec2 from "../../DataTypes/Vec2";
|
||||||
|
|
||||||
|
export default class TilemapFactory {
|
||||||
|
private scene: Layer;
|
||||||
|
// TODO: get the resource manager OUT of here, it does not belong
|
||||||
|
private resourceManager: ResourceManager;
|
||||||
|
|
||||||
|
constructor(scene: Layer){
|
||||||
|
this.scene = scene;
|
||||||
|
this.resourceManager = ResourceManager.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
add<T extends Tilemap>(constr: new (...a: any) => T, path: string, ...args: any): void {
|
||||||
|
// this.resourceManager.loadTilemap(path, (tilemapData: TiledTilemapData) => {
|
||||||
|
// // For each of the layers in the tilemap, create a tilemap
|
||||||
|
// for(let layer of tilemapData.layers){
|
||||||
|
// let tilemap = new constr(tilemapData, layer);
|
||||||
|
// tilemap.init(this.scene);
|
||||||
|
|
||||||
|
// // Add to scene
|
||||||
|
// this.scene.addTilemap(tilemap);
|
||||||
|
|
||||||
|
// if(tilemap.isCollidable()){
|
||||||
|
// // Register in physics as a tilemap
|
||||||
|
// this.scene.physics.addTilemap(tilemap);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Load images for the tilesets
|
||||||
|
// tilemap.getTilesets().forEach(tileset => {
|
||||||
|
// let imagePath = StringUtils.getPathFromFilePath(path) + tileset.getImageUrl();
|
||||||
|
// this.resourceManager.loadImage(imagePath, (path: string, image: HTMLImageElement) => {
|
||||||
|
// tileset.setImage(image);
|
||||||
|
// })
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,15 +4,15 @@ import SceneGraph from "../SceneGraph/SceneGraph";
|
||||||
import SceneGraphArray from "../SceneGraph/SceneGraphArray";
|
import SceneGraphArray from "../SceneGraph/SceneGraphArray";
|
||||||
import CanvasNode from "../Nodes/CanvasNode";
|
import CanvasNode from "../Nodes/CanvasNode";
|
||||||
import CanvasNodeFactory from "./Factories/CanvasNodeFactory";
|
import CanvasNodeFactory from "./Factories/CanvasNodeFactory";
|
||||||
import GameState from "./GameState";
|
import Scene from "./Scene";
|
||||||
import Tilemap from "../Nodes/Tilemap";
|
import Tilemap from "../Nodes/Tilemap";
|
||||||
import TilemapFactory from "./Factories/TilemapFactory";
|
import TilemapFactory from "./Factories/TilemapFactory";
|
||||||
import PhysicsManager from "../Physics/PhysicsManager";
|
import PhysicsManager from "../Physics/PhysicsManager";
|
||||||
import PhysicsNodeFactory from "./Factories/PhysicsNodeFactory";
|
import PhysicsNodeFactory from "./Factories/PhysicsNodeFactory";
|
||||||
import MathUtils from "../Utils/MathUtils";
|
import MathUtils from "../Utils/MathUtils";
|
||||||
|
|
||||||
export default class Scene {
|
export default class Layer {
|
||||||
private gameState: GameState;
|
private gameState: Scene;
|
||||||
private viewport: Viewport
|
private viewport: Viewport
|
||||||
private parallax: Vec2;
|
private parallax: Vec2;
|
||||||
private sceneGraph: SceneGraph;
|
private sceneGraph: SceneGraph;
|
||||||
|
@ -27,7 +27,7 @@ export default class Scene {
|
||||||
public tilemap: TilemapFactory;
|
public tilemap: TilemapFactory;
|
||||||
public physics: PhysicsNodeFactory;
|
public physics: PhysicsNodeFactory;
|
||||||
|
|
||||||
constructor(viewport: Viewport, gameState: GameState){
|
constructor(viewport: Viewport, gameState: Scene){
|
||||||
this.gameState = gameState;
|
this.gameState = gameState;
|
||||||
this.viewport = viewport;
|
this.viewport = viewport;
|
||||||
this.parallax = new Vec2(1, 1);
|
this.parallax = new Vec2(1, 1);
|
||||||
|
@ -114,9 +114,7 @@ export default class Scene {
|
||||||
|
|
||||||
// Render tilemaps
|
// Render tilemaps
|
||||||
this.tilemaps.forEach(tilemap => {
|
this.tilemaps.forEach(tilemap => {
|
||||||
if(tilemap.isReady() && tilemap.isVisible()){
|
tilemap.render(ctx, origin, size);
|
||||||
tilemap.render(ctx, origin, size);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Render visible set
|
// Render visible set
|
41
src/Scene/Scene.ts
Normal file
41
src/Scene/Scene.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import Stack from "../DataTypes/Stack";
|
||||||
|
import Layer from "./Layer";
|
||||||
|
import Viewport from "../SceneGraph/Viewport";
|
||||||
|
import Vec2 from "../DataTypes/Vec2";
|
||||||
|
|
||||||
|
export default class Scene{
|
||||||
|
private layers: Stack<Layer>;
|
||||||
|
private worldSize: Vec2;
|
||||||
|
private viewport: Viewport;
|
||||||
|
private running: boolean;
|
||||||
|
|
||||||
|
constructor(viewport: Viewport){
|
||||||
|
this.layers = new Stack(10);
|
||||||
|
this.worldSize = new Vec2(1600, 1000);
|
||||||
|
this.viewport = viewport;
|
||||||
|
this.viewport.setBounds(0, 0, 2560, 1280);
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadScene(): void {}
|
||||||
|
|
||||||
|
unloadScene(): void {}
|
||||||
|
|
||||||
|
setRunning(running: boolean): void {
|
||||||
|
this.running = running;
|
||||||
|
}
|
||||||
|
|
||||||
|
isRunning(): boolean {
|
||||||
|
return this.isRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
start(){}
|
||||||
|
|
||||||
|
update(deltaT: number): void {
|
||||||
|
this.layers.forEach((scene: Layer) => scene.update(deltaT));
|
||||||
|
}
|
||||||
|
|
||||||
|
render(ctx: CanvasRenderingContext2D): void {
|
||||||
|
this.layers.forEach((scene: Layer) => scene.render(ctx));
|
||||||
|
}
|
||||||
|
}
|
39
src/Scene/SceneManager.ts
Normal file
39
src/Scene/SceneManager.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import Scene from "./Scene";
|
||||||
|
import ResourceManager from "../ResourceManager/ResourceManager";
|
||||||
|
import Viewport from "../SceneGraph/Viewport";
|
||||||
|
|
||||||
|
export default class SceneManager{
|
||||||
|
|
||||||
|
private currentScene: Scene;
|
||||||
|
private viewport: Viewport;
|
||||||
|
private resourceManager: ResourceManager;
|
||||||
|
|
||||||
|
constructor(viewport: Viewport){
|
||||||
|
this.resourceManager = ResourceManager.getInstance();
|
||||||
|
this.viewport = viewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addScene<T extends Scene>(constr: new (...args: any) => T){
|
||||||
|
let scene = new constr(this.viewport);
|
||||||
|
this.currentScene = scene;
|
||||||
|
|
||||||
|
// Enqueue all scene asset loads
|
||||||
|
scene.loadScene();
|
||||||
|
|
||||||
|
// Load all assets
|
||||||
|
this.resourceManager.loadResourcesFromQueue(() => {
|
||||||
|
scene.start();
|
||||||
|
scene.setRunning(true);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(ctx: CanvasRenderingContext2D){
|
||||||
|
this.currentScene.render(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public update(deltaT: number){
|
||||||
|
if(this.currentScene.isRunning()){
|
||||||
|
this.currentScene.update(deltaT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,15 +2,15 @@ import Viewport from "./Viewport";
|
||||||
import CanvasNode from "../Nodes/CanvasNode";
|
import CanvasNode from "../Nodes/CanvasNode";
|
||||||
import Map from "../DataTypes/Map";
|
import Map from "../DataTypes/Map";
|
||||||
import Vec2 from "../DataTypes/Vec2";
|
import Vec2 from "../DataTypes/Vec2";
|
||||||
import Scene from "../GameState/Scene";
|
import Layer from "../Scene/Layer";
|
||||||
|
|
||||||
export default abstract class SceneGraph{
|
export default abstract class SceneGraph{
|
||||||
protected viewport: Viewport;
|
protected viewport: Viewport;
|
||||||
protected nodeMap: Map<CanvasNode>;
|
protected nodeMap: Map<CanvasNode>;
|
||||||
protected idCounter: number;
|
protected idCounter: number;
|
||||||
protected scene: Scene;
|
protected scene: Layer;
|
||||||
|
|
||||||
constructor(viewport: Viewport, scene: Scene){
|
constructor(viewport: Viewport, scene: Layer){
|
||||||
this.viewport = viewport;
|
this.viewport = viewport;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.nodeMap = new Map<CanvasNode>();
|
this.nodeMap = new Map<CanvasNode>();
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import SceneGraph from "./SceneGraph";
|
import SceneGraph from "./SceneGraph";
|
||||||
import CanvasNode from "../Nodes/CanvasNode";
|
import CanvasNode from "../Nodes/CanvasNode";
|
||||||
import Viewport from "./Viewport";
|
import Viewport from "./Viewport";
|
||||||
import Scene from "../GameState/Scene";
|
import Layer from "../Scene/Layer";
|
||||||
|
|
||||||
export default class SceneGraphArray extends SceneGraph{
|
export default class SceneGraphArray extends SceneGraph{
|
||||||
private nodeList: Array<CanvasNode>;
|
private nodeList: Array<CanvasNode>;
|
||||||
private turnOffViewportCulling_demoTool: boolean;
|
private turnOffViewportCulling_demoTool: boolean;
|
||||||
|
|
||||||
constructor(viewport: Viewport, scene: Scene){
|
constructor(viewport: Viewport, scene: Layer){
|
||||||
super(viewport, scene);
|
super(viewport, scene);
|
||||||
|
|
||||||
this.nodeList = new Array<CanvasNode>();
|
this.nodeList = new Array<CanvasNode>();
|
||||||
|
|
124
src/main.ts
124
src/main.ts
|
@ -9,80 +9,80 @@ import OrthogonalTilemap from "./Nodes/Tilemaps/OrthogonalTilemap";
|
||||||
function main(){
|
function main(){
|
||||||
// Create the game object
|
// Create the game object
|
||||||
let game = new GameLoop();
|
let game = new GameLoop();
|
||||||
let gameState = game.getGameState();
|
let gameState = game.getSceneManager();
|
||||||
|
|
||||||
let backgroundScene = gameState.createScene();
|
// let backgroundScene = gameState.createScene();
|
||||||
backgroundScene.setParallax(0.5, 0.8);
|
// backgroundScene.setParallax(0.5, 0.8);
|
||||||
backgroundScene.setAlpha(0.5);
|
// backgroundScene.setAlpha(0.5);
|
||||||
let mainScene = gameState.createScene();
|
// let mainScene = gameState.createScene();
|
||||||
let uiLayer = gameState.createScene();
|
// let uiLayer = gameState.createScene();
|
||||||
uiLayer.setParallax(0, 0);
|
// uiLayer.setParallax(0, 0);
|
||||||
let pauseMenu = gameState.createScene();
|
// let pauseMenu = gameState.createScene();
|
||||||
pauseMenu.setParallax(0, 0);
|
// pauseMenu.setParallax(0, 0);
|
||||||
|
|
||||||
// Initialize GameObjects
|
// // Initialize GameObjects
|
||||||
let recordButton = uiLayer.canvasNode.add(Button);
|
// let recordButton = uiLayer.canvasNode.add(Button);
|
||||||
recordButton.setSize(100, 50);
|
// recordButton.setSize(100, 50);
|
||||||
recordButton.setText("Record");
|
// recordButton.setText("Record");
|
||||||
recordButton.setPosition(400, 30);
|
// recordButton.setPosition(400, 30);
|
||||||
recordButton.onClickEventId = "record_button_press";
|
// recordButton.onClickEventId = "record_button_press";
|
||||||
|
|
||||||
let stopButton = uiLayer.canvasNode.add(Button);
|
// let stopButton = uiLayer.canvasNode.add(Button);
|
||||||
stopButton.setSize(100, 50);
|
// stopButton.setSize(100, 50);
|
||||||
stopButton.setText("Stop");
|
// stopButton.setText("Stop");
|
||||||
stopButton.setPosition(550, 30);
|
// stopButton.setPosition(550, 30);
|
||||||
stopButton.onClickEventId = "stop_button_press";
|
// stopButton.onClickEventId = "stop_button_press";
|
||||||
|
|
||||||
let playButton = uiLayer.canvasNode.add(Button);
|
// let playButton = uiLayer.canvasNode.add(Button);
|
||||||
playButton.setSize(100, 50);
|
// playButton.setSize(100, 50);
|
||||||
playButton.setText("Play");
|
// playButton.setText("Play");
|
||||||
playButton.setPosition(700, 30);
|
// playButton.setPosition(700, 30);
|
||||||
playButton.onClickEventId = "play_button_press";
|
// playButton.onClickEventId = "play_button_press";
|
||||||
|
|
||||||
let cycleFramerateButton = uiLayer.canvasNode.add(Button);
|
// let cycleFramerateButton = uiLayer.canvasNode.add(Button);
|
||||||
cycleFramerateButton.setSize(150, 50);
|
// cycleFramerateButton.setSize(150, 50);
|
||||||
cycleFramerateButton.setText("Cycle FPS");
|
// cycleFramerateButton.setText("Cycle FPS");
|
||||||
cycleFramerateButton.setPosition(5, 400);
|
// cycleFramerateButton.setPosition(5, 400);
|
||||||
let i = 0;
|
// let i = 0;
|
||||||
let fps = [15, 30, 60];
|
// let fps = [15, 30, 60];
|
||||||
cycleFramerateButton.onClick = () => {
|
// cycleFramerateButton.onClick = () => {
|
||||||
game.setMaxFPS(fps[i]);
|
// game.setMaxFPS(fps[i]);
|
||||||
i = (i + 1) % 3;
|
// i = (i + 1) % 3;
|
||||||
}
|
// }
|
||||||
|
|
||||||
let pauseButton = uiLayer.canvasNode.add(Button);
|
// let pauseButton = uiLayer.canvasNode.add(Button);
|
||||||
pauseButton.setSize(100, 50);
|
// pauseButton.setSize(100, 50);
|
||||||
pauseButton.setText("Pause");
|
// pauseButton.setText("Pause");
|
||||||
pauseButton.setPosition(700, 400);
|
// pauseButton.setPosition(700, 400);
|
||||||
pauseButton.onClick = () => {
|
// pauseButton.onClick = () => {
|
||||||
mainScene.setPaused(true);
|
// mainScene.setPaused(true);
|
||||||
pauseMenu.enable();
|
// pauseMenu.enable();
|
||||||
}
|
// }
|
||||||
|
|
||||||
let modalBackground = pauseMenu.canvasNode.add(UIElement);
|
// let modalBackground = pauseMenu.canvasNode.add(UIElement);
|
||||||
modalBackground.setSize(400, 200);
|
// modalBackground.setSize(400, 200);
|
||||||
modalBackground.setBackgroundColor(new Color(0, 0, 0, 0.4));
|
// modalBackground.setBackgroundColor(new Color(0, 0, 0, 0.4));
|
||||||
modalBackground.setPosition(200, 100);
|
// modalBackground.setPosition(200, 100);
|
||||||
|
|
||||||
let resumeButton = pauseMenu.canvasNode.add(Button);
|
// let resumeButton = pauseMenu.canvasNode.add(Button);
|
||||||
resumeButton.setSize(100, 50);
|
// resumeButton.setSize(100, 50);
|
||||||
resumeButton.setText("Resume");
|
// resumeButton.setText("Resume");
|
||||||
resumeButton.setPosition(400, 200);
|
// resumeButton.setPosition(400, 200);
|
||||||
resumeButton.onClick = () => {
|
// resumeButton.onClick = () => {
|
||||||
mainScene.setPaused(false);
|
// mainScene.setPaused(false);
|
||||||
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);
|
||||||
|
|
||||||
pauseMenu.disable();
|
// pauseMenu.disable();
|
||||||
|
|
||||||
game.start();
|
game.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
"src/Events/GameEvent.ts",
|
"src/Events/GameEvent.ts",
|
||||||
"src/Events/Receiver.ts",
|
"src/Events/Receiver.ts",
|
||||||
|
|
||||||
"src/GameState/Factories/CanvasNodeFactory.ts",
|
"src/Scene/Factories/CanvasNodeFactory.ts",
|
||||||
"src/GameState/Factories/PhysicsNodeFactory.ts",
|
"src/Scene/Factories/PhysicsNodeFactory.ts",
|
||||||
"src/GameState/Factories/TilemapFactory.ts",
|
"src/Scene/Factories/TilemapFactory.ts",
|
||||||
"src/GameState/GameState.ts",
|
"src/Scene/Scene.ts",
|
||||||
"src/GameState/Scene.ts",
|
"src/Scene/Layer.ts",
|
||||||
|
|
||||||
"src/Input/InputHandler.ts",
|
"src/Input/InputHandler.ts",
|
||||||
"src/Input/InputReceiver.ts",
|
"src/Input/InputReceiver.ts",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user