Я не могу придумать, как двигать шары - PullRequest
0 голосов
/ 29 апреля 2019

В настоящее время я работаю над проектом игры в бильярд на 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 голосов
/ 29 апреля 2019

Кажется, в общем есть несколько вещей, которые нужно выяснить:

  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;
    }
0 голосов
/ 29 апреля 2019

Вот простой пример, который я придумал, чтобы показать, как шар движется и отскакивает от краев.

Направление изменяется в зависимости от границы.Левый и верхний края просто проверьте на 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);

   }
}
...