I cannot figure out a way to move the balls

流过昼夜 提交于 2019-12-26 03:08:57

问题


I am currently working on a 3 cushion billiards game project. I have added two balls on the table so far. I am trying to move one of the balls but I am having a hard time doing that. Should I use a timer? If so then could you tell me an effective way to use the timer on my code so I can move my balls?

Your help would be much appreciated. Thanks in advance. Farhan Hasan

I have tried to create a move function for the class balls. But I am not sure what I should put inside the function, I have added the xSpeed and ySpeed. The xLocation and the yLocation changes depending on the xSpeed and ySpeed.

public class Balls
{

    private Color ballFillColor;
    private Color ballBorderColor;

    private int ballX = 0;
    private int ballY = 0;
    private int xSpeed = 5;
    private int ySpeed = 0;
    private int ballWidth = 0;
    private int ballHeight = 0;
    Timer t; 

    public boolean fillBall = false;
    private static Balls ballArray[]; //Required for drawMultipleBalls





    Balls(){ //Constructor
        ballBorderColor = Color.black;
    }

    Balls(int ballX, int ballY, int ballWidth, int ballHeight, Color ballBorderColor, JFrame window){ //Constructor
        // X , Y , Width, Height, Border Colour, container
        this.setBallBorderColor(ballBorderColor);
        this.setBallWidth(ballWidth);
        this.setBallHeight(ballHeight);
        this.setBallX(ballX);
        this.setBallY(ballY);
        this.drawBall(window);
    }


    //Here is the move function. I am not really sure what to do here. 
    public void move()
    {
        if(this.ballX < 1000 - this.ballWidth)
        {
            this.ballX += this.xSpeed; 
        }
        try
        {
            Thread.sleep(1);
        }
        catch(Exception e)
        {

        }
    }

//GET AND SET FUNCTIONS HERE 

//HERE ARE THE FUNCTIONS WHICH ARE RESPONSIBLE FOR DRAWING MY BALLS IN JFRAME

 public void drawBall(JFrame frame) 
    {
        frame.getContentPane().add(new MyComponent());
    }

    public void drawMultipleBalls(JFrame frame, Balls[] balls)
    {
        ballArray = balls;
        frame.getContentPane().add(new MyComponent2());
    }




    private class MyComponent extends JComponent{
        public void paintComponent(Graphics g){

            if (fillBall) //Fill first, and then draw outline.
            {
                g.setColor(ballFillColor);
                g.fillOval(getBallX(),getBallY(), getBallHeight(),getBallWidth());
            }

            g.setColor(getBallBorderColor());
            g.drawOval(getBallX(),getBallY(), getBallHeight(),getBallWidth());

        }
    }

    private class MyComponent2 extends JComponent{
        public void paintComponent(Graphics g){

            for (int i = 0; i < ballArray.length; i++)
            {
                if (ballArray[i].fillBall) //Fill first, and then draw outline.
                {
                    g.setColor(ballArray[i].ballFillColor);
                    g.fillOval(ballArray[i].getBallX(),ballArray[i].getBallY(), ballArray[i].getBallHeight(),ballArray[i].getBallWidth());
                }

                g.setColor(ballArray[i].getBallBorderColor());
                g.drawOval(ballArray[i].getBallX(),ballArray[i].getBallY(), ballArray[i].getBallHeight(),ballArray[i].getBallWidth());
            }
        }
    }

Hopefully, I can have two movable balls for the game, the should bounce back as the hit the edge of the screen and they should be able to slow down over time. For that, I am thinking to use a damper (I will multiply the xSpeed and ySpeed with a number less than 1, eventually it will slow down the ball)


回答1:


Here is a simple example I came up with to show a ball moving and bouncing off the edges.

The direction changes based on the boundary. Left and top edges just check for 0. Bottom and right edges need to include the diameter of the ball.

The x and y increments are independent. And these amounts in conjunction with the timer can change the movement. Notice however, that to have objects bounce off of each other (as in a pool game) is more complicated due to angle of trajectories, etc. And the distances bounced will vary and slow with time based on frictional values. Everything else is documented in the Java API.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MovementDemo extends JPanel implements ActionListener {

   JFrame frame      = new JFrame("Movement Demo");
   int    size       = 500;
   int    x          = 50;
   int    y          = 200;
   int    diameter   = 50;
   int    yinc       = 2;
   int    xinc       = 2;
   int    xdirection = 1;
   int    ydirection = 1;

   public MovementDemo() {
      setPreferredSize(new Dimension(size, size));
      frame.add(this);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);

   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(() -> new MovementDemo().start());
   }

