Skip to main content
Improved style and corrected grammar and spelling.
Source Link
jcora
  • 7.9k
  • 4
  • 53
  • 88

Edit: Just saw that my answer was based on your code but didn't actually answeredanswer your question XD. I kept the old answer in case you can use that information.

I added some comments and the Viewport class I'm using in the example and added

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be loudedloaded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

I hope this gives you an idea, how it could be done. But this approach won't work very good, when every level has to be simulated during the game. But if you can freeze unused levels this should work fine.

Old Answer: What

What I do when rendering the level (also tile based) is to calculate, which items from the tile array intersect with the viewport and then I only render those tiles. Like that you can have big maps but only need to render the portion on screen.

Edit: Just saw that my answer was based on your code but didn't actually answered your question XD I kept the old answer in case you can use that information.

I added some comments and the Viewport class I'm using in the example and added

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be louded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

I hope this gives you an idea, how it could be done. But this approach won't work very good, when every level has to be simulated during the game. But if you can freeze unused levels this should work fine.

Old Answer: What I do when rendering the level (also tile based) is to calculate, which items from the tile array intersect with the viewport and then I only render those tiles. Like that you can have big maps but only need to render the portion on screen.

Edit: Just saw that my answer was based on your code but didn't actually answer your question. I kept the old answer in case you can use that information.

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be loaded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

I hope this gives you an idea how it could be done. But this approach won't work very good, when every level has to be simulated during the game. But if you can freeze unused levels this should work fine.

Old Answer:

What I do when rendering the level (also tile based) is to calculate which items from the tile array intersect with the viewport and then I only render those tiles. Like that you can have big maps but only need to render the portion on screen.

Bounty Awarded with 150 reputation awarded by test
added js version of viewport
Source Link
tom van green
  • 1.6k
  • 12
  • 13

A javascript representation would look like

<script type="text/javascript">
//Declaration
//Constructor
var Viewport = function(xVal, yVal, wVal, hVal){
    this.x = xVal;
    this.y = yVal;
    this.w = wVal;
    this.h = hVal;
}
//Prototypes
Viewport.prototype.x = null;
Viewport.prototype.y = null;
Viewport.prototype.w = null;
Viewport.prototype.h = null;
Viewport.prototype.toString = function(){
    return ["Position: (", this.x, "/" + this.y + "), Size: (", this.w, "/", this.h, ")"].join("");
}

//Usage
var viewport = new Viewport(23, 111, 640, 480);
//Alerts "Position: (23/111), Size: (640/480)
alert(viewport.toString());
</script>

If you take my code example, you simple have to replace the int and float declarations with var. Also make sure that you use Math.floor on those calculations, that are assigned to the int based values, to get the same behavior.

One thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

One thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

A javascript representation would look like

<script type="text/javascript">
//Declaration
//Constructor
var Viewport = function(xVal, yVal, wVal, hVal){
    this.x = xVal;
    this.y = yVal;
    this.w = wVal;
    this.h = hVal;
}
//Prototypes
Viewport.prototype.x = null;
Viewport.prototype.y = null;
Viewport.prototype.w = null;
Viewport.prototype.h = null;
Viewport.prototype.toString = function(){
    return ["Position: (", this.x, "/" + this.y + "), Size: (", this.w, "/", this.h, ")"].join("");
}

//Usage
var viewport = new Viewport(23, 111, 640, 480);
//Alerts "Position: (23/111), Size: (640/480)
alert(viewport.toString());
</script>

If you take my code example, you simple have to replace the int and float declarations with var. Also make sure that you use Math.floor on those calculations, that are assigned to the int based values, to get the same behavior.

One thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

Updated answer
Source Link
tom van green
  • 1.6k
  • 12
  • 13

Edit 2: I have fixed 2 issues with the original code:

  • The +1 addition in the calculation of end x and y was by mistake inside the brackets, but it needs to be added after the division.
  • I forgot to validate the x and y values.

I added some comments and the Viewport class I'm using in the example and added

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be louded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

//Mock values
//camera position x
//viewport.x = 233f;
//camera position y
//viewport.y = 100f;
//viewport.w = 640
//viewport.h = 480
//levelWidth = 10
//levelHeight = 15
//tilesize = 32;

