GML Erase tool for painting (for a painting software made with GMS2)

  • Thread starter Deleted member 16767
  • Start date
D

Deleted member 16767

Guest
I've practically given up on how to make an erase tool for sprites that are created in GML on layers. Is it possible to make an erase tool that can erase pixels on sprites in GML?
 
R

robproctor83

Guest
There has to be an easier way, but off the top of my head I'm thinking it should at least be possible to draw the Sprite to a surface then use blend modes and another Sprite to erase part of y surface and then you can create a new new Sprite from the surface.
 
You have this function:

draw_getpixel_ext(x, y)

I'm thinking you loop across the sprite, and build up a data list of its pixels - perhaps storing its x / y positions and colour data in a string. Then when you want to change the colour of, or remove, a pixel you change that value within the list: edit the colour value to a new one, or give it "no value" so that nothing is drawn later.

To find the place in the list you could use some straightforward maths (if I'm figuring this correctly): get the height of the pixel to change, and minus one. Take that result and multiply by the sprite width. Add to that the x position of the pixel, and you get the list position you want to alter (NOTE: I couldn't get this to work, so changed it below)

Once you've altered all the points you'd then have to loop through the list again, break down the string into those three components and use:

draw_point_colour(x, y, col1)

to redraw the image pixel by pixel onto a surface (if it has a colour value). Then save the surface as a sprite, and overwrite the already existing image or make a new one.

create event:
Code:
list = ds_list_create();
left = bbox_left;
top = bbox_top;
right = bbox_right;
bottom = bbox_bottom;
end_result = undefined; // checking purposes only - can be removed
is_pos = undefined; // checking purposes only - can be removed
is_colour = undefined; // checking purposes only - can be removed
cur_x = undefined; // checking purposes only - can be removed
cur_y = undefined; // checking purposes only - can be removed
do_draw = false;
blue = undefined;
green = undefined;
red = undefined;
actual_colour = undefined;
draw end event:
Code:
if !do_draw // "reads" the current sprite into the ds list (list)
{
var width = sprite_width;
var height = sprite_height;
for (var a = 0; a < width; a++)
{
for (var b = 0; b < height; b++)
{
var result = draw_getpixel_ext(left + a, top + b);
end_string = string(a) +"/" + string(b) + "\" + string(result)
ds_list_add(list, end_string)
}
}
do_draw = true;
}

draw_text(20, 20, ds_list_size(list)); // checking purposes only - can be removed
draw_text(20, 40, end_result); // checking purposes only - can be removed
draw_text(20, 60, cur_x); // checking purposes only - can be removed
draw_text(20, 80, cur_y); // checking purposes only - can be removed
draw_text(20, 100, actual_colour); // checking purposes only - can be removed
draw_text(20, 120, red); // checking purposes only - can be removed
draw_text(20, 140, green); // checking purposes only - can be removed
draw_text(20, 160, blue); // checking purposes only - can be removed
if is_colour != undefined // checking purposes only - can be removed
{
draw_rectangle_colour(20, 220, 40, 260, actual_colour, actual_colour, actual_colour, actual_colour, false);
}
end step event:
Code:
if point_in_rectangle(mouse_x, mouse_y, left, top, right, bottom)
{
if ds_list_size(list) > 0
{
var is_width = mouse_x - left;
var is_height = mouse_y - top;
var list_size = ds_list_size(list)
for (var c = 0; c < list_size; c++)
{
end_result = ds_list_find_value(list, c);
var is_break_one = string_pos("/", end_result);
var is_break_two = string_pos("\", end_result);
var is_length = string_length(end_result);
var x_pos = real(string_copy(end_result, 1, is_break_one - 1));
var y_pos = real(string_copy(end_result, is_break_one + 1, is_break_two - (is_break_one + 1)));
if ((x_pos == is_width) && (y_pos == is_height))
{
cur_x = x_pos;
cur_y = y_pos;
is_colour = real(string_copy(end_result, is_break_two + 1, is_length - (is_break_two)))
break;
}
}
var alpha = (is_colour >> 24) & 255;
blue = (is_colour >> 16) & 255;
green = (is_colour >> 8) & 255;
red = is_colour & 255;
actual_colour = make_colour_rgb(red, green, blue);
}
}
else
{
is_colour = undefined;
cur_x = undefined;
cur_y = undefined;
}
I couldn't quite figure out how to do anything more advanced with finding the corresponding list entry to the mouse point, so it's just looping through them all and parsing the result until it finds the same x / y value.

At this stage I was only using it to draw a colour onscreen and check that it matched up with the current mouse position.

This works and would now just need to have the function to rewrite entries added to it. To redraw the edited list would be pretty much the same parsing process, but with a small addition.

PS It's badly coded, and could be tidied up a fair bit :)
 
Last edited:
Top