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

2013/10/23

Damage timer

Baenefin Baenefin

2013/10/23

#
Hello, I would like to make it possible that when my player hits an enemy it loses a life, but can't lose a life for a certain amount of time. This is what i have sofar:
public void checkCollisionEnemy()
    {
        List<Enemy> enemies = getWorld().getObjectsAt(getX(), getY() + getImage().getHeight()/2+5, 
                Enemy.class);
        if (enemies != null && !enemies.isEmpty()) {  
            getWorld().removeObject(enemies.get(0));
        }
        else
        {
            Actor collided;
            collided = getOneIntersectingObject(Walker.class);
            if (collided !=null)
            {
                ((Score) getWorld().getObjects(Score.class).get(0)).add(-1);
            }    
        }
    }
How would I be able to do this? Thanks in advance.
GreenHouse GreenHouse

2013/10/23

#
An idea:
import java.util.Date;
 
// get the time in miliseconds (after damage)
long now = new Date().getTime();

// some time later ...

long now2 = new Date().getTime();
if(now2 > now  + 100) // 1000 milisec
{
  // damage
}
This way you can do damage only if a certain time-range has passed.
danpost danpost

2013/10/23

#
What is the purpose in delaying the damage?
Baenefin Baenefin

2013/10/23

#
danpost wrote...
What is the purpose in delaying the damage?
Well, i want my player to be able to not die instantly when touching an enemy. So if i touch an enemy, i want to lose 1 life, and for a certain amount of time, not be able to lose a life.
Baenefin Baenefin

2013/10/23

#
This is what I have come up with
public void checkCollisionEnemy()
    {
        List<Enemy> enemies = getWorld().getObjectsAt(getX(), getY() + getImage().getHeight()/2+5, 
                Enemy.class);
        if (enemies != null && !enemies.isEmpty()) {  
            getWorld().removeObject(enemies.get(0));
        }
        else
        {
            Actor collided;
            collided = getOneIntersectingObject(Walker.class);
            if (collided !=null)
            {
                contactTimer = (contactTimer + 1) % 20;
                if (contactTimer == 0)  
                {
                    ((Score) getWorld().getObjects(Score.class).get(0)).add(-1);
                }
            }    
        }
    }
Now I was not able to make the image blink for a while, say 3 seconds.
danpost danpost

2013/10/23

#
You already added a timer, but the implementation is not quite right:
private int contactTimer;
// the 'checkCollisionEnemy' method
public void checkCollisionEnemy()
{
    Actor enemy = getOneObjectAtOffset(0, getImage().getHeight()/2+5, Enemy.class);
    if (enemy != null) getWorld().removeObject(enemy);
    Actor collided = getOneIntersectingObject(Walker.class);
    if (collided != null && collisionTimer == 0) collisionTimer = 150;
}
// add the following method and call it from the act method
public void runCollisionTimer()
{
    if (collisionTimer > 0)
    {
        collisionTimer --;
        if (collisionTimer == 0)  ((Score)getWorld().getObjects(Score.class).get(0)).add(-1);
    }
}
Line 8 is the main crux of the system. The timer must be zero before setting it at 150 or you could continually contact the walker object and maintain only one damage. That statement is only used to start the timer when necessary. The new 'runCollisionTimer' method is what actually controls the timer.
Baenefin Baenefin

2013/10/23

#
The runCollisionTimer gives me an error. "cannot find symbol - variable collisionTimer" So I added "private int collisionTimer; " Thanks for the reply danpost. GreenHouse thank you for the input.
danpost danpost

2013/10/23

#
Sorry, I had started to change all 'collisionTimer' entries to 'contactTimer', but never finished. They should all be 'contactTimer'.
Baenefin Baenefin

2013/10/24

#
For some reason, my lived keep counting down now that I have a scrolling world Does that have to do anything with the fact that in my SWorld i have now
for(Object obj : genActors)
Edit: As long as my enemy is in the level, my lives count down
public void runCollisionTimer()  
    {  
        if (contactTimer > 0)  
        {  
            contactTimer --;  
            if (contactTimer == 0)  ((Score)getWorld().getObjects(Score.class).get(0)).add(-1);  
        }  
    }

    public void checkCollisionEnemy()  
    {  
        Actor enemy = getOneObjectAtOffset(0, getImage().getHeight()/2+5, Enemy.class);  
        if (enemy != null) getWorld().removeObject(enemy);  
        Actor collided = getOneIntersectingObject(Enemy.class);  
        if (collided != null && contactTimer == 0) contactTimer = 150;  
    }  
danpost danpost

2013/10/25

#
Baenefin wrote...
For some reason, my lived keep counting down now that I have a scrolling world Does that have to do anything with the fact that in my SWorld i have now
for(Object obj : genActors)
From what you posted here, I would have to guess that you altered the SWorld class in some way. Again, let me say the the SWorld class should not have been edited at all. It might be best if you remove the class and re-import it into your scenario (if you have done anything to it).
Baenefin Baenefin

2013/10/25

#
Hi Danpost, If i implement your superscrolling world, the Sworld won't compile for me. (left unedited) So i tried editing it (suggested) Is is maybe smarter to edit the rest of my code? I have no clue.
danpost danpost

2013/10/25

#
Do this: (1) download my 'Scrolling Super World' scenario again (2) open windows explorer and find the folder 'SWorld.JAVA within its folder (3) copy/paste it in the 'Greenfoot/lib/greenfoot/common' folder (4) open your project (5) remove the 'SWorld' class from it (6) choose 'Edit>Import file...' in menubar and select 'SWorld' and click Import (7) compile the project If the project does not compile, post here exactly what message you are getting and where it is being highlighted.
Baenefin Baenefin

2013/10/25

#
I have it compiling now, thank you for the effort. It seems I hade a class called Object (which I have now renamed) so there is no more error. But for some reason my contactTimer goes haywire. I do not get instant damage when i touch an enemy. The timer goed off first and then I get damage. The code is unchanged
private int contactTimer;


public void checkCollisionEnemy()  
    {  
        Actor enemy = getOneObjectAtOffset(0, getImage().getHeight()/2+5, Walker.class); 
        if (enemy != null) getWorld().removeObject(enemy);  
        Actor collided = getOneIntersectingObject(Walker.class);  
        if (collided !=null && contactTimer ==0) contactTimer = 150;
    }  

    public void runCollisionTimer()  
    {  
        if (contactTimer > 0)  
        {  
            contactTimer --;  
            if (contactTimer == 0)  ((Score)getWorld().getObjects(Score.class).get(0)).add(-1);  
        }  
    }
danpost danpost

2013/10/25

#
I think there was a mis-understanding (you not being quite clear enough, and me not inferring correctly what you wanted). Now, I believe what you want is this:
private int contactTimer;

public void checkCollisionEnemy()  
{  
    Actor enemy = getOneObjectAtOffset(0, getImage().getHeight()/2+5, Walker.class); 
    if (enemy != null) getWorld().removeObject(enemy);  
    Actor collided = getOneIntersectingObject(Walker.class);  
    if (collided !=null && contactTimer ==0)
    {
        ((Score)getWorld().getObjects(Score.class).get(0)).add(-1);
        contactTimer = 150;
    }
}  

public void runCollisionTimer()  
{  
    if (contactTimer > 0) contactTimer --;  
}
Baenefin Baenefin

2013/10/25

#
That is exactly it. If I understand correctly, in the old code, if i touch an enemy the timer starts to count, when it reacher 150, i take damage.
You need to login to post a reply.