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

2017/4/26

Help with storing values into an Array of an object to be used by another class

1
2
Asiantree Asiantree

2017/4/26

#
Hello all. I need some help with storing values into an array of a certain class that is called "BallInfo" in order to spawn in a "Ball" object. Here is the constructor for the Ball object:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public Ball(BallInfo bi)
    {
        ballData = bi;
 
        // build an image for this ball.
        GreenfootImage img = new GreenfootImage(DIAMETER, DIAMETER);
         
        // draw an appropriately colored circle in the image
        img.setColor(bi.getColor());
        img.fillOval(0,0,DIAMETER,DIAMETER);
         
        // use the image just drawn as this ball's image
        setImage(img);
         
   
        this.ySpeed = 0.05;       
    }
I need to use values read in by a file to store into a BallInfo array to be used for the construction of a new Ball. The values read in by the file contain the red, green and blue values of a given Ball respectively. Here is the code inside the World class for reading in the values to spawn in a BallInfo object:
1
2
3
4
5
6
7
8
9
10
int Y = 35;
        int red, green, blue;
        while(fReader.hasNext())
        {
            red = fReader.nextInt();
            green = fReader.nextInt();
            blue = fReader.nextInt();
            addObject(new BallInfo(red, green, blue), 85, Y);
            Y += 12;
        }
So what I need help with is taking the values from the file being read in to spawn a BallInfo object and storing those values into a BallInfo array and then using that array to spawn in a new ball(s). Here is the structure of the construction of a Ball that I am trying to explain:
1
addObject(new Ball(ballInfo[]), x value, y value);
I hope I explained it somewhat thoroughly. Thanks!
danpost danpost

2017/4/27

#
Asiantree wrote...
I need to use values read in by a file to store into a BallInfo array to be used for the construction of a new Ball. The values read in by the file contain the red, green and blue values of a given Ball respectively.
I think what you mean is that you 'need to use the values stored in a BallInfo object for constructing a new Ball object'.
So what I need help with is taking the values from the file being read in to spawn a BallInfo object and storing those values into a BallInfo array and then using that array to spawn in a new ball(s). Here is the structure of the construction of a Ball that I am trying to explain:
1
addObject(new Ball(ballInfo[]), x value, y value);
You do not want the entire array of BallInfo objects going to the Ball constructor -- only a randomly chosen one of them. The only chosen will have thee color part values (or a Color object created from those values) stored within it. That will be where the new ball will get its color from. Please show your current code for the BallInfo class.
Asiantree Asiantree

2017/4/27

#
Okay, so I actually got all of the Balls to spawn in based on the values read in from the file. Here is the code that is located in my 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
public void spawnBallInfos()
    {
        if (Greenfoot.isKeyDown("l"))
        {
            FileDialog fd = null;
            fd = new FileDialog(fd, "Pick a file" , FileDialog.LOAD);
            fd.setVisible(true);
         
            String fname = fd.getDirectory() + fd.getFile();
         
            File file = new File(fname);
         
            Scanner fReader = null;
        try
        {
            fReader = new Scanner(file);
        }
        catch(FileNotFoundException fne)
        {
            System.out.println(fne);
            return;
        }
        int Y = 35;
        int red = 0;
        int green = 0;
        int blue = 0;
        int X = 80; // I also need help spawning the balls at a random x location along the 0 y axis
        while(fReader.hasNext())
        {
            red = fReader.nextInt();
            green = fReader.nextInt();
            blue = fReader.nextInt();
            addObject(new BallInfo(red, green, blue), 85, Y);
            Y += 12;
            info = new BallInfo(red, green, blue); // info is a private variable of the BallInfo class
            addObject(new Ball(info), X, 0);
            X += 40;
        }
       }
    }
Now I am having trouble spawning them in as they are being read from the file. They all spawn in at one time and I need them to spawn in one at a time and keep spawning in until I hit the stop button. But here is the BallInfo class if you would like to see what components make up the BallInfo 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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public class BallInfo extends Actor
{
    private Color ballColor;  // color of the balls being summarized
    private int totalCount;   // number of balls of this color ever seen in the world
    private int caughtCount;  // number of balls of this color ever "caught"
 
    /**
     * constructor for color and stats information about a ball type.
     * @param redValue the amount of red (0-255) in the RGB color to use
     * @param greenValue the amount of green (0-255) in the RGB color to use
     * @param blueValue the amount of blue (0-255) in the RGB color to use
     */
    public BallInfo(int redValue, int greenValue, int blueValue)
    {
        // initially, all counts will be zero.
        totalCount=0;
        caughtCount=0;
         
        // use specified color to create (redraw) image
        ballColor = new Color(redValue,greenValue,blueValue);
        redraw();
    }
     
    // private method to redraw the stats image.
    private void redraw(Color col)
    {
        // build a new image for this object
        GreenfootImage img = new GreenfootImage(150,12);
         
        // fill in the background color.
        img.setColor(new Color(200,200,200)); // could use Color.GRAY
        img.fill();
         
        // add an "icon" that shows the corresponding color
        GreenfootImage ball = new GreenfootImage(10,10);
        ball.setColor(col);
        ball.fillRect(0,0, ball.getWidth(), ball.getHeight());
        img.drawImage(ball, 1, 1);
         
        // add in the count statistics for this ball color
        img.setColor(new Color(0,0,0) ); // could use Color.BLACK
        String stats = String.format("#:%6d", totalCount);
        img.drawString(stats, 21, 11);
        stats = String.format("C:%6d", caughtCount);
        img.drawString(stats, 85, 11);
 
         
        setImage(img); // use the image we've built up.
    }
     
    // redraw the image with the current ball calor.
    private void redraw()
    {
        redraw(ballColor);
    }
     
    /**
     * returns the color for this ball type. Might be useful to help draw a ball in the game
     *   @return the color for this type
     */
    public Color getColor()
    {
        return ballColor;       
    }
     
    /**
     * returns the number of times a ball of this color has been added to the world
     *   @return the count of the number of balls of this color ever seen in the world
     */
    public int getTotal()
    {
        return totalCount;
    }
     
    /**
     * returns the number of times a ball of this color has been caught
     *   @return the count of the number of balls of this color ever been caught
     */
    public int getCaught()
    {
        return caughtCount;
    }
     
    /**
     * adds one to the total number of balls of this color seen in the world.
     */
    public void incTotal()
    {
        totalCount++;
        redraw();
    }
     
    /**
     * adds one to the total number of ballos of this color that have been caught
     */
    public void incCaught()
    {
        caughtCount++;
        redraw();
    }   
}
I know you referenced to using an Array or ArrayList, but I was having trouble creating an Array that holds the values of the BallInfo objects being created in the world. And also, here are the instance variables located in the World class:
1
2
3
private BallInfo ballInfos[];
    private int balls[];
    private BallInfo info; // a reference to the BallInfo class
danpost danpost

2017/4/27

#
Asiantree wrote...
Now I am having trouble spawning them in as they are being read from the file. They all spawn in at one time and I need them to spawn in one at a time and keep spawning in until I hit the stop button.
You do not want to spawn them when (or while) the file is read. The spawning of a ball is not triggered by a user keystroke like loading a file and merging a file are. The code for spawning of balls goes in a separate part of the act method. I have come to the realization that no List or array is actually needed. You can always get a list of the BallInfo objects that are currently in the world:
1
List infos = getObjects(BallInfo.class);
Therefore, you will not need any of the 3 instance variable that you just listed that are in your World subclass. Spawning a ball will look like this:
1
2
3
int infoSize = getObjects(BallInfo.class).size();
int index = Greenfoot.getRandomNumber(infoSize);
Ball ball = new Ball((BallInfo)getObjects(BallInfo.class).get(index));
The Ball constructor can use:
1
Color color = bi.getColor();
to get the ball's color.
Asiantree Asiantree

2017/4/27

#
Here is the method I created called "spawnBalls" but it does not create any Balls when called:
1
2
3
4
5
6
7
8
public void spawnBalls()
    {
        if (!infos.isEmpty()){
            int infoSize = getObjects(BallInfo.class).size();
            int index = Greenfoot.getRandomNumber(infoSize);
            Ball ball = new Ball((BallInfo)getObjects(BallInfo.class).get(index));
        }
    }
danpost danpost

2017/4/27

