Collision Detection - How to Make a 2D Game in Java #6
Aug 15, 2023
Collision Detection - How to Make a 2D Game in Java #6
In this video, we will implement collision detection so player character stops when he tries to walk through solid tiles. Caution: This is a tutorial for Java 2D beginners so it’s pretty verbose! (and the pacing is a bit slow…) If you have any questions, feel free to leave a comment. If you want to use my asset (images/maps/sound) that are used in this tutorial, here’s the link:https://drive.google.com/drive/folder … *I’m releasing my art/music/sound effects to help your smooth learning with this series. If you wish to use them to create public content (profitable/non-profitable), please contact me via Twitter or email. Both links are in the About section of this channel. In any case, please don’t re-distribute my asset (graphics/sound) and limit it to personal use. Thanks for watching. Timestamps: 0:00 Set tile collision status 1:54 Set player’s solid area 7:28 Set up Collision Checker 10:28 Detect collision 25:40 Final result #javagamedevelopment #java2D #javagametutorial #javagameprogramming
Content
0.504 -> Hi guys, this is RyiSnow
2.345 -> so last time, we loaded our world map
5.286 -> and implemented a camera function
8.571 -> so now we can move around the world, like this
12.201 -> but still, we can walk through these trees and waters
17.775 -> so in this video, we will implement collision detection in our program
23.156 -> so the player won't be able to walk through solid tiles
29.492 -> when we created this Tile class, we created this collision boolean
35.874 -> so it's time to use this
38.431 -> first, we go to this TileManager
42 -> and look for a tile that we want to change it to a solid tile
48.469 -> for example, this wall tile should be solid
53.081 -> we don't want our player character walk through this tile
61.936 -> we call this collision boolean and set it "true"
72 -> also this water tile... this one too
82.654 -> and this one too
91.837 -> and if it's not a solid tile... like this grass tile
96.755 -> then you don't need to add anything because the collision is false as default
104.829 -> so you only need to add this if the tile is solid
111.366 -> ok so tiles' collision setting is done
114.568 -> then we decide which part of the player character is solid and which part is not
123.836 -> the easiest way is setting the whole tile is solid
127.905 -> but sometimes it won't produce the best result
132.478 -> for example, if the whole player tile is soid,
137.051 -> then he hits this wall at this point and cannot move further
144.94 -> but maybe you want to move him a bit further... like this
153.811 -> also, there's another issue
156.342 -> if everything is solid, it's really difficult to get through a narrow path like this
164.921 -> because even if the player is 1 pixel to the left, collision still happens here
175.039 -> so you need to place him very precisely, like this
181.257 -> and that is simply pretty stressful
184.928 -> and bad control mechanics in my opinion
189.501 -> for example, "oh i'm hitting this tile so let's move to the right little bit"
195.533 -> and "oh now i'm hitting this tile and still i cannot go further"
201.035 -> so to avoid this kind of hassle,
204.918 -> we set a specific area of the character as solid, not everything
211.189 -> like, only this part is solid
216 -> then the player can get through this kind of narrow path
220.918 -> and to set this kind of collision area,
224.616 -> first, open this Entity
233.363 -> we use this Rectangle class
239.395 -> and i'm gonna name this solidArea
248.769 -> with this class, we can create an invisible or abstract rectangle
255.199 -> and we can store data such as x, y, width, and height
260.594 -> also, we create a boolean called collisionOn, and the default is false
272.913 -> now go to this Player class
276.292 -> and instantiate that rectangle
295.906 -> wait, oh what is this... soidArea... sorry
311.17 -> and when we instantiate this rectangle, we can pass 4 parameters to the constructor
323.093 -> for example, if you want to create a rectangle which is the same size as our tiles,
330.823 -> you type like this:
332.823 -> x = 0, y = 0, widht = 48, and height = 48
339.969 -> or you can also type like this: gp.tileSize
346.187 -> either way is fine
348.797 -> or we can also leave this blank and set these values one by one
383.158 -> either way is fine
385.158 -> and since we want to make this rectangle a bit smaller than the player character
391.734 -> we change these values a little bit
396.287 -> maybe something like this
398.307 -> so this gray area is not solid, and this area is solid
403.968 -> so this slid area starts from x 8
410.716 -> and width is 32
414.865 -> and height is also 32
418.828 -> so the top left corner is x = 8, and y = 16
425.868 -> so in that case, we're gonna change this x to 8, and y to 16
434.871 -> and widht is 32 and height is also 32
442.548 -> you can adjust these numbers and find what works best for your game
448.474 -> so we got this collision area for the player character
452.57 -> now let's create a class to check collision
456.851 -> inside this main package, create a class
461.557 -> and i'm gonna name this CollisionChecker or whatever name you want
472.868 -> and first, constructor
480.121 -> and we receive GamePanel
497.586 -> and create a method
508.154 -> and we receive Entity here
520.34 -> not Player but Entity
523.189 -> because we will use this method to check not only player collision but also monster and NPC collisions as well
536.304 -> now go to the GamePanel
539.206 -> and instantiate this CollisionChecker class
559.085 -> and pass this GamePanel
564.268 -> and now go to this Player class
566.825 -> and we check collision inside of this update method
575.801 -> after this direction if statement,
580.506 -> first, we set this collisionOn to false
590 -> then call this...
600.17 -> oh sorry
603.231 -> this needs to be "public"
608.936 -> so we're gonna call this checkTile method from here
615.552 -> and pass this Player class as Entity
619.542 -> since this Player class is a subclass of this Entity class
623.77 -> so the CollisionChecker can receive the Player class as Entity
629.722 -> alright, now the main part of this video
633.632 -> so what we need to do is, to check if the player is hitting a solid tile or not
643.484 -> to do that, first, we want to know the worldX and the worldY of the player's solidArea
651.797 -> not the player's worldX and Y because collision needs to be detected based on these solidArea coordinates
661.225 -> there are 4 points to be checked
677.668 -> and we can find out these 4 numbers like this:
772.672 -> then based on these coordinates, we will find out their column and row numbers
795.204 -> we simply divide it by tileSize
871.401 -> and finally we will create two more integers
886.505 -> because basically, we only need to check two tiles for each direction
894 -> if the player is going up,
896.5 -> we only need to check what tiles, so the player's left shoulder and right shoulder are hitting
905.591 -> so in this case, if the player is going up like this
909.751 -> this is hitting maybe this wall tile
912.786 -> and this right shoulder is hitting this grass tile
916.404 -> so now we're gonna create a switch statement
925.301 -> we're gonna check the entity's direction
959.107 -> so let's take care of this "up" first
992.267 -> for example, the player is here right now
995.779 -> and he is trying to go up
999.53 -> what we are doing here is, we kind of predict where the player will be after he moved
1019.276 -> so we subtract this player's speed from the player's worldY
1025.441 -> or the player's solidArea's worldY, to be precise
1030.97 -> now we know this row number so we can find out what tile the player is trying to step in
1040.451 -> and there are possibly two tiles
1055.422 -> so we're gonna call this mapTileNum
1058.908 -> this stores all the map tile information
1083.165 -> oh this also needs to be "public"
1093.123 -> and the other one is...
1107.132 -> we checked this point, this is tile1
1110.22 -> now we want to check this point, the right side
1131.453 -> with this information, we create an if statement
1136.265 -> and call this Tile array... this also needs to be "public"
1154.712 -> we're gonna use this tileNum1 as an index
1159.153 -> and check if this tile is solid or not
1184.943 -> if one of them or both are true, the player is hitting a solid tile
1191.771 -> so he cannot move this direction
1220.553 -> so if these collisions are false, then we don't do anything
1227.779 -> ok so this "up" case is done
1230.256 -> let's go back to this Player class
1296.647 -> and now we're gonna move these player movement lines from here to here
1322.175 -> maybe i like this format better...
1348.103 -> yeah because now we're checking collision so the player can move only when the tiles are not solid
1357.557 -> so first we only check the direction
1361.467 -> and based on this direction, we check collision
1367.605 -> and if collision is not happening, then we let the player move
1375.707 -> ok let's check this
1383.623 -> so now this tree tile is stopping the player character
1392 -> but it's still only the up direction
1395.247 -> you can still go left, down, and right
1399.37 -> so let's take care of the other directions too
1405.111 -> i think we can copy and paste
1413.223 -> we only change some variables
1419.308 -> so if the player is going down, we're not gonna check the top row but the bottom row
1431.229 -> so change this to bottomRow
1458 -> we're gonna change this from top to bottom
1468.615 -> and if the player is going left then...
1471.73 -> we're gonna check the left col
1479.381 -> and the left col will be...
1493.637 -> so now we're gonna check this point and this point
1512.747 -> if going right then...
1540.452 -> that's it, i think
1545.98 -> ok let's check this
1553.244 -> ok hitting the tile
1562.512 -> and this water tile too
1565.308 -> so collision is happening
1569.829 -> yup, looks good
1575.105 -> so this is getting more and more like a game
1578.75 -> so we took care of the collision detection
1581.917 -> next time, we will create objects and display them on the screen
1587.206 -> so the player can pick them up
1590.851 -> thanks for watching, and until next time
Source: https://www.youtube.com/watch?v=oPzPpUcDiYY