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

2012/12/31

How to display my hero's life variable on the screen

Minion1 Minion1

2012/12/31

#
Hello everyone. Thanks to your assistance my little "game" is coming along swimmingly, I'm almost read to post it here. I have a concern that is stumping me majorly: How do you display his life variable on the screen? Here's how it's working, the hero has a variable inside of him called "life" that starts with a value of 50. Each time he is hit, his life variable decreases, and if he eats apples and bananas then the life variable is increased by 5 and 20 respectively. Pretty simple. It's working great. But what I would like to do is display this variable on the world so that the player can always see how much life is remaining. I DON'T want to use a counter for this. Is there some way to just display the value of "life"?
Minion1 Minion1

2012/12/31

#
It seems like it would be an easy thing to do. Claim a value from an Actor class, and display it. That's it. But I am stumped. Working on it now..
danpost danpost

2012/12/31

#
Displaying something always requires an image. That means you need a world or actor object to display that image. Drawing the value of 'life' directly on the background image could get messy. Displaying it by drawing it directly on the hero's image could be one solution; but not really the optimal way. Creating a new actor class to display the value is the only other way (and probably the correct way); so, if not a counter, a text object would be the way to go.
import greenfoot.*;
import java.awt.Color;

public void Text extends Actor
{
    public Text(String text)
    {
        updateImage(text);
    }

    public void updateImage(String text)
    {
        setImage(new GreenfootImage(text, 18, Color.black, new Color(0, 0, 0, 0)));
    }
}
One instance of this can be added to the world during world construction. You can hold a reference to the text object in the hero's class and have it set to the object through a method call or through the hero's constructor call; or, if only one instance of text is ever in the world, use 'Actor text = getWorld().getObjects(Text.class).get(0);' to locally get a reference to it, so you can update the image when the life count changes, using:
text.updateImage(""+life);
Minion1 Minion1

2012/12/31

#
Trying this out, thank you..
Minion1 Minion1

2012/12/31

#
That was my thought as well, I already created a new class called "Display" that will be used to display various actor variables on the world.. But I just couldn't seem to find a way to get it going..
Minion1 Minion1

2012/12/31

#
I'm disappointed in myself. I'm so lost I don't even know where to begin asking.. I get that the text needs to be displayed on an image object on the world.. I've created a "Display" class that prepares the same type of image that the Counter class uses.. But while the Counter class only works if you are adding or subtracting values from the displayed number, I want the display class to simply ask for a predetermined value from my Hero class. Here is my Display class code: import greenfoot.*; import java.awt.Color; /**the display class will take values from actor classes and display them on the world*/ public class Display extends Actor { private static final Color textColor = new Color(255, 255, 255); private String text; private int stringLength; private static int value; public Display(String prefix) { text = prefix; stringLength = (text.length() + 2) * 10; setImage(new GreenfootImage(stringLength, 16)); GreenfootImage image = getImage(); image.setColor(textColor); updateImage(); } public void updateImage() { GreenfootImage image = getImage(); image.clear(); image.drawString(text + value, 1, 12); } public void displayValue(int score) { value += score; } public void act() { // Add your action code here. } } (BTW, I have no idea how to post code including number lines) Here is the World constructor's call for the display to be set and the method used to update the display: public CoolDudeWorld() { super(900, 600, 1); sMenu = new StatusMenu(); addObject(sMenu, 50, getHeight() / 2); test = new Test("Life: "); addObject(test, 40, 75); //constructs the elements lifeCounter = new HeroLifeCounter("Life: "); addObject(lifeCounter, 60, 35); lifeDisplay = new Display("Life: "); addObject(lifeDisplay, 60, 55); //adds the characters addObject(new Hero(), getWidth() / 2, getHeight() / 2); inst = new Instructions(); addObject(inst, getWidth() / 2, getHeight() / 2); } public void updateLifeDisplay() { lifeDisplay.displayValue(); lifeDisplay.updateImage(); } I am aware that the udateLifeDisplay is incomplete (wrong parameters and such) but that's just it. I'm not certain how to complete it. I WANT to just do something like this: public void updateLifeDisplay(Hero().life) { lifeDisplay.displayValue(); lifeDisplay.updateImage(); }
Minion1 Minion1

2012/12/31

#
Currently, I was using a counter to keep track of the Hero's life value. Unfortunately, the counter object is a separate object, so the value it's keeping track of is only a "mirror" of the hero's actual life. Sometimes the numbers get off from each other. Rather than deal with two separate objects, I would much rather have a Display object merely fetch the hero's current life variable and display it. That's what I'm shooting for. Do I need to perhaps convert the hero's life to a string first?
Minion1 Minion1

2013/1/1

#
Ah, I believe I fixed the problem. The counter class is at it's core a display anyway right? Instead of sending it numbers to add to the total life score, I'm not sending it the total life score itself. Additonally, if you look at the counter class in the greenfoot asteroids example, you'll see a method called "add()" that has this in it: target += score; value += score; Well, I changed it to be this instead: //target += score; (this wasn't needed) value = score; So now instead of adding the numbers I give it to the total, it just claims the total and displays it. Fuureaakin yay. You have no idea how long I've been trying to fix this. Man, it seems so simple now. Blaaargh.
danpost danpost

2013/1/1

#
To post code using number lines, use the 'code' tag below the 'Post a reply' input box and copy/paste your code in the pop-up input box supplied. If you cannot get that to work, (1) key before pasting your code in the reply box, then (2) paste the code, and finally (3) key after the code. Remove the following from the 'CoolDudeWorld' class code:
//  THIS
test = new Test("Life: ");
addObject(test, 40, 75);

//constructs the elements
lifeCounter = new HeroLifeCounter("Life: ");
addObject(lifeCounter, 60, 35);

// AND THIS
public void updateLifeDisplay()
{
    lifeDisplay.displayValue();
    lifeDisplay.updateImage();
}
Then change the order and modify
// THIS
lifeDisplay = new Display("Life: ");
addObject(lifeDisplay, 60, 55);

//adds the characters
addObject(new Hero(), getWidth() / 2, getHeight() / 2);

// TO
//adds the characters
Hero hero = new Hero();
addObject(hero, getWidth() / 2, getHeight() / 2);

//adds the life text object
lifeDisplay = new Display("Life: ");
lifeDisplay.displayValue(hero.getLifes());
addObject(lifeDisplay, 60, 55);
Then, in the Hero class, add the following method
public int getLifes()
{
    return lifes;
}
Finally, in the Display class, change
// THIS
public void displayValue(int score)
{
    value += score;
}

// TO
public void displayValue(int score)
{
    value+=score;
    updateImage();
}

// AND REMOVE

public void act()
{
    // Add your action code here.
}
You can also remove your 'Test' and 'HeroLifeCounter' classes (unless you still have a need for one or both). EDIT: ignore the code changes if you got it working!
Minion1 Minion1

2013/1/1

#
Oooh. Thank you. I did get it working, but I'm not convinced it's the best way. I will try out your suggestion. Thank you so much for the help. Happy New Year.
You need to login to post a reply.