Jump to content


Photo

Randomized Isometric Level Generator

gm8.1

  • Please log in to reply
8 replies to this topic

#1 ffomega

ffomega

    GMC Member

  • New Member
  • 5 posts
  • Version:GM:Studio

Posted 27 March 2016 - 12:13 AM

Hi guys.  I am new here and new to game maker.  I have used the Clickteam products as my creation tool for years and have had performance issues with a particular project I am working on.  This project uses borrowed (and very large) isometric tiles (a floor tile by itself if 360 x 180 so it gives you an idea of the scale of my intended maps ~ approx 7200 x 3600 for a 20 x 20 grid).

 

That being said, I decided to try out game maker to learn how to create randomly generated levels and came across HeartBeast on youtube, who has a vast amount of video tutorials I have been digging through in hopes that of finding something.  I did find a random level generator series he created among 7 videos, which, at its base level, uses ds_grid and accessors, and uses just two background objects rather than sprites.  The problem I have is that I do not know how to convert the ds_grid's x and y into a diamond isometric grid, while maintaining the integrity of his code.  I looked at the demo for the isometric game engine, but it did not have random generation.  Furthermore it uses the room editor to create the levels, while HeartBeast's code generates everything at runtime.

 

In case anyone is interested, here is basically everything within the engine:

 

------------------------------------------------------------------------------------------------------------------

Here are his macros:

 

macros.png

 

Here is the tree structure (only one room needed in the example).  There are just two backgrounds at the moment, and one object:

 

tree_and_room.png

 

Once I figure out how to readjust the grid using his code, I will edit the backgrounds, turning them from squares into diamonds.

 

