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

2012/12/17

Random Timer

Johnathon Johnathon

2012/12/17

#
Okay, so the last piece of my game I need is to make a resource of ammo appear and slide across the screen on random intervals. I need generate a random integer between 5 to 15 seconds that is tested to loop and create an object. I've tried doing animations in the past and i'm pretty lousy when it comes to timers. Any help is greatly appreciated!
danpost danpost

2012/12/17

#
Timers are not really that difficult. You mentioned that your range for generating resources was between 5 and 15 seconds. Well, that makes a total of 11 possible good values. Therefore you would be using 'Greenfoot.getRandomNumber(11)'; and the first value is 5, so add 5 to the random number. This gives us: Greenfoot.getRandomNumber(11) + 5 Now, the average number of cycles per second in a normal speed scenario is about 60, we can multiply by 60 to get the number of cycles to wait before generating the resource. Of course, the number 60 can be adjusted to suit the rate at which generation occurs. The value we now have (the number of cycles to wait) can be set the the timer value and that value can be decremented each act cycle until it is zero, at which point the generation of the resource can be executed and the timer can be reset.
Johnathon Johnathon

2012/12/17

#
So I would Do ((Greenfoot.getRandomNumber(11) + 5) x 60) and then make a loop like... int a; the act loop{ While (A < ((Greenfoot.getRandomNumber(11)+5) x 60) { a++ } (code for spawning this) a = 0; }
danpost danpost

2012/12/17

#
No. Using a 'for', 'while', or 'do' loop will not accomplish what you need done properly. The loop you will use is provided by the construct of object-oriented programming. Each 'active' object (the currently set world and all objects added to that world) all have their 'act' methods executed; after which the external environment settings (display, sound, etc.) are adjusted to the new values. Each cycle is called a frame. It is this cycling that produces the loop you need to use. First, you need to declare the timer as an 'int' field that will be given to each object that needs it. In your case, just the world object; although you could make it the player object or possibly some other object (provided you only have one, and only one, of that type object in the world and it is always and only in the world when spawning can occur).
// in the world class code, add the field
private int resourceTimer=(Greenfoot.getRandomNumber(11)+5)*60;
// in the act method
runResourceTimer();
// add the methods
private void runResourceTimer()
{
    resourceTimer--;
    if (resourceTimer==0)
    {
        spawnResource();
        resourceTimer=(Greenfoot.getRandomNumber(11)+5)*60;
    }
}

private void spawnResource()
{
    // code to add resource
}
danpost danpost

2012/12/17

#
On second thought, it might be better for you to have the timer in the player (or gun) class; as the resource is dependent on having it in the world. Also, this will add some control as to which resource is allowed at what time; or, at least, make it easier to code in that control, if neccessary.
Johnathon Johnathon

2012/12/18

#
Okay, so I have that all working now! Thank you so much. The only problem I have left is now if someone builds up two or more shots, pressing the fire key will fire a large sum if not all of them at once, either making for a easy one hit kill or a massive waste of ammo. Here is my code for firing and ammo.
    public void act() 
    {
       controls();
    }
    
    public void controls()
    {
        Actor collided = getOneObjectAtOffset(40, 0, Wall.class);
        if(collided == null && Greenfoot.isKeyDown("d")){setLocation(getX() + 3, getY());}
        if (Greenfoot.isKeyDown("w")){setLocation(getX(),getY() - 3);}
        if (Greenfoot.isKeyDown("s")){setLocation(getX(),getY() + 3);}
        if (Greenfoot.isKeyDown("a")){setLocation(getX() - 3, getY());}
        if (Greenfoot.isKeyDown("space")){missile();}
        Actor pickup = getOneObjectAtOffset(30, 0, ammo.class);
        if(pickup != null){
                limitera = limitera + 1;
                getWorld().removeObject(getOneObjectAtOffset(30,0,ammo.class));
         }
    }
and an extremely similar coding for the second player. If possible i'd like to only limit to one missile fired per every half a second or so.
danpost danpost

2012/12/18

#
You can use the same technique as used for the random spawning to create a timer for spawning the missles.
Entity1037 Entity1037

2012/12/18

#
Use a timer for a cooldown. Heres what I would do: public void act() { controls(); } public void controls() { Actor collided = getOneObjectAtOffset(40, 0, Wall.class); if(collided == null && Greenfoot.isKeyDown("d")){setLocation(getX() + 3, getY());} if (Greenfoot.isKeyDown("w")){setLocation(getX(),getY() - 3);} if (Greenfoot.isKeyDown("s")){setLocation(getX(),getY() + 3);} if (Greenfoot.isKeyDown("a")){setLocation(getX() - 3, getY());} if (misslecooldown==0){ if (Greenfoot.isKeyDown("space")){ missile(); misslecooldown=30; } }else{ if (misslecooldown>0){ misslecooldown-=1; } } Actor pickup = getOneObjectAtOffset(30, 0, ammo.class); if(pickup != null){ limitera = limitera + 1; getWorld().removeObject(getOneObjectAtOffset(30,0,ammo.class)); } } I know you can make it smaller, but its just an example.
You need to login to post a reply.