Question

I have a little Android game I've been working on and have also implemented some pixel perfect collision checking based on code here (I say based on, the only thing I changed was the class name). This used to work fine a few months ago but I stopped development for a while, came back and had to rebuild a lot of code including that. Now when I implement it to collisions seem horribly off. If the large weight is on the left of the player, there's a significant distance and yet it still counts as a collision. I have also noticed that the player can pass through some of the smaller weights but not all the way through. I know the player has some non-transparent white pixels which don't help, but I tried with a transparent smaller image and the same thing happened. I edited the player image to remove the white pixels, but I'm still getting the odd collision detection. Any ideas?

The second issue, when the player collides with a weight, it goes to the next activity (which it does) however it jerks all the objects on screen for about a second, and then proceeds to the next activity. Any ideas on this? I have a feeling it's to do with the way I handle the threads, or the way I close them. Check GitHub link below for the GameThread class which handles the main operations on my surface thread.

Collision code can be found in above link, my calling of the class can be found below:

// handles game over circumstances
                if (CollisionUtil.isCollisionDetected(player.getBitmap(), player.getX(), player.getY(), weight.getBitmap(), weight.getX(), weight.getY())) {
                    Intent gameOverIntent = new Intent(this.getContext(), GameOverActivity.class);
                    player.setTouched(false);
                    this.getContext().startActivity(gameOverIntent);
                    ((Activity) this.getContext()).finish();
                    save(score, time);
                    try {
                        gameTimers.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    gameOver = true;
                }

The rest of the classes and all my other code can be found here: https://github.com/addrum/Francois/tree/master/src/com

Thanks for your help in advance.

Edit: Forgot to mention that if you need to test it (you probably will to see what I'm talking about) you can download it here: https://play.google.com/store/apps/details?id=com.main.francois

Edit: I've now uploaded a short recording on YouTube to make it easier to see what I'm talking about: http://youtu.be/vCjKmTmhabY

Was it helpful?

Solution

Thanks for the video; now I understand the "jerk" part.

The explanation for that is simple: your code is doing this (simplified):

while (running) {
    canvas = this.surfaceHolder.lockCanvas();
    this.gameLogic.update();
    this.gameLogic.render(canvas);
    surfaceHolder.unlockCanvasAndPost(canvas);
}

public void render(Canvas canvas) {
    if (!gameOver) {
        ...draw...
    }
}

If gameOver is true, your render() function doesn't draw anything, so you get the previous contents of the buffer.

You might expect this to show whatever was drawn from the frame just before this one. However, the SurfaceView surface is double- or triple-buffered. So if you just keep calling lock/post without drawing anything, you'll cycle through the last two or three frames.

Simple rule: if you lock the surface, you need to draw. If you don't want to draw when the game is over, you need to put your "game over" test back before you lock the canvas.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top