• 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!

Legacy GM Isometric Vertical Movement

Anixias

Member
I've been working this game for a little while and while I've gotten my graphics to a point where I love them, I just thought about a player-movement flaw. The game is an infinite random world in a survival aspect. Here is a screenshot:

How should I handle the player attempting to walk down a slope, but up-right/up-left?

Like, if they attempt to walk behind something to where the camera would no longer see them?

I'm using chunks and vertex buffers, so all of those tiles are below the player's depth, which causes the player to draw over the whole world, even if he is behind the map. I would rather not mess with occlusion.

Should I just restrict the player from walking behind anything? Thanks.

EDIT:
Also, how would I handle hold A/D (W,S, and diagonal combos are easy)? Like, would it count as up-right/left if there is a higher block? I just don't know.
 
Last edited:
S

Sandro

Guest
as far as movement goes, ignore height. To draw the sprite use you map position to get a height value and use that value to offset the y position of the sprite. Do not use height to change the position of the object. Treat all movement and collisions as if the map and all it objects are flat. You will need special collision masks for this. I recommend setting the origin of your sprite the the center location where the object touches the ground. Collision masks should only consider the ground level of an object.

Rendering is more complicated. In old Gamemaker we would have used depth = -y; Now, however, It may be necessary to have a controller object preform the draw events. In any case sprites need to be draw in order based off y position on the map, where object which are further back are draw first, then those closer up are draw on top. If you want that to work with terrain, you'll have to break it up based on it y and draw them along with the rest of the sprites. You may need to be careful of texture swaps.
 

Anixias

Member
A lot of that isn't very useful information. Let me explain again:
The whole map (the terrain) is drawn to a vertex buffer. This basically merges the whole terrain into one big draw call, and makes the whole terrain have a single depth. Therefore, all objects are either 100% above the terrain or 100% below the terrain (invisible). I do use depth = -cart_iso_y(x,y); for the chunks so they render in the proper order, but all entities will always draw over the terrain.
I also will not have issues with texture swaps, as the whole terrain uses one texture image (Marked as "Use for 3D").

I will probably restrict the player from moving behind anything, and I'll figure something out for moving left/right.
 
A

arirish

Guest
Could you only draw part of the sprite if they're behind something?
 

CMAllen

Member
Without multiple draw depths or some kind depth masking method, you can't really do even pseudo-depth. You could do old school 'fake depth' (for an example, see Lineage: The Blood Pledge), but since your current system is already drawing depth that doesn't exist outside that initial draw, it would come across as rather awkward.
 

Anixias

Member
Occlusion for this game would be extraordinarily tedious. I've decided to restrict moving behind terrain.

Now my only issue is walking left/right. Diagonal and vertical movement is easy to code, but I'm not sure how to handle horizontal movement in some cases.

I would assume that if there is an adjacent block in the horizontal direction that is a different height, take that path. Or something similar. This way, walking through corners doesn't happen.
 
S

Sandro

Guest
A lot of that isn't very useful information. Let me explain again:
The whole map (the terrain) is drawn to a vertex buffer. This basically merges the whole terrain into one big draw call, and makes the whole terrain have a single depth. Therefore, all objects are either 100% above the terrain or 100% below the terrain (invisible). I do use depth = -cart_iso_y(x,y); for the chunks so they render in the proper order, but all entities will always draw over the terrain.
I also will not have issues with texture swaps, as the whole terrain uses one texture image (Marked as "Use for 3D").

I will probably restrict the player from moving behind anything, and I'll figure something out for moving left/right.
The way you doing it now it just fine if you want the units to always draw over the terrain, getting the terrain to draw over the units in certain cases though would require you either 1) break up the vertex buffer by row, or 2) do as @arirish suggested and only draw part of the image if something should be covering it (which would prolly require surfaces). In either case you *may* have a problem with texture swamp; The way your doing it now with 1 vertex buffer, you won't have that problem.

My suggestion with movement applies no matter how you plan to do the rendering. You do not need to check height, unless you want 3D collision. Just Draw the sprite higher then the collision mask. you could write a function get_y_offset(x,y) to achieve this. It should return the height of the cell in pixels. In the case of slopes it should calculate the height based on the angle of the slope + it's base height. For Example a slope shaped like this / at a 45 degree angle would return a y_offset based on the x possiton: y_offset = object.x - cell.x + cell.base_height; where one facing this direction \ would reverse the x: y_offset = cell.width - (object.x - cell.x) + cell.base_height; Those facing front/back would use y position instead.

Since your using blocks though you prolly won't need to calculate angles and the height of the cell should work just fine. If you want it to collide with the blocks only at certain heights you could fake 3D collision by checking if cell.height > object.height; (This should be an internal height set by you grid, not the y position)

2D collsion will greatly simplify your work, you just need to remember that the masks only cover the base of the object/cells. You will have cases where the object's sprite is draw much higher then it's collision mask and that's fine. Draw_y != y
 

Anixias

Member
image.jpg I was planning on having a z value (draw entities at (x,y-z)) but I guess I could just add a sort of grid-based movement allowing diagonals. My question is say there is flat land, and there are two blocks, adjacent such that their corners touch, and there is an entity between them (on either side, just adjacent to both blocks) that tries to move diagonally through the blocks. What should happen? Should it just step up onto one of them?

As you can see in the image above, the player (block p) wants to move between two blocks (to n). The player can't just walk through the block. Diagonals are not allowed through a corner. I don't want to just stop the player from walking, as this would make gameplay less smooth. I could just block it and see how I like it, but I'd prefer having a better method of handling this.
 
Last edited:
S

Sandro

Guest
You would need to check for that case as you would in a 2D 8-directional grid. If the player is moving north-east, make sure that not only is north-east clear, but also that either north or east is clear, if not stop them or move them up.

I assuming in your game the player if locked to the grid, in strange cases like this is up to you what you want to have happen to the player, just check for that case and do something about it. You could just stop the player, or jump him up to one of the blocks at random, or always jump to the east/west blocks, ect.
 

TheSnidr

Heavy metal viking dentist
GMC Elder
You could enable 3D and use an orthographic projection. This would be the most natural solution!
 
Top