GML [SOLVED] Deactivate tiles not in camera view.

C

Chris Livermore

Guest
Good evening guys and girls,

Im having some issues trying to figure out how to Deactivate tiles outside of the camera View, I basically have a tiling object that draws in random tiles to the whole room (which is 20000x20000) this is basically killing the memory usage of the game So I was hoping the instance_deactivate_region would help, but it seems it is not...

maybe you guys can point where I am going wrong?

My tile creation code:

Code:
// @description Create Tile Map

global.background_Layer = "Background";
global.background_Tilemap_Space = layer_tilemap_create(global.background_Layer,0,0,tsSpace,room_width,room_height);


/// @description Automatically draw background.

var tileWidth,tileHeight;
tileWidth = 64; // tile width
tileHeight = 64; // tile height
var Down, Across;
Across = room_width / tileWidth; // number of time to go accross
Down = room_height /tileHeight; // number of time to go down


for (var a =1; a < Down; a++;){ // simple for loop to go down the room
    for(var i =1; i < Across; i++;){ // simple for loop to go accross the room
        var ran_data = irandom_range(1,100);
        tilemap_set_at_pixel(global.background_Tilemap_Space,ran_data,((tileWidth/2)+1)*i,((tileHeight/2)+1)*a)
    }
}


my objectController Code:

Code:
x = camera_get_view_x(view_camera[0])+camera_get_view_width(view_camera[0])/2;
y = camera_get_view_y(view_camera[0])+camera_get_view_height(view_camera[0])/2;


var _vx = camera_get_view_x(view_camera[0]);
var _vy = camera_get_view_y(view_camera[0]);
var _vw = camera_get_view_width(view_camera[0]);
var _vh = camera_get_view_height(view_camera[0]);

instance_deactivate_region(_vx - 64, _vy - 64, _vw + 128, _vh + 128, 0,1);

instance_activate_region(_vx - 64, _vy - 64, _vw + 128, _vh + 128, 1);


Thank you so much for your help in advance!
 

TheouAegis

Member
Well tiles aren't instances, so you can't deactivate them. You could generate the tile map to a 2D array instead of directly to the room, then add tiles as defined by the grid. That way you'd only be loading/deleting one row or one column (or at most one row and one column) of tiles every 64 pixels moved.

By the way, 20000x20000 is a bad number if your tiles are 64x64. If you want that size, either go with 20032x20032 or 19968x19968. Either way, it'd require 4 arrays. The "optimal" room size would be 19776x19776, which would only require 3 arrays (if handled properly).

tilemap_set_at_pixel(global.background_Tilemap_Space,ran_data,((tileWidth/2)+1)*i,((tileHeight/2)+1)*a)
Why are you creating the tiles every 33 pixels when your tiles are 64 pixels? Just curious.
 
C

Chris Livermore

Guest
Well tiles aren't instances, so you can't deactivate them. You could generate the tile map to a 2D array instead of directly to the room, then add tiles as defined by the grid. That way you'd only be loading/deleting one row or one column (or at most one row and one column) of tiles every 64 pixels moved.

By the way, 20000x20000 is a bad number if your tiles are 64x64. If you want that size, either go with 20032x20032 or 19968x19968. Either way, it'd require 4 arrays. The "optimal" room size would be 19776x19776, which would only require 3 arrays (if handled properly).


Why are you creating the tiles every 33 pixels when your tiles are 64 pixels? Just curious.

Thanks for your reply,

Thanks for the tip on the room size, I didnt think about that!

the 33 pixel thing I thought would be the middle of each Tile?

Would it be better maybe to draw them as sprites?

and would a DS gird be an option here for easier handling?


also, I know this is cheeky but could you help with some sample code for this? Im fairly new so Getting my head round everything !
 
Last edited by a moderator:

TheouAegis

Member
To have those tiles offset in the room by 32 pixels, you x the width of the tile and then add 32.

Greater slower and you are going to be doing a lot of reading every time you need to access the tile mapping.

Your coat is already set up to create the array just fine. Declare the array, then run your loop that randomizes the tiles, but instead of actually creating a tile, just store its value in the array.

If you treat their Ray as a 1D array, you'd need to initialize indexes 95999, 63999, and 31999. If you use a 2D array, you need to initialize [0-(Across-1), (Down-1] or [0-(Down-1), (Across-1)]. Initializing those indexes will make the initial array generation much, much faster. In your case, just use a 2D array, since you have some code already.
 
C

Chris Livermore

Guest
To have those tiles offset in the room by 32 pixels, you x the width of the tile and then add 32.

Greater slower and you are going to be doing a lot of reading every time you need to access the tile mapping.

