haelix Posted March 10, 2017 Share Posted March 10, 2017 I had a few questions about Tilemap's implementation and some general questions about having a player walk around a top-down 2d "overworld" and having enemies hundreds of pixels offscreen that the player would eventually walk near. Question 1: Using Tiled to generate a tilemap, is there a maximum size that you can generate using Phaser.Tilemap? I've read 2048x2048 are limits for some mobile devices for an actual "tilesheet" or images, but is there any max size for the map you can generate in Tiled and use in Phaser? Question 2: Does the Tilemap implementation render tiles only in the viewport or maybe a tile or two "offscreen" as a buffer? It doesn't render the entire map and layers? Are offscreen tiles receiving update events (ex: if a tile had its own water animation) or are only the in-viewport tiles receiving update calls? Question 3: Assuming my "Enemy" class on update just walks back and forth until it "spots" the Player, when initializing the tilemap, should I be creating/adding my Enemy classes and placing them way offscreen outside the viewport at initialization and they wont take update/moving/rendering until they're in the viewport? Or should I be listening to viewport xy changes and "spawn" enemies as they walk into the viewport? While the player is moving, are the Enemies actually moving around or do they not start getting those update events until they're inside the viewport? Basically, do Sprites added to a tilemap layer but off screen exist and are able to do things or do they have to be in the viewport for the tilemap to update them? I've found several examples of how to build Tilemap levels platforming and such, but when it's used in this context with other actors existing as children of a tilemap layer, I haven't found much. Anyone know of any good examples of this? Thanks! Link to comment Share on other sites More sharing options...
hicotech Posted March 12, 2017 Share Posted March 12, 2017 Interested in points 2 and 3 as well.. If we talk about point 3 then its probably worth to mention that in my case I created concept map in Tiled with just grass and stones plus 3 objects.. everything is handled by createFromObjects function and all these 3 objects are added to the same group.. I need to loop through them in create function and sadly also in update function.. however two of the objects share same sprite and they have same gid and one of those two is off screen.. when they are added by createFromObjects function autoCull parameter is set to true.. forEach function loops through that one as well anyway.. it would mean that all objects (enemies or whatever) are added in the beginning and are updated all the time if this approach is used.. probably there is another approach with which not all objects in group are updated when update function is called but didnt find it yet EDIT: I guess sprite.inCamera property can help EDIT2: in this example http://phaser.io/examples/v2/tilemaps/create-from-objects question mark and exit "tiles" disappear when they are off screen.. move slowly and you will see that once camera view passes the middle of tile it just go invisible This is what I mean function preload() { game.load.atlas('terrain', 'resources/images/terrain/terrain.png', 'resources/images/terrain/terrain.json', Phaser.Loader.TEXTURE_ATLAS_JSON_HASH); game.load.atlas('characters', 'resources/images/characters/characters.png', 'resources/images/characters/characters.json', Phaser.Loader.TEXTURE_ATLAS_JSON_HASH); game.load.tilemap('staticMap', 'resources/map/map.json', null, Phaser.Tilemap.TILED_JSON); } function create() { // Create map var map = game.add.tilemap('staticMap'); map.addTilesetImage('terrain', 'terrain'); // Create layers grass = map.createLayer('Grass'); stones = map.createLayer('Stones'); // Create characters group charactersGroup = game.add.group(); charactersGroup.enableBody = true; // Create characters // Two of the objects have same gid but different names map.createFromObjects('Characters', 11, 'characters', 'jim/walk/down/01', true, false, charactersGroup); map.createFromObjects('Characters', 47, 'characters', 'bob/walk/down/01', true, true, charactersGroup); // Initialize character charactersGroup.forEach(function (character) { // some setup // here all 3 objects are available }); } function update() { charactersGroup.forEach(function (character) { // random moving code // again all 3 objects are updated }); } Link to comment Share on other sites More sharing options...
samme Posted March 12, 2017 Share Posted March 12, 2017 It looks like TilemapLayer tries to render only relevant/visible portions. But any Sprites follow Phaser's normal rules: they update unless exists=false, animate unless visible=false. So your enemies will behave the same whether they're in viewport or not. Link to comment Share on other sites More sharing options...
hicotech Posted March 12, 2017 Share Posted March 12, 2017 I have set condition in my update function so it checks if sprite/character is in viewport.. but still I dont like the idea of looping through all characters in an update function just to check if they are inCamera and to get them moving Link to comment Share on other sites More sharing options...
msickle Posted March 12, 2017 Share Posted March 12, 2017 You could spread out this check by putting it on a timer. Every 200ms check 1/4 of them or something like that. Link to comment Share on other sites More sharing options...
hicotech Posted March 13, 2017 Share Posted March 13, 2017 I am starting to think that this whole approach is not correct.. it can get pretty slow if there are many NPCs In create function I set loop so NPC checks every 5 seconds if its in camera view and moving.. if in camera view but standing then it generates random point where to go (can be off screen) and sets isMoving flag to true.. Then in update function I check (in every frame) for isMoving flag and if its true then NPC starts traversing the generated path (array of points) Whole idea is that every 5 seconds I can set character to isMoving state and update function will start moving NPC on next call.. I added simple code with comments so you can imagine what I mean function create() { // Every 5 seconds check if character is in viewport and moving // If yes and not moving then get random path where to go game.time.events.loop(5000, function () { if(character.inCamera) { if (!characters[character.name].isMoving) { // Here we generate path for character (pathfinding) // And set isMoving flag to true getPath(character); } } }, this); } function update() { charactersGroup.forEach(function (character) { // Stop character from physical movement character.body.velocity.set(0); if(character.inCamera) { // If character has isMoving flag set to true (set by getPath func) then traverse path if (characters[character.name] && characters[character.name].isMoving) { // Move to next tile in path array // Last tile set isMoving flag to false traversePath(character); playAnimation(character); } } }); } Link to comment Share on other sites More sharing options...
hicotech Posted March 14, 2017 Share Posted March 14, 2017 after discussion with a colleague and after I read some articles then most likely finite state machine approach will be much better.. and in update function I will check only those which are supposed to be updated.. Link to comment Share on other sites More sharing options...
kabuto178 Posted March 16, 2017 Share Posted March 16, 2017 What was the conclusion you went with? The last option with a timeout or check for viewport in update loop? Link to comment Share on other sites More sharing options...
hicotech Posted March 16, 2017 Share Posted March 16, 2017 as I said.. I will use finite state machine for NPCs in general I will have an object or any kind of "grouping functionality" where I keep data about my NPCs.. for example if I have two states "walk" and "idle" I will need to do physical update of position only for those NPCs which are in "walk" state.. in separate function/class I will be handling state change and viewport checks something like this function create () { // create NPCs // init state machine } function update () { // forEach of to be updated NPCs do something group.forEach(function (npc) { // move to x,y } } function stateMachine (npcs) { // for each of npcs check if in viewport // set the state and // assign to "group" or do something else } Link to comment Share on other sites More sharing options...
Recommended Posts