#
Asiantree wrote...
So could I use all of this in a method called "spawnBalls()?"
Just the 3-liner in the middle. They will need to be placed in an 'if' block that regulates their spawning (you do not want one to be spawn every act cycle). The first one-liner was just showing how a list of BallInfo objects currently in the worl can be acquired. The second one-liner could be used in the Ball class constructor.
Asiantree Asiantree

2017/4/27

#
Also, this is located inside the Ball's constructor:
1
img.setColor(bi.getColor());
So the color is already getting acquired, I believe.
danpost danpost

2017/4/27

#
Asiantree wrote...
Also, this is located inside the Ball's constructor:
1
img.setColor(bi.getColor());
So the color is already getting acquired, I believe.
That is correct.
Asiantree Asiantree

2017/4/27

#
So does this code not work for spawning in Balls?
1
2
3
4
5
6
7
8
public void spawnBalls()
    {
        if (!infos.isEmpty()){
            int infoSize = getObjects(BallInfo.class).size();
            int index = Greenfoot.getRandomNumber(infoSize);
            Ball ball = new Ball((BallInfo)getObjects(BallInfo.class).get(index));
        }
    }
Nothing appears when this method is called in the act cycle of the World class.
danpost danpost

2017/4/27

#
Correct, you created a ball object properly; but, you have to now add it into the world (after line 6). Change 'infos' in line 3 to 'getObjects(BallInfo.class)'.
Asiantree Asiantree

2017/4/27

#
Oh, right duh haha. Thank you so much danpost. You have helped me a lot. I have one more question though, how can I delay how many get spawned in at once? Also, I may have further questions later on because I still need to sort the BallInfo objects in order of how many balls spawned, and when I toggle a button, it will switch to how many balls have touched the paddle at the bottom. But for now, I will try to work on that on my own.
danpost danpost

2017/4/27

#
Asiantree wrote...
how can I delay how many get spawned in at once?
You can use a time to spawn them at regular intervals; or you can use a random chance to spawn them at irregular intervals; or you can use a combination of both to spawn them at irregular intervals with a minimum time gap.
Asiantree Asiantree

2017/4/27

#
Okay, I have worked on the sorting part of the project now, but I am having trouble with where to place my code. Here is what is in the Paddle class that removes Balls when it touches them. I need to increase the total number of Balls spawned every call to act, but when a paddle touches a Ball, it needs to increase the "amount caught." Here is what I have inside the Paddle class to show the code I have attempted:
1
2
3
4
5
6
7
8
9
10
11
12
Ball ball = (Ball) getOneIntersectingObject(Ball.class);
        if (ball != null)
        {
            getWorld().removeObject(ball);
            //ballInfo.incCaught(); should this line of code be located here?
            return;
        }
        if(!getIntersectingObjects(Ball.class).isEmpty())
        {   
            ballInfo.incCaught(); //or down here? Or am I doing something wrong that's not changing the amount caught?
            ballInfo.getCaught();
        }
I am just unsure if this is the right code to accomplish the task I am trying to do.
danpost danpost

2017/4/27

#
It would be more simple if the ball detected the paddle instead of the other way around since the ball is what carries the reference to its BallInfo object:
1
2
3
4
5
6
/** in Ball class */
if (isTouching(Paddle.class))
{
    ballInfo.incCaught();
    getWorld().removeObject(this);
}
Question: is not the one paddle used to catch balls of any color? if that is the case, then 'ballInfo' as used in lines 10 and 11 have no meaning in the paddle class unless you got the reference from the ball that is being caught; but you are certainly not doing anything like that with the code given (which you can remove from the Paddle class).
Asiantree Asiantree

2017/4/27

#
Yes, I get a NullPointerException for this line of code:
1
ballInfo.incCaught();
The same error was happening for when I had the code in the paddle class for when it touches a ball, as shown above. The paddle catches Balls of any color. Does it have to do with the "ballInfo" variable? Is it not able to update the caughtAmount for some reason? I believe I provided the BallInfo class above if you would like to look at it. I also get an Actor not in world error for the if statement you have provided. Here are the two if statements used in the Ball's act method currently:
1
2
3
4
5
6
7
8
if (this.getY() == getWorld().getHeight() - 5)
        {
            getWorld().removeObject(this);
        }
        if (isTouching(Paddle.class))
        {
            getWorld().removeObject(this);
        }
There are more replies on the next page.
1
2