LWJGL - AABB Problem

Hello I got a lil problem.
I made a camera class and added AABB.
AABB on the Y axis works.
AABB on the X and Z axis don’t.

I can walk into a block, at each side (Except up and down (Y Axis)), I tried many things and idk how to fix.
When walking on a block its OK. When walking to a block. I can get inside and it pushes me down inside the world.
The world is empty from the inside because it’s not visible so not rendered (Face checking for more fps).

Y Axis Code:


    if(space && !shift){
    	if(Game.world.getBlock(this.x, this.y - 3, this.z) != null){
    		this.y -= 0F;
    	}else{
    		this.y += speed * delta * 0.003F;
    	}
    }else if(!space && !shift){
    	if(Game.world.getBlock(this.x, this.y - 3, this.z) != null){
    		this.y += 0F;
    	}else{
    		this.y -= (speed / 8) * 1F;
    	}
    }

X And Z Axis Code:


    if((keyUp)){
    	if(Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z).isOpaque() || Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2).isOpaque()) {
    		moveLookDir(0.0F, 0.0F, -1.0F);
    	}else{
    		moveLookDir(0.0F, 0.0F, -speed * delta * 0.003F);
    	}
    }
    
    if((keyDown)){
    	if(Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z).isOpaque() || Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2).isOpaque()) {
    		moveLookDir(0.0F, 0.0F, -1.0F);
    	}else{
    		moveLookDir(0.0F, 0.0F, speed * delta * 0.003F);
    	}
    }
    
    if((keyRight)){
    	if(Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2).isOpaque() || Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2).isOpaque()) {
    		moveLookDir(-1.0F, 0.0F, 0.0F);
    	}else{
    		moveLookDir(speed * delta * 0.003F, 0.0F, 0.0F);
    	}
    }
    
    if((keyLeft)){
    	if(Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x, (int)this.y, (int)this.z - 2).isOpaque() || Game.world.getBlock((int)this.x  - 2, (int)this.y, (int)this.z - 2) != Block.air && Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2) == null && !Game.world.getBlock((int)this.x - 2, (int)this.y, (int)this.z - 2).isOpaque()) {
    		//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(-1.0F, 0.0F, 0.0F);
    	}else{
    		moveLookDir(-speed * delta * 0.003F, 0.0F, 0.0F);
    	}
    }  

I hope someone can help me.
If u need more detail or code tell me.

Thanks for reading

I think you need to make your code a bit more readable.

What do you mean?

The if statements are a few screens wide.

Make some functions to avoid duplicate code.

It’s not duplicate code :slight_smile:
It’s all the code needed to check if the block isn’t Air, isn’t null, isOpaque and hasBoundings.

Yes, but you’re doing it 4 times. And any tiny error could be in just one of them and will be extremely hard to find.

Each of the 4 iss for different positions. :slight_smile:

1: Forward
2: Backward
3: right
4: Left

Think he means using something like this:


//where x, y, and z are offsets from this.* for convenience
private Block getBlock(int x, int y, int z) {
      ...
}

//so then you can do this:

if((keyUp)){
      Block b = getBlock(-2, 0, 0);
      Block b2 = getBlock(-2, 0, -2);

      if(b != Block.air && b == null && !b.isOpaque() || b2 != Block.air && b2 == null && !b2.isOpaque()) {
            moveLookDir(0.0F, 0.0F, -1.0F);
      }else{
            moveLookDir(0.0F, 0.0F, -speed * delta * 0.003F);
      }
}

Don’t have to be that ‘aggressive’ with the simplification, but it cleans it up a bit.

Also not much changes between those 4 direction check blocks. You could pretty easily evaluate a conditional expression at the several places where the information does change, for example:


moveLookDir(keyRight || keyLeft ? -1.0F : 0.0F, 0.0F, keyUp || keyDown ? -1.0F : 0.0F);

Ah ok, :), Ill send the code soon.

Usually we’re not talking about 100% duplicate code, but about seeing repetitive patterns.

BurntPizza made the first step with the [icode]getBlock()[/icode] method, which I’d like to call [icode]getRelativeBlock()[/icode] for now :point:

You could also add another function for finding out, whether a block is visible:


public boolean isVisibleBlock(Block b) {
    return b != null && b != Block.air && !b.isOpaque();
}
public boolean isRelativeBlockVisible(int x, int y, int z) {
    return isBlockVisible(getRelativeBlock(x, y, z));
}

And then you could simplify your code and make it more readable (only x-axis code for now):


float xResponsiveMove = keyRight || keyLeft ? -1.0f : 0.0f;
float zResponsiveMove = keyUp || keyDown ? -1.0f, 0.0f;

if (isRelativeBlockVisible(-2, 0, 0) || isRelativeBlockVisible(-2, 0, -2)) {
    moveLookDir(xResponsiveMove, 0.0F, zResponsiveMove);
} else {
    moveLookDir(0.0F, 0.0F, -speed * delta * 0.003F);
}

Which is, (I admit it :wink: ) pretty much what BurntPizza suggested ;D

This syntax:


float variable = someStatement ? oneExpression : anotherExpression;

de-sugers into this:


float variable = anotherExpression;
if (someStatement) variable = oneExpression;

(not quite, but almost. The difference with strictness doesn’t need to be mentioned here…)