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

2017/3/5

Points counter?

1
2
3
OKNEM OKNEM

2017/3/5

#
Hello, I'm fairly new to Greenfoot and Java, and would like to know how to do some pretty specific stuff. Episode 16 of mik's tutes explains a counter, with direct contact from the object eating the enemy. In my game, the object shoots another object, that eats the enemy. Mik's tutorial showed that you need to create something like Rocket rocket = new Rocket(points) for this to work. However, my "Boop" is not spawned in the world, it is spawned in the Rocket class. I don't know how the Rocket class can communicate with the Points class without going through the World, so I will need some help. Here is the code to summon the Boop :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
     * Firing the bullet. If there is no delay, create a new Boop facing the rotation of the ship.
     * Reset the delay timer, too. Speed & movement of bullet is in Boop class.
     */
    public void fire()
    {
        if(!delay())
        {
            if (Greenfoot.isKeyDown("space"))
            {
                Actor b00p = new Boop(getRotation());
                getWorld().addObject(b00p, getX(), getY());
                b00p.setRotation(getRotation());
                delayTimer = 20;
            }
        }
    }
And I think that's all you need? Please comment if you need more. Thanks! :)
danpost danpost

2017/3/5

#
It looks like there is a little redundancy in setting the rotation of the b00p object; other than that, the method looks okay. However, there is nothing in the code given that remotely resembles anything dealing with a counter (one that counts enemy hits). Where is that attempted code?
OKNEM OKNEM

2017/3/6

#
I used some of the content from this website, but I can't get it to work. Everything seems fine, but the counter isn't moving. I renamed "MyWorld" "Space" and "Points" "Counter" for simplicity. Here's what's in Counter, I used mik's from Tutorial 16:
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
78
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
 
/**
 * A simple counter with graphical representation as an actor on screen.
 *
 * @author mik
 * @version 1.0
 */
public class Counter extends Actor
{
    private static final Color transparent = new Color(0,0,0,0);
    private GreenfootImage background;
    private int target;
    private int value;
 
    /**
     * Create a new counter, initialised to 0.
     */
    public Counter()
    {
        background = getImage();  // get image from class
        value = 0;
        target = 0;
        updateImage();
    }
 
    public void bumpCount(int amount)
    {
        value += amount;
    }
     
    /**
     * Animate the display to count up (or down) to the current target value.
     */
    public void act()
    {
        if (value < target) {
            value++;
            updateImage();
        }
        else if (value > target) {
            value--;
            updateImage();
        }
    }
 
    /**
     * Add a new score to the current counter value.
     */
    public void add(int score)
    {
        target += score;
    }
 
    /**
     * Set a new counter value.
     */
    public void setValue(int newValue)
    {
        target = newValue;
        value = newValue;
        updateImage();
    }
 
    /**
     * Update the image on screen to show the current value.
     */
    private void updateImage()
    {
        GreenfootImage image = new GreenfootImage(background);
        GreenfootImage text = new GreenfootImage("" + value, 22, Color.BLACK, transparent);
        image.drawImage(text, (image.getWidth()-text.getWidth())/2,
            (image.getHeight()-text.getHeight())/2);
        setImage(image);
    }
 
}
This is Space:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import greenfoot.*;  // (Game, MyWorld, background.png)
 
/**
 * My World! :)
 */
public class Space extends World
{
    private Counter theCounter;
    /**
     * Default constructor that prepares the world.
     */
    public Space()
    {   
        super(800, 600, 1);
        Rocket rocket = new Rocket();
        addObject(new Rocket(270),410,510);
        theCounter = new Counter();
        addObject(theCounter, 73, 40);
    }
     
    public Counter getCounter()
    {
        return theCounter;
    }
And the Boop:
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
import greenfoot.*;  // Game, Boop, boop.png
 
/**
 * Boop is what the Rocket fires. Basically, the bullets.
 */
public class Boop extends Thing
{
    // Setting the speed of the Boop, and the direction it fires.
    private int direction, speed = 10;
    private int points = 0;
    /**
     * Setting the speed and direction.
     */
    public Boop(int dir)
    {
        speed = 10;
        direction = dir;
    }
 
    /**
     * Executes the move and hitAsteroid methods.
     */
    public void act()
    {
        move();
        hit();
    }
 
    /**
     * Moves the Boop forwards at the set speed, which is 15.
     */
    public void move()
    {
        move(speed);
    }
 
    /**
     * This attempts to eat an Asteroid. If it does, it gets rid of the Asteroid
     * and the Boop. If it doesn't, it sees if it's at the edge of the world.
     */
    public void hit()
    {
 
        if(canSee(Asteroid.class))
        {
            Space spaceWorld = (Space) getWorld();
            Counter counter = spaceWorld.getCounter();
            counter.bumpCount(1);
            eat(Asteroid.class);
            getWorld().removeObject(this);
        }
        else
        {
            if(canSee(Barrel.class))
            {
                Space spaceWorld = (Space) getWorld();
                Counter counter = spaceWorld.getCounter();
                counter.bumpCount(3);
                eat(Barrel.class);
                getWorld().removeObject(this);
            }
            else
            {
                if(atWorldEdge())
                {
                    getWorld().removeObject(this);
                }
            }
        }
 
    }
}
danpost danpost

2017/3/6

#
It looks like you amended the Counter class by adding the 'bumpCount' method. It adjusts the 'value' field, but the value of 'target' remains at zero. So, the value quickly (within a few act cycles) returns to zero. Add the following lines after the one line you already have in the 'bumpCount' method:
1
2
target = value;
updateImage();
OKNEM OKNEM

2017/3/6

#
Alright, that fixed it. Thanks heaps. One more quick question though: Is there a method or anything that could say, "If an object's image is this image, change it to another image."? I want to change the picture of the health bar of the Rocket when it is hit by the Asteroids. So something like this:
1
2
3
4
5
6
7
if(canSee(Rocket.class))
{
     if(getImage(Health.class) == "health5.png")
     {
           Health.class.setImage("health4.png");
     }
}
Obviously, this isn't right, and I need a link to Space here. Any way how?
OKNEM OKNEM

2017/3/6

#
I had a look at this website, and it said to reference the images. But I want to change the image of the Health bar from the Asteroid. Any way?
danpost danpost

2017/3/6

#
OKNEM wrote...
I had a look at this website, and it said to reference the images. But I want to change the image of the Health bar from the Asteroid. Any way?
Since I do not see any Health object being added from your Space class, I will presume that the Rocket is adding it to the world. That means you need a reference to the Rocket object -- not to the Space object (the world). So:
1
if (canSee(Rocket.class))
can be replaced with Rocket rocket = (Rocket)getOneIntersectingObject(Rocket.class); if (rocket != null) Then, hopefully, you will have access to the Health object of the Rocket object. Maybe just having access to the value of the health of the Rocket object is enough (it would depend on whether the int field that holds the amount of health is an instance field in the Rocket class or in the Health class). For further insights, show codes (Rocket and Health classes).
OKNEM OKNEM

2017/3/6

#
Oh, I haven't updated my Space code. This is what's happening:
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
import greenfoot.*;  // (Game, MyWorld, background.png)
 
/**
 * My World! :)
 */
public class Space extends World
{
    private Counter theCounter;
    /**
     * Default constructor that prepares the world.
     */
    public Space()
    {   
        super(800, 600, 1);
        prepare();
    }
 
    public Counter getCounter()
    {
        return theCounter;
    }
    // Checks the width and height of the Rocket.
    public int x = (new Rocket()).getImage().getWidth();
    public int y = (new Rocket()).getImage().getHeight();
 
    // Sets the delay for the Asteroid at 0.
    private int delayAsteroid=0;
    /**
     * Checks the delay of the Asteroid class, and if it's at zero, adds another Asteroid at a
     * an x coordinate of 40 degrees, and a random y coordinate.
     */
    public void act()
    {
        if (delayAsteroid>0 && --delayAsteroid>0)
        {
            return;
        }
        addObject(new Asteroid(), 30, (Greenfoot.getRandomNumber(570)));
        delayAsteroid = (Greenfoot.getRandomNumber(60));
         
    }
    public void prepare()
    {
        Health health = new Health();
        addObject(health,690,34);
        Rocket rocket = new Rocket();
        addObject(new Rocket(270),410,510);
        theCounter = new Counter();
        addObject(theCounter, 76, 30);
    }
}
There's nothing in Health at the moment, I just want it to change to health4 if it's health5. I presume that the changing image will come directly from when the Asteroid hits the Rocket, so that it needs to be in Asteroid? Any difference to the solution now? Thanks.
danpost danpost

2017/3/6

#
Since you do not have anything yet, maybe you can check out my Value Display Tutorial scenario. It should give you insights on how to continue. I suggest looking it totally over to get as much general information out of it as you can. It will help you out in the long run. You will probably still need help as far as the imaging; but you can return here when you have something more.
OKNEM OKNEM

2017/3/6

#
I've literally spent the last ten minutes trying to open the scenario on Chrome, Internet Explorer and Edge, with no luck. Tried troubleshooting through the Microsoft and Java websites to no avail. Could you explain how it works, generally in a succinct way? Thanks.
danpost danpost

2017/3/6

#
OKNEM wrote...
I've literally spent the last ten minutes trying to open the scenario on Chrome, Internet Explorer and Edge, with no luck. Tried troubleshooting through the Microsoft and Java websites to no avail. Could you explain how it works, generally in a succinct way? Thanks.
Use IE. Add 'http://www.greenfoot.org/' to your java control panel's security tab site exceptions list, set security level to 'High' (not 'Very High') and check the 'Enable Java content in the browser' checkbox.
OKNEM OKNEM

2017/3/6

#
This is what it says when I open the scenario webpage. I tried turning the Protected Mode off altogether but it still won't run. "More Info" takes me to the Microsoft help page, "OK" doesn't run the scenario, and "X" doesn't run it either.
OKNEM OKNEM

2017/3/6

#
I got it working. The scenario's open, I'll have a look now.
OKNEM OKNEM

2017/3/6

#
I didn't really get much out of that, I already knew the most of it. The text part I know, but what I do need to know is how to detect whether an object is a specific image.
OKNEM OKNEM

2017/3/6

#
I think I need to do something like this:
1
2
3
private GreenfootImage health5 = new GreenfootImage("health5.png")
 
private GreenfootImage health4 = new GreenfootImage("health4.png")
And...
1
2
3
4
5
6
7
if(canSee(Rocket.class))
{
     if(getImage() == health5)
     {
          this.setImage(health4);
     }
}
...although this turns the Asteroid into the health4 picture, because it's not connected to the Health class. Any way around this?
There are more replies on the next page.
1
2
3