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

2014/1/10

An interval for my spawning actor

1
2
Aaron91 Aaron91

2014/1/10

#
I got this game where my ship has to avoid barrels. But the barrels are comming with 4 at once.. is it possible to set an interval between the spawning barrels? My code looks like this at the moment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
 
/**
 * Write a description of class barrel here.
 *
 * @author (your name)
 * @version (a version number or a date)
 */
public class barrel extends Actor
{
     
     /* Act - do whatever the barrel wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.*/
  
      
         
   public void act()
    
   
    if(isGeraakt())   
    {   
        removeHealth(); 
        getWorld().removeObject(this); 
        return;        
            
    }   
    int x = Greenfoot.getRandomNumber(2);   
    move(-x);   
    if(atWorldEdge()) getWorld().removeObject(this);    
   }      
     
   public void removeHealth()
   {
     BotenUpgrade subWorld = (BotenUpgrade) getWorld();  
     heart heartObject = (heart) subWorld.getObjects(heart.class).get(0);  
     heartObject.adjustValue(-1);   
        
     if (heartObject.getValue() == 0) removeLive(); 
      
   }
   
   public boolean isGeraakt()
   {
     boolean raak = false;
     Actor r = getOneObjectAtOffset(0,0,boot.class);
     if ( r !=null)
     {
      raak = true;
     }
     return raak;
   }
        
   public boolean atWorldEdge() 
   
     return getX() == 0 ||  
               getX() == getWorld().getWidth() - 1 || 
               getY() == 0 ||
               getY() == getWorld().getHeight() - 1
   }
    
   public void removeLive()   
    {   
        int lives = getWorld().getObjects(heart.class).size();   
        getWorld().removeObject((Actor)getWorld().getObjects(heart.class).get(lives-1)); 
 
        if (lives != 1
        
            //
        
        else 
        {    
            Greenfoot.setWorld(new GameOver());
        
    }  
     
 }
danpost danpost

2014/1/10

#
It is not the barrel class that spawn the barrels. We probably need to look at the BotenUpgrade world class.
Aaron91 Aaron91

2014/1/10

#
My bad there.. this is the spawn code i got in my world class..
1
2
3
4
5
6
7
8
public void spawn()
{
  if (Greenfoot.getRandomNumber(100) == 1)
  {
      while (getObjects(barrel.class).size() < 4) { 
     addObject(new barrel(), 750, Greenfoot.getRandomNumber(250)+500); 
    }
  }
danpost danpost

2014/1/10

#
Once the 'while' loop executes, all four barrels will be added into the world. Changing 'while' to 'if' should produce the desired behavior -- on average, the 4 barrels will appear individually in about 8 seconds.
Aaron91 Aaron91

2014/1/10

#
And lets say.. i want to increase the amount of spawning barrels as time passes. Like this is my TimeChecker actor
1
2
3
4
5
6
7
8
9
10
    public TimeChecker() { 
        initialTime = System.currentTimeMillis(); 
    
       
    public void act() { 
        if(System.currentTimeMillis() > initialTime + 181000) { 
            Greenfoot.setWorld(new GameOver());
        
    
}
And i want to let my barrels spawn 5 barrels if 1 minute has passed, and 6 barrels as the second minute has passed. Is this possible ?
danpost danpost

2014/1/10

#
Sure it is possible. However, I would suggest you count act cycles rather than using the System clock. There are several advantages to using act cycles which I will not get into right now. First, we want to make '4' (the current limit on the number of barrels) a variable field. So declare an instance int field, call it 'maxBarrels', and initialize it to '4'. Then replace the '4' in your 'spawn' method with 'maxBarrels'. Now all we have to do is increment the field at the appropriate time. We now, need another instance int field to count the act cycles (call it actCounter). A minute (on a standard speed scenario) is about 3000 act cycles. So, if we increment 'actCounter' and check its value for 3000 every act cycles, we can increment the 'maxBarrels' field and reset the 'actCounter' field back to zero. If your game is to end after about 3 minutes (which is what it appears you want to happen), then just check for a value of 7 in the 'maxBarrels' field ('4' for the first minute, '5' for the second, and '6' for the third -- at '7' the game is over). So, this is what we have
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// instance fields
private int maxBarrels = 4;
private int actCounter;
// in act method
runActCounter();
// new method
private void runActCounter()
{
    actCounter++; // count act cycle
    if (actCounter < 3000) return; // wait for a minute to pass  (50 cycles/second * 60 seconds)
    actCounter = 0; // reset actCounter
    maxBarrels++; // increment maximum number of barrels
    if (maxBarrels == 7) Greenfoot.stop(); // after three minutes, stop
}
danpost danpost

2014/1/10

#
For over-simplifying:
1
2
3
4
private void runActCounter()
{
    if (++actCounter%3000 == 0 && ++maxBarrels == 7) Greenfoot.stop();
}
Aaron91 Aaron91

2014/1/10

#
Thanks! i rather have the extended 1... explains it better for myself.. and by the way.. do you know how many act cycles there are at max speed? iam guessing it isnt 6000.
danpost danpost

2014/1/10

#
There are several factors that come into play when a scenario is set to run that fast. You can get an idea of how many cycles can occur in a second, plus how the number of actors (or moving images) effects the speed by trying out my Timed Scrolling scenario.
Aaron91 Aaron91

2014/1/10

#
Thanks ill take a look at the scenario!
Aaron91 Aaron91

2014/1/11

#
Got the timer abut right now. thanks again for that. but another question about the runActCounter method.
danpost wrote...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// instance fields
private int maxBarrels = 4;
private int actCounter;
// in act method
runActCounter();
// new method
private void runActCounter()
{
    actCounter++; // count act cycle
    if (actCounter < 3000) return; // wait for a minute to pass  (50 cycles/second * 60 seconds)
    actCounter = 0; // reset actCounter
    maxBarrels++; // increment maximum number of barrels
    if (maxBarrels == 7) Greenfoot.stop(); // after three minutes, stop
}
I did the same thing, but then with a bomb. I set an instance field for bomb like this
1
private int maxBomb = 1;
1
2
3
4
5
6
7
private void runActCounterBomb() 
   
    actCounter++; // count act cycle 
    if (actCounter < 3000) return; // wait for a minute to pass  (50 cycles/second * 60 seconds) 
    actCounter = 0; // reset actCounter 
    maxBomb++; // increment maximum number of barrels 
   }
it starts with 1 bomb, as expected, but after a minute in medium speed.. i already see 3 bombs. That shouldnt be happening right? shouldnt the 3rd bomb come after 2 minutes have passed?
danpost danpost

2014/1/11

#
If you are using the same field 'actCounter' for both then you need to do the following:
1
2
3
4
5
6
7
8
9
// from act method
runCounters();
// with the method
private void runCounters()
{
    actCounter++;
    runActCounterBarrel();
    runActCounterBomb();
}
with separate methods for the barrels and the bombs. Now, however, you do not increase the value of 'actCounter' within the 'runActCounter...' methods.
Aaron91 Aaron91

2014/1/11

#
The barrels are doing what they should do at the moment, unlike the bombs. The bombs staying to spawn 1 at a time. Am i overlooking something? This is my bomb method at the moment.
1
2
private int maxBomb = 1
private int actCounter;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  public void act()
{
    if(scrollSpeed > 0 && scrollPosition <= 0) {
        scrollPosition = getWidth();
    }
    if(scrollSpeed < 0 && scrollPosition >= getWidth()) {
        scrollPosition = 0;
    }
    scrollPosition -= scrollSpeed;
    paint(scrollPosition);
     
    spawnBarrel();
    spawnBomb();
    runCounters();
      
}
1
2
3
4
5
6
7
8
9
10
public void spawnBomb()
    {
      if (Greenfoot.getRandomNumber(200) == 1)
      {
         if (getObjects(Bomb.class).size() < maxBomb) { 
         addObject(new Bomb(), 750, Greenfoot.getRandomNumber(250)+500); 
        }
      }
   
    }
1
2
3
4
5
6
7
private void runActCounterBomb() 
  
    
   if (actCounter < 3000) return; // wait for a minute to pass  (50 cycles/second * 60 seconds) 
   actCounter = 0; // reset actCounter 
   maxBomb++; // increment maximum number of bombs
  }
Aaron91 Aaron91

2014/1/11

#
1
2
3
4
5
6
private void runCounters() 
  
   actCounter++; 
   runActCounterBarrel(); 
   runActCounterBomb(); 
  }
forgot this one to the previous comment
danpost danpost

2014/1/11

#
Change the 'runActCounterBomb' method to the following:
1
2
3
4
private void runActCounterBomb() 
 
    if (actCounter%3000 == 0)  maxBomb++;
}
Every time the actCounter gets to a multiple of 3000, another bomb will be added to the max count. Do the same with the barrel max, but keep the check for game over. Something like this:
1
2
3
4
5
6
7
8
private void runActCounterBarrel()
{
    if (actCounter%3000 == 0)
    {
        maxBarrels++;
        if (maxBarrels == 7) Greenfoot.stop();
    }
}
There are more replies on the next page.
1
2