Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

SpriteBatch gotchas? (performance issue)


jcs
 Share

Recommended Posts

I just grabbed Pixi 1.5 and straight-away I went to test SpriteBatch with my tilemap scroller torture test. the results were not what I expected - I get about half the frame-rate that I get using DispayObjectContainer...

 

so... my question is: are there particular "gotchas" or things I need to watch out for when using SpriteBatch? (all I did was change the DisplayObjectContainer that was I was using to a SpriteBatch. perhaps that isn't such a great idea and there are other factors I need to be aware of?)

 

cheers!

Link to comment
Share on other sites

It should be a drop-in replacement, with a speed increase providing the following conditions are met:

 

1) Your children are only 1 level deep, no nesting allowed

2) All children are sprites, nothing else

 

If you meet those conditions and are seeing slow-down please post da codez and we can see what is going on there!

Link to comment
Share on other sites

interesting. no nested children, but it is inside a DisplayObjectContainer (inside a DisplayObjectContainer) which are used as the 'camera'. and nothing but Sprites are added.

 

the code is rendering tile maps (using a variety of methods, refer to this thread), but primarily using the technique where every tile in the world is a Sprite (all using different UVs into the same texture), with their visibility toggled if they are on/off screen, and all added to a DOC SpriteBatch whose position is set to the camera position. nothing too fancy; the code is rather straightforward.

 

Link to comment
Share on other sites

