我想不出办法移动球

时间:2019-04-29 17:07:50

标签: java project billiards

我目前正在研究3垫式台球游戏项目。到目前为止,我已经在桌上增加了两个球。我正在尝试移动其中一个球,但是这样做很难。我应该使用计时器吗?如果是这样,那么您能告诉我在代码上使用计时器的有效方法,以便我可以移动球吗?

非常感谢您的帮助。 提前致谢。 法罕·哈桑

我试图为类球创建一个移动函数。但是我不确定应该在函数中放什么,我已经添加了xSpeed和ySpeed。 xLocation和yLocation随xSpeed和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());
            }
        }
    }

希望我能有两个可移动的球,在击打屏幕边缘时弹回,并且随着时间的推移它们应该会变慢。为此,我正在考虑使用阻尼器(我将xSpeed和ySpeed乘以小于1的数字,最终会减慢球的速度)

2 个答案:

答案 0 :(得分:0)

这是我想到的一个简单示例,展示了一个球在边缘移动并弹起。

方向根据边界改变。左边缘和上边缘仅需检查0。下边缘和右边缘需要包括球的直径。

x和y的增量是独立的。并且这些数量与计时器一起可以改变机芯。但是请注意,由于轨迹的角度等原因,使对象彼此反弹(如在台球游戏中)更加复杂。反弹的距离将根据摩擦值随着时间而变化并且变慢。其他所有内容都记录在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);

   }
}

答案 1 :(得分:0)

通常看来,您需要弄清楚一些事情:

  1. 球与另一个球相撞
  2. 球碰到墙壁了
  3. 否则只需根据球的速度找出球的新位置

下面是一些示例代码,将其中的一些代码存根了。您可以首先将当前球的位置与所有其他球的位置进行比较(当然不包括当前球)。如果位置相等,则与球碰撞。如果球在窗口边界处,即撞到墙壁,请与墙壁碰撞。否则,只需根据其当前速度计算其新位置即可。

过程冲突部分只是将物理力学应用到您需要的任何复杂程度。建议的一项一般更改是更新球的速度,然后将其应用于之后的位置。您可以根据需要应用特定的速度变化计算,并且可以想象它会涉及到很多,这就是为什么我建议使用单独的方法以及可能的速度子类,而不是管理球本身中速度矢量的每个部分。因此,我将墙用作对象。物体碰撞的成分,重量,速度等都会影响最终的碰撞,但您希望处理的复杂程度取决于您。

对不起,我不是物理学专家,但我希望这能给您正确的编码方向!此外,这可能有助于您可能要使用的特定计算: 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;
    }