And the code (he placed everything within a single create code in the object "level":

/// Create the level
// resize the room
room_width = (CELL_WIDTH/16) * 720;
room_height = (CELL_HEIGHT/16) * 720;

// set grid width and height
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 a void
ds_grid_set_region(grid, 0, 0, width-1, height-1,VOID);

// randomize the world
randomize();

// create the controller in the center of the grid
var cx = width div 2;
var cy = height div 2;

// give the controller a random direction
var cdir = irandom(3);

//The odds variable for changing direction
var odds = 1;

// create the level using 1,000 steps
repeat (1000) {
    // place a floor tile at the controller position
    grid[# cx, cy] = FLOOR;
    
    // randomize the direction of the controller
    if (irandom(odds) == odds){
       cdir = irandom(3);
    }

    // move the controller
    var xdir = lengthdir_x(1, cdir*90);
    var ydir = lengthdir_y(1, cdir*90);
    cx += xdir;
    cy += ydir;

    // stay within the grid
    cx = clamp(cx, 1, width-2);
    cy = clamp(cy, 1, height-2);
}

//Add the walls
for (var yy = 1; yy < height-1; yy++) {
    for (var xx = 1; xx < width - 1; xx++) {
        if (grid[# xx, yy] == FLOOR) {
            // Check the walls
            if (grid[# xx+1, yy] != FLOOR) grid[# xx+1, yy] = WALL;
            if (grid[# xx-1, yy] != FLOOR) grid[# xx-1, yy] = WALL;
            if (grid[# xx, yy+1] != FLOOR) grid[# xx, yy+1] = WALL;
            if (grid[# xx, yy-1] != FLOOR) grid[# xx, yy-1] = WALL;
            }
        }
}
// draw the level visually
for (var yy = 0; yy < height; yy++) {
    for (var xx = 0; xx < width; xx++) {
        if (grid[# xx, yy] == FLOOR) {
            // Draw the floor
            tile_add(bg_floor, 0, 0, CELL_WIDTH, CELL_HEIGHT, xx*CELL_WIDTH, yy*CELL_HEIGHT, 0);   
        } else if (grid[# xx, yy] == WALL) {
            // Draw the walls
            tile_add(bg_wall, 0, 0, CELL_WIDTH, CELL_HEIGHT, xx*CELL_WIDTH, yy*CELL_HEIGHT, 0);
        }
    }

}

A second code was created using a button press (Spacebar)

/// restart the room
room_restart();

...and finally, the finished result:

 

level.png

 

(Sorry if this thread is really huge).


  • 0

#2 Paolo Mazzon

Paolo Mazzon

    Has Too Much Time

  • GMC Member
  • 811 posts
  • Version:GM:Studio

Posted 27 March 2016 - 07:10 AM

If you tile the screen of an isometric game 45 degrees and look from birds eye view it is just a top down game. You just need to project the game world as an isometric game.


  • 0

#3 ffomega

ffomega

    GMC Member

  • New Member
  • 5 posts
  • Version:GM:Studio

Posted 27 March 2016 - 08:24 AM

Yes, but what I am trying to figure out is what the coordinates of the grid should be adjusted for isometric tiling.

 

Currently, the grid starts at x 0, y 0, then performs its loops, each time, changing to a random direction, 0-3 (multiplied by 90), which then places the next check randomly to the right, left, above, or below by 32 pixels (the tiles' current size.  I am using a placeholder image that is 32 x 32, with a diamond shaped tile that is 32 x 16.  I am confused as to how to reposition the grid.  Originally I tried to reposition the tiles by way of angles but I never could come up with the right angle, and isometric games are commonly misread to have 30 degree angled tiles.  This is not always true.  The angle of my tiles (and those I am used to seeing) are at an angle of approx. 26.565.

 

I cannot simply plug in 45 to the code where 90 is, as this will not give me an accurate angle when repositioning tiles, and I cannot plug in 26.565 either because this too will give an ill-positioned angle.

 

Math was not always my worst subject xD


  • 0

#4 YanBG

YanBG

    GMC Member

  • GMC Member
  • 217 posts
  • Version:GM:Studio

Posted 27 March 2016 - 10:59 AM

Exact offsets are here: http://clintbellange...isometric_math/

 

Your diamond map tiling will start from the top so you need to place it on room_width/2(instead of 0)

 

You can check this topic for more info: http://gmc.yoyogames...howtopic=677388

 

This is about pathifinding: http://gmc.yoyogames...howtopic=675928


  • 0

#5 ffomega

ffomega

    GMC Member

  • New Member
  • 5 posts
  • Version:GM:Studio

Posted 28 March 2016 - 03:28 AM

Thanks :) I looked at the information you provided, and I kind of understand the jist of things.  However, when I tried to implement it I rand into a couple problems:

 

I tried repositioning the created grid to the center of the room (room_width/2, room_height/2) instead of 0, 0).  And the isometric tiles I created for the project do not appear within the window (I assume they are being drawn, just out of bounds).

 

I tried to create a formula (as explained in the article):

iso_h = (xx - yy) * ISO_WIDTH;  // Where ISO_WIDTH is CELL_WIDTH / 2
iso_v = (xx + yy) * ISO_HEIGHT; // Where ISO_HEIGHT is CELL_HEIGHT / 2

Then, I added the line:

tile_add(iso_floor, 0, 0, ISO_WIDTH, ISO_HEIGHT, iso_h, iso_v, 0); 

within the section of the code that draws the original grid-based map, expecting the isometric tiles to be drawn in as well.

 

Tweaking the line of code draws them on screen, but either stacked on top of one another in a single coordinate, or with weird 1-2 pixel offsets in all directions.

 

Sorry if this is frustrating, but this is part of the learning process (:


  • 0

#6 YanBG

YanBG

    GMC Member

  • GMC Member
  • 217 posts
  • Version:GM:Studio

Posted 28 March 2016 - 10:19 AM

Y should be still 0 not room_height/2, diamond shaped tiles usually have double width compared to height. What's your tiles size?

 

Are you using double for loops to position them through the grid? In tile_add, the entries where you use iso_width and iso_height should use the dimensions of your tile asset(e.g. 360 and 180) since it's a rectangle with some blank corners but it still needs space to draw all of it or there will be cuts.

 

Btw is your view locked on a character? I'm using a trick to set the view_xview and view_yview always on a regular distance from the player object so it won't snap on the edges of the room.


  • 0

#7 ffomega

ffomega

    GMC Member

  • New Member
  • 5 posts
  • Version:GM:Studio

Posted 28 March 2016 - 07:33 PM

For testing purposes, I am using a sprite size of 36 x 18 for the floor tiles and 36 x 36 for the wall tiles.  the official tiles will be 360 x 180 for floor tiles and 360 x 482 for walls.

 

I decided to remove the iso_h and iso_v lines from the code, as they were not showing the isometric tiles on screen.

 

the question I should have probably asked is:

 

Since I am using the grid to display the regular top-down tiles to the level, will I have to create a second grid to display the isometric tiles? Because currently the grid is using for loops to determine its origin on the screen.  xx and yy both start at 0, so that is where the grid is drawn from.  If I try using the same grid to draw the isometric tiles, by plugging in any formulas that use the "square" grid, the tiles are not drawn (at least on the screen).  Likewise, if I alter the square grid's parameters in any way, the square grid no longer draws correctly.  the only way I am able to see the tiles is if I draw them in the exact same manner as the square tiles.  The closest I can get to laying them side-by-side is this:

 

iso_draw.png

 

As far as pathfinding is concerned, I won't be using it for enemies since battles were planned to be random encounter.  I suppose I could use them for NPCs though.  Camera will be fixed on the player.  I will tackle that problem once past this drwing 'mess'.


  • 0

#8 YanBG

YanBG

    GMC Member

  • GMC Member
  • 217 posts
  • Version:GM:Studio

Posted 28 March 2016 - 10:58 PM

You just need the offsets mate and they won't be drawn like the top-down, the grid is the same you need it to check which cell(this corresponds to the double for loop) is floor and which is wall.

 

Get back to the iso_h an iso_v.

 

Ok this is from my code(i started it from the same HeartBeast's tutorial as you):

tile_add(iso_floor,0,0,36,18,(xx-yy)*18+room_width/2,(xx+yy)*9,0);

Hm your offsets were wrong it seems, you need half a tile w/h not a cell w/h(which are square).


  • 0

#9 ffomega

ffomega

    GMC Member

  • New Member
  • 5 posts
  • Version:GM:Studio

Posted 28 March 2016 - 11:43 PM

omg thank you so much <3 All this stuff is so confusing to me xD


  • 0





Also tagged with one or more of these keywords: gm8.1