Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (565) Games in Android Showcase (151) games submitted by our members Games in WIP (606) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Tiled Level Collision Help  (Read 963 times) 0 Members and 1 Guest are viewing this topic.
_Scyth_

Junior Devvie

 « Posted 2013-01-15 18:59:39 »

I have a tiled level, which is expressed as:
 1  2 `int[][] level1 = {{1,0,0,0,0,0,1,1},                       {1,0,0,0,0,0,0,1};`

etc

I then render the tiles with code from mattheus
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16 ` // Render the Level     public void renderTiles(Graphics g) {         // Iterate through all tiles:         for (int y = 0; y < level1.length; y++) {               for (int x = 0; x < level1[y].length; x++) {               renderTile(x, y, level1[y][x], g);            }         }      }     public void renderTile(int x, int y, int tileID, Graphics g) {           switch (tileID) {           // don't forget the breaks! :)           case 0: g.setColor(Color.BLACK); g.fillRect(x * 16, y * 16, 16, 16); break;            case 1: g.setColor(Color.GREEN); g.fillRect(x * 16, y * 16, 16, 16); break;           }      }`

My player info:
 1 `int playerX = 16, playerY = 16;`

how can I check collision between the player and the tiles which are 1?

I've tried, some different methods:
• Surround wall tiles in a Rectangle each the player in a Rectangle and check for collision between them. But I needed to use an array of Rectangles, and I hit the problem: i had to define what [] is for the .intersects() method.
• I tried checking if playerX and playerY were 'Beside' a wall so that it wouldn't allow them to move, again, I think I need to define what tile I'm comparing them to.

Anyone have any suggestions I can try?
krasse
 « Reply #1 - Posted 2013-01-15 19:15:10 »

If you assume that the player is a rectangle, it is pretty easy to check collisions within a grid. Just get the grid index from the (minX, minY) and (maxX, maxY) points for the player and iterate over those cells to check if they are occupied in your tile map.

Also, when the player moves you also want to perform several checks that the player doesn't move into an occupied cell in the next tick.
Also, if you allow diagonal movement, you would like to know if the player can move in one direction (either x or y) only to avoid that it just stops when diagonally moving into a wall.

krasse
 « Reply #2 - Posted 2013-01-15 19:17:57 »

You don't need to specify rectangles for each cell. You just need to know the total grid size, it's start position and the number of cells in each direction. Then you can calculate all the rectangles with some very simple math.

_Scyth_

Junior Devvie

 « Reply #3 - Posted 2013-01-15 19:29:46 »

First, what do you mean by minX minY and maxX and maxY of player? Would that be 0,0 and say 320,240.

any tips on how to do the Rectangles?

and what math? I'm completely confuzzled
krasse
 « Reply #4 - Posted 2013-01-15 20:52:40 »

Is the player a point or has it some width or height? If it is a point then you can just ignore the minX, minY etc and just use playerX and playerY instead.

Is the player supposed to move in steps of whole cells or can it move a fraction of a cell? If it can just move in whole grid cells you can just perform a simple array[playerY][playerX] (with bounds checking). If it can move within fractions of cells, the player can overlap several cells at the same time. You need to check what cells that the player overlaps and then you need to know the size of the cells.

Here is some code where I assume that the level starts at position (0, 0) and the player position is at center of the player rectangle.
 1  2  3  4  5  6  7  8  9  10 `int startCellX = (int) Math.floor((playerX - playerWidth * 0.5) / cellWidth);int startCellY = (int) Math.floor((playerY - playerHeight * 0.5) / cellHeight);int endCellX = (int) Math.ceil((playerX + playerWidth * 0.5) / cellWidth);int endCellY = (int) Math.ceil((playerY + playerHeight * 0.5) / cellHeight);for (int i=startCellX; i<=endCellX; i++) {  for (int j=startCellY; j<=endCellY; j++) {    // Check if level1[j][i] is occupied here, if so, the player intersects something  }}`

You also have to add some checks for not referencing something outside the array.

_Scyth_

Junior Devvie

 « Reply #5 - Posted 2013-01-15 21:12:52 »

It moves one cell which is 16*16, but I haven't really done a cell if you know what I mean, just the level1[][], ahhh! I'm so confused!

I can't get this to work! It's probably something extremely easy, I'm just missing it!

My character now jumps several spaces, regardless of where it is.
I'm using a simple Graphics package because that is what I'm restricted too.
I need to try and have it that the character can move if its on an '0' tile but it can't move onto a 1 tile.
i've tried trying to predict what the tiles around the character are, but I can't get that to work either

sorrry, I've been trying to fix this for the last couple of days, and haven't had a clue.

is there anyway I could do
 1 `int[][] playerPos;`

and then use it to define the player position?
but how can i  use it for rendering the image according to the
 1 `playerPos[y][x]`
Ultroman

JGO Knight

Medals: 25
Projects: 1

Snappin' at snizzes since '83

 « Reply #6 - Posted 2013-01-15 23:13:47 »

It's a bit too hard-coded to just check if the tile is 0 or 1, if you want to have several types of tiles. If you only need 2 types of tiles (walls and not walls) then it is fine.

If you have more types of tiles, like grass, forest (makes player move slower or leaves could fly around the player), or water (stops the player unless his name is Jesus) or whatever, then I'd recommend a Tile-class, which has an int ID (which refers to the number used in the map[][]), and an int type to recognize which kind of tile it is, and lastly a boolean passable indicating if it can be traversed at all.

Using simple rectangles to check for collisions is fine, but I believe there's an easier method, which also makes it much easier to control what to do, depending on which side of the player is colliding with a tile. Not to mention the freedom for precision, in that you can put the points as close to the actual player-part of your image, if he doesn't fill out the entire image.

