T
Taddio
Guest
Hey,
I'm trying to learn some functions which were on my to-learn list since some time, and I tried to tackle the frowned-upon surface_getpixel().
My idea is to split the map into a ds_grid, whose values will depend on the color of the pixel checked.
In the create event, that works like I want, I can adjust grid size for more or less precision.
But the roadblock came when trying to update the grid values when the pixel is erased.
The idea is to have a destructible terrain which will update the grid when a hole is punched in the surface (think something like Worms), and where I could do semi-random maps based on very small sprites.
Screenshot on top is the level as it's created (this works good as I said)
Screenshot at bottom after a collision. Notice the number should be 0 when it's above anything but a pure red pixel, and 1 when it is red.
The surface updates, the user event runs, but the grid doesn't update as I expect.
My train of thoughts is pretty much commented all the way. Let me know if you have any idea or if you need more code/info.
Screenshot
I'm trying to learn some functions which were on my to-learn list since some time, and I tried to tackle the frowned-upon surface_getpixel().
My idea is to split the map into a ds_grid, whose values will depend on the color of the pixel checked.
In the create event, that works like I want, I can adjust grid size for more or less precision.
But the roadblock came when trying to update the grid values when the pixel is erased.
The idea is to have a destructible terrain which will update the grid when a hole is punched in the surface (think something like Worms), and where I could do semi-random maps based on very small sprites.
Screenshot on top is the level as it's created (this works good as I said)
Screenshot at bottom after a collision. Notice the number should be 0 when it's above anything but a pure red pixel, and 1 when it is red.
The surface updates, the user event runs, but the grid doesn't update as I expect.
My train of thoughts is pretty much commented all the way. Let me know if you have any idea or if you need more code/info.
Code:
//=== obj_world_gen_pixel ===//
/// @description Generate world
col = false; //Collsion flag triggered by obj_projectile
grid_check_x = 0; //Will get x grid-position of projectile when colliding
grid_check_y = 0; //Will get y grid-position of projectile when colliding
#region Surface
_spr_surf = 0; //Will be a sprite of the surface, to save it
spr_ind = 1; //Sprite index of the chunk to load (make random eventually)
application_surface_enable(false); //We don't really need it
var _spr_w, _spr_h, _x_scale, _y_scale;
surf_sky = surface_create(room_width, room_height); //This is the blue sky surface
surf_bg = surface_create(room_width, room_height); //This is the terrain surface
_spr_w = sprite_get_width(spr_get_pixel); //Get width of terrain sprite
_spr_h = sprite_get_height(spr_get_pixel); //Get height of terrain sprite
_x_scale = (room_width/_spr_w); //get aspet ration in X
_y_scale = (room_height/_spr_h); //Get aspect ratio in Y
//Draw sky background
surface_set_target(surf_sky);
draw_sprite_ext(spr_sky_pixel, 0, 0, 0, room_width, room_height, 0, c_white, 1);
surface_reset_target();
//Draw red sprite for terrain
surface_set_target(surf_bg);
draw_sprite_ext(spr_get_pixel, spr_ind, 0, 0, _x_scale, _y_scale, 0, c_white, 1);
surface_reset_target();
//Copy the surface to a sprite
_spr_surf = sprite_create_from_surface(surf_bg, 0, 0, room_width, room_height, 0, 0, 0, 0);
#endregion
#region Creates world based on red color of bg
max_chunk_w = room_width/TILE_SIZE; //Get number of horizontalgrid cell in room
max_chunk_h = room_height/TILE_SIZE; //Get number of vertical grid cell in room
terrain_grid = ds_grid_create(max_chunk_w, max_chunk_h); //This ds_grid holds all terrain values
//Loop variables
var _w, _h, _i, _j, _col, _red, _bin, _xx, _yy, _offset;
draw_set_font(font0);
_offset = (TILE_SIZE/2);
//Loops through grid to find red pixels at middle center of grid
for(_i=0; _i<=max_chunk_w-1; _i++) { //Loops through all ds_grid in X
for(_j=0; _j <=max_chunk_h-1; _j++) { //Loops through all ds_grid in Y
_xx = _i<<4; //Multiply _i by 16 (TILE SIZE)
_yy = _j<<4; //Multiply _j by 16 (TILE SIZE)
//Get pixel color of the middle-center of the grid cell
_col = surface_getpixel(surf_bg, (_xx+_offset), (_yy+_offset));
//Get the red value
_red = (color_get_red(_col));
//Divide so a full red value(255) will equal to 1
_bin = _red >>7;
//Set grid position to 1 if pixel is red
ds_grid_set(terrain_grid, _i, _j, _bin);
//Draw grid value at grid position
draw_text(_xx+ _offset, _yy+_offset, string(_bin));
}
}
#endregion
Code:
//********STEP EVENT******//
if(col){
event_user(0);
}
Code:
//********USER EVENT 0******//
/// @description updates grid after a collision
var _i, _j, _col, _red, _xp, _yp;
draw_set_font(font0); //Set font
//Loops a 2-grid square area around collision point
for(_i=-2; _i<=2; _i++){
for(_j=-2; _j<=2; _j++){
_xp = (grid_check_x+_i)<<4; //Multiply grid_x by 16 (TILE_SIZE) to get pixel position
_yp = (grid_check_y+_j)<<4; //Multiply grid_y by 16 (TILE_SIZE) to get pixel position
_col = surface_getpixel(surf_bg, ((_xp)+(TILE_SIZE/2)), ((_yp)+(TILE_SIZE/2))); //Get color of surface at pixel position
_red = (color_get_red(_col)); //Get redness of pixel
if(_red == 0){ //If there is no red, set grid position to 0
ds_grid_set(terrain_grid, grid_check_x+_i, grid_check_y+_j, 0);
}
}
}
col = false;
Code:
//********DRAW EVENT******//
#region Draw world on a surface
//Draw blue background (sky)
if(!surface_exists(surf_sky)) {
surf_sky = surface_create(room_width, room_height);
surface_set_target(surf_sky);
draw_sprite_ext(spr_sky_pixel, 0, 0, 0, room_width, room_height, 0, c_white, 1);
surface_reset_target();
draw_surface(surf_sky, 0, 0);
} else {
draw_surface(surf_sky, 0, 0);
}
//Draw red BG for terrain
if(!surface_exists(surf_bg)) {
surf_bg = surface_create(room_width, room_height);
surface_set_target(surf_bg);
draw_sprite(_spr_surf, 0, 0, 0);
surface_reset_target();
draw_surface(surf_bg, 0, 0);
} else {
draw_surface(surf_bg, 0, 0);
}
//Draw grid cell value (updates every step for debug purposes, remove on compile)
draw_set_halign(fa_center);
draw_set_valign(fa_middle);
for(var _w=0; _w <= (max_chunk_w-1); _w++) {
for(var _h=0; _h <= (max_chunk_h-1); _h++) {
var _cell = ds_grid_get(terrain_grid, _w, _h);
draw_text((_w<<4)+(TILE_SIZE>>2), (_h<<4)+(TILE_SIZE>>2), _cell);
}
}
#endregion
Screenshot
Last edited by a moderator: