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

2014/11/17

How to end the game when a score reaches a certain number?

1
2
Czaherin Czaherin

2014/11/17

#
Hi everyone, I'm at a complete loss here. I've been researching this for a couple hours and I can't find anything that is helping me solve this issue. I am making a game where a hunter shoots birds, when the hunter has shot a certain number of birds the game is supposed to end. I cannot get this to work at all. I have a working scoreboard and score counter, but I cannot get the game to end properly. Any help would be greatly appreciated, thanks.
EnderPicture EnderPicture

2014/11/17

#
How do you want your game to end?
danpost danpost

2014/11/17

#
Please post the code you have tried (use the 'code' link below the reply box to insert code into your post).
Czaherin Czaherin

2014/11/17

#
We have to shoot 50 birds, when 1/4 of them are killed or 3 minutes have elapsed, the game is supposed to end.
danpost danpost

2014/11/17

#
What code do you have that registers a bird being shot?
Czaherin Czaherin

2014/11/17

#
Hunter class
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
79
80
81
82
83
84
85
86
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 * Write a description of class Hunter here.
 *
 * @author (Ryan Sepesy)
 * @version (Version 1.0)
 */
public class Hunter extends SmoothActor
{
    private static final int gunReloadTime = 50;
    private int reloadDelayCount;
    private GreenfootImage hunter = new GreenfootImage ("hunter.png");
     
 
    /**
     * initialize the hunter
     */
    public Hunter()
    {
        reloadDelayCount = 0;
    }
     
    /**
     * This is what where the hunter does everything specified.
     */
    public void act()
    {
        checkKeys();
        checkIntersect();
        reloadDelayCount++;
    }   
     
    /**
     * this is where we check what keys are pressed, and respond accordingly.
     */
    private void checkKeys()
    {
        if (Greenfoot.isKeyDown("left"))
        {
            setRotation(getRotation() - -10);
        }
        if (Greenfoot.isKeyDown("right"))
        {
            setRotation(getRotation() - 10);
        }
        if (Greenfoot.isKeyDown("up"))
        {
            move(3);
        }
        if (Greenfoot.isKeyDown("down"))
        {
            move(-3);
        }
        if (Greenfoot.isKeyDown("space"))
        {
            fire();
        }
    }
     
     /**
     * Fire a bullet if the gun is ready.
     */
    private void fire()
    {
          if (reloadDelayCount >= gunReloadTime)
          {
              Bullet bullet = new Bullet (new Vector(getRotation(),15), getRotation());
              getWorld().addObject (bullet, getX(), getY());
              bullet.move();
              reloadDelayCount = 0;
          }
    }
     
    /**
     * check if our hunter is intersecting a tree. If true, stop him from moving.
     */
    public void checkIntersect()
    {
        if (canSee(Tree.class))
        {
            move(-3);
        }
    }
     
}
World Class
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
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)
import java.awt.Color;
 
/**
 * A world for the boids.
 *
 * @author Poul Henriksen
 * @version 2.0
 */
public class Sky extends World
{
    /**
     * Constructor for objects of class Sky.
     *
     */
    public Counter scoreCounter;
    public Sky()
    {   
        super(800, 600, 1);
        getBackground().setColor(new Color(220,220,100));
         
        getBackground().fill();
        populateTrees(100);
        populateBoids(50);
         
        scoreCounter = new Counter("Score: ");
        addObject(scoreCounter, 790, 590);
    }
     
    public void populateBoids(int number) {
        for(int i=0; i < number; i++) {           
             int x = (int) (Math.random() * getWidth());         
             int y = (int) (Math.random() * getHeight());
             Boid b = new Boid();
             addObject(b, x, y);
        }
    }
     
    public void populateTrees(int number) {
        // Size of block in pixels
        int blockSize = 70;
        // Trees per block
        int treesPrBlock = 10;
        // How close together trees in a block are. Higher number, the closer they are.
        int blockCoherence = 1;
        for(int block = 0; block < number / treesPrBlock; block++) {          
             int x = Greenfoot.getRandomNumber(getWidth()/blockSize) * blockSize;  
             int y = Greenfoot.getRandomNumber(getHeight()/blockSize) * blockSize; 
             for(int t = 0; t < treesPrBlock; t++) {
                 int dx = Greenfoot.getRandomNumber(blockSize/blockCoherence);
                 int dy = Greenfoot.getRandomNumber(blockSize/blockCoherence);
                 Tree b = new Tree();
                 addObject(b, x  + dx, y + dy);               
             }   
        }       
    }  
     
    public void countScore()
    {
        scoreCounter.add(1);
    }
     
    public void gameOver()
    {
        ScoreBoard board = new ScoreBoard(scoreCounter.getValue());
        addObject(board, getWidth()/2, getHeight()/2);
    }
}
Bird code
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)
import java.util.*;
 
/**
 * A boid is an object that is part of a flock.
 * The boid follows a few simple rules that gives emergent behaviour when lots of boids are placed in the world.
 *
 * @author Poul Henriksen
 * @version 2.0
 */
public class Boid extends SmoothActor
{
    /** Distance the wall-force will start working from.  */
    private final static int WALL_DIST = 50;   
    /** The size of wall force when it is at max. */
    private final static int WALL_FORCE = 200;
     
    /**  Maximum speed of the boid. */
    private final static int MAX_SPEED = 75;
    /**  Minimum speed of the boid. */
    private final static int MIN_SPEED = 25;
    /** The speed is divided by this. */
    private final static int SPEED_DIVIDER = 15;
      
    /** Distance from which repulsion from other objects start working.*/
    private final static int REPULSE_DIST = 40;  
    /** Distance from which alignment with other boids start working. */
    private final static int ALIGN_DIST = 150;   
    /** Distance from which attraction to other boids start working. */
    private final static int ATTRACT_DIST = 150;
     
    /**
     * Creates a new boid with minimum speed in a random direction.
     */
    public Boid()
    {
        setMaximumSpeed(MAX_SPEED);
        setMinimumSpeed(MIN_SPEED);
        setSpeedDivider(SPEED_DIVIDER);
         
        Vector vel = new Vector();
        vel.setDirection((Math.random())*360);
        vel.setLength(MIN_SPEED);
        setVelocity(vel);
    }
     
    /**
     * Flock!
     */
    public void act()
    {     
        acc();
        super.act();
    }   
     
    /**
     * Calculate accelaration by appling the boid rules
     */
    private void acc() {
        Vector acc = new Vector(0,0);
        acc.add(getFlockAttraction(ATTRACT_DIST).divide(7.5));    
        acc.add(getFlockRepulsion(REPULSE_DIST).multiply(1));
        acc.add(getFlockAlignment(ALIGN_DIST).divide(8));
        acc.add(getWallForce());
        setAccelaration(acc);
    }
     
    /**
     * Get the size of the wall force on this boid. Will make the boid avoid the world boundaries.
     */   
    public Vector getWallForce() {
        Vector location = getLocation();
        //Special border repulse rules:
        Vector wallForce = new Vector(0,0);
        if(location.getX() <= WALL_DIST) {
            double distFactor = (WALL_DIST - location.getX()) / WALL_DIST;
            wallForce.add(new Vector(WALL_FORCE * distFactor, 0));
        }
        if( (getWorld().getWidth() - location.getX()) <= WALL_DIST) {
            double distFactor = (WALL_DIST - (getWorld().getWidth() - location.getX())) / WALL_DIST;
            wallForce.subtract(new Vector(WALL_FORCE * distFactor, 0));
        }
        if(location.getY() <= WALL_DIST) {
            double distFactor = (WALL_DIST - location.getY()) / WALL_DIST;
            wallForce.add(new Vector(0, WALL_FORCE * distFactor));
        }
        if(getWorld().getHeight() - location.getY() <=  WALL_DIST) {
            double distFactor = (WALL_DIST - (getWorld().getHeight() - location.getY())) / WALL_DIST;
            wallForce.subtract(new Vector(0, WALL_FORCE * distFactor));
        }
        return wallForce;
    }
     
    /**
     * Get the other objects that are within the given distance.
     */
    private List getNeighbours(int distance, Class cls) {
        return getObjectsInRange(distance, cls);
    }
     
    /**
     * Get the center of all the boids within the given distance.
     * That is, the average of all the positions of the other boids.
     */
    public Vector getCentreOfMass(int distance) {
        List neighbours = getNeighbours(distance, Boid.class);
        //add me
        neighbours.add(this);
        Vector centre = new Vector();
        for(Object o : neighbours) {
            Boid b = (Boid) o;
            centre.add(b.getLocation());
        }
        return centre.divide(neighbours.size());
    }
 
    /**
     * Get the attraction from the other boids within the given distance.
     */
    public Vector getFlockAttraction(int distance) {
        Vector com = getCentreOfMass(distance);
        //distance to the centre of mass
        Vector distCom = getCentreOfMass(distance).subtract(getLocation());
        return distCom;       
    }
     
    /**
     * Get the repulsion from the other boids within the given distance.
     */
    public Vector getFlockRepulsion(int distance) {
        Vector repulse = new Vector();
        List neighbours = getNeighbours(distance, SmoothActor.class);
        for(Object o : neighbours) {           
            SmoothActor other = (SmoothActor) o;
            //dist to other actor
            Vector dist = getLocation().subtract(other.getLocation());
            if(dist.getLength() > distance) {
                // Make sure we are looking at the logical distance.
                continue;
            }
            repulse.add(dist.setLength(distance - dist.getLength()));
        }
        return repulse;       
    }
     
    /**
     * Get the average velocity of all boids within the given distance.
     */
    private Vector getAverageVelocity(int distance) {
        List neighbours = getNeighbours(distance, Boid.class);
        //add me
        neighbours.add(this);
        Vector avg = new Vector();
        for(Object o : neighbours) {
            Boid b = (Boid) o;
            avg.add(b.getVelocity());
        }
        return avg.divide(neighbours.size());
    }
     
    /**
     * Get the relative direction this boid should be facing to match the average direction of the flock.
     */
    private Vector getFlockAlignment(int distance) {
        Vector avgVel = getAverageVelocity(distance);
        avgVel.subtract(getVelocity());
        return avgVel;
    }
     
    public void hit()
    {
        ((Sky)getWorld()).countScore();
        getWorld().removeObject(this);
    }
}
Dr_Diabetes Dr_Diabetes

2014/11/17

#
Ryan, we are in the same class =) What I did was create a counter class that extends Actor and used the code:
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
79
80
81
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color;
import java.awt.Graphics;
 
//This is how counting systems are made =)
 
public class Counter extends Actor
{
    private static final Color textColor=new Color (255,255,255);
    private int value = 0;
    private int target = 0;
    private String text;
    private int stringLength;
     
    public Counter()
    {
        this("");
    }
     
    public Counter(String prefix)
    {
        this(prefix, 0);
    }
     
    public Counter(String prefix,int value)
    {
        this.value=value;
        text = prefix;
        stringLength = (text.length()+2)*10;
         
        setImage(new GreenfootImage (stringLength, 16));
        GreenfootImage image = getImage();
        image.setColor(textColor);
        updateImage();
    }
     
    public void updateImage()
    { //this is where images are born from
        GreenfootImage image = getImage();
        image.clear();
        image.drawString(text+value,1,12);
    }
     
    public void add(int score)
    {
        target += score;
    }
     
    public int getValue()
    {
        return value;
    }
     
    public void act()
    {
        if(value < target)
        {
            value++;
            updateImage();
        }
        else if (value>target)
        {
            value--;
            updateImage();
        }
        endGame();
    }
     
    public void killCount()
    {
        value++;
        updateImage();
    }
     
    public void endGame()
    {
        if (target==13)
        {
            Greenfoot.stop();
        }
    }
I just havent figured out a way to make the final scoreboard
Dr_Diabetes Dr_Diabetes

2014/11/17

#
25% of 50 = 12.5 so I rounded up to 13
Czaherin Czaherin

2014/11/17

#
I have a counter class as well, but I did not try to end the game through that, so I'll try changing up my code to try that. I'll let you know how that goes!
Czaherin Czaherin

2014/11/17

#
Also I think yours is not working because of the greenfoot.stop. You don't want to stop the program entirely, just have the scoreboard display.
danpost danpost

2014/11/17

#
If there is a 'get' method in your Counter class to get the current value, then your 'hit' method in the Boid class should start with:
1
2
3
4
5
6
7
8
9
public void hit()
{
    ((Sky)getWorld()).countScore();
    if (((Sky)getWorld()).scoreCounter.getValue() > 50*1/4)
    {
        // code for game won
    }
    getWorld().removeObject(this);
}
For the 3 minute timer, that would go in your Sky class using the act method in that class to run the timer. EDIT: I did not see the last 4 posts while I wrote this.
Czaherin Czaherin

2014/11/17

#
Woo! I got it working! Thanks for your help everyone!
Dr_Diabetes Dr_Diabetes

2014/11/17

#
So Danpost, with using code lines 75-81 of the code I posted. How would I display a scoreboard instead of calling greenfoot.stop? When I plug in sky.scoreboard() it tells me that I can't call a nonstatic method from a static method?
Dr_Diabetes Dr_Diabetes

2014/11/17

#
Here's what I'm trying to do. its sky.gameOver();
1
2
3
4
5
6
7
8
9
public void hit()
    {
        ((Sky)getWorld()).getScoreCounter();
        if (((Sky)getWorld()).scoreCounter.getValue()>(50*1/4))
        {
           Sky.gameOver();
        }
    }
}
Dr_Diabetes Dr_Diabetes

2014/11/17

#
It highlights .gameOver and says "non-static method gameOver() cannot be referrenced from a static context:"
There are more replies on the next page.
1
2