   public void start() {

      Timer timer = new Timer(100, this);
      timer.setDelay(5);
      timer.start();
   }

   public void actionPerformed(ActionEvent ae) {

      if (x < 0) {
         xdirection = 1;
      }
      else if (x > size - diameter) {
         xdirection = -1;
      }
      if (y < 0) {
         ydirection = 1;
      }
      else if (y > size - diameter) {
         ydirection = -1;
      }
      x = x + xdirection * xinc;
      y = y + ydirection * yinc;
      repaint();
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g.create();
      g2d.setColor(Color.BLUE);
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.fillOval(x, y, diameter, diameter);

   }
}



回答2:


It seems in general there are a few things you need to figure out:

  1. has the ball collided with another ball
  2. has the ball collided with a wall
  3. otherwise just figure out what is the ball's new position based on its velocity

Below is some sample code that stubs some of this out. You can first compare the current ball's position to all others (not including the current ball of course). If there are any equal positions, process a collision with a ball. If the ball is at the window border i.e it hit a wall, process a collision with a wall. Otherwise just calculate its new position based on its current velocity.

The process collision part is just to apply physics mechanics to whatever degree of complexity you require. One general suggested change would be to update the velocity of the balls then apply it to the position after. The specific calculations for velocity changes you could apply as needed and as you can imagine it can get pretty involved which is why I suggest using a separate method and possibly a sub class for velocity instead of managing each part of the velocity vector in the ball itself. I used the wall as an object because of this. The composition, weights, velocities etc of the object's colliding can affect the resulting collision, but how complex you want that processing to be is up to you.

Sorry I'm no physics expert but I hope this sends you in the right direction in terms of code! Also this might help with the specific calculations you might want to use: https://www.khanacademy.org/science/physics/one-dimensional-motion/displacement-velocity-time/v/calculating-average-velocity-or-speed

public void move()
    {
        // check if balls are on same position not including this ball
        for(Ball b: ballArray){
            if (this.position == b.position && this != b){
                processCollision(this, b, null);
            } else{
                // if the ball hasn't collided with anything process its movement based on speed
                // this assumes a 1000 x 1000 window for keeping objects inside it
                if(this.ballX < 1000 - this.ballWidth && this.ballY < 1000 - this.ballHeight){
                    this.ballX += this.xSpeed;
                    this.ballY += this.ySpeed;
                }else {
                    processCollision(this, null, new Wall());
                }
            }
        }
        try
        {
            Thread.sleep(1);
        }
        catch(Exception e)
        {

        }
    }

    public void processCollision(Ball b1, Ball b2, Wall w){
        // if ball hasn't collided with a wall, process a ball - ball collision
        if(w == null){
            // apply physics mechanics according the complexity desired for ball collisions
            b1.xSpeed -= b2.xSpeed;
            b1.ySpeed -= b2.ySpeed;

            // ball 2 would end up slowing down
            b2.xSpeed -= b1.xSpeed;
            b2.ySpeed -= b1.ySpeed;
        }

        // if ball hasn't collided with a ball, process a ball - wall collision
        if(b2 == null){
            // apply physics mechanics for hitting a wall
            // e.g as below: just send ball in opposite direction
            b1.xSpeed = b1.xSpeed * -1;
            b1.ySpeed = b1.ySpeed * -1;
        }

        // either way, process ball's new position based on its new speed
        b1.ballX += b1.xSpeed;
        b1.ballY += b1.ySpeed;

        b2.ballX += b2.xSpeed;
        b2.ballY += b2.ySpeed;
    }


来源:https://stackoverflow.com/questions/55907928/i-cannot-figure-out-a-way-to-move-the-balls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!