Interesting, I am getting something similar as well now (though I wasn't a week ago). Did we make a change to SpriteBatch recently? Here are two performance graphs from grapefruit that show the difference:

 

perf_spritebatch.png

 

The spritebatch has the spikes of bad performance (higher on the graph is longer time). It feels even worse visually than it does in these graphs. Did we change something recently?

Link to comment
Share on other sites

  • 2 months later...

Seems Like sprite batch has poor performance when you upload different textures to the same batch! I assume that you have different texture for each tile type (land, grass, road, etc.)

 

But I managed to solve this problem by dynamically creating new batches for each tile type, and then removing them if not needed. I have tested it with more than 5000 tiles of 10 types each type having a different image (10 image urls for texture not 5000 different images) and still have 60fps.

 

As long as you separate the tiles between different batches you will be able to keep performance up to 60fps.

Link to comment
Share on other sites

  • 3 months later...

Well from my experience sprite batch is amazing for the same sprite but the performance falls down when you start adding different ones.

 


THIS IS A DEMO VIDEO. SORRY FOR THE MESSED UP SCAR ON THE SCREEN BUT I DON'T HAVE A PROPER VIDEO RECORDING SOFTWARE.

Game runs on a 3-4 year old dell laptop. For all the time between 54-60 fps!

The rain effect is generated by a pure sprite batch.

 



 

I MADE THE SAME MISTAKE WHEN RENDERING THE TILED MAP AND FPS WENT DOWN TO 30

 

In my case what I did i rendered the tiledmap into a bigger texture divided into things that i call sectors and cameras. 

 

What you do is create a group of containers to hold the tiles in my case i have 9 of them. (central camera and eight other surrounding them)!

 

You use a diaplayObjectContainer the is not added to the stage as a mixer fot the tiles and then you use RenderTExture() to create a single bigger sprite representing all the single sprites. (remember to pass the width and height of the sprites in other way our texture will have size 0,0), and sich added bigger tile you add to the stage.

 

THIS IMPROVESSS THE PERFORMANCE BECAUSE PIXI HAS TO CHANGE THE POSITION OF ONLY ONE SPRITE THAT IS A REPRESENTATION OF A 10*10 TILES THAN MOVING 100 TILES SEPARATELY AND RENDER THEM ONE AFTER ANOTHER.

 

This is a part of the code that i have used to create tiles with elements overlapping other ones to give them a more natural look

 



var gameCanvas = document.getElementById('multiverse_id');
var dim = Math.floor(gameCanvas.width/18);

if(!_world){ _world = world(); };
if(!_camera){ _camera = camera(); };
if(!_viewport){ _viewport = viewport(); };
if(!_renderer){ _renderer = renderer(); };
if(!mixContainer){

mixContainer = new PIXI.DisplayObjectContainer();

};

_world.map = data.map;
_world.bottom = data.bottom;

var h = 0, v = 0, background_id = 0, cont = false, myContainer;

for(var r = 0; r < 10; r++){

if(!cont){

myContainer = new PIXI.DisplayObjectContainer();
cont = true;

}

var randomBoolean = function(){ return Math.random()<.5 };

var probability = function(x){

return Math.random() < x;

}

for(var c = 0; c < 10; c++){

var tile;
var floorEle;
var mapVal = _world.map[r + (h * 10)][c + (v * 10)];

if(mapVal == 0 || mapVal == 1 || mapVal == 3){

tile = mapVal + '/' + Math.floor(Math.random() * 4);

}else if(mapVal == 7){

tile = mapVal + '/' + Math.floor(Math.random() * 3);

}else{

tile = mapVal;

}

var tileTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+ tile + '.png');
tileTexture.width = dim;
tileTexture.heigth = dim;
var tile = new PIXI.Sprite(tileTexture);
if(mapVal == 0 || mapVal == 7){

if(randomBoolean()){tile.scale.x = -1;};
if(randomBoolean()){tile.scale.y = -1;};

}
tile.width = dim;
tile.height = dim;
tile.position.x = 0;
tile.position.y = 0;

floorEle = _world.bottom[r + (h * 10)][c + (v * 10)];

var floorTexture = new PIXI.Texture.fromImage('assets/images/world/floor/'+ floorEle + '.png');
floorTexture.width = dim;
floorTexture.heigth = dim;
var floor = new PIXI.Sprite(floorTexture);
floor.width = dim;
floor.height = dim;
floor.position.x = 0;
floor.position.y = 0;

mixContainer.children = [];
mixContainer.addChild(tile);

// top left edges
if(mapVal == 0 || mapVal == 1 || mapVal == 2 || mapVal == 4 || mapVal == 5){

try{

var context_top = _world.map[(r - 1) + (h * 10)][c + (v * 10)];
var context_left = _world.map[r + (h * 10)][(c - 1) + (v * 10)];
var context_right = _world.map[r + (h * 10)][(c + 1) + (v * 10)];

}catch(e){};

Math.radians = function(degrees) {
return degrees * Math.PI / 180;
};

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+context_top+'_cuts/top/'+ Math.floor(Math.random() * 6) + '.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
if(probability(0.5)){ grassCut.scale.x = -1; };
mixContainer.addChild(grassCut);

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+context_left+'_cuts/top/'+ Math.floor(Math.random() * 6) + '.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
if(probability(0.5)){ grassCut.scale.x = -1; };
grassCut.rotation = Math.radians(270);
mixContainer.addChild(grassCut);

};

if(mapVal == 7 || mapVal == 9 || mapVal == 10 || mapVal == 11){

try{

var context_top = _world.map[(r - 1) + (h * 10)][c + (v * 10)];
var context_bottom = _world.map[(r + 1) + (h * 10)][c + (v * 10)];
var context_left = _world.map[r + (h * 10)][(c - 1) + (v * 10)];
var context_right = _world.map[r + (h * 10)][(c + 1) + (v * 10)];

}catch(e){};

if(context_left != mapVal){

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+mapVal+'_cuts/0.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
// if(probability(0.5)){ grassCut.scale.x = -1; };
mixContainer.addChild(grassCut);

};

if(context_right != mapVal){

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+mapVal+'_cuts/2.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
// if(probability(0.5)){ grassCut.scale.x = -1; };
mixContainer.addChild(grassCut);

};

if(context_top != mapVal){

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+mapVal+'_cuts/1.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
// if(probability(0.5)){ grassCut.scale.x = -1; };
mixContainer.addChild(grassCut);

};

if(context_bottom != mapVal){

var grasCutTexture = new PIXI.Texture.fromImage('assets/images/world/map/'+mapVal+'_cuts/3.png'); // Math.floor(Math.random() * 6)
grasCutTexture.width = dim;
grasCutTexture.heigth = dim;
var grassCut = new PIXI.Sprite(grasCutTexture);
grassCut.width = dim;
grassCut.height = dim;
grassCut.position.x = dim/2;
grassCut.position.y = dim/2;
grassCut.anchor.x = 0.5;
grassCut.anchor.y = 0.5;
// if(probability(0.5)){ grassCut.scale.x = -1; };
mixContainer.addChild(grassCut);

};

};

// this part was ment to generate random elements
if(mapVal == 0){

if(probability(0.075)){

var grasTexture = new PIXI.Texture.fromImage('assets/images/world/map/0_elements/'+ Math.floor(Math.random() * 68) + '.png');
var grass = new PIXI.Sprite(grasTexture);
grass.position.x = dim/2;
grass.position.y = dim/2;
grass.anchor.x = 0.5;
grass.anchor.y = 0.5;

if(mapVal == 0 || mapVal == 3){

if(randomBoolean()){grass.scale.x = -1;};

}
mixContainer.addChild(grass);

}

};

mixContainer.addChild(floor);

var finalTileTexture = new PIXI.RenderTexture();
finalTileTexture.render(mixContainer);

var finalTile = new PIXI.Sprite(finalTileTexture);
finalTile.position.x = c * dim;
finalTile.position.y = r * dim;

myContainer.addChild(finalTile);

}

if(r === 9){

var texture = new PIXI.RenderTexture(dim * 10, dim * 10);
texture.render(myContainer);
var background = new PIXI.Sprite(texture);
background._id = background_id;
background.position.x = v * dim * 10;
background.position.y = h * dim * 10;
_camera[data.sector].addChild(background);
cont = false;
background_id++;

h++;
r = -1;

}


if(h === 3){

v++;
h = 0;

console.log('calculating maps')

}

if(v === 3){

break;

}

}



 

