Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (494)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  LWJGL - Collision problem.  (Read 618 times)
0 Members and 1 Guest are viewing this topic.
Offline ADGDeveloping

Senior Newbie


Exp: 2 years



« Posted 2014-03-04 17:12:27 »

Hello, I got a bit of a problem here.
I made simple code for collision detection.

When I start the game, I fly to a block and I get stuck in the block, No errors, I just can't move in any direction.

The colliion detection happens In the block, I can't seem to fix it. (Im new to AABB)

Code:
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  
    if((keyUp) && (keyRight) && (!keyLeft) && (!keyDown)){
       if(Game.world.getBlock((byte)this.x - 1, (byte)this.y + 1, (byte)this.z) == 0){
          moveLookDir(speed * delta * 0.003F + 2, 0.0F - 2, -speed * delta * 0.003F - 2);
       }
    }
   
    if((keyUp) && (keyLeft) && (!keyRight) && (!keyDown)){
       if(Game.world.getBlock((byte)this.x - 1, (byte)this.y - 1, (byte)this.z) == 0){
          moveLookDir(-speed * delta * 0.003F + 2, 0.0F + 2, -speed * delta * 0.003F - 2);
       }
    }
   
    if ((keyUp) && (!keyLeft) && (!keyRight) && (!keyDown)) {
       if(Game.world.getBlock((byte)this.x - 1, (byte)this.y, (byte)this.z) == 0){
          moveLookDir(0.0F + 2, 0.0F, -speed * delta * 0.003F - 2);
       }
    }
   
    if ((keyDown) && (keyLeft) && (!keyRight) && (!keyUp)) {
       if(Game.world.getBlock((byte)this.x + 1, (byte)this.y - 1, (byte)this.z) == 0){
          moveLookDir(-speed * delta * 0.003F - 2, 0.0F + 2, speed * delta * 0.003F - 2);
       }
    }
   
    if ((keyDown) && (keyRight) && (!keyLeft) && (!keyUp)) {
       if(Game.world.getBlock((byte)this.x + 1, (byte)this.y + 1, (byte)this.z) == 0){
          moveLookDir(speed * delta * 0.003F - 2, 0.0F - 2, speed * delta * 0.003F - 2);
       }
    }  
   
    if ((keyDown) && (!keyUp) && (!keyLeft) && (!keyRight)) {
       if(Game.world.getBlock((byte)this.x + 1, (byte)this.y, (byte)this.z) == 0){
          moveLookDir(0.0F - 2, 0.0F, speed * delta * 0.003F - 2);
       }
    }
   
    if ((keyLeft) && (!keyRight) && (!keyUp) && (!keyDown)) {
       if(Game.world.getBlock((byte)this.x, (byte)this.y - 1, (byte)this.z) == 0){
          moveLookDir(-speed * delta * 0.003F, 0.0F + 2, 0.0F - 2);
       }
    }
     
    if ((keyRight) && (!keyLeft) && (!keyUp) && (!keyDown)) {
       if(Game.world.getBlock((byte)this.x, (byte)this.y + 1, (byte)this.z) == 0){
          moveLookDir(speed * delta * 0.003F, 0.0F - 2, 0.0F - 2);
       }
    }
   
    if ((space) && (!shift)) {
       if(Game.world.getBlock((byte)this.x, (byte)this.y, (byte)this.z + 1) == 0){
          this.y += 1 * delta * 0.003F;
       }
    }
   
    if (!(space) && (!shift)) {
       if(Game.world.getBlock((byte)this.x, (byte)this.y, (byte)this.z - 1) == 0){
          this.y -= 1 * delta * 0.003F;
       }
    }

    /**
    * this.x, this.y, this.z is the camera position.
    */


Thanks for reading.
Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #1 - Posted 2014-03-04 18:39:34 »

Ok first off, why are you casting everything to a byte?

Second, collision detection and response are two different things. Quite obviously your detection works. Now you need to figure out how to respond to the collision. Basic response is easy, don't do anything (besides not letting the player move in the direction of the block of course!). I have found a couple of issues with your code, I believe.

First, the casting thing. Are you seriously telling me the player positions are limited to the range of a byte?

Second, you shouldn't be checking for each key combination. What you need to do is every frame you need to find where the player will be next. That means you will need some variables:

Movespeed - obvious what it is
Position - Player position
Next direction - basically on what axis will the player be moving next?

Then, use the following formula to calculate the next position of the player:

1  
position.x + nextPos.x * moveSpeed (optionally also multiply by the delta if you calculate it, which you should)

When you have the next position, use your getBlock method to determine which block the player will be in next frame. If its empty, let the plate move. If not, well don't.

This is how basic collision detection works, its not AABB.

Offline ADGDeveloping

Senior Newbie


Exp: 2 years



« Reply #2 - Posted 2014-03-04 18:52:19 »

Well, I removed the byte casting (Didn't change anything) and how should I calculate the next position?

And. I still got the problem that its detecting the collision inside the block. For some reason..
How can I fix that?

And isn't Collision Detection AABB?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #3 - Posted 2014-03-04 19:07:15 »

No. AABBs are just a form of collision detection. It stands for Axis Aligned Bounding Box because the boxes never rotate. More specifically the model axis always line up with the world axis. If they did rotate you would have to use something like SAT.

You aren't using AABBs right now, you're just checking to see if you are going to be inside a block space. Its completely different.

I just gave you the "formula" to calculate the next position.

Offline ADGDeveloping

Senior Newbie


Exp: 2 years



« Reply #4 - Posted 2014-03-04 19:27:08 »

I meant.

1  
position.x + nextPos.x * moveSpeed


How can I calculate
1  
 nextPos.x 
?
Offline opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #5 - Posted 2014-03-04 19:48:10 »

Ah yes. Well, think about it. Your blocks are in an array, and arrays have indices. 1, 2, 3... Etc... So, it you want to get the next position of your player relative to your block array, you need to access the next block in which you are going to move. So, logically nextPos would only hold a value of 1 or 0 for its components.

What that's means is that when you hit 'W' for example, you want to move forward on the Z axis. So, you set nextPos.z to be 1. Then you move the player. After you have moved the player, do two collision detection checks. Like this:

1  
2  
3  
if(Game.world.getBlock(pos.x + nextPos.x * moveSpeed, pos.x, pos.z) != null) {
//do collision response for x axis. In this case, you can simply not move the player. Repeat this if statement for the y and z axis accordingly. You must check each axis separately though.
}


Pretty simple really, and you don't need all those if statements that you already have. Just three simple if statements.

Offline ADGDeveloping

Senior Newbie


Exp: 2 years



« Reply #6 - Posted 2014-03-04 19:54:45 »

Oh thx, Ill try it out after I finished the Block placement and removement Smiley
Offline Longor1996
« Reply #7 - Posted 2014-03-04 20:33:39 »

I meant.

1  
position.x + nextPos.x * moveSpeed


How can I calculate
1  
 nextPos.x 
?

You have to calculate the velocity of your players bounding-box into the given Voxels bounding-box you are checking for collision, reducing the velocity on each axis for every voxel-collision so you don't go trough any block.

Super-Pseudocode:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
LIST<Voxels> nearbyVoxels = world.getNearbyVoxels(PLAYER_COLLISION_RANGE);
BOX playerBounds = ???;
VEC3 playerVelocity = ???;

for_each SPATIAL_AXIS [+-X,+-Y,+-Z]
{
  for_each VOXEL in nearbyVoxels
  {
    BOX voxelBounds = ??get boundingbox from given voxel??;
   
    (( the per-Axis difference method is applied here, using the velocity on the given spatial axis, the player-boundingbox, and the voxels boundingbox ))
   
  }
}


Actual Code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
vec3 playerPos = ...;
vec3 playerVelocity = ...;


// Check for all collisions on the Y-Axis.
for_each VOXEL in PLAYER_SURROUNDINGS
{
  playerVelocity.y = VOXEL.?.boundingBox.getYOffset(playerVelocity.Y);
}


// Check for all collisions on the X-Axis.
for_each VOXEL in PLAYER_SURROUNDINGS
{
  playerVelocity.x = VOXEL.?.boundingBox.getXOffset(playerVelocity.x);
}

// Check for all collisions on the Z-Axis.
for_each VOXEL in PLAYER_SURROUNDINGS
{
  playerVelocity.z = VOXEL.?.boundingBox.getZOffset(playerVelocity.z);
}

playerPosition += playerVelocity * moveSpeed;


Difference Method:
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  
    public double getXOffset(AABB3D playerBoundings, double movementOnX)
    {
        if ((aabb.b.y <= this.a.y) || (aabb.a.y >= this.b.y))
         return movementOnX;

        if ((aabb.b.z <= this.a.z) || (aabb.a.z >= this.b.z))
         return movementOnX;

        if ((movementOnX > 0D) && (aabb.b.x <= this.a.x))
        {
            double d = this.a.x - aabb.b.x;

            if (d < movementOnX)
            movementOnX = d;
        }

        if ((movementOnX < 0D) && (aabb.a.x >= this.b.x))
        {
            double d1 = this.b.x - aabb.a.x;

            if (d1 > movementOnX)
            movementOnX = d1;
        }
       
        return movementOnX;
    }


The difference method takes some time to understand,so don't worry if you don't understand it!
Nobody understands it in the beginning.

I understand it, but I have serious trouble explaining it, so this is probably the worst explanation for this method, ever(?).

Have a nice day!

- Longor1996

PS: This is the method that is used in Minecraft.

Sorry for my bad English! That's because i am from Germany.
Offline ADGDeveloping

Senior Newbie


Exp: 2 years



« Reply #8 - Posted 2014-03-04 22:03:26 »

WEll, Thanks you all for your replies.

It got fixed for like 90%.
I used all of your code and put it together.

I now can't pass through blocks. But its clipping like crazy.


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  
    if((keyUp)){
       if(Game.world.getBlockB(this.x + 1, this.y, this.z) == 0) {
          //do collision response for x axis. In this case, you can simply not move the player. Repeat this if statement for the y and z axis accordingly. You must check each axis separately though.
         moveLookDir(0.0F, 0.0F, -speed * delta * 0.003F - 1);
       }else{
          moveLookDir(0.0F, 0.0F, 4.0F);
       }
    }
   
    if((keyDown)){
       if(Game.world.getBlockB(this.x - 1, this.y, this.z) == 0) {
          //do collision response for x axis. In this case, you can simply not move the player. Repeat this if statement for the y and z axis accordingly. You must check each axis separately though.
         moveLookDir(0.0F, 0.0F, speed * delta * 0.003F + 1);
       }else{
          moveLookDir(0.0F, 0.0F, -4.0F);
       }
    }
   
    if((keyRight)){
       if(Game.world.getBlockB(this.x, this.y, this.z + 1) == 0) {
          //do collision response for x axis. In this case, you can simply not move the player. Repeat this if statement for the y and z axis accordingly. You must check each axis separately though.
         moveLookDir(speed * delta * 0.003F + 1, 0.0F, 0.0F);
       }else{
          moveLookDir(4.0F, 0.0F, 0.0F);
       }
    }
   
    if((keyLeft)){
       if(Game.world.getBlockB(this.x, this.y, this.z - 1) == 0) {
          //do collision response for x axis. In this case, you can simply not move the player. Repeat this if statement for the y and z axis accordingly. You must check each axis separately though.
         moveLookDir(-speed * delta * 0.003F - 1, 0.0F, 0.0F);
       }else{
          moveLookDir(-4.0F, 0.0F, 0.0F);
       }
    }
   
    if ((space) && (!shift)) {
       if(Game.world.getBlockB(this.x, this.y, this.z + 1) == 0){
          this.y += speed * delta * 0.003F;
       }else{
          this.y -= 2.0F;
       }
    }
   
    if ((!space) && (!shift)) {
       if(Game.world.getBlockB(this.x, this.y, this.z - 1) == 0){
          this.y -= speed * delta * 0.003F;
       }else{
          this.y += 2.0F;
       }
    }
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.

Dwinin (22 views)
2014-09-12 09:08:26

Norakomi (55 views)
2014-09-10 13:57:51

TehJavaDev (67 views)
2014-09-10 06:39:09

Tekkerue (33 views)
2014-09-09 02:24:56

mitcheeb (55 views)
2014-09-08 06:06:29

BurntPizza (39 views)
2014-09-07 01:13:42

Longarmx (24 views)
2014-09-07 01:12:14

Longarmx (30 views)
2014-09-07 01:11:22

Longarmx (30 views)
2014-09-07 01:10:19

mitcheeb (37 views)
2014-09-04 23:08:59
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!