added y sorting for object layers

This commit is contained in:
Joe Weaver 2020-09-23 14:30:29 -04:00
parent 9cb4f55d9a
commit cf3c801bdb
8 changed files with 67 additions and 30 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -13,6 +13,8 @@ export default class Layer {
protected hidden: boolean;
protected alpha: number;
protected items: Array<GameNode>;
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);

View File

@ -14,7 +14,6 @@ import Receiver from "../Events/Receiver";
import Emitter from "../Events/Emitter";
export default class Scene{
protected layers: Stack<Layer>;
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();
}
/**

View File

@ -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<CanvasNode>;
protected idCounter: number;
protected scene: Scene;
protected layers: Stack<Layer>;
constructor(viewport: Viewport, scene: Scene){
this.viewport = viewport;
this.scene = scene;
this.nodeMap = new Map<CanvasNode>();
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<Layer> {
return this.layers;
}
abstract update(deltaT: number): void;
/**

View File

@ -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<CanvasNode>;
@ -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;
}
}

View File

@ -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();
}
}