D
Drazah
Guest
- Ultimately, I'm wanting to be able to change a circular selection of tiles in a ds_grid using a function like "ds_grid_set_disk". I have not been able to get this to work. The method I have been using is to manually select all the tiles that I want to change, and if I'm wanting to destroy tiles in a circle that is bigger than the one I currently have, I have to code it together - this takes forever!
- So any help with getting the "ds_grid_set_disk" function working would be appreciated!
- I currently have randomly generated levels that are made using a ds_grid. It all works as I would like it to. It works just about the same as the random level generation tutorial by HeartBeast.
So, I have an object "obj_level", with this code in its Create event (which all works fine):
Code:
///obj_level Create
//Resize the room
room_width = (CELL_WIDTH/8) * 360
room_height = (CELL_HEIGHT/8) * 360
//Set the grid
var width = room_width div CELL_WIDTH;
var height = room_height div CELL_HEIGHT;
//Create the grid
grid = ds_grid_create(width, height);
//Fill the grid with empty/air cells
ds_grid_set_region(grid, 0, 0, width, height, bk_air);
//Randomize the world
randomize();
//Create the controller on the side of the grid
var cx = 0;
var cy = height div 2;
//The odds of changing direction
var odds = 1;
//The odds of going up or down
//Up = 1
//Down = 0
var updown = 1;
//Create the earth
repeat(width)
{
ds_grid_set(grid, cx, cy, bk_block_dirt);
if (irandom(odds) = 1)
{
cx ++;
} else {
if (irandom(updown) = 1)
{
cx ++;
cy ++;
} else {
cx ++;
cy --;
}
}
}
//Fill the crust with dirt tiles
repeat(height)
{
for(var yy = 1; yy < height; yy ++)
{
for(var xx = 0; xx < width; xx ++)
{
if (grid[# xx, yy] == bk_block_dirt)
{
grid[# xx, yy + 1] = bk_block_dirt;
}
}
}
}
//Draw the level using the grid
for(var yy = 0; yy < height; yy ++)
{
for(var xx = 0; xx < width; xx ++)
{
if (grid[# xx, yy] != bk_air)
{
tile_add(ds_grid_set(grid, cx, cy, bk_block_dirt), 0, 0, CELL_WIDTH, CELL_HEIGHT, xx * CELL_WIDTH, yy * CELL_HEIGHT, 0)
}
}
}
- I'm wanting to be able to destroy the dirt blocks (bk_block_dirt) in a circle of a certain radius, and leave behind nothing (bk_air). So far, I've only been able to get this working with a very time consuming and clunky method, shown below.
Code:
var tile_above = tile_layer_find(0, mouse_x, mouse_y - CELL_HEIGHT);
var tile_above_left = tile_layer_find(0, mouse_x - CELL_WIDTH, mouse_y - CELL_HEIGHT);
var tile_above_right = tile_layer_find(0, mouse_x + CELL_WIDTH, mouse_y - CELL_HEIGHT);
var tile = tile_layer_find(0, mouse_x, mouse_y);
var tile_left = tile_layer_find(0, mouse_x - CELL_WIDTH, mouse_y);
var tile_right = tile_layer_find(0, mouse_x + CELL_WIDTH, mouse_y);
var tile_below = tile_layer_find(0, mouse_x, mouse_y + CELL_HEIGHT);
var tile_below_left = tile_layer_find(0, mouse_x - CELL_WIDTH, mouse_y + CELL_HEIGHT);
var tile_below_right = tile_layer_find(0, mouse_x + CELL_WIDTH, mouse_y + CELL_HEIGHT);
if mouse_check_button(mb_left)
{
//Center row
if tile_exists(tile) { tile_delete(tile); }
if tile_exists(tile_left) { tile_delete(tile_left); }
if tile_exists(tile_right) { tile_delete(tile_right); }
//Top row
if tile_exists(tile_above) { tile_delete(tile_above); }
if tile_exists(tile_above_left) { tile_delete(tile_above_left) }
if tile_exists(tile_above_right) { tile_delete(tile_above_right) }
//Bottom row
if tile_exists(tile_below) { tile_delete(tile_below); }
if tile_exists(tile_below_left) { tile_delete(tile_below_left) }
if tile_exists(tile_below_right) { tile_delete(tile_below_right) }
}
- So, if I wanted to create a circle in the terrain that was any bigger than the circle created here, I'd have to add more variables, such as "var tile_above_above_above_left", etc. This takes forever.
Code:
///obj_level Step
radius = 5
var gx = scr_mx_to_gx(mouse_x);
var gy = scr_my_to_gy(mouse_y);
if mouse_check_button_pressed(mb_left)
{
ds_grid_set_disk(grid, gx, gy, radius, bk_air)
for(yy = 0 ; yy < height ; yy ++)
{
for(xx = 0; xx < width ; xx ++)
{
if (grid[# xx, yy] == bk_air)
{
if tile_exists(bk_block_dirt) { tile_delete(bk_block_dirt) }
}
}
}
}
- I'm aware that once you left click that it goes through the whole grid again. In the end, I'd want it to just look at the grid co-ordinates near where the left click was made. For now, I'm just trying to get it working.
The two variables gx and gy are used to get the x and y of the grid. They use these scripts:
Code:
///scr_mx_to_gx(mouse_x)
var gx = argument0;
var xcell = gx div CELL_WIDTH;
return xcell;
Code:
///scr_my_to_gy(mouse_y)
var gy = argument0;
var ycell = gy div CELL_HEIGHT;
return ycell;
Any help getting circles made in the terrain with something like the function "ds_grid_set_disk" would be appreciated.
I hope this isn't too long and makes sense...
Thanks!