Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [SOLVED]Collision Detection Crash Bug [Slick-2D Game]  (Read 687 times)
0 Members and 1 Guest are viewing this topic.
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Posted 2014-04-06 21:39:46 »

I have a strange bug in my collision detection. Everytime I go to move in general the game crashes and gives me this error.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
Sun Apr 06 16:42:03 CDT 2014 INFO:Slick Build #237
Sun Apr 06 16:42:03 CDT 2014 INFO:LWJGL Version: 2.9.1
Sun Apr 06 16:42:03 CDT 2014 INFO:OriginalDisplayMode: 1366 x 768 x 32 @60Hz
Sun Apr 06 16:42:03 CDT 2014 INFO:TargetDisplayMode: 800 x 600 x 0 @0Hz
Sun Apr 06 16:42:04 CDT 2014 INFO:Starting display 800x600
Sun Apr 06 16:42:04 CDT 2014 INFO:Use Java PNG Loader = true
Sun Apr 06 16:42:04 CDT 2014 INFO:Controllers not available
Sun Apr 06 16:42:05 CDT 2014 ERROR:720
java.lang.ArrayIndexOutOfBoundsException: 720
   at org.newdawn.slick.tiled.Layer.getTileID(Layer.java:148)
   at org.newdawn.slick.tiled.TiledMap.getTileId(TiledMap.java:261)
   at ml.ardamax.epik.Game.update(Game.java:86)
   at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:266)
   at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:663)
   at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
   at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
   at ml.ardamax.epik.Main.main(Main.java:30)
Sun Apr 06 16:42:05 CDT 2014 ERROR:Game.update() failure - check the game code.
org.newdawn.slick.SlickException: Game.update() failure - check the game code.
   at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:669)
   at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
   at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
   at ml.ardamax.epik.Main.main(Main.java:30)


I'm not really sure whats going on...? Here is the source code for the Main Game State in my slick2d game.

Game.java:

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  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
package ml.ardamax.epik;

import java.util.ArrayList;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.Music;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Color;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.GameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;

@SuppressWarnings("unused")
public class Game extends BasicGameState {
   private SpriteSheet sprites;
   private Music main;
   private TiledMap level1;
    private Image wizard;
    private Image archer;
    public int x;
    public int y;
    public int mx;
    public int my;
    public int objectLayer;
   
   
   
   @Override
   public void init(GameContainer gc, StateBasedGame game)
         throws SlickException {
      x = 736;
      y = 526;
      sprites = new SpriteSheet("/res/sprites.png", 16, 16);
      wizard = sprites.getSubImage(64, 96, 16, 16);
      archer = sprites.getSubImage(80, 96, 16, 16);
      level1 = new TiledMap("/res/level1.tmx");
   }

   
   @SuppressWarnings("static-access")
   @Override
   public void render(GameContainer gc, StateBasedGame game, Graphics g)
         throws SlickException {
      Input input = gc.getInput();
      //wizard.draw(736, 526, 2.0f);
      archer.draw(x, y, 2.0f);
      level1.render(0, 0);
     
      if (input.isMouseButtonDown(input.MOUSE_LEFT_BUTTON)){
         mx = input.getAbsoluteMouseX();
         my = input.getAbsoluteMouseY();
         g.drawString("X: "+mx+" Y:" +my, 0, 0);
      }
     
   }

   @Override
   public void update(GameContainer gc, StateBasedGame game, int delta)
         throws SlickException {
      objectLayer = level1.getLayerIndex("Objects");
     
     
      Input input = gc.getInput();
     
      if (input.isKeyPressed(input.KEY_Q)){
         gc.exit();
      }
      if (input.isKeyPressed(input.KEY_D) || input.isKeyDown(input.KEY_D)|| input.isKeyDown(input.KEY_RIGHT)|| input.isKeyPressed(input.KEY_RIGHT)){
         if (level1.getTileId(x, y+16, objectLayer) == 33 || level1.getTileId(x, y+16, objectLayer) == 40 || level1.getTileId(x, y+16, objectLayer) == 90){
            y +=5;
         }
         x+=16;
      }else if (input.isKeyPressed(input.KEY_W) || input.isKeyDown(input.KEY_W)|| input.isKeyDown(input.KEY_UP)|| input.isKeyPressed(input.KEY_UP)){
         if (level1.getTileId(x, y+16, objectLayer) == 33 || level1.getTileId(x, y+16, objectLayer) == 40 || level1.getTileId(x, y+16, objectLayer) == 90){
            y +=5;
         }
         y-=16;
         
      }else if (input.isKeyPressed(input.KEY_A) || input.isKeyDown(input.KEY_A) || input.isKeyDown(input.KEY_LEFT)|| input.isKeyPressed(input.KEY_LEFT)){
         if (level1.getTileId(x-16, y, objectLayer) == 33 || level1.getTileId(x-16, y, objectLayer) == 40 || level1.getTileId(x-16, y, objectLayer) == 90){
            x -=5;
         }
         x-=16;
      }
   }

