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

2014/12/11

Timer Issue/ spawn issue

Kickero Kickero

2014/12/11

#
Im back again.... my new goal is to use a timer to spawn an Exit at a certain amount of time and also cut off the enemy spawns. I haven't messed with cutting off the spawns yet but suggestions are appreciated. Any way my current problem is the LevelDone() method wont grab the time like i want it to and spawn the Ladder()
public class Forest extends World
{
    ForestFloor forestFloor;
    SirB sirB;
    Porcubutt porcubutt;
    BlackKnight blackKnight;
    public int pausePorky = 50;
    public int pauseBK = 185;
    private int screenSide = 0;
    private boolean running = false;
    private int millisElapsed = 0;
    private long lastTime = 0;
    private boolean levelDone =false; 
    private int kills = 0;
    public Forest()
    {    
        super(750, 360, 1); 
        forestFloor = new ForestFloor();
        addObject ( forestFloor, 375, 347);
        sirB = new SirB();
        addObject ( sirB, 76, 272);
    }

    public void act()
    {
        spawnPorcubutts();
        spawnBlackKnights();
        Time();
        Objects();
    }
    
    public void Objects()
    {
        if (getObjects(Exits.class).isEmpty())
        {
            LevelDone();
        }
    }
    
    public void LevelDone()
    {
        if (millisElapsed == 30000)
        {
           addObject ( new Ladder(), 413, 182);
        }
    }

    public void start()
    {
        millisElapsed = 0;
        lastTime = 0;
    }

    public void Time()
    {
        long time = System.currentTimeMillis();
        if(lastTime !=0)
        {
            long diff = time - lastTime;
            millisElapsed += diff;
        }
        lastTime = time;
    }

    public void spawnPorcubutts()
    {
        porcubutt = new Porcubutt();
        if (pausePorky > 0 )
        {
            pausePorky --;
            return;
        }
        if (pausePorky == 0 && levelDone == false)
        {
            int x = getScreenSide();
            addObject (new Porcubutt(), x , 314);
            pausePorky = 50;
        }
    }

    public void spawnBlackKnights()
    {
        blackKnight = new BlackKnight();
        if (pauseBK > 0)
        {
            pauseBK --;
            return;
        }
        if (pauseBK == 0 && levelDone == false)
        {
            int x = getScreenSideBK();
            addObject (new BlackKnight(), x , 286);
            pauseBK = 50;
        }
    }

    public int getScreenSide()
    {
        screenSide = Greenfoot.getRandomNumber(4);
        if (screenSide >=2)
        {
            return 684;
        }
        if (screenSide <= 2)
        {
            return 75;
        }
        return 684;
    }

    public int getScreenSideBK()
    {
        screenSide = Greenfoot.getRandomNumber(4);
        if (screenSide >=2)
        {
            return 79;
        }
        if (screenSide <= 2)
        {
            return 645;
        }
        return 684;
    }
}
danpost danpost

2014/12/11

#
Instead of saving 'elapsedTime' and 'lastTime' and having to mess with real time where you need to account for the stopping and re-starting of the scenario and you cannot account for any lag that may occur, just count act cycles. A scenario running at normal speeds will execute between 50 and 60 act cycles per second; so count to some number around 1500 to 1800 act cycles before adding the ladder. You seem to have an abundance of fields that are not necessary. Unless you need to retain a value from one act method to the next, using a variable local to the method is the way to go. For example, both methods you use 'screenSide' in, it is assigned a value at the beginning of the method and the field is not used anywhere else within the class. Its value is not important after either method is done executing. Also, in your 'spawn' methods, the first line creates or 'spawns' the actor in question before you even know if one will be added to the world. Then, you go ahead and create a different one to add to the world when you figure out one does need added. The first lines in both 'spawn' methods can be removed. I notice you are retaining references to the Porcubutt and BlackKnight objects spawned. If there is only to be one of each in the world at any time, you will need to restrict the spawning of them to when none of that type are in the world (the references can be put to good use with this issue). By convention, method names should begin with a lowercase letter -- 'Time' should be 'time', 'Objects' should be 'objects', 'LevelDone' should be 'levelDone', etc. Actually 'objects' and 'time' are weak names; they really do not say what the method does. I do not see anywhere where the boolean 'levelDone' field is set to true or where 'running' is used at all. The 'levelDone' state can be acquired by checking if the Ladder object is in the world. With all the changes listed, you should end up with something like this:
public class Forest extends World
{
    ForestFloor forestFloor;
    SirB sirB;
    Porcubutt porcubutt;
    BlackKnight blackKnight;
    private int pausePorky = 50;
    private int pauseBK = 185;
    private int levelTimer = 1800;
    private int kills = 0;

    public Forest()
    {    
        super(750, 360, 1); 
        forestFloor = new ForestFloor();
        addObject ( forestFloor, 375, 347);
        sirB = new SirB();
        addObject ( sirB, 76, 272);
    }

    public void act()
    {
        spawnPorcubutts();
        spawnBlackKnights();
        runLevelTimer;
    }
    
    public void runLevelTimer()
    {
        if (levelTimer > 0)
        {
            levelTimer--;
        }
        if (levelTimer == 0 && getObjects(Exits.class).isEmpty())
        {
            addObject ( new Ladder(), 413, 182);
        }
    }

    public void spawnPorcubutts()
    {
        if (pausePorky > 0 )
        {
            pausePorky --;
        }
        if (pausePorky == 0 && getWorld().getObjects(Ladder.class).isEmpty())
        {
            int x = getScreenSide();
            addObject (new Porcubutt(), x , 314);
            pausePorky = 50;
        }
    }

    public void spawnBlackKnights()
    {
        if (pauseBK > 0)
        {
            pauseBK --;
        }
        if (pauseBK == 0 && getWorld().getObjects(Ladder.class).isEmpty())
        {
            int x = getScreenSideBK();
            addObject (new BlackKnight(), x , 286);
            pauseBK = 50;
        }
    }

    public int getScreenSide()
    {
        int screenSide = Greenfoot.getRandomNumber(4);
        if (screenSide >=2)
        {
            return 684;
        }
        return 75;
    }

    public int getScreenSideBK()
    {
        int screenSide = Greenfoot.getRandomNumber(4);
        if (screenSide >=2)
        {
            return 79;
        }
        return 645;
    }
}
I did not change anything as far as limiting the number of Porcubutt and BlackKnight objects in the world. Either a condition needs to be used to restrict them from spawning when one is already in the world or your fields should be removed (I cannot see having more than one object in the world of a type and only referencing one of them).
Kickero Kickero

2014/12/11

#
Thanks again! I only had one problem
    public void spawnBlackKnights()  
    {  
        if (pauseBK > 0)  
        {  
            pauseBK --;  
        }  
        if (pauseBK == 0 && getWorld().getObjects(Ladder.class).isEmpty())  // this part of your script worked but only once i removed the getWorld() part of the line.
        {  //why would it be needed there if i was able to take it out is it because this is an extension of the world class?
            int x = getScreenSideBK();  
            addObject (new BlackKnight(), x , 286);  
            pauseBK = 50;  
        }  
    } 
danpost danpost

2014/12/11

#
Yeah. I forgot the code was in a subclass of World (remove all 'getWorld()' calls).
Kickero Kickero

2014/12/11

#
ok cool just double checking
You need to login to post a reply.