• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

tiling an image between sets of coordinates

Didjargo

Member
GM Version: GMS2 v2.0.3.56
Target Platform: ALL
Download: N/A
Links: N/A

Summary:
GML has a function to draw a sprite and tile it, but that is designed to fill the whole room with the tiled image. I have come up with a script which allows you to draw a sprite at one set of coordinates and tile it until it reaches a second set of coordinates. This can be useful for creating in-game menu windows with a tiled image in it.

Tutorial:
- import an image you wish to tile. It does not have to be a perfect square. I created this one for you to test out and called it "window_bg_spr"
https://s28.postimg.org/jimhi4ei5/window_bg_spr.png
-create a new script and call it "tile_image_scr" or whatever you like.
- for the "tile_image_scr" script, write this code.
Code:
//argument0 = x1, argument1 = y1, argument2 = x2, argument3 = y2, arguemnt4 = alpha argument5 = image

bg_width = sprite_get_width(argument5); //obtain the width of the tiled image
bg_height = sprite_get_height(argument5); //obtain the height of the tiled image

x_tile = (argument2-argument0)/bg_width;  //the number of horizontal tiles
y_tile = (argument3-argument1)/bg_height;  //the number of vertical tiles

x_tile_place = argument0  +  (floor(x_tile)*bg_width);  //the x coordinate of the last tile
y_tile_place = argument1  +  (floor(y_tile)*bg_height);  //the y coordinate of the last tile

//count the number of tiles that should be there (x_tile and y_tile) and place a tile at each point
//until it reaches the needed count.
x_show_tile = floor(x_tile)+1;
y_show_tile = floor(y_tile)+1;

//check to see if the difference between the sets of coordinates requires image tiling
if (x_show_tile * y_show_tile) > 0
{
    x_row = 0;
    y_row = 0;
    count = 0;
    row_count = 0;
   
    draw_set_alpha(argument4);
   
    //this do statment will draw the tiles to fill in between the coordinates
    do
    {
    if (argument0+(x_row*bg_width))+ bg_width <= argument2
    x_scale = bg_width
    else
    x_scale= (x_tile-floor(x_tile)) * bg_width
   
    if (argument1+(y_row*bg_height))+ bg_height <= argument3
    y_scale = bg_height
    else
    y_scale= (y_tile-floor(y_tile)) * bg_height
   
    //if the whole image fits within the coordinates, draw it whole. Otherwise, draw part of it
    if (x_scale = bg_width) and (y_scale = bg_height)
    draw_sprite(argument5,0,argument0+(x_row*bg_width),argument1+(y_row*bg_height))
    else
    draw_sprite_part(argument5,0,0,0,  x_scale, y_scale ,argument0+(x_row*bg_width),argument1+(y_row*bg_height))
    x_row += 1;
    row_count += 1;
    if row_count = x_show_tile
        {
        y_row += 1;
        x_row = 0;
        row_count = 0;
        }
   
    count += 1;
    }
    until (count = x_show_tile * y_show_tile)
}
You should call upon the script in the "draw" or "draw GUI" events of an object. the variables for the script are
tiled_image_obj(x1,y1,x2,y2,alpha, sprite)
so for example:
tiled_image_obj(x,y,mouse_x,mouse_y,0.8,window_bg_spr)
 

chance

predictably random
Forum Staff
Moderator
I haven't tried this, so we'll leave it for readers to test.

But please add some brackets to the two if / else segments in the middle of the main loop to make it clear what statements are included inside the conditional. The way it's written makes it difficult to read -- and potentially ambiguous.
 
P

Poddington

Guest
Whilst it does work it's very limited. Keeping the script as originally written it only work on a positive x,y from the starting point. So where either the starting x and y is it will only draw tiles correctly to the right and/or down. This will also show tiles to the edge, even if the regions right and bottom aren't the full tiles size. I'm sure it has a use, but I often find when making an auto tiler that you'd only want to show full tiles. A simple for loop within a for loop drawing tiles from the region start to the region end with increments of the tile size will have the same effect if in the draw event. I could be missing it's purpose and maybe it didn't work properly for me. Here is code I used recently that did the same thing I saw when using the script above.

Code:
if(object_current_x > object_start_x and object_current__y > object_start_y) //if the current x and y is greater than the x and y when the mouse button was pressed then...
        {
        for (i = object_start_x; i < object_current_x; i += 32)
            {
            for (j = object_start_y; j < object_current__y; j += 32)
                {
                 draw_sprite(spr_draw_tile,0,i,j);
                 draw_select_x = i;  //the x position after the loops useful to capture the last tiles x and y to use afterwards. This was used to select the region in a DS grid when I wrote this.
                 draw_select_y = j; //the y position after the loops useful to capture the last tiles x and y to use afterwards. This was used to select the region in a DS grid when I wrote this.
                }
            }
        }
 
S

sludgecoyote

Guest
This works great but had to add a line in there to reset the alpha back to default.
 
Top