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:
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:
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.