//startX defines the starting index for the x axis.
// 7 = 233 / 32
int startX = viewport.x / tilesize; 

//startY defines the starting index
// 3 = 100 / 32
int startY = viewport.y / tilesize;

//End index y
// 28 = (233 + 640) / 32 + 1
int endX = ((viewport.x + viewport.w) / tilesize) + 11;

//End index y
// 19 = (100 + 480) / tilesize;32 + 1
int endX = ((viewport.x + viewport.w) +/ 1tilesize) /+ tilesize;1;

//Validation
if(startX < 0) startX = 0;
if(startY < 0) startY = 0;
//endX is set to 9 here
if(endX >= levelWidth) endX = levelWidth - 1;
//endX is set to 14 here
if(endY >= levelHeight) endY = levelHeight - 1;

for(int y = startY; y < yEnd; y++)
    for(int x = startX; x < xEnd; x++)
          [...]

I'm not sure if theNote: The code above is completly correct, as I just tried to fill in the code from my memory,not tested but I hope you understandit should give an idea what i meanto do.

Also oneFollowing a basic example for a viewport representation:

public class Viewport{
    public float x;
    public float y;
    public float w;
    public float h;
}

One thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be louded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

int startX = viewport.x / tilesize;
int startY = viewport.y / tilesize;
int endX = (viewport.x + viewport.w + 1) / tilesize;
int endX = (viewport.x + viewport.w + 1) / tilesize;
if(startX < 0) startX = 0;
if(startY < 0) startY = 0;
for(int y = startY; y < yEnd; y++)
    for(int x = startX; x < xEnd; x++)
          [...]

I'm not sure if the code above is completly correct, as I just tried to fill in the code from my memory, but I hope you understand what i mean.

Also one thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

Edit 2: I have fixed 2 issues with the original code:

  • The +1 addition in the calculation of end x and y was by mistake inside the brackets, but it needs to be added after the division.
  • I forgot to validate the x and y values.

I added some comments and the Viewport class I'm using in the example and added

You could simply have the current map in memory and load the surrounding maps. Imagine a world that consists of a 2d array of single levels of the size 5x5. The player starts in field 1. As the top and the left bounds of the level are on the edge of the world, they do not need to be louded. So in that case level 1/1 is active and level 1/2 and 2/1 are loaded... If the player now moves to the right, all levels (besides the one your moving to) are unloaded and the new surroundings are loaded. Means level 2/1 is now active, 1/1, 2/2 and 3/1 are now loaded.

//Mock values
//camera position x
//viewport.x = 233f;
//camera position y
//viewport.y = 100f;
//viewport.w = 640
//viewport.h = 480
//levelWidth = 10
//levelHeight = 15
//tilesize = 32;

//startX defines the starting index for the x axis.
// 7 = 233 / 32
int startX = viewport.x / tilesize; 

//startY defines the starting index
// 3 = 100 / 32
int startY = viewport.y / tilesize;

//End index y
// 28 = (233 + 640) / 32 + 1
int endX = ((viewport.x + viewport.w) / tilesize) + 1;

//End index y
// 19 = (100 + 480) / 32 + 1
int endX = ((viewport.x + viewport.w) / tilesize) + 1;

//Validation
if(startX < 0) startX = 0;
if(startY < 0) startY = 0;
//endX is set to 9 here
if(endX >= levelWidth) endX = levelWidth - 1;
//endX is set to 14 here
if(endY >= levelHeight) endY = levelHeight - 1;

for(int y = startY; y < yEnd; y++)
    for(int x = startX; x < xEnd; x++)
          [...]

Note: The code above is not tested but it should give an idea what to do.

Following a basic example for a viewport representation:

public class Viewport{
    public float x;
    public float y;
    public float w;
    public float h;
}

One thing I would consider (though I'm not sure if this matters in javascript) is to put all tiles (or as many as possible) in one big texture instead of using many single files.

fixed typo
Source Link
tom van green
  • 1.6k
  • 12
  • 13
Loading
fixed typo
Source Link
tom van green
  • 1.6k
  • 12
  • 13
Loading
Source Link
tom van green
  • 1.6k
  • 12
  • 13
Loading