# tiling an image between sets of coordinates

Discussion in 'Tutorials' started by Didjargo, Jan 12, 2017.

1. ### DidjargoMember

Joined:
Jun 21, 2016
Posts:
47
GM Version: GMS2 v2.0.3.56
Target Platform: ALL

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)

NeZvers and sludgecoyote like this.
2. ### chancepredictably randomForum StaffModerator

Joined:
Apr 22, 2016
Posts:
795
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.

3. ### PoddingtonMember

Joined:
Jul 15, 2016
Posts:
13
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.
}
}
}```

NeZvers likes this.
4. ### sludgecoyoteMember

Joined:
Apr 7, 2019
Posts:
9
This works great but had to add a line in there to reset the alpha back to default.