What I did for my game, was to check 8 points around the player (see image below), and react if one of these points are within a tile that cannot be traversed. If any of the 4 top/bottom points are within a tile, I move the player back to his previous Y-position (which I save in a variable every update). If any of the 4 left/right points are within a tile, I move the player back to his previous X-position (which I save in a variable every update).

It is important to do the X and Y separately, or your player will get stuck in weird ways, meaning you can't be walking left into a wall and still move upwards or downwards along it.

This is what I used in my very first game, and it works perfectly. (See for yourself.

Extremely simplified code to move the player. Use whatever you'd like:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14 `    public void movePlayer(){       if(keys[KeyEvent.VK_UP]){          player.setPlayerPositionY(player.getPlayerPositionY()-3);       }       if(keys[KeyEvent.VK_DOWN]){          player.setPlayerPositionY(player.getPlayerPositionY()+3);       }       if(keys[KeyEvent.VK_LEFT]){          player.setPlayerPositionX(player.getPlayerPositionX()-3);       }       if(keys[KeyEvent.VK_RIGHT]){          player.setPlayerPositionX(player.getPlayerPositionX()+3);       }    }`

When the player has been moved, we do the collision-checking.
Code to check all points for collisions and reacting to them (the offsets for the points are hardcoded after the size of my player image; the playerPosition is the dead center of the player image in my game):
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27 `    public void checkCollisionsAroundPlayer(){       int tileCoordX = player.getPlayerPositionX();       int tileCoordY = player.getPlayerPositionY();       Point upRight = new Point(), upLeft = new Point(), rightTop = new Point(), rightBot = new Point(), leftTop = new Point(), leftBot = new Point(), downRight = new Point(), downLeft = new Point();              upRight.setLocation(tileCoordX+9,tileCoordY-13);       upLeft.setLocation(tileCoordX-9,tileCoordY-13);       rightTop.setLocation(tileCoordX+13,tileCoordY-9);       rightBot.setLocation(tileCoordX+13,tileCoordY+9);       leftTop.setLocation(tileCoordX-13,tileCoordY-9);       leftBot.setLocation(tileCoordX-13,tileCoordY+9);       downRight.setLocation(tileCoordX-9,tileCoordY+13);       downLeft.setLocation(tileCoordX+9,tileCoordY+13);              if(checkCollisionForPoint(upRight) || checkCollisionForPoint(upLeft)){          player.setPlayerPositionY(player.getLastY());       }       if(checkCollisionForPoint(downRight) || checkCollisionForPoint(downLeft)){          player.setPlayerPositionY(player.getLastY());       }       if(checkCollisionForPoint(leftTop) || checkCollisionForPoint(leftBot)){          player.setPlayerPositionX(player.getLastX());       }       if(checkCollisionForPoint(rightTop) || checkCollisionForPoint(rightBot)){          player.setPlayerPositionX(player.getLastX());       }    }`

Code to check a single point for collisions. The tiles are referenced by their ID in the ground[][], which is looked up in my TileList, which is a list of all loaded Tile-objects. Each Tile-object knows if it is passable:
 1  2  3  4  5  6  7  8 `    public boolean checkTileCollisionsFromMapCoordinates(int tileCoordX, int tileCoordY){       boolean collides = false;       int tileX = getTilePosX(tileCoordX);       int tileY = getTilePosY(tileCoordY);       if(!tileList.getTileList().get(map.getGround()[tileY][tileX]).isPassable()) collides = true;              return collides;    }`

- Jonas
_Scyth_

Junior Devvie

 « Reply #7 - Posted 2013-01-16 16:47:20 »

I understand the points so i'll try that thanks for the suggestions. If it helps, I'm not looking for a complex collision system just an extremely simple one, my map is all squares and the character will end up being a circle, so it doesn't need to be too complicated. Everything i try seems to fail but.
Ultroman

JGO Knight

Medals: 25
Projects: 1

Snappin' at snizzes since '83

 « Reply #8 - Posted 2013-01-16 19:10:30 »

I wrote this: "How to approach 2D side-scrolling platformer collisions easily"
Meant for a platformer, but many of the same points apply. It'll help you around some devious traps

- Jonas
_Scyth_

Junior Devvie

 « Reply #9 - Posted 2013-01-16 19:30:16 »

Thanks I'll read through that now

Thanks for the help everyone, I'll update you all if I get this working.
_Scyth_

Junior Devvie

 « Reply #10 - Posted 2013-01-16 20:34:17 »

I got it working!

I think some people said this already, and with that and by reading through Ultroman's code, I got a way of doing it formed in my head. Thanks

I simply let the player walk onto a "wall" then check to see if the player is on a "wall" by using
 1  2  3  4  5 `if( level1[pY][pX] == 1 ){   pX = prevX;   pY = prevY;}`

I knew something simple would have been what it takes to do it, thanks everyone for helping me out! This took much longer than I had anticipated
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 theagentd (11 views) 2015-03-27 23:08:20 wxwsk8er (52 views) 2015-03-20 15:39:46 Fairy Tailz (46 views) 2015-03-15 21:52:20 Olo (28 views) 2015-03-13 17:51:59 Olo (30 views) 2015-03-13 17:50:51 Olo (37 views) 2015-03-13 17:50:16 Olo (44 views) 2015-03-13 17:47:07 ClaasJG (57 views) 2015-03-10 11:36:42 ClaasJG (41 views) 2015-03-10 11:33:01 Pippogeek (47 views) 2015-03-05 14:36:23
 LiquidNitrogen 21x BurntPizza 21x basil_ 20x KevinWorkman 18x EgonOlsen 17x theagentd 16x Roquen 16x 65K 11x wessles 10x Varkas 10x princec 9x SHC 8x Ashedragon 8x Riven 8x Ecumene 7x nsigma 7x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org