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

2013/8/11

Power up help?

1
2
alicija alicija

2013/8/11

#
Hello, I am fairly new to Greenfoot, so I don't fully understand it yet. I am designing a Zombie game where the zombie eats brains and has to avoid the people. At random points, a golden brain will spawn. When the zombie eats the golden brain, he gets bigger for around 10 seconds and is then able to eat the people that chase the zombie. After the 10 seconds, the zombie goes back down to normal size. Does anyone know a basic code for this? Or at least just making the zombie get bigger for a certain amount of time when he eats the golden brain and then go back down to his normal size? I have made an image on photoshop of the larger zombie if that is required. Thanks in advance :)
Gevater_Tod4711 Gevater_Tod4711

2013/8/11

#
First your zombie has to notice that he has found the brain. You'll probably know this from some crab games. After eating the brain you need to set the image of the zombie to the greater zombie image (using setImage(new GreenfootImage("bigZombieImage.png")) or however your image is called) and you need to start counting until the 10 seconds are over. To count you could use some code like this:
private int bigZombieCounter = 0;


public void act() {
    //...
    if (bigZombieCounter > 0) {
        bigZombieCounter--;
        if (bigZombieCounter == 0) {
            setImage(new GreenfootImage("smalZombie.png");//probably a different name;
        }
    }
}
Then you just have to set the value of bigZombieCounter to a value greater than 0 (you'll have to try which value needs about 10 seconds). Now your zombie will grow for about 10 seconds. To check whether the zombie can now eat the people you just have to check whether the value of bigZombieCounter is greater than null:
public boolena isAbleToEatPeople() {
    return bigZombieCounter > 0;
}
Using this code the growing of the zombie should work. If you got other questions just ask.
alicija alicija

2013/8/12

#
Thank you for that. Majority of it seems to be working fine, except for a couple of things. When my zombie eats the gold brain, it grows but as soon as I hit the keys to move, it shrinks back down to normal size. And the zombie stays big unless I hit a key to move it. Also, I haven't added the code for it to eat the people yet as I am unsure where to put the code. Here is the code for my zombie. You might be able to see where I am going wrong:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Zombie here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Zombie extends Actor
{
    private int bigZombieCounter = 0; 

    /**
     * Act - do whatever the Zombie wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        keyboard(); 
        eat();

        Actor brain;
        brain = getOneObjectAtOffset(0, 0, Brain.class);
        if (brain != null)
        {
            World world;
            world = getWorld();
            world.removeObject(brain);

            getWorld().addObject(new Brain(), Greenfoot.getRandomNumber(getWorld().getWidth()), Greenfoot.getRandomNumber(getWorld().getHeight()));  

        }  
    }

    public boolean canSee()
    {
        Actor goldBrain = getOneObjectAtOffset(0, 0, goldBrain.class);
        return goldBrain != null;        
    }

    public void eat()
    {
        Actor goldBrain = getOneObjectAtOffset(0, 0, goldBrain.class);
        if(goldBrain != null) {
            getWorld().removeObject(goldBrain);

            setImage(new GreenfootImage("zombieBig.png"));
        }

        if (bigZombieCounter > 10) {  
            bigZombieCounter--;  
            if (bigZombieCounter == 10) {  
                setImage(new GreenfootImage("zombier.png"));  
            }  
        }  
    } 

    public void keyboard()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            leftControl();
        }

        if(Greenfoot.isKeyDown("right"))
        {
            rightControl();
        }

        if(Greenfoot.isKeyDown("up"))
        {
            upControl();
        }

        if(Greenfoot.isKeyDown("down"))
        {
            downControl();
        }
    }

    public void leftControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x-5,y);
        setImage("zombieleft.png");
    }

    public void rightControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x+5,y);
        setImage("zombieright.png");
    }

    public void upControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x,y-5);
    }

    public void downControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x,y+5);
    }
}
danpost danpost

2013/8/12

#
Since you have a left and right image for the small zombie, you should probably add an instance field to the class to hold the direction currently facing; then in the rightControl and leftControl methods use an if statement to only set the image when the bigZombieCounter is 10 (strange number to end at). Also, I do not see where the bigZombieCounter is set to any higher number around where the zombieBig image is set. For 10 seconds, you should probably set it to between 500 and 600 when a gold brain is eaten. Sidenote: your canSee method can be removed (it is not being used). Finally, when the bigZombieCounter does decrement down to 10, you should use the field holding the direction facing to determine which image to set (left or right).
alicija alicija

2013/8/12

#
Thanks for the reply @danpost. As I am new to greenfoot, I don't fully understand it and I am unsure as to how I code what you explained. Could you please help me out? Thank you :)
Gevater_Tod4711 Gevater_Tod4711

2013/8/12

#
First you should add this line: bigZombieCounter = 500; at line 46 of your code. So the zombie will be small again after about 10 seconds. The problem that your zombie turns back to a small zombie when you press a moving key is because you set the image of the zombie when you move it (lines 86, 94). You should try not to set the image of the zombie but to rotate it's current image: So if the starting image of your zombie looks up you should use: setRotation(270); in line 86 instead of setImage("zombieLeft"); and setRotation(90) instead of setImage("zombieRight") in line 94).
danpost danpost

2013/8/12

#
Declare a second instance field (line 11 declares an instance int field called bigZombieCounter), this one can be either a boolean or another int (I am going to use an boolean called facingLeft). In the leftControl and rightControl methods, set the value of this field appropriately. Then, also in those methods, change the image only if the bigZombieCounter is not decrementing (or if it is at whatever value you stop it at).
// add this instance field
private boolean facingLeft; // '= false' is by default optional
// one of the methods
public void leftControl()
{
    int x = getX();
    int y = getY();
    setLocation(x-5, y);
    facingLeft = true;
    if (bigZombieCounter == 10) setImage("zombieleft.png");
}
// lines 52 to 54 of your code post should then be
if (bigZombieCounter == 10)
{
    if (facingLeft) setImage("zombieleft.png");
    else setImage("zombieright.png");
}
It is best to have counters, such as bigZomieCounter, terminate at zero. This facilitates ease and consistency in coding. Also, unless you initialize the value of the counter at the terminal value, bugs are more apt to occur (the default value for all numberic fields is zero).
alicija alicija

2013/8/13

#
Thank you both for your replies. Most of it seems to be working, except before I eat the gold brain, my zombie isn't turning to face the other way when I hit the keys. It stays facing the right. However, once the zombie eats the gold brain and returns back to his normal size, the zombie's image flips like it should when I hit the keys. Could you possibly help me so that the zombie's image flips before he eats the gold brain as well? Also, is there a code to flip the zombie's image when it is large? I have an image flipped if that needs to be added anywhere. Here is my new code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Zombie here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Zombie extends Actor
{
    private boolean facingLeft;
    private boolean facingRight;
    private int bigZombieCounter = 0; 

    /**
     * Act - do whatever the Zombie wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        keyboard(); 
        eat();
        spawn();
    }

    public void spawn()
    {
        Actor brain;
        brain = getOneObjectAtOffset(0, 0, Brain.class);
        if (brain != null)
        {
            World world;
            world = getWorld();
            world.removeObject(brain);

            getWorld().addObject(new Brain(), Greenfoot.getRandomNumber(getWorld().getWidth()), Greenfoot.getRandomNumber(getWorld().getHeight()));  

        }  
    }

    public void eat()
    {
        Actor goldBrain = getOneObjectAtOffset(0, 0, goldBrain.class);
        if(goldBrain != null) 
        {
            getWorld().removeObject(goldBrain);
            bigZombieCounter = 500; 
            setImage(new GreenfootImage("zombieBig.png"));
        }

        if (bigZombieCounter > 10) 
        {  
            bigZombieCounter--;  
            if (bigZombieCounter == 10) 
            {  
                if (facingLeft) setImage("zombieleft.png");
                else setImage("zombieright.png");
            }  

        } 
    }

    public void keyboard()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            leftControl();
        }

        if(Greenfoot.isKeyDown("right"))
        {
            rightControl();
        }

        if(Greenfoot.isKeyDown("up"))
        {
            upControl();
        }

        if(Greenfoot.isKeyDown("down"))
        {
            downControl();
        }
    }

    public void leftControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x-5,y);
        facingLeft = true;
        if (bigZombieCounter == 10) setImage("zombieleft.png");
    }

    public void rightControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x+5,y);
        facingRight = true;
        if (bigZombieCounter == 10) setImage("zombieright.png");
    }

    public void upControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x,y-5);
    }

    public void downControl()
    {
        int x = getX();
        int y = getY();
        setLocation(x,y+5);
    }
}
danpost danpost

2013/8/13

#
Change line 13 to:
private int bigZombieCounter = 10;
Note: you should rather change all checks and conditions that say 10 to zero instead (lines 51, 54, 92, and 101). I noticed you added two booleans: facingRight and facingLeft, where you should only have one; its state, true or false, will determine the direction facing whether it is right or left. In leftControl, set facingLeft to true; in rightControl, set facingLeft to false.
alicija alicija

2013/8/14

#
Alright, thank you for that! That's all working fine now! Just a couple more things though: First, how do I make it so that when the big zombie image flips when I hit the arrow keys. Right now, the big zombie just faces the right. I have made the image on photoshop of the flipped zombie image if that helps? What code do I use to flip the big zombie? Also, how do I make it so that when my zombie is bigger, he is able to eat the people that chase him? When he is back to his normal smaller size, the people can eat the zombie, but when the zombie is big, I want it so that the zombie can then eat the people for the 10 seconds he is big for, if that makes sense. Thanks
danpost danpost

2013/8/14

#
You just have to expand your code to account for two big zombie images instead of one. This means line 48 will be:
if (facingLeft) setImage("zombieBigleft.png"); else setImage("zombieBig.png");
and lines 92 and 101 will have 'else' parts for the big left and right images;
// in 'leftControl' method (line 92)
if (bigZombieCounter == 10) setImage("zombieleft.png");
else setImage("zombieBigleft.png");
... similar for 'rightControl' using 'zombieBig.png'.
alicija alicija

2013/8/14

#
Alright, that's all fine now. Thank you heaps! :) Final thing, how do I make it so that only when the zombie is big, he is able to eat the people that are chasing him? When the zombie is his normal size, the people are able to eat the zombie but I want it so that once the zombie has eaten the golden brain, for the 10 seconds that he is big, he can eat people.
danpost danpost

2013/8/14

#
The zombie eating people part is the easy part. Just add to the act method code that puts the condition that the counter is not 10 and intersects person to remove person. The people eating zombie part is not as easy. First, if intersecting a zombie, then if either the image of the zombie is normal size or the value of its counter is ten, then remove zombie. Getting the value of the counter of a zombie is a little harder than getting the size of its image. If having trouble coding, please do not hesitate to reply.
danpost danpost

2013/8/14

#
It might be easier to put both parts in the zombie class (although, there may be good reason to code it as I had suggested above). To do so: add to the zombie act method, if intersecting person, then if counter is 10 remove self else remove person.
alicija alicija

2013/8/14

#
How would I code that and where about's in my code would I put it? Sorry for all the questions by the way.
There are more replies on the next page.
1
2