This site requires JavaScript, please enable it in your browser!
Greenfoot back
ddemarco06
ddemarco06 wrote ...

2014/8/1

Collision Detection Issues

1
2
3
4
ddemarco06 ddemarco06

2014/8/1

#
I'm having some issues with collision detection in my game. When my Hero dies I have it respawning in the same position or very close to it. The problem is, oftentimes it repawns right on top of the enemy and immediately dies again. This is especially true with my Boss enemy, which is quite a bit bigger than the average enemies. My hero has 10 lives, but if it gets stuck on the side or in a corner and is hit by an enemy it just keeps dying and respawning until all its lives are gone. I think the solution might be to define a boolean in my Hero's class : boolean touchingEnemy = false; but I'm not 100% sure where to take it from there. Here is my code:
    private void checkBossCollision() 
    {
        if (getWorld() == null) return;
        
        Actor a = getOneIntersectingObject(Boss.class);
        if (a != null) 
        {
            if (touchingEnemy == false)
            {
                int x = Greenfoot.getRandomNumber(340);
                lives--;
                counter.loseLife();
                
                Space space = (Space) getWorld();
                space.addObject(new Explosion(), getX(), getY());
                space.removeObject(this);
                space.addObject(new Rocket(), 65, x);
                space.addObject(this, 65, x);
                movement.setNeutral(); 
                touchingEnemy = true;
            }
        }
        if (lives <= 0){
            Space space = (Space) getWorld();
            space.addObject(new Explosion(), getX(), getY());
            space.removeObject(this);
            GameOver gameover = new GameOver();
            space.addObject(gameover, space.getWidth()/2, space.getHeight()/2);
        }
        else{
            touchingEnemy = false;
    }    
Any help would be appreciated. Thank you in advance!
NikZ NikZ

2014/8/2

#
First, Space is removing Hero and therefore Hero cannot preform lines 17 onward. Second, you are adding Hero back into the world at a random x.
NikZ NikZ

2014/8/2

#
What does touchingEnemy do? It seems as though it's only true when lives is less than or equal to 0.
ddemarco06 ddemarco06

2014/8/2

#
I guess I was trying to use a boolean to set the state of the Hero right after it is hit. If there is a better way to do it I've been stuck on this a while. What I'm trying to do is spawn my character in the same place, but if it is killed there, it just dies over and over until out of lives. I could try respawning in random locations, or moving the enemy after they collide with the Hero but I'm wondering if there's a better way.
NikZ NikZ

2014/8/2

#
The best way if you want the hero in the same exact place is to move the boss. Of course, an alternative would be to create a small makeshift platform the hero spawns on, also where the boss cannot harm the hero. Therefore the hero can choose to move left or right. See here (0:04). This video is from Super Smash Bros. Brawl.
NikZ NikZ

2014/8/2

#
I'm not sure it's necessary to remove the hero after it loses a life.
ddemarco06 ddemarco06

2014/8/2

#
My Hero respawns in the bottom left of the screen so if it is killed there it just keeps dying until out of lives. That platform is a great idea idea, but would involve a lot more code. I will try moving the Boss. Thank you.
NikZ NikZ

2014/8/2

#
Hmm, maybe instead of the platform, you can have an "invincibility mode" for a few seconds where the hero can move into position. Maybe use setTransparency() in GreenfootImage (check out the API). You can have a Boolean isInvinsible. You can use a timer like this:
int delay = 0;
    if(delay == x) {
        isInvinsible = false;
    }
    else {
        delay++;
    }
ddemarco06 ddemarco06

2014/8/2

#
That is a awesome idea! I'm sorry I'm still very new to this, where would I put that in the above method?
NikZ NikZ

2014/8/2

#
Lines 10 - 20? You'll need to update delay every act...
NikZ NikZ

2014/8/2

#
You can use isInvinsible (make it private) in act() like if(isInvinsible) then do the delay stuff.
danpost danpost

2014/8/2

#
NikZ wrote...
First, Space is removing Hero and therefore Hero cannot preform lines 17 onward.
That is incorrect. Only those methods that require the Hero to be in the world cannot be performed; and none of those are being used. It is not necessary to remove and add the actor back into the world. The ''invinsibility' idea is probably the best; however, when to discontinue it should be determined by the state of the actor still intersecting the boss. That is, once the actor clears the boss, then the actor should become vulnerable again.
// pseudo code
if vulnerable and intersects boss, apply damage and set not vulnerable;
if not vulnerable and does not intersect boss, set vulnerable;
In the initial code given, the 'if' block starting at line 23 should probably be inside the inner 'if' block above it after decrementing the 'lives' value.
ddemarco06 ddemarco06

2014/8/2

#
So I added the boolean boolean isInvincible = false; at the top of my Hero class. Then I added in the act method: public void act() { move(); checkKeys(); checkCollision(); checkBossCollision(); reloadDelayCount++; if (isInvincible) { int delay = 0; if(delay == x) { isInvisible = false; } else { delay++; } } } and in the collison method: /** * Check whether we are colliding with the Boss. * If we are, remove cat from world until Rocket drops off a new cat. * If lives = 0, game over. */ private void checkBossCollision() { if (getWorld() == null) return; Actor a = getOneIntersectingObject(Boss.class); if (a != null) { if isInvincible=false { int x = Greenfoot.getRandomNumber(340); lives--; if (lives <= 0){ Space space = (Space) getWorld(); space.addObject(new Explosion(), getX(), getY()); space.removeObject(this); GameOver gameover = new GameOver(); space.addObject(gameover, space.getWidth()/2, space.getHeight()/2); } counter.loseLife(); Greenfoot.playSound("catscreech2.wav"); Space space = (Space) getWorld(); space.addObject(new Explosion(), getX(), getY()); space.removeObject(this); isInvisble = true; space.addObject(new Rocket(), 65, x); space.addObject(this, 65, x); movement.setNeutral(); } } } Am I even close? What am I missing?
NikZ NikZ

2014/8/2

#
Every act, if isInvinsible is true, delay is being reset to 0. You should save it into a private variable.
NikZ NikZ

2014/8/2

#
Like this:
private int delay = 0;

public act() 
{

}
There are more replies on the next page.
1
2
3
4