Please refer to this code as a template. REMEMBER !!! FUNCTION CONSTRUCTING YOUR WORLD RUNS ONLY ONCE WHEN YOU ENTER THE NEW AREA BUT THE LOOP HAS TO COPE WITH ALL OF THE TILES EVERY INTERATION!!! :D

 

 

Another thing to boost your performance is to use spirte property visible

 


 

if you take a look at how pixi works under the hood you'll notice how pixi determines what should be rendered.

 

For every iteration of pixi before rendering it checks if the sprite is visible. if it is set to false it will not be rendered by the engine!

 

YOU THIS FOR THE ELEMENTS THAT ARE OUTSIDE YOUR VIEWPORT. All the sprites position can be moved with the same code as before but the the ones outside your viewport should be set as visible  =  false;

 

THIS IS A SIMPLE CLASS THAT I'M USING IN A GAME THAT I'M WORKING ON!

 



_li.define(
'multiverse.game.map.map_backgrounds',
function (camera, player, renderer, world, viewport) {
'use strict';

var init,
backgrounds = {},
_camera,
_player,
_renderer,
_world,
_viewport,
gameCanvas = document.getElementById('multiverse_id'),
dim = Math.floor(gameCanvas.width/18),
map_watcher = {

pause : false

};

init = function () {

if(map_watcher.pause === true){ return false; };

if(!_viewport){ _viewport = viewport(); }
if(!_camera){ _camera = camera(); };
if(!_player){ _player = player(); };
if(!_world){ _world = world(); };

for(var cam in _viewport.children){

if(_viewport.children[cam]._class === 'tileHolder'){

for(var bck in _viewport.children[cam].children){


if(

(_viewport.children[cam].children[bck].position.x + _viewport.children[cam].position.x >= 0
&&
(_viewport.children[cam].children[bck].position.x + _viewport.children[cam].position.x < gameCanvas.width))
||
(_viewport.children[cam].children[bck].position.x + _viewport.children[cam].children[0].width/3 >= 0)
&&
_viewport.children[cam].children[bck].position.x + _viewport.children[cam].position.x < 0


){

if(

(_viewport.children[cam].children[bck].position.y + _viewport.children[cam].position.y >= 0
&&
(_viewport.children[cam].children[bck].position.y + _viewport.children[cam].position.y < gameCanvas.height))
||
(_viewport.children[cam].children[bck].position.y + _viewport.children[cam].children[0].height/3 >= 0)
&&
_viewport.children[cam].children[bck].position.y + _viewport.children[cam].position.y < 0

){

_viewport.children[cam].children[bck].visible = true;

}else{

_viewport.children[cam].children[bck].visible = false;

};


}else{

_viewport.children[cam].children[bck].visible = false;

};

};

};

};

return map_watcher;

};

return init;
},
[
'multiverse.game.camera',
'multiverse.game.player',
'multiverse.renderer',
'multiverse.world',
'multiverse.viewport'
]
);


 

