This site requires JavaScript, please enable it in your browser!
Greenfoot back
Çðæyœn
Çðæyœn wrote ...

2019/3/4

Prevent overlap of objects

Çðæyœn Çðæyœn

2019/3/4

#
I have created this agar.io like game but I can't seem to get past one particular issue. When all of the balls randomly spawn in, some of them overlap, and I want to prevent that. I tried to do this by detecting if they are overlapping, and if so then pushing one of them away until they are no longer intersecting. My current code for the "Ball" actor class does not do this:
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
public class Ball extends Actor
{
    //Instance Constants
 
    //Instance Variables   
    int size;
    Color ballColor;
    private boolean debug=false;
    private boolean readyToStart=false;
 
    /**
     * Constructor for objects of class Ball.
     * If no input parameters are specified it defaults to ball size of 20
     */
    public Ball()
    {
        this(20);
    }// End Constructor
 
    /***
     * Constructor for objects of class Ball.
     *
     * @param sizeIn The size of the ball to create
     */
    public Ball(int sizeIn)
    {
        this.size = sizeIn;
        ballColor = Color.CYAN;
        updateImage();
        readyToStart = false;
    }//End Constructor
 
    /**
     * Returns the size of the ball
     *
     * @return size the size of the ball
     */
    public int getSize() {
        return this.size;
    }
 
    /**
     * Checks to see if the ball is touching a ball bigger than it. If it is
     * touching another ball it repositions itself.
     *
     * @return true if ready, false if reposition was required
     */
    public boolean getReady() {
        readyToStart = false;
         
        //Check to see if ball is touching something bigger and save result
        if (this.isTouchingBigger() != null) {
            this.moveAway(this.isTouchingBigger());
            return false;
        }
 
 
        return true;
    }
 
    /**
     * Update the image to be displayed on the screen for the Ball object
     *
     */
    void updateImage()
    {
        //Create an image of the set size using built in greenfoot commands
        GreenfootImage displayImage;
        displayImage = new GreenfootImage(size,size);
 
        //Draw Circle
        displayImage.setColor(ballColor); //Set color to ballColor
        displayImage.drawOval(0, 0, this.getSize(), this.getSize()); //Draw a circle
 
        //Display the number inside circle
        Font displayFont = new Font( (int)(size*0.75) );
        displayImage.setColor(ballColor.BLACK); //Set color to Black
        displayImage.setFont(displayFont);
        displayImage.drawString(Integer.toString(size),(int)(size*0.1),(int)(size*0.8));
        //Add the image as the new image for this object
        setImage(displayImage);
 
    }
 
    /**
     * Check to see if the Ball is touching another ball that is bigger than it
     *
     * @return null if not touching, or the object reference of the biggest ball it is touching
     */
    Ball isTouchingBigger()
    {
        //Get list of all Objects that are intersecting this one
        List<Ball> touchingBalls = getIntersectingObjects(Ball.class);
        //Create a variable to store the biggest ball intersecting
        Ball biggestBall = null;
        Ball tempBall = null;
         
        if (debug) System.out.println(touchingBalls);
        
        //Check to see if list is empty (ie, no intersections)
        if (!touchingBalls.isEmpty()) {
             
 
            for(int i = 0; i < touchingBalls.size(); i++) {
                  if(touchingBalls.get(i).getSize() > this.getSize()) {            
                       tempBall = (Ball)touchingBalls.get(i);
                  }
            }
        
            //Iterate through the list and find the biggest ball it is touching.
                //Get a single ball from the list
                 //Note, I have to do a cast conversion here to tell Java to expect a specific object type
                //Check the size of the ball and save if needed
        System.out.println(tempBall);
        if(biggestBall != null) {
             biggestBall = tempBall;
        }
            
         
 
        //Return the correct value as specfied in javadoc at start of method
         
 
     
    return biggestBall;
}
     
     
    /**
     * Move away from the specified ball so that they no longer intersect.
     *
     * @param The ball to be moving away from
     */
    void moveAway(Ball runFromThis) {
         
        //if(this.isTouchingBigger() != null) {
            //this.move(-movement / 2); // Kinda works
            //this.setLocation(this.getX() - 1, this.getY());
            //this.setLocation(runFromThis.getX() + movement, runFromThis.getY() + movement);
        //}
         
        int movement = Greenfoot.getRandomNumber(10);
         
        while(this.getIntersectingObjects(Ball.class).size() > 0) {
         this.turn(movement);
         this.setLocation(runFromThis.getX() + movement, runFromThis.getY() + movement);
        }
         
         
         
         
         
    }
I have just started learning Java, so any help is appreciated.
danpost danpost

2019/3/4

#
Override the addedToWorld(World) method to re-position a ball until not touching another:
1
2
3
4
5
6
7
8
9
protected void addedToWorld(World world)
{
    while (isTouching(Ball.class))
    {
        int x = Greenfoot.getRandomNumber(world.getWidth());
        int y = Greenfoot.getRandomNumber(world.getHeight());
        setLocation(x, y);
    }
}
You need to login to post a reply.