Tilemap Collisions in GMS 2 - GMWolf

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone this is Felix from GM wolf today we're going to be looking at tile map collisions or how you can get your players or different objects to detect collisions with a tile map in game maker studio 2 so the advantages of that are better performance more flexibility as well as some other needs tricks you can do to improve your code so before we get started we must make two observations in order to make a code a bit easier to understand first of all is that we need to do two checks for every directions that is because as you can see on this diagram the player which is an orange maybe overlapping a a tile represented in blue just by a bit and so simply doing a single check in center of an edge isn't going to be enough to detect a any collisions what you must do is check every corner of the objects depending on the direction that will cover any case where your player is smaller or the same size as your tiles if your player is bigger than your tiles you may have to do even more checks generally speaking though one in each corner should be enough perhaps one in the center if your object is slightly larger than your tiles next we need to understand that we can snap a core set of coordinates simply by removing a couple bits at the end of a number now this only works for powers of two but since most tile sets tend to be 32 by 32 64 by 64 and so on it's perfectly acceptable to use so here is an example for example if your screen if your tile was 64 by 64 you can simply end it with the compliment of 63 which is one less than 64 and as you can see over on the right if we have 587 which is not a multiple of 64 and we end it with the compliment of 63 which is basically all the ones apart from 32 and downwards what we end up with is 4 176 which is the next lowest multiple of 64 from 587 so now that that's out of the way we can get started looking at how we can code this in game maker studio 2 so the project we're going to start off with it is quite simple I just have a room here with a basic tile set set out just to give a bit of aesthetics to it and as a background as you can see most of it is pretty standard so if I go back to workspace you can see it's just a normal Auto tile tile set created from this image here you can really use whatever you like so the first thing we need to do to be able to collide with our with that tile map is to actually create a special time app for collisions and so what we're going to do is first create a new sprite which I'm going to call SPR underscore mask which will represent the the tiles for collisions just so we can see them in the room and so I'm going to quickly edit the end image we're going to resize it I'll raise the resize button resize all frames and we're going to make it a 64 by 128 like so I'm going to quickly turn on the grid make it 64 by 64 okay so and what I like to use for my collisions is a sort of a square like so I'd like to make a double width of two pixels so you can see it in the room editor and then I'll turn down the grid to 16 by 16 and add another square in the middle and this is the way I like to have my masks some other people like to have diagonal lines in the middle instead I don't I don't think it looks very nice I think this looks a lot better so this is what I'm going to use and that's it that's all you need it's nothing for in-game doesn't have to look good it's just there to be able to be viewed in the room editor so we can close this go back to our workspace and create our tile set so you can just go here you create title sets and I'm going to call it TS underscore mask and for the sprite is going to be the one we just created and over when the properties we're going to make it 64 by 64 so I - I choose to make mine 64 by 64 because that's the same size as this title set over here however if yours is smaller say 32 by 32 you can use that as well in fact you could have this be a different size from your main tile set the important thing is for this tutorial at least is that it's a power of two because it does make it oval Maps much easier you may have noticed that I left a blank space on the left of the tile that's because jamika requires you to do that just to optimize things that likes to have a blank space top left corner so even if you only have one tile you need to read the space for two tiles so we're going to do now is go into our room and add a quick tile set to this room tell set layer so I'm going to click this button here create new tile layer and I'm going to call it a collision underscore map because this will be the map we collide with down here on the bottom left you can choose a towel set to use we're going to use TS underscore mask and I'm simply going to add these wherever there should be a collision so this is quite simple you just click and drag you can either feel or not feel your you're regions it doesn't really matter since since it won't impact performance because of the weight all maps work which is great this is one of the big advantages of tile maps over objects is the performance is much much better I choose not to fill it because I think it looks better and so so clear to me to see just that you'll be able to collide with the edges you will never be inside a block and as you can see this quite quick to do it will take more time for bigger levels but the nice things that you don't have to deal with different edges and so on you just have to put down the tiles this is why I like to use two tile sets one for collisions one for the aesthetics is that not as tied down to making things correct when dealing with my aesthetics things and for now I'll leave it on is you can toggle it on and off to see what your level looks like without it I'm going to leave it on so that we can have a better idea in game of what is happening and that's really it you don't have to do much more in the room editor everything is already set up so now we're going to create a new object which will be our player object and we're going to give it a sprite there you go so I'm going to call it obj Andrus for player and the first event we're going to add is a create event because we're going to have to define a couple things I'm just going to close the room for now so we can make a bit more space in the project area and what we're going to do is first of all we're going to do some basic player variables so that will be things like the movement speed so how fast it can move he can move left and right and I'm actually running this game at 60fps so I think a value of 8 will be good next will be the jump impulse this is going to represent how high your player will jump this will depend on the gravity values you choose as well I'm going to go with 21 I found it to work rather nice next the gravity which I'm going to call graph and I found that a value of 0.75 works nicely if you're working at 30fps that value will have to be different and if you're using double timing again that will be different as well finally we have the variable for the vertical speed we're going to set that to zero this is not something that you always have to keep that as zero to start off with this is something that that we'll need to calculate in order to change how fast your pair is falling next we need to get some values about the tile maps that we need to basically retrieve a bit of time up information before we start colliding with it so the first thing we need to find out is the layered tile map is on and we can just do VAR l equals layer and the score gets underscore ID and we can just give the name of the layer now remember in our room editor we call it collision underscore map so this is all we need to do to get there layer ID and our layer contains a tile map so we can get our tile map by doing tile map is equal to layer underscore tile map underscore get the score ID and the layer we want to check is L the layer we defined up here finally we have a couple more things to do to find and that is a couple sprite informations first of all we have to get the bounding boxes of our sprites so we're going to do sprites feed box underscore left is equal to sprite and the score gaps and score B box the score left our sprite index did I set the sprite for player inside a sprite index and we're going to subtract this bright get offset from it and that will be also sprite index so what we're doing here is finding how far from the sprite origin the bounding boxes and this will help us with collisions a lot because we'll be able to determine where the position of a player should be based on where the position of a bounding ball should be so then we have to do the same for each of the other four a bunch of the other bounding boxes so next we have the right bounding box and over here we also need this to be right and over on the right here this will be get Y still X offset left lined down here we're checking for the bottom belding box so here we're right about beat box and score button and here we'll change this to the y offset and here finally the top bounding box get a box and score top and again the y offset so again the B box information will be used to snap our player in the correct location so this is it for the create event what we need now is a bit more information a bit more code in the step event so we're going to add a step step event and I'm just going to split this view into two columns and put my step event over on the right this way we still have the variable names over here on the left that we can refer to if we need and we have plenty of space on the right to have our movement code so first of all what we want to do is get some some player inputs so what I'm going to write first is var D X so our difference in X will be move on score speed times our keyboard check VK and so left sorry VK right - keyboard check VK left so let me just move the view around so you can see this clearer so this is a just as you would do usually in most gaming projects you just subtract the right check - a left check and multiplied by the movement speed which gives us how much the player wants to move left or right next diwaii that will simply be the V speed so we want to we're basically saying that our player will will want to move by V speed amount and now we can update our V speed value by incrementing it by our gravity value so this is the basic input code we can move left and right I will add jumping later because we first because it needs a bit of a collision checking so first what wheel tackle is vertical movement because right now our player isn't even falling so what we want to do is a quickly comment our code do vertical move and what we're going to do is first of all move the player so we're going to do y plus equals dy and now we can start doing our collision checking and essentially move our player back move a player outside of the tile map it if we do collide so first we're going to check if we were moving downwards so this is quite simple we just do if dy is greater than zero then we're moving downwards down words if not we're moving upwards or not moving however if we're not moving up we're not colliding so it should still work up words so if we are moving downwards what we want to do is first of all get the two collision points we were talking about in in the slides so VAR t 1 is equal to tilemap get at pixel and the tow map element ID is a tile map we defined over here in the create event so that is just tile map then we want to check the what we're moving downwards so you want to check the bottom left corner first so we can do B box on the score left B box in the score bottom so that will be checking at the bottom left and what this will do is return a some tile map information apparently there is an error somewhere and it's not telling me what it is oh I did not spell var correct here you go still your variables correctly are your keywords correctly so what this tell map got a pixel does is return us a tile information piece of packet which includes the index of the tile map of the title a stud that is what image it's using it has some extra information like if its flipped rotated and so on but we're just interested in the index so is there something or is there not and we're just to retrieve that information we need to end this this tile information by tile underscore index in the score mask so what this is doing is basically only keeping the bits that represent our index so it's really quite a bit Malaysian if you're not too sure what's going on there is also a function called tile get I believe it's tell get index over here and you can just put a tile map get index in there it also works it's a bit more typing it's a bit more functions I prefer to use this and tile index mask over here also if you look at the examples that yo-yo games have provided they also tend to use this a bit masking over here so this is the bottom left collision check we've done now we need to check the bottom right so we're going to write VAR t 2 equals tile map underscore and get underscore adds pixel again we're checking the tile map we got before and this time it's v box right V box underscore bottom and again we're just interested in the tile Windex so now we have the two collision points at each corner what we want to do is basically say that if either of those have collided then we want to we want to shift our our objects back so that we're no longer colliding and because we're using a power of two we can use all neat little trick so we're going to do is say if t1 is not equal to 0 so if t1 had something there or t2 is not equal to 0 then we are currently colliding what we're going to first do is calculate where we want our bounding box to be because our player is not necessarily 64 by 64 it could be smaller so what we want to fund is say that the bounding box the bottom bounding box should really be aligned to the 64 by 64 grid and so that it's not in the grid and what we can say is B box underscore button and we use a little trick where we ended with the compliment of 63 now if you're using a 32 by 32 grid you would use the 31 complement if you're using a 16 by 16 with complement with 15 it's always one less than the size of the grid so beat box bottom and complement 63 will align the 64 by 64 grid will align the the bottom bounding box however we wanted to be one above that because we don't want to be just on the limit we want to be just above the tail so we're going to subtract 1 to that from that and this gives us where we want our bounding box to be now unfortunately you cannot just say B box equals that because B box is a read only variable and so what we're going to do is subtract sprite underscore B box score bottom which is the value we calculated over here and this smell will represent the Y position of our object and where we should be so we can simply say y equals where we want our bounding box to be minus the offset from our bounding box to our y-coordinate so sorry this is a little complicated to understand I'll try to explain it again for those of you who have a harder time understanding bit patterns and so on this section over here basically allowing cellpadding box to the 64 by 64 grid this here makes it be just one above that 64 grid because we don't want our player to be one pixel into the ground we want it to be one just on the ground and here by subtracting our beat box bottom we are basically converting our bounding box coordinates to a $2 origin coordinate to a player coordinate and so we can just set our y position to that now because this is a platformer game we want to stop falling as soon as we hit a wall vertically so we can write V underscore speed equals zero and this will stop your player from a thump thump this will stop the speed of your player from increasing it when he's on the ground so this is it for a downward falling we can actually test this to see if it works by opening our room quickly and just placing our player inside out instances so make sure you select your instance layer and drop your player somewhere here I'll drop in here and now if we press play we should be able to see our player fold downwards however we haven't done anything with our inputs yet I mean we are storing them in a variable but we're not doing much else with it so we won't be able to move our player around but we'll be able to see that our proof of concept for the collisions work vertically so we're still compiling game should run pretty soon and here you go as you can see all players down here and it is not falling through the blocks even though we are increasing the Y variable before their collisions so what we can do now is quickly I want to set the view over here so that we won't be able to so that we'll be able to follow the player around I just have a basic view set up over here to follow the player around so what we're going to do now is do the same for our upwards movements and all we need to do is essentially copy this whole code paste it in here and we're just going to move the camera over hide these trays so we have a bit more work space to work with and what we need to change is over here we're not dealing with the bottom left and bottom right quarters anymore we're dealing with the top left and top right so we're going to change these two to be box top and D box top as well and down here as well we're actually dealing with our top bounding box now there is something else we need to change over here and that is because if you can imagine and before when we're moving downwards we wanted to move into a smaller and we want to move into a smaller tile map coordinate because we wanted to move back up where the coordinates a smaller however if we're going if we were moving upwards and colliding we now want to move downwards so we want to move to the next biggest multiple of 64 not the next smallest and this is a pretty simple fix all we need to do is remove this minus one over here because we won't be needing that and instead we'll add 64 over here and make sure it is in parentheses so now we're talking the next biggest cell to be in rather than the next smallest cell to be in this way instead of snapping upwards we snap downwards we also need to change this bounding box over here to sprite underscore beat box top so this should handle our upwards collisions pretty well as you can see it's essentially the same code however we cannot move up and down yet so it won't really change much what we're going to do now is deal with our horizontal movement so we're going to write do horizontal move give ourselves some space and we're just going to copy this whole code and change it to work with our horizontal movement so first of all we need to change our x coordinates based on DX next what we need to do is check that we're moving to the right and so we're just checking if DX is greater than zero therefore we're moving to the right if not else we're moving towards the left so if we're moving to the right then what we want to do is check our top right corner and our bottom right corner so what we're going to do here is change this to right and top and here we already have right and bottom so what we have to do now is change this lines here so that we're actually changing our x coordinate so we're moving to the right so if we're colliding on the right we want to move to the next lowest x coordinate so we're going to change this to X is equal to B box write the complement of 63 minus 1 minus the sprite B box right so if we are overlapping on the rights we want to find the correct position for a right bounding box and then adjust that to get our x coordinate now here we have these B equals zero we don't need this if we're colliding along the x axis we should not change how fast we're falling now to the left side of things it's also quite simple this time we're checking for the left collision so we're checking a left top and left bottom and again we want to change this here this line over here so that it's changing our x coordinate so x equals B box left plus the 64 because now if we're colliding over on the left side we want to snap to next-biggest so you want to move to the right so we're adding 64 and complementing this with 63 and we're subtracting our left bounding box offset and we don't need the V speed either because we're doing this and on the x-axis and this is it for colliding left and right and moving left and right over here so now if we save this here and run this we should be able to move our character around with the keys no jumping yet however this is just a small bit more of code we need to add but as soon as the game ran we'll be able to see that we can now move left and right and collide left and right as soon as it finishes compiling here it is as you can see I can move left and right and I am NOT going through the walls which is great as you can see on the left I'm staying nice and against the wall and if I move to the right I'm also staying nice it's flush against the wall so this is great so all that's left to do now is adding the jump and the ability to jump and that is again pretty simple organ dues go move back up and before all all of this code over here where we change out the X and T Y variables we're going to have to change the P speed web if we're pressing up however we only want to be able to jump if we're on the floor so we need to check whether the bottom left or bottom right corner is currently just above the ground so what we're going to do is var underscore T 1 is equal to tile map underscore get at pixel as usual again we're using the toe map we calculated earlier and we're going to use the bottom left corner so we're going to write D box on the score left B box on the score bottom and we're going to end this with a tile index mask now there's one more thing we have to think about before we move on to the right side collision is that our player is always just one pixel above the ground or at least above the bounding box is always one pixel above the ground and therefore we need to check one pixel below the ground I mean below the player to make sure he's hitting if he's inside the ground and also we're just going to add one to be box bottom over here just to check right beneath the player we can do the same for t2 which will be our bottom right corner match is going to copy this line and change this to be box right now we just have to use the same code again if t1 is not equal to 0 or T 2 is not equal to 0 in space here then we are currently just above the ground and therefore we can say if keyboard oops if keyboard check if I could only press keyboard check fvk up so if the player is currently pressing up then we can say that the v-- speed is equal to minus jump underscore impulse and if you remember jump impulse is the variable we defined over here as our as kind of the speed at which a player was type jumping and remember to spell it correctly like so so now we should be able to jump because if we are over the ground and we press up we're changing our vertical speed so we just have to save this and run it again and again let's take a small wall to compile but hopefully we now have all the features for a basic platformer because we are already able to move left and rights collide vertically and now we added the ability to jump so we'll be able to make sure that our upwards collision works as well so it's uh just felt finished compiling it's just putting together the game here we go so I cannot move left right and if I press up I can jump which is perfect and if I go below a wall and press up as you can see I now hit my head against the wall and fall straight back down and as you can see it's a pretty robust system I'm not getting stuck or anything even if I keep jumping it's a red nice system so this is basically it for all the code all that's left to do now is to turn off the tile map so that we can just have our nice tile set in the background so we have to do is open the room go to a collision map and turn it off with a little eye icon over here as you can see that turns it off and if we now press play which is she pretty much exactly the same project I showed you at the start of this video where it didn't look like there was a collision map there which is great so Wells is complaining I'll talk about using two different maps one for the tiles one for the collisions this is great because it makes a little easier to just check one value it is sorry it also means you can have multiple different tiles for dangers maybe you may have a they may want to create a red one which when colliding with it you would die and it's also nice because maybe you're not using a towel set for your level maybe you're using a hand-drawn background and you just want to add tiles to that it's a rad a nice way of doing things so thanks for watching I hope you have enjoyed it this video on making collisions with tile Maps if you have please give it a like and subscribe if you haven't already to see more if you have any questions about tile maps or any suggestions for future videos please put them in the in the comment section below and I'll see you guys next time for some more game maker tutorials
Info
Channel: GM Wolf
Views: 40,460
Rating: undefined out of 5
Keywords: Tilemaps, tilemap, tile, map, set, tileset, collision, collisions, physics, platform, game, maker, studio, gamemaker, gms2, gamemaker studio 2, fast, easy, tutorial, simple, quick, tile info, howto, GMWolf, creation, fall, through, snap, grid, check, tiles
Id: 7NHJ6A34V6I
Channel Id: undefined
Length: 33min 20sec (2000 seconds)
Published: Sun Nov 20 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.