Why is this an improvement??? js engine will use less cpu (and none gpu in case of webGl) for checking what should be visible and not than when rendering even one additional part of the world. CUT THE FAT TO THE BONE!!! :D

 

EXPERMIENTAL PART !!!

 

since my game sometimes has a lot of non tiled entities (npc, buildings, rocks, etc.) i have decided to make them an illusion for the player and render them into one texture. Initially it gives you a high performance boost but then you have to deal with oter problems which i manged to solve with masking and dynamic entity adding to the stage. 

 

WHAT I DO IS THAT I HAVE A DIFFERENT DISPLAYOBJECT CONTAINER WITH ALL NPC'S AND OBJECTS RENDERED INTO ONE TEXTURE AND OTHER ONE THAT I USE TO DYNAMICALLY SET VISIBLE = TRUE IN CASE THE PLAYER IS GETTING CLOSER TO THEM.

 

initially game performed with 30 fps or under when having so many entities of different sizes and textures on the screen by I managed to push it back to over 50 - 60 fps.

 

this is the code for rendering the two types of object containers:

 



if(data.sector === 4){

var entityContainer = new PIXI.DisplayObjectContainer();

// HIS IS THE PART THAT IS ADDING SINGLE SPRITES

for(var ent in data.entities){


console.log('dim: ', dim);

var entityTexture = new PIXI.Texture.fromImage(data.entities[ent].asset);
var entity = new PIXI.Sprite(entityTexture);
entity.M_id = data.entities[ent].M_id;
entity.position.x = ( data.entities[ent].position.x * dim) + _camera[4].position.x;
entity.position.y = ( data.entities[ent].position.y * dim) + _camera[4].position.y;
entity.anchor.x = data.entities[ent].anchor.x;
entity.anchor.y = data.entities[ent].anchor.y;

if(typeof data.entities[ent].dimensions !== 'undefined'){

entity.width = data.entities[ent].dimensions.x * dim;
entity.height = data.entities[ent].dimensions.y * dim;

};

entity.collision = {};
entity.collision.x = data.entities[ent].collision.x;
entity.collision.y = data.entities[ent].collision.y;
entity.maskable = data.entities[ent].maskable;
if(typeof entity.maskable === 'undefined'){

entity.maskable = false;

};

entity.setInteractive(true);
entity.click = function(){

actionsRouter(this);

};

entity.tap = function(){

actionsRouter(this);

};

for(var opt in data.entities[ent].options){
entity[opt] = data.entities[ent].options[opt];

};

if(data.entities[ent].npc == true){

entity.visible = true;

}else{

entity.visible = false;

};

_camera['entitesRedraw'].addChild(entity);

var entityPosterTexture = new PIXI.Texture.fromImage(data.entities[ent].asset);
var entityPoster = new PIXI.Sprite(entityPosterTexture);
entityPoster.M_id = data.entities[ent].M_id;
entityPoster.position.x = ( data.entities[ent].position.x * dim) + _camera[4].position.x;
entityPoster.position.y = ( data.entities[ent].position.y * dim) + _camera[4].position.y;
entityPoster.anchor.x = data.entities[ent].anchor.x;
entityPoster.anchor.y = data.entities[ent].anchor.y;

if(typeof data.entities[ent].dimensions !== 'undefined'){

entityPoster.width = data.entities[ent].dimensions.x * dim;
entityPoster.height = data.entities[ent].dimensions.y * dim;

};

if(data.entities[ent].maskable == false){

console.log('nonmaskable', entityPoster);

};

entityContainer.addChild(entityPoster);

};

var compare = function(a, {

if (a.position.y < b.position.y)
return -1;
if (a.position.y > b.position.y)
return 1;

return 0;

};

entityContainer.children.sort(compare);

var finalEntityTexture0 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture0.render(entityContainer);
finalEntityTexture0.setFrame({x: 0, y: 0, width: dim * 10, height: dim * 10});

var finalEntity0 = new PIXI.Sprite(finalEntityTexture0);
finalEntity0.position.x = 0;
finalEntity0.position.y = 0;

_camera['entities'].addChild(finalEntity0);

var finalEntityTexture2 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture2.render(entityContainer);
finalEntityTexture2.setFrame({x: 0, y: dim * 10, width: dim * 10, height: dim * 10});

var finalEntity2 = new PIXI.Sprite(finalEntityTexture2);
finalEntity2.position.x = 0;
finalEntity2.position.y = dim * 10;

_camera['entities'].addChild(finalEntity2);

var finalEntityTexture3 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture3.render(entityContainer);
finalEntityTexture3.setFrame({x: 0, y: dim * 20, width: dim * 10, height: dim * 10});

var finalEntity3 = new PIXI.Sprite(finalEntityTexture3);
finalEntity3.position.x = 0;
finalEntity3.position.y = dim * 20;

_camera['entities'].addChild(finalEntity3);

var finalEntityTexture4 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture4.render(entityContainer);
finalEntityTexture4.setFrame({x: dim * 10, y: 0, width: dim * 10, height: dim * 10});

var finalEntity4 = new PIXI.Sprite(finalEntityTexture4);
finalEntity4.position.x = dim * 10;
finalEntity4.position.y = 0;

_camera['entities'].addChild(finalEntity4);

var finalEntityTexture5 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture5.render(entityContainer);
finalEntityTexture5.setFrame({x: dim * 10, y: dim * 10, width: dim * 10, height: dim * 10});

var finalEntity5 = new PIXI.Sprite(finalEntityTexture5);
finalEntity5.position.x = dim * 10;
finalEntity5.position.y = dim * 10;

_camera['entities'].addChild(finalEntity5);

var finalEntityTexture6 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture6.render(entityContainer);
finalEntityTexture6.setFrame({x: dim * 10, y: dim * 20, width: dim * 10, height: dim * 10});

var finalEntity6 = new PIXI.Sprite(finalEntityTexture6);
finalEntity6.position.x = dim * 10;
finalEntity6.position.y = dim * 20;

_camera['entities'].addChild(finalEntity6);

var finalEntityTexture7 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture7.render(entityContainer);
finalEntityTexture7.setFrame({x: dim * 20, y: 0, width: dim * 10, height: dim * 10});

var finalEntity7 = new PIXI.Sprite(finalEntityTexture7);
finalEntity7.position.x = dim * 20;
finalEntity7.position.y = 0;

_camera['entities'].addChild(finalEntity7);

var finalEntityTexture8 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture8.render(entityContainer);
finalEntityTexture8.setFrame({x: dim * 20, y: dim * 10, width: dim * 10, height: dim * 10});

var finalEntity8 = new PIXI.Sprite(finalEntityTexture8);
finalEntity8.position.x = dim * 20;
finalEntity8.position.y = dim * 10;

_camera['entities'].addChild(finalEntity8);

var finalEntityTexture9 = new PIXI.RenderTexture(dim * 30, dim * 30);
finalEntityTexture9.render(entityContainer);
finalEntityTexture9.setFrame({x: dim * 20, y: dim * 20, width: dim * 10, height: dim * 10});

var finalEntity9 = new PIXI.Sprite(finalEntityTexture9);
finalEntity9.position.x = dim * 20;
finalEntity9.position.y = dim * 20;

_camera['entities'].addChild(finalEntity9);

var thing = new PIXI.Graphics();
_renderer.stage.addChild(thing);
thing.position.x = 0;
thing.position.y = 0;
thing.lineStyle(0);
thing.beginFill(0xFFFF0B, 0.5);

thing.moveTo(0,0);
thing.lineTo((gameCanvas.width/10) * 5, 0);
thing.lineTo((gameCanvas.width/10) * 5, (gameCanvas.height/10) * 3.25);
thing.lineTo((gameCanvas.width/10) * 4.77, (gameCanvas.height/10) * 3.35);
thing.lineTo((gameCanvas.width/10) * 4.6, (gameCanvas.height/10) * 3.7);
thing.lineTo((gameCanvas.width/10) * 4.525, (gameCanvas.height/10) * 4.15);
thing.lineTo((gameCanvas.width/10) * 4.6, (gameCanvas.height/10) * 4.6);
thing.lineTo((gameCanvas.width/10) * 4.77, (gameCanvas.height/10) * 4.95);
thing.lineTo((gameCanvas.width/10) * 5, (gameCanvas.height/10) * 5);
thing.lineTo((gameCanvas.width/10) * 5.23, (gameCanvas.height/10) * 4.95);
thing.lineTo((gameCanvas.width/10) * 5.4, (gameCanvas.height/10) * 4.6);
thing.lineTo((gameCanvas.width/10) * 5.475, (gameCanvas.height/10) * 4.15);
thing.lineTo((gameCanvas.width/10) * 5.4, (gameCanvas.height/10) * 3.7);
thing.lineTo((gameCanvas.width/10) * 5.23, (gameCanvas.height/10) * 3.35);
thing.lineTo((gameCanvas.width/10) * 5, (gameCanvas.height/10) * 3.25);
thing.lineTo((gameCanvas.width/10) * 5, 0);
thing.lineTo(gameCanvas.width, 0);
thing.lineTo(gameCanvas.width, gameCanvas.height);
thing.lineTo(0, gameCanvas.height);

thing.endFill();

_camera['entities'].mask = thing;

};


 

This element involves also masking to create a "seethrough" illusion for larger objects.

 

and this is the class that sets entities as visible when they are close to the player.

 



if(cam === 'entitesRedraw'){

var player_position = 0;

for(var child in camera[cam].children){

if(camera[cam].children[child]._class !== 'player'){

if(camera[cam].children[child].maskable === false){

camera[cam].children[child].visible = true;
camera[cam].children[child].collidable = true;

}else{

// vertical division
if(

camera[cam].children[child].width/2 + camera[cam].children[child].x > (gameCanvas.width/10) * 3.5 &&
(camera[cam].children[child].x - camera[cam].children[child].width/2) < (gameCanvas.width/10) * 6.5 )

{
// horizontal division
if(

camera[cam].children[child].position.y <= (gameCanvas.height/10) * 5 &&
camera[cam].children[child].position.y >= (gameCanvas.height/10) * 3

)
{

camera[cam].children[child].visible = true;
camera[cam].children[child].collidable = true;

}else{

var positionTest = (camera[cam].children[child].position.y > (gameCanvas.height/10) * 5 && camera[cam].children[child].position.y <= (gameCanvas.height/10) * 7);

if(positionTest){

if(camera[cam].children[child].maskable === false){

// || camera[cam].children[child].maskable == 'undefined'

camera[cam].children[child].visible = true;

}else{

camera[cam].children[child].visible = false;

};

camera[cam].children[child].collidable = true;

}else{

camera[cam].children[child].visible = false;
camera[cam].children[child].collidable = false;

};

};

};

};

camera[cam].children[child].position.x += camera.velocity.x * camera.step;
camera[cam].children[child].position.y += camera.velocity.y * camera.step;

}else{

player_position = child;

};

};

if(camera[cam].children[player_position].position.y < camera[cam].children[player_position - 1].position.y){

for(var i = player_position; i >= 0; i-- ){

if((camera[cam].children[player_position].position.y <= camera[cam].children[i].position.y) && camera[cam].children[i]._class !== 'player'){

Mover(camera[cam].children, player_position, i);
player_position = i;
};

};

}else if(camera[cam].children[player_position].position.y > camera[cam].children[parseInt(parseInt(player_position) + 1)].position.y){

for(var i = parseInt(player_position); i <= camera[cam].children.length; i++ ){

if(camera[cam].children[player_position].position.y > camera[cam].children[i].position.y){

Mover(camera[cam].children, parseInt(player_position), i);
player_position = i;

};

} ;

};

}


 

 

I hope this is helpful in case of how to boost your tiled game performance.

 

 


 

Link to comment
Share on other sites

In that case... nope... sprite batch can handle only the same texture from my experience.

 

I assume that this is not a tilemap but something else. What is it?

 

Maybe you could tell us more about it? There might be some other technique to render that much of sprites at the same time??

 

Initially I thought that spritebatch will solve all my problems, but I had to use other techniques for different elements.

 

http://www.sevenative.com

Link to comment
Share on other sites

  • 3 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...