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

2012/4/4

removing objects at the left of screen

1
2
3
4
e_e13 e_e13

2012/4/5

#
Hello, I've changed my code slightly and now it dosen't work again. I've done as you said however changed the totalCount to 4, as I want it only to show the picture when 4 'invaders' have been shot. This dosen't happen however, and the game just continues playing without showing the image. Here is the code for my counter:
public class Counter extends Actor
{
    /**
     * Act - do whatever the Counter wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    int totalCount = 0;
    public void bumpCount()
    {
        totalCount = totalCount+ 1;
        
    }
    public void act() 
    {
        World world;  
        world = getWorld();  
        if (totalCount == 4 && world.getObjects(GameWon.class).isEmpty())  
        {  
            GameWon gw;  
            gw = new GameWon();  
            world.addObject(gw, 450, 300);  
        }
        
    }    
    
}
And here is my code for the bullet:
public class Bullet extends Rocket
{
    /**
     * Act - do whatever the Bullet wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // Add your action code here.
        setLocation(getX() + 30, getY() );
        
        
        Actor Creepinginvader;
        Creepinginvader = getOneObjectAtOffset(0,0,Invader.class);
        if (Creepinginvader!=null)
        {
            World world;
            world = getWorld();
            world.removeObject(Creepinginvader);
            world.removeObject(this);
            return;
        }
//this is the part I'm using to trigger the counter:
        if (Creepinginvader!=null)
        {
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();  
            Counter counter = spaceWorld.getCounter();  
            counter.bumpCount();
        }
        
        Actor spasmInvader;
        spasmInvader = getOneObjectAtOffset(0,0,Invader.class);
        if (spasmInvader!=null)
        {
            World world;
            world = getWorld();
            world.removeObject(spasmInvader);
            world.removeObject(this);
            return;
        }
        if (spasmInvader!=null)
        {
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();  
            Counter counter = spaceWorld.getCounter();  
            counter.bumpCount();
        }
        
        Actor ZigZagInvader;
        ZigZagInvader = getOneObjectAtOffset(0,0,Invader.class);
        if (ZigZagInvader!=null)
        {
            World world;
            world = getWorld();
            world.removeObject(spasmInvader);
            world.removeObject(this);
            return;
        }
        if (ZigZagInvader!=null)
        {
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();  
            Counter counter = spaceWorld.getCounter();  
            counter.bumpCount();
        }
        
        Actor CustomInvader;
        CustomInvader = getOneObjectAtOffset(0,0,Invader.class);
        if (CustomInvader!=null)
        {
            World world;
            world = getWorld();
            world.removeObject(CustomInvader);
            world.removeObject(this);
            return;
        }
        if (CustomInvader!=null)
        {
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();  
            Counter counter = spaceWorld.getCounter();  
            counter.bumpCount();
        }
        
        if (this.atWorldEdge()==true)
        {
           World world;
           world = getWorld();
           world.removeObject(this);
           return;
        }
    
    }  
    
    public boolean atWorldEdge()
    {
        if (getX() > getWorld().getWidth() - getImage().getWidth() || getY() > getWorld().getHeight() - getImage().getHeight())    
    
        {    
            return true;    
        }    
        else    
        {    
            return false;
        }    
    }
    
}
Thanks all for your help so far :)
SPower SPower

2012/4/5

#
I've got a question: Does Greenfoot give you an error, does your code crash or something else? I give you a tip: instead of this:
World world;  
world = getWorld();  world.removeObject(CustomInvader);  
world.removeObject(this);  
return;
You better do this:
getWorld().removeObject(CustomInvader);
getWorld().removeObject(this);
This uses less memory. Probably it's not so much memory, but it's just better to don't use more memory than you need to. And instead of this:
if (this.atWorldEdge()==true) 
you can also do this:
if(atWorldEdge() == true)
The "this." isn't necessary, but if you like it you can use it.
e_e13 e_e13

2012/4/5

#
It dosen't crash, nor do I get an error. It just dosen't work as it's supposed to- 'gw' just dosen't appear as a picture on the screen. And I've also changed it so that I use less memory :)
SPower SPower

2012/4/5

#
I think you now have to look where the bug exactly is. In act is this if statement:
if (totalCount == 4 && world.getObjects(GameWon.class).isEmpty())
{
GameWon gw;    
gw = new GameWon();    
world.addObject(gw, 450, 300);
}
You can change it to this:
if (totalCount == 4 && world.getObjects(GameWon.class).isEmpty())
{
Greenfoot.stop();
world.addObject(new GameWon(), 450, 300);
}
Now your scenario will stop if totalCount is 4 and there's no GameWon in the world. The Greenfoot.stop() line is a handy line to find bugs in your scenario. I use it too. I hope this helps.
e_e13 e_e13

2012/4/5

#
Indeed, this is quite handy, but as the code isn't stopping I can assume the count dosen't go to 4. It dosen't go to 1 either with this code- which means there must be a problem somewhere before this. Despite re-reading and checking the code once again though, I still can't find any faults. All I can assume therefore is that some other code is wrong, however the only other code involved in this is the world code, which hardly has any involvement in it at all. I could post it up for everyone to check, but I don't think there is anything wrong there. It's pretty much just as it was on the tutorial :/ Thanks for the help anyway though, I'll surely be using Grenfoot.stop again :)
trash1000 trash1000

2012/4/5

#
Unless you do something wrong in GameWon (try manually adding an object of GameWon) it could be that you return a new instance of Counter anytime you call getCounter() in spaceinvaders. In that case you would increase totalCounter to 1 on lots of objects from Counter.
e_e13 e_e13

2012/4/5

#
trash1000 wrote...
.. on lots of objects from Counter.
I get your drift, but this bit is a bit vague. I tried to change the original bit of TotalCounter in the beginning to 1, but this didn't help (and I think you're referring to something else). Also, manually adding GameWon is fine, so I must have made a mistake somewhere else.
SPower SPower

2012/4/5

#
You maybe can change bumpCount() from:
public void bumpCount()  
{  
    totalCount = totalCount+ 1; 
} 
to:
public void bumpCount()  
{ 
    Greenfoot.stop();
    totalCount = totalCount+ 1; 
} 
Again, you have to look where the bug is. If Greenfoot also doesn't stop now, you know that bumpCount() isn't executed.
danpost danpost

2012/4/5

#
SPower wrote...
And instead of this:
if (this.atWorldEdge()==true) 
you can also do this:
if(atWorldEdge() == true)
The "this." isn't necessary, but if you like it you can use it.
Also, instead of
if(atWorldEdge() == true)
you can also do this:
if(atworldEdge())
On all your checks for (1)Creepinginvader, (2)spasmInvader, (3)ZigZagInvader, and (4)CustomInvader, those four names are just that, NAMES, and you are casting all to Actor and looking for an Invader.class object. Having one search for an Invader.class object is enough (with the check for atWorldEdge()). It really does not matter what you call the Actor class object that is returned from the getOneObjectAtOffset(0, 0, Invader.class), but you could just call it 'invader' in
Actor invader;
invader = getOneIntersectingObject(Invader.class);
(it might be better to use this method instead).
trash1000 trash1000

2012/4/5

#
e_e13 wrote...
trash1000 wrote...
.. on lots of objects from Counter.
I get your drift, but this bit is a bit vague. I tried to change the original bit of TotalCounter in the beginning to 1, but this didn't help (and I think you're referring to something else). Also, manually adding GameWon is fine, so I must have made a mistake somewhere else.
Ok, let's see. You call getCounter() whenever you have a certain object of a class on (0|0). I don't know how your getCounter() looks, but it could be (assuming here) that it looks like this:
public Counter getCounter() {
    Counter counter = new Counter();
    return counter;
}
Then you set totalCounter to 1 with bumpCount(). Next time you get another Counter object and set totalCounter to 1 as well. In the end you have lots of objects with totalCounter == 1 but none of those will ever have totalCounter == 4. However, I just noticed your mistake. With
        
        Actor Creepinginvader;  
        Creepinginvader = getOneObjectAtOffset(0,0,Invader.class); 
        if(Creepinginvader!=null)
you check for an object of Invader.class at (0|0). With
        if (Creepinginvader!=null)  
        {  
            World world;  
            world = getWorld();  
            world.removeObject(Creepinginvader);  
            world.removeObject(this);  
            return;  
        }  
You immediately remove that object from the world and your variable Creepinginvader is now null. With this however
        
        if (Creepinginvader!=null)  
        {  
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();    
            Counter counter = spaceWorld.getCounter();    
            counter.bumpCount();  
        }  
you would increase totalCounter from your counter. But Creepinginvader is null as you deleted it before - bumpCount() will never be called. Here's how you solve it:
       
        Invader Creepinginvader = (Invader) getOneObjectAtOffset(0,0,Invader.class);  
        if (Creepinginvader!=null)  {  
            Counter counter = ((spaceinvaders) getWorld()).getCounter();
            counter.bumpCount();    
            getWorld().removeObject(Creepinginvader);
            getWorld().removeObject(this);
        }  
You have to change it whereever you need to increase the counter when an invader is at a certain position.
danpost danpost

2012/4/5

#
Also, now, the 'return' statement deprives the counter from being advanced. It might be best to re-write your Bullet.class act method to something like this:
public void act()
{
    setLocation(getX() + 30, getY());
    spaceinvaders spi = (spaceinvaders) getWorld();
    Actor invader = getOneIntersectingObject(Invader.class);
    if (invader != null)
    {
        spi.removeObject(invader);
        spi.removeObject(this);
        Counter counter = spi.getCounter();
        counter.bumpCount();
        return;
    }
    if (atWorldEdge()) spi.removeObject(this);
}
The key is getting an early reference to your sub-class of world (before the Bullet is removed from it). What was happening is the bullet was removed from the world, and your reference was not to that specific world, so that specific counter was not being bumped.
danpost danpost

2012/4/5

#
trash1000 wrote...
However, I just noticed your mistake. With
        
        Actor Creepinginvader;  
        Creepinginvader = getOneObjectAtOffset(0,0,Invader.class); 
        if(Creepinginvader!=null)
you check for an object of Invader.class at (0|0). With
        if (Creepinginvader!=null)  
        {  
            World world;  
            world = getWorld();  
            world.removeObject(Creepinginvader);  
            world.removeObject(this);  
            return;  
        }  
You immediately remove that object from the world and your variable Creepinginvader is now null. With this however
        
        if (Creepinginvader!=null)  
        {  
            spaceinvaders spaceWorld = (spaceinvaders) getWorld();    
            Counter counter = spaceWorld.getCounter();    
            counter.bumpCount();  
        }  
you would increase totalCounter from your counter. But Creepinginvader is null as you deleted it before - bumpCount() will never be called.
This is not true. Just because you remove an object from the world does not mean the reference to the object will be 'null'. You can create an object and set it to a reference before adding it to the world (and you are not adding 'null' to the world). You can remove an object and the reference stands, and if you had gotten a reference to the world before removing it, you can add it right back in (that is how I make an object appear over all other objects in the world, so it does not appear to slide underneath another object when moved around).
danpost danpost

2012/4/5

#
I prefer, instead of using 'Greenfoot.stop();', to use the terminal output, with 'System.out.println("Text to output");'. That way I can output specific information to see what is happening. For example
System.out.println("The value of the counter is: " + counter.getCount());
e_e13 e_e13

2012/4/6

#
I've changed all the code as everyone suggested, and now I think I've pin-pointed the problem- bumpCount dosen't continue carrying the totalCount int value. It continues to stay at 1 each time. I don't understand why, but totalCount isn't saving it's number, it is lost after bumpCount is executed. As far as I know, this shouldn't happen since it isn't defined to be zero in the act method. Here is the code for the counter so far:
public class Counter extends Actor
{
    /**
     * Act - do whatever the Counter wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    int totalCount = 0;
    public void bumpCount()
    {
        totalCount = totalCount+ 1;
        System.out.println("The value of the counter is: " + totalCount); 
    }
    public void act() 
    {
        World world;  
        world = getWorld();  
        if (totalCount == 4 && world.getObjects(GameWon.class).isEmpty())  
        {  
            
            world.addObject(new GameWon(), 450, 300);  
        }
        
    }    
}
Thanks all, and Happy Easter
SPower SPower

2012/4/6

#
Maybe you have to change this line:
int totalCount = 0;
to this:
private int totalCount = 0;
After you've done that, you can add the Counter() method, where you set the totalCount to 0:
public Counter()
{
     totalCount = 0;
}
this method is called when you create objects from this class. And than, you can change this line:
private int totalCount = 0;
to this:
private int totalCount;
After all this, the top of your code will looklike this:
public class Counter extends Actor  
{
      private int totalCount;
      
      public Counter()
      {
           totalCount = 0;
      }
I hope this will fix it.
There are more replies on the next page.
1
2
3
4