Your coat is already set up to create the array just fine. Declare the array, then run your loop that randomizes the tiles, but instead of actually creating a tile, just store its value in the array.

If you treat their Ray as a 1D array, you'd need to initialize indexes 95999, 63999, and 31999. If you use a 2D array, you need to initialize [0-(Across-1), (Down-1] or [0-(Down-1), (Across-1)]. Initializing those indexes will make the initial array generation much, much faster. In your case, just use a 2D array, since you have some code already.

I see, Ok ill set up as Arrays, Now actually initialising the tiles.... wont I still be drawing too many tiles in the long run?
As camera moves > draw next line of tiles from array.

But then how do I kill the first line of tiles?

or are you saying blank the array with the tiles I no longer need? But then will this not cause issued when I move backwards towards the now dead tiles?



So Above, I am trying to visialise it..... Lets say we use 1 for a tile 0 for not.

the active screen currently is on the 1s but we move 1 block to the right, we now make Col 2 0 so the tiles are not Drawn on the next step!?

then add 1s to Col 13 so Tiles are drawn?

Am I understanding that correctly?

also what is the function to clear tile screen/Undraw the tiles?

Thanks for taking the time to explain this to me. Once I have solved this I will post Code for anyone who stumbles apon this thread.
 
Last edited by a moderator:

TheouAegis

Member
Quick answer: No, not like that.

What all are you doing with the tiles? I get a steady 60 fps and average 8000 fps_real with a 19776x19776 room filled with 64x64 tiles. I gotta get to work now, so I'll get back to the other issue later.
 
C

Chris Livermore

Guest
wow, OK i must have something going on then. because when I enable the above code, my Mem usage goes from 30MB to 1560MB..... I shall investigate and report back!
 

TheouAegis

Member
Memory usage according to the Debugger?
My baseline is 17.6MB with a 512x512 layout of tiles.
I got 18MB with an irandom(80) specification filling the whole room.
With a 96000-entry 1D array, I "jumped" to 19MB.
With a 312x312 2D array, it was the same as the 1D array.
Doubling the view's dimensions (even leaving the port small so the view gets scaled) made no difference.
Granted, this was just in a quick test project with no much in the game.

Code:
var Width = room_width div 64, Height = room_height div 64, i, j, n;
for(i = 0; i<Width; i++;) for(j=0; j<Height; j++;) {
    n = irandom(100);
    tilemap_set_at_pixel(_tilelayer, n, i*64, j*64);
    tile_map[i,j] = n;
}
^
18.9MB of memory, according to the Debugger.

With a quick simple test, it seems as soon as you create a tile layer and assign a tile set to it, it automatically partitions out the memory for storing the tile data. So if you remove the tiles from your room completely but leave the tile layer there, you should get a baseline.

the whole room (which is 20000x20000)
Are you talking 20,000 pixels by 20,000 pixels, or 20,000 tiles by 20,000 tiles? If you meant 20,000 tiles by 20,000 tiles, that would explain why your memory use is so high! That's overkill. If that's the case, you should learn to break up the world into chunks. No one wants to play a game that takes up a whole gig of memory just for the tilemap.
 
C

Chris Livermore

Guest
Memory usage according to the Debugger?
My baseline is 17.6MB with a 512x512 layout of tiles.
I got 18MB with an irandom(80) specification filling the whole room.
With a 96000-entry 1D array, I "jumped" to 19MB.
With a 312x312 2D array, it was the same as the 1D array.
Doubling the view's dimensions (even leaving the port small so the view gets scaled) made no difference.
Granted, this was just in a quick test project with no much in the game.

Code:
var Width = room_width div 64, Height = room_height div 64, i, j, n;
for(i = 0; i<Width; i++;) for(j=0; j<Height; j++;) {
    n = irandom(100);
    tilemap_set_at_pixel(_tilelayer, n, i*64, j*64);
    tile_map[i,j] = n;
}
^
18.9MB of memory, according to the Debugger.

With a quick simple test, it seems as soon as you create a tile layer and assign a tile set to it, it automatically partitions out the memory for storing the tile data. So if you remove the tiles from your room completely but leave the tile layer there, you should get a baseline.


Are you talking 20,000 pixels by 20,000 pixels, or 20,000 tiles by 20,000 tiles? If you meant 20,000 tiles by 20,000 tiles, that would explain why your memory use is so high! That's overkill. If that's the case, you should learn to break up the world into chunks. No one wants to play a game that takes up a whole gig of memory just for the tilemap.

Your code seems to have fixed it. Must have been something scuffed in my code!

Thanks so much for your help I am now running at 93mb Vice 1500!!!

and I can finally move on from what I thought would be a simple creation code :D

Thanks again for taking the time to teach a noob!
 
Top