Gryz Posted March 28, 2017 Share Posted March 28, 2017 I am building a tile based game with procedural generated worlds that contain a large number of tiles. I have this working by using Phaser's Tiled integration to dynamically create tile maps, e.g. const map = this.game.add.tilemap('world'); const tile = new Phaser.Tile(...) map.layers[0].data = [tile, ...]; The world is represented as a matrix of tiles. But due to memory usage, I need restrict the number of tiles using an object pool. My idea is to break the world matrix into sub-matrices, loading them into memory from disk (using web workers and IndexedDb). The tiles would be loaded into memory according to their proximity to the player as he moves through the world-- tiles close to the player, but outside of the viewport, would overwrite tiles in the object pool that are further away and outside the viewport. My question is whether this can work with Phaser's rendering engine. I tried changing a tile's attributes after loading the map, and the new attributes seem to take effect when the screen is re-rendered when a sprite moves. My assumption is that new tiles updated in the object pool will be shown correctly when they are re-rendered after becoming visible again in the viewport. Link to comment Share on other sites More sharing options...
Aquarius Posted March 28, 2017 Share Posted March 28, 2017 I use this kind of Pool (based on the work of NIKLAS BERG in http://metroid.niklasberg.se/2016/02/29/making-a-custom-pool-class-by-extending-phaser-group/) My implementation is very similar : import { Spawnable } from 'app/phaser/spawnable' export class Pool extends Phaser.Group { public sprites:Array<Phaser.Sprite>; constructor(game: Phaser.Game, private spriteType: typeof Spawnable, instances: number, name: string) { super(game, game.world, name, false, true, Phaser.Physics.ARCADE); this.initializePool(instances); } private initializePool(instances) { this.sprites = new Array(); if (instances <= 0) { return; } // We don't need to add anything to the group for (var i = 0; i < instances; i++) { let sprite = this.add(new this.spriteType(this.game)); // Add new sprite sprite.poolId = i; this.sprites.push(sprite); } } public createNew(x: number, y: number, data?: Object) { let obj: Spawnable = this.getFirstDead(false); if (!obj) { console.log('createNew'); obj = new this.spriteType(this.game); this.add(obj, true); } obj.spawn(x, y, data); return obj; } } //Note I had to extends de Phaser.Sprite Class export class Spawnable extends Phaser.Sprite { // decorator for Typescript constructor(game: Phaser.Game, x?: number, y?: number, texture?: string) { super(game, x, y, texture); } spawn(x: number, y: number, data?: any) { this.reset(x, y); this.data = data; this.exists = true; this.alive = true; } } So when i want to "kill" a pooled sprite, I just need to hide it and flag it as dead //initializePool this.SomeSpritePool = new Pool(game, SomeSprite, 200, 'visibleMarker'); // pick a new Sprite let theSomeSprite = this.SomeSpritePool.createNew(x, y) ... // killing it theSomeSprite.alive = false; theSomeSprite.visible = false; Link to comment Share on other sites More sharing options...
Gryz Posted April 19, 2017 Author Share Posted April 19, 2017 A follow up to this. I am rendering a large world and pooling only tile objects that need to be displayed on screen. The general idea is to keep a buffer of tiles offscreen, and reposition them in the direction the player is moving in, updating their attributes to the new tiles to be displayed. Can this be done via update() in Phaser? This code seems to lag behind, probably because it doesn't use a time delta: Quote update() { // Get the distance that the player has moved since last frame. const distanceX = this.player.sprite.x - this.prevPlayerX; const distanceY = this.player.sprite.y - this.prevPlayerY; this.prevPlayerX = this.player.sprite.x; this.prevPlayerY = this.player.sprite.y; ... if (Math.abs(distanceX) > delta) { // Reposition buffer of tiles and update tile attributes } } Is the alternative to create my own time-based loop? Link to comment Share on other sites More sharing options...
Recommended Posts