1
votes

First of all i want to say that my English isnt that good, and I'm a beginner programmer. So take it easy with me :L

So I'm making a 2D game where ground is randomly spawned. And its made of blocks... How I do this is first i create the blocks and then I add them to Rectangle ArrayList. Blocks render correctly. But they won't take any collision when player hits them.

At this moment collision doesn't work at all. When i press D (right) player runs towards right ignoring collision complitely. When i press A (left) player don't move at all.

First I make this ArrayList:

static ArrayList<Rectangle> BlockArray = new ArrayList<Rectangle>();

Then I give blocks their X,Y,Width,Height... values in a for loop and after that I add them to the list like this :

BlockArray.add(Block[i]);

Then In player class I run this function every render loop. It should tell if player can move to right or left or none...:

ArrayList<Rectangle> rects = WorldGenerator.BlockArray;
        for(int i = 0; i < rects.size(); i++) {
            // LEFT
            if(player.x >= rects.get(i).getX() + rects.get(i).getWidth() && player.y >= rects.get(i).getY() + rects.get(i).getHeight()){
                canGoLeft = true;
            }
            else{
                canGoLeft = false;
            }

            // RIGHT
            if(player.x <= rects.get(i).getX() && player.y >= rects.get(i).getY() + rects.get(i).getHeight()){
                canGoRight = true;
            }
            else{
                canGoRight = false;
            }
        }

And then finally when user gives input it checks if those booleans are true or not :

if (Gdx.input.isKeyPressed(Keys.A) && canGoLeft == true){
            player.x -= delta * 350f;
        }
        if (Gdx.input.isKeyPressed(Keys.D) && canGoRight == true){
            player.x += delta * 350f;
        }

So thats my code. Hopyfully I didn't forget to mention something. And hopefully someone can help me to solve this problem. Also Like I said before I'm beginner at programming so I might have just a stupid fail in game logic...

1
Also I tried to System.out.println this loop and it returned me (as long as i can tell correct values. (x,y,w,h) 0.0,-44.0, 90.0,84.0 and so on.. - user3389464
I recommend using Box2D (which included in libgdx) to handle your collisions for you, instead of writing your own collision handling. Collision handling is a problem solved a hundred times over, and you should only be re-solving it if your program needs something far out of the norm - Martin
Ok, thanks... I will check out Box2D. However did you or someone else notice another typo or just a fail in code? Just wondering why isnt it working... - user3389464
@MartinCarney you can handle simple collision in plain libgdx as well using overlaps method, no need to add Box2D just for that - donfuxx
@user3389464 is your player a Sprite ? - donfuxx

1 Answers

0
votes

As far as your collision logic goes, you are changing canGoRight and canGoLeft for each rectangle regardless of previous collision checks. This means that effectively, the last rectangle in your list is the only one being checked for collisions.

To resolve that issue, you'll want to change it to be like this (I just added a ! to the conditions, you should rework them rather just inverting the final result):

ArrayList<Rectangle> rects = WorldGenerator.BlockArray;

canGoLeft = true;
canGoRight = true;
for(int i = 0; i < rects.size(); i++) {
    // LEFT
    if(!(player.x >= rects.get(i).getX() + rects.get(i).getWidth() && player.y >= rects.get(i).getY() + rects.get(i).getHeight())) {
        canGoLeft = false;
    }

    // RIGHT
    if(!(player.x <= rects.get(i).getX() && player.y >= rects.get(i).getY() + rects.get(i).getHeight())) {
        canGoRight = false;
    }
}

This way, you assume they can move in a given direction, and any single rectangle that would block that direction will prevent movement that direction.

EDIT: I also looked into your conditions, and it looks like any rectangle to the right of the player will prevent them going to the left, not just a rectangle whose right side is up against the left side of the player. A much better comparison would be the difference between the player's and rectangle's half-widths and half-heights. This article can explain in detail why.

As far as bigger picture goes, I mentioned in a comment that collision detection has already been written many times, and libgdx includes solid collision detection code that you should use, rather than writing your own collision detection code.