From cf3c801bdb1bad3e973270231f56d2ce718b6984 Mon Sep 17 00:00:00 2001 From: Joe Weaver Date: Wed, 23 Sep 2020 14:30:29 -0400 Subject: [PATCH] added y sorting for object layers --- src/MainScene.ts | 4 ++-- src/ResourceManager/ResourceManager.ts | 3 +++ src/Scene/Factories/TilemapFactory.ts | 8 +++++--- src/Scene/Layer.ts | 20 +++++++++++++++++++ src/Scene/Scene.ts | 7 ++----- src/SceneGraph/SceneGraph.ts | 16 +++++++++++++++ src/SceneGraph/SceneGraphArray.ts | 12 ++++++++++++ src/SecondScene.ts | 27 +++++++------------------- 8 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/MainScene.ts b/src/MainScene.ts index dff186f..bfc0a74 100644 --- a/src/MainScene.ts +++ b/src/MainScene.ts @@ -100,7 +100,7 @@ export default class MainScene extends Scene { pauseButton.setText("Pause"); pauseButton.setPosition(700, 400); pauseButton.onClick = () => { - this.layers.forEach((layer: Layer) => layer.setPaused(true)); + this.sceneGraph.getLayers().forEach((layer: Layer) => layer.setPaused(true)); pauseLayer.enable(); } @@ -114,7 +114,7 @@ export default class MainScene extends Scene { resumeButton.setText("Resume"); resumeButton.setPosition(360, 150); resumeButton.onClick = () => { - this.layers.forEach((layer: Layer) => layer.setPaused(false)); + this.sceneGraph.getLayers().forEach((layer: Layer) => layer.setPaused(false)); pauseLayer.disable(); } diff --git a/src/ResourceManager/ResourceManager.ts b/src/ResourceManager/ResourceManager.ts index def15d9..4aae2ed 100644 --- a/src/ResourceManager/ResourceManager.ts +++ b/src/ResourceManager/ResourceManager.ts @@ -172,8 +172,11 @@ export default class ResourceManager { // Load everything in the queues. Tilemaps have to come before images because they will add new images to the queue this.loadTilemapsFromQueue(() => { + console.log("Loaded Tilemaps"); this.loadImagesFromQueue(() => { + console.log("Loaded Images"); this.loadAudioFromQueue(() => { + console.log("Loaded Audio"); // Done loading this.loading = false; this.justLoaded = true; diff --git a/src/Scene/Factories/TilemapFactory.ts b/src/Scene/Factories/TilemapFactory.ts index e7d2e76..3cd5bcb 100644 --- a/src/Scene/Factories/TilemapFactory.ts +++ b/src/Scene/Factories/TilemapFactory.ts @@ -88,9 +88,11 @@ export default class TilemapFactory { // Check if obj is collidable let collidable = false; - for(let prop of obj.properties){ - if(prop.name === "Collidable"){ - collidable = prop.value; + if(obj.properties){ + for(let prop of obj.properties){ + if(prop.name === "Collidable"){ + collidable = prop.value; + } } } diff --git a/src/Scene/Layer.ts b/src/Scene/Layer.ts index ddb8bcf..5ac5e6d 100644 --- a/src/Scene/Layer.ts +++ b/src/Scene/Layer.ts @@ -13,6 +13,8 @@ export default class Layer { protected hidden: boolean; protected alpha: number; protected items: Array; + protected ySort: boolean; + protected depth: number; constructor(scene: Scene){ this.scene = scene; @@ -21,6 +23,8 @@ export default class Layer { this.hidden = false; this.alpha = 1; this.items = new Array(); + this.ySort = false; + this.depth = 0; } setPaused(pauseValue: boolean): void { @@ -65,6 +69,22 @@ export default class Layer { return this.parallax; } + setYSort(ySort: boolean): void { + this.ySort = ySort; + } + + getYSort(): boolean { + return this.ySort; + } + + setDepth(depth: number): void { + this.depth = depth; + } + + getDepth(): number { + return this.depth; + } + addNode(node: GameNode): void { this.items.push(node); node.setLayer(this); diff --git a/src/Scene/Scene.ts b/src/Scene/Scene.ts index 9db1acb..bf190ac 100644 --- a/src/Scene/Scene.ts +++ b/src/Scene/Scene.ts @@ -14,7 +14,6 @@ import Receiver from "../Events/Receiver"; import Emitter from "../Events/Emitter"; export default class Scene{ - protected layers: Stack; protected worldSize: Vec2; protected viewport: Viewport; protected running: boolean; @@ -42,7 +41,7 @@ export default class Scene{ public load: ResourceManager; constructor(viewport: Viewport, sceneManager: SceneManager, game: GameLoop){ - this.layers = new Stack(10); + this.worldSize = new Vec2(1600, 1000); this.viewport = viewport; this.viewport.setBounds(0, 0, 2560, 1280); @@ -138,9 +137,7 @@ export default class Scene{ * Adds a new layer to the scene and returns it */ addLayer(): Layer { - let layer = new Layer(this); - this.layers.push(layer); - return layer; + return this.sceneGraph.addLayer(); } /** diff --git a/src/SceneGraph/SceneGraph.ts b/src/SceneGraph/SceneGraph.ts index 06a8238..59e6580 100644 --- a/src/SceneGraph/SceneGraph.ts +++ b/src/SceneGraph/SceneGraph.ts @@ -3,6 +3,8 @@ import CanvasNode from "../Nodes/CanvasNode"; import Map from "../DataTypes/Map"; import Vec2 from "../DataTypes/Vec2"; import Scene from "../Scene/Scene"; +import Layer from "../Scene/Layer"; +import Stack from "../DataTypes/Stack"; /** * An abstract interface of a SceneGraph. Exposes methods for use by other code, but leaves the implementation up to the subclasses. @@ -12,12 +14,14 @@ export default abstract class SceneGraph { protected nodeMap: Map; protected idCounter: number; protected scene: Scene; + protected layers: Stack; constructor(viewport: Viewport, scene: Scene){ this.viewport = viewport; this.scene = scene; this.nodeMap = new Map(); this.idCounter = 0; + this.layers = new Stack(10); } /** @@ -87,6 +91,18 @@ export default abstract class SceneGraph { */ protected abstract getNodeAtCoords(x: number, y: number): CanvasNode; + addLayer(): Layer { + let layer = new Layer(this.scene); + let depth = this.layers.size(); + layer.setDepth(depth); + this.layers.push(layer); + return layer; + } + + getLayers(): Stack { + return this.layers; + } + abstract update(deltaT: number): void; /** diff --git a/src/SceneGraph/SceneGraphArray.ts b/src/SceneGraph/SceneGraphArray.ts index b3db413..9feb36e 100644 --- a/src/SceneGraph/SceneGraphArray.ts +++ b/src/SceneGraph/SceneGraphArray.ts @@ -2,6 +2,8 @@ import SceneGraph from "./SceneGraph"; import CanvasNode from "../Nodes/CanvasNode"; import Viewport from "./Viewport"; import Scene from "../Scene/Scene"; +import Stack from "../DataTypes/Stack"; +import Layer from "../Scene/Layer" export default class SceneGraphArray extends SceneGraph{ private nodeList: Array; @@ -65,6 +67,16 @@ export default class SceneGraphArray extends SceneGraph{ } } + // Sort by depth, then by visible set by y-value + visibleSet.sort((a, b) => { + if(a.getLayer().getDepth() === b.getLayer().getDepth()){ + return (a.getPosition().y + a.getSize().y*a.getScale().y) + - (b.getPosition().y + b.getSize().y*b.getScale().y); + } else { + return a.getLayer().getDepth() - b.getLayer().getDepth(); + } + }); + return visibleSet; } } \ No newline at end of file diff --git a/src/SecondScene.ts b/src/SecondScene.ts index b060224..20f7439 100644 --- a/src/SecondScene.ts +++ b/src/SecondScene.ts @@ -12,11 +12,9 @@ import { GameEventType } from "./Events/GameEventType"; export default class SecondScene extends Scene { loadScene(){ - this.load.tilemap("level2", "assets/tilemaps/OtherMap.json"); - this.load.tilemap("background2", "assets/tilemaps/OtherBackground.json"); + this.load.tilemap("level2", "assets/tilemaps/TopDown2.json"); this.load.image("player", "assets/sprites/player.png"); - this.load.audio("player_jump", "assets/sounds/jump-3.wav"); - this.load.audio("level_music", "assets/sounds/level.wav"); + this.load.audio("music", "assets/sounds/level.wav") let loadingScreen = this.addLayer(); let box = this.add.graphic(Rect, loadingScreen, new Vec2(200, 300), new Vec2(400, 60)); @@ -34,23 +32,12 @@ export default class SecondScene extends Scene { } startScene(){ - // Add the background tilemap - let backgroundTilemapLayer = this.add.tilemap("background2")[0]; - // ...and make it have parallax - backgroundTilemapLayer.setParallax(1, 1); - backgroundTilemapLayer.setAlpha(0.2); - - // Add the music and start playing it on a loop - this.emitter.fireEvent(GameEventType.PLAY_SOUND, {key: "level_music", loop: true, holdReference: true}); - // Add the tilemap - this.add.tilemap("level2"); - - // Create the main game layer - let mainLayer = this.addLayer(); + let mainLayer = this.add.tilemap("level2")[1]; + mainLayer.setYSort(true); // Add a player - let player = this.add.physics(Player, mainLayer, "platformer"); + let player = this.add.physics(Player, mainLayer, "topdown"); let playerSprite = this.add.sprite("player", mainLayer); player.setSprite(playerSprite); @@ -99,7 +86,7 @@ export default class SecondScene extends Scene { pauseButton.setText("Pause"); pauseButton.setPosition(700, 400); pauseButton.onClick = () => { - this.layers.forEach((layer: Layer) => layer.setPaused(true)); + this.sceneGraph.getLayers().forEach((layer: Layer) => layer.setPaused(true)); pauseLayer.enable(); } @@ -113,7 +100,7 @@ export default class SecondScene extends Scene { resumeButton.setText("Resume"); resumeButton.setPosition(400, 200); resumeButton.onClick = () => { - this.layers.forEach((layer: Layer) => layer.setPaused(false)); + this.sceneGraph.getLayers().forEach((layer: Layer) => layer.setPaused(false)); pauseLayer.disable(); } }