-1

我目前正在做一个 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 的数字,最终它会减慢球的速度)

4

2 回答 2

0

一般来说,您需要弄清楚以下几点:

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

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

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

抱歉,我不是物理学专家,但我希望这会在代码方面向您发送正确的方向!这也可能有助于您可能想要使用的特定计算: https ://www.khanacademy.org/science/physics/one-dimensional-motion/displacement-velocity-time/v/calculating-average-velocity-or-速度

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;
    }
于 2019-04-29T18:07:57.993 回答
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);

   }
}
于 2019-04-29T17:39:01.770 回答