   @Override
   public int getID() {
      // TODO Auto-generated method stub
      return 1;
   }

}


Sorry for the really messy code.

Offline ctomni231

JGO Wizard


Medals: 99
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #1 - Posted 2014-04-06 21:47:58 »

It is complaining about an Out of Bounds exception.

In your case, this is a logic error. Try messing with the values at line 75, 80 and 86. Specifically
 level1.getTileId(x, y+16, 0) 
to make sure you are calling the values within the bounds.

Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #2 - Posted 2014-04-06 22:03:03 »

I'm confused? So should I change the +16 value or something like that? Because every value i add to either x, or y gives me the same error and the game crashes regardless? is there another method to do this?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ctomni231

JGO Wizard


Medals: 99
Projects: 1
Exp: 7 years


Not a glitch. Just have a lil' pixelexia...


« Reply #3 - Posted 2014-04-06 22:26:26 »

Well, by the looks of this, you are trying to implement collision detection with tiles. There is another method to do it, but I don't know why you aren't limiting your bounds and checking to see whether x and y+16 is valid before execution. Make sure the values are within the map by making a boolean  Smiley.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #4 - Posted 2014-04-06 22:26:47 »

if I'm reading this correctly, it sounds like you're getting the exact X/Y coordinates of the tile and giving that to getTileId, not the tile itself.

level1.getTileId(x, y+16, 0) the X and Y need to be the tile on the .TMX file, not the coordinates of the tile on the map.

For example, if you wanted to check tile 15 , 5 on layer 0 in the TMX file:
level1.getTileId(15, 5, 0);

Thus, depending on how your code is setup, you actually need something that takes the X/Y value you're giving it, divide it by your tile width/height and round it. That should give you the tile ID.

Not knowing how your code is setup, I can't give you exacts, but you need to be putting your X/Y values through something like this:

1  
2  
tileLocationX = Math.round(X-mX)/level1.getTileWidth());
tileLocationY = Math.round(Y-mY)/level1.getTileHeight());


then pass tileLocationX and Y to getTileId instead:
1  
level1.getTileId(tileLocationX , tileLocationY, 0);


The output of tileLocationX and Y should result in the tile itself you're trying to check. Depending on your code.

Your out of bounds exception is firing because you're asking for tile No. 392,593 (just an example coordinate) on the map, by giving it the coordinates 392,593 in relation to where the map is being rendered..

EDIT: Also to note, if your map has multiple layers be sure getTileId is looking at the correct layer on the map. You have it checking layer 0, the absolute bottom layer. If your objects are on layer 1 or 2 (or higher) you need to change the 0 to something else.

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #5 - Posted 2014-04-06 22:38:11 »

What my idea was is that if the tile id the the player is about to encounter is equal to either 40, 33, or 90, the player won't move. What I was trying to do was add to the x or y coordinate, and check to see whether or not the tile in front of the player is one of the tiles that need to be blocked, and in doing so will prevent the player from moving.

That Explains this
1  
2  
3  
if (level1.getTileId(x-16, y, objectLayer) == 33 || level1.getTileId(x-16, y, objectLayer) == 40 || level1.getTileId(x-16, y, objectLayer) == 90){
x-=5;
}


The reason the code is like this is because this if statement is trying to determine what tile is gonna be in front of the player before the player moves, and if the block is one that is blocked, the player won't move. The reason I either add or subtract 16 from the x or y value is because that is the size of the tiles in this map. And the X, and Y value thats being inserted into this method are local variables that represent the players coordinates.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #6 - Posted 2014-04-06 22:48:28 »

this is some (modified for this post) code I wrote a very, very long time ago to handle tile-based collision detection in slick2d, this is just an example of moving one direction. You'll have to mod it for the other 3. Basically instead of checking for specific tileIDs, it would check if that tile it's trying to move to has a "blocked" property, if it does, it will not allow you to move.

This way is better, because you don't have to an "If tile 23 || 55 || 22 || 33112 || 43532 || 323432" (etc) for every single tile you want to be blocked. Instead, open up your map in TilEd, right click on the texture in your tileset and add "blocked" with a value of "true" to everything you want to be unpassable, and use this code as your foundation to build your movement:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   if ((input.isKeyDown(Input.KEY_UP)) || (input.isKeyDown(Input.KEY_W))){
      //NOTE:: The -1 after TileHeight is looking at the tile ABOVE the character. Adjust for the other 3 directions!!
      int tileID = level1.getTileId(x/level1.getTileWidth(), y/level1.getTileHeight()-1, objectLayer);
      String value = level1.getTileProperty(tileID, "blocked", "false");
      if (value.equals("true")){
         //Can't move code fires here!
         return;
      }else{
         //Move code fires here!!
      }
   }      

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #7 - Posted 2014-04-06 22:52:06 »

So why do you divide the x and y coordinates by the tile width/height? and how do i adjust this for the other directions.

Sorry for all the questions, I'm really new at this and this is my first game.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #8 - Posted 2014-04-06 22:57:39 »

So why do you divide the x and y coordinates by the tile width/height? and how do i adjust this for the other directions.

Sorry for all the questions, I'm really new at this and this is my first game.

Reference my first reply, it explains it. Cheesy

Basically, getTileId is looking for the X/Y location of the tile on the TMX file not it's actual coordinates it is being rendered on the map. For example in your code if you were wanting tile 2,2's tileID you're currently actually asking it for 32,32's tileID (assuming you have 16x16 map tiles). You have to divide the coordinates by your tile's height and width and the output should be the tile on the map, not it's actual coordinates.

EDIT: also, to adjust it for other directions just simply change this line, adjusting the +-1 to the correct coords of the tile infront of whatever direction you're moving to:

For up:
      int tileID = level1.getTileId(x/level1.getTileWidth(), y/level1.getTileHeight()-1, objectLayer);

for down:
      int tileID = level1.getTileId(x/level1.getTileWidth(), y/level1.getTileHeight()+1, objectLayer);

for left:
      int tileID = level1.getTileId(x/level1.getTileWidth()-1, y/level1.getTileHeight(), objectLayer);

for right:
      int tileID = level1.getTileId(x/level1.getTileWidth()+1, y/level1.getTileHeight(), objectLayer);

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #9 - Posted 2014-04-06 23:06:12 »

OHHHH I get it know.. Wow.. I am so blind lol.. took me a minute.

thank you

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #10 - Posted 2014-04-06 23:07:48 »

OHHHH I get it know.. Wow.. I am so blind lol.. took me a minute.

thank you


Awesome. Cheesy

I do highly recommend you go with my suggestion of looking at the property values of the tile though (set in tilEd) instead of looking for tileIDs.. it'll make your life a LOT easier down the road if your game ever has a ton of artwork. You won't have to ever change any code, just add blocked = true to all your texture's properties.

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #11 - Posted 2014-04-06 23:12:46 »

Alright with this in mind, how do I move the character
I tried adding to the x value again and the game crashed with the same error.
should i create another value for the coordinates of the player.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #12 - Posted 2014-04-06 23:22:46 »

Alright with this in mind, how do I move the character
I tried adding to the x value again and the game crashed with the same error.
should i create another value for the coordinates of the player.

Thats a much much more complicated question.. depending on how you want him to move. The answer might effect how your collision works too.

Do you want him to move:
An entire tile at a time like he's on a grid (Like a chessboard) or not fixed on a grid like say, Zelda on SNES?

Grid like, you would just simply add/remove +whatever your tile size is every button click, for example if your tiles are 16x16, and you wanted to move down 1 tile, it would be y += 16;

..but, if you wanted zelda like movement (and this will break your collision detection probably, and you'll need a more complicated syetem) you can do: y+= 0.1f *delta (or y += 1, but you should use * delta because the movement will be smoother) Keep in mind though, the zelda-like movement will require you to change your player's coordinates to floats instead of ints.

There's many more complicated/better ways of doing movement (like using slick2d's vector2f class) but for now you should stick to basics. Cheesy

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #13 - Posted 2014-04-06 23:26:26 »

It still isn't working for me, do you have a skype or something, because I can't get this to work. I can't get the detection to work and I can't get the player to move without crashing unless i create two new variables.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #14 - Posted 2014-04-06 23:29:41 »

this might help you as well, it's slow paced (and very basic) but it can give you a foundational idea of how to get started with some basic top down movement in slick:
http://thenewboston.org/list.php?cat=54

It doesnt cover the fancy stuff though, it's just core basics.

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #15 - Posted 2014-04-06 23:31:33 »

It still isn't working for me, do you have a skype or something, because I can't get this to work. I can't get the detection to work and I can't get the player to move without crashing unless i create two new variables. When i add to the new playerx. the player will move but it wont be stopped when moving through tiles that need to be blocked. and if i try and add to the regular x and y the game crashes.

Offline Rayvolution

JGO Kernel


Medals: 216
Projects: 2
Exp: 1 year


Resident Crazyman


« Reply #16 - Posted 2014-04-06 23:34:13 »

I don't use skype. Wink

But I would highly recommend returning to the java basics though, it sounds like you're trying to do too much too fast. Shocked
http://thenewboston.org/list.php?cat=31

- Raymond "Rayvolution" Doerr.
Retro-Pixel Castles - Survival Sim/Builder/Roguelike!
LIVE-STREAMING DEVELOPMENT: http://www.twitch.tv/SG_Rayvolution
Offline pkmasterpwnz

Senior Newbie


Exp: 4-6 months



« Reply #17 - Posted 2014-04-06 23:49:14 »

Nevermind lol, I figured it out lol.. I was trying to move right with the up code.. lol DERP.
Thanks so much for your help. I got it now.. and now I know what to do for this. and I will be checking out those vids on that site for the intermediate java, because I don't know all that much about Arrays which is what this is dealing with i guess.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (42 views)
2014-10-16 15:22:06

Norakomi (32 views)
2014-10-16 15:20:20

lcass (37 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (66 views)
2014-10-14 00:35:47

TehJavaDev (59 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (85 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!