Как я могу перемещать шары в случайных направлениях и как я могу держать их подпрыгивая внутри рамки?

Вопрос:

Вот код:

public class BallGame extends JPanel implements Runnable {

JPanel panel1 = new JPanel();

private int ballX = 10, ballY = 110, ...;
Thread aThread;
int toRight=5;
int toLeft= -5;
int upWard=5;
int downWard= -5;
int widthBall, heightBall;

public BallGame(){
game=true;
aThread=new Thread(this);
aThread.start();
}

public void paintComponent(Graphics g){
setOpaque(false);
super.paintComponent(g);

g.setColor(Color.RED);
g.fillOval(ballX, ballY, 7,7);
g.setColor(Color.BLUE);
g.fillOval(ballX + 15, ballY + 10, 7,7);
g.setColor(Color.GREEN);
g.fillOval(ballY - 10, ballY - 15, 7,7);

}

public void positionBall(int sx, int sy)
{
ballX = sx;
ballY = sy;
this.widthBall = this.getWidth();
this.heightBall = this.getHeight();
repaint();
}
public void run() {
boolean leftRight = false;
boolean upDown = false;

while(true){

if(game){

if (leftRight)
{
ballX += toRight;
if (ballX >= (widthBall - 5))
leftRight= false;
}
else
{
ballX += toLeft;
if ( ballX <= 0)
leftRight =  true;
}

if (upDown)
{
ballY += upWard;
if (ballY >= (heightBall - 5))
upDown = false;

}
else
{
ballY += downWard;
if ( ballY <= 0)
upDown =  true;
}
positionBall(ballX, ballY);

try
{
Thread.sleep(70);
}
catch(InterruptedException ex)
{

}

Я не знаю, была ли та часть, где я нарисовала шары, была права. Шары движутся по тому же пути. Как я могу перемещать их в разных направлениях и как я могу ограничить их внутри рамки? Мне нужно это для нашего исследования. Спасибо за ваше время!

Лучший ответ:

Для того, чтобы шары двигались независимо, вам нужно рассматривать их как 3 шара. Причина, по которой они всегда идут в одном направлении, заключается в том, что вы используете одну и ту же дельта, просто инвертируя знак delta x и delta y, таким образом, вы всегда будете поддерживать ту же скорость и откатываться на 90 градусов.

В приведенном ниже коде, который в основном такой же, как и у вас, я сохраняю состояние каждого шара в отдельных экземплярах, изменяю скорость дельта х и дельта y после того, как сторона коснулась, и используйте таймер Swing, который является лучшим подходом с уважением к времени в Свинге, как указано Робин выше.

enter image description here

Я обновил пример, так что 4 шара начинаются посередине, и они уходят друг от друга. Это должно дать вам достаточно информации, чтобы адаптировать его к вашим требованиям. На картинке ниже производится только 10 итераций и настройка

ballGame.setOpaque(true);

enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.*;

public class BallGame extends JPanel {

    private class Ball {
        private int x;
        private int y;
        private int width;
        private int height;
        private Color color;
        private boolean leftRight;
        private boolean upDown;
        private int deltaX;
        private int deltaY;

        Ball(Color color, int x, int y, int width, int height) {
            this(color, x, y, width, height, false, false);
        }

        Ball(Color color, int x, int y, int width, int height, boolean leftRight, boolean upDown) {
            this.color = color;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftRight = leftRight;
            this.upDown = upDown;
            updateDelta();
        }

        private void updateDelta() {
            final int minimumMovement = 5;
            final int maxExtra = 10;
            deltaY = minimumMovement + (int) (Math.random() * maxExtra);
            deltaX = minimumMovement + (int) (Math.random() * maxExtra);
        }

        public void positionBall() {
            if (leftRight) {
                x += deltaX;
                if (x >= (BallGame.this.getWidth() - width / 2)) {
                    leftRight = false;
                    updateDelta();
                }
            } else {
                x += -deltaX;
                if (x <= 0) {
                    leftRight = true;
                    updateDelta();
                }
            }

            if (upDown) {
                y += deltaY;

                upDown = !(y >= (BallGame.this.getHeight() - height / 2));
                if (y >= (BallGame.this.getHeight() - height / 2)) {
                    upDown = false;
                    updateDelta();
                }
            } else {
                y += -deltaY;
                if (y <= 0) {
                    upDown = true;
                    updateDelta();
                }
            }
        }

        public Color getColor() {
            return color;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getWidth() {
            return width;
        }

        public int getHeight() {
            return height;
        }
    }

    private ArrayList<Ball> balls = new ArrayList<>(3);

    public BallGame() {
        createBalls();
        startGame();
    }

    private void startGame() {
        int framesPerSecond = 30;
        int timeToWait = 1000 / framesPerSecond;
        Timer timer = new Timer(timeToWait, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (Ball ball : balls) {
                    ball.positionBall();
                }
                repaint();
            }
        });
        timer.start();
    }

    private void createBalls() {
        int startX = 400;
        int startY = 200;
        balls.add(new Ball(Color.green, startX, startY, 10, 10));
        balls.add(new Ball(Color.blue, startX, startY, 15, 15, true, true));
        balls.add(new Ball(Color.red, startX, startY, 20, 20, false, true));
        balls.add(new Ball(Color.orange, startX, startY, 20, 20, true, false));
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        for (Ball ball : balls) {
            g2.setColor(ball.getColor());
            g2.fillOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
            g2.setColor(ball.getColor().darker());
            g2.drawOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
        }
        g2.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Ball Game");
                BallGame ballGame = new BallGame();
                ballGame.setOpaque(false);
                frame.getContentPane().add(ballGame);
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setMinimumSize(new Dimension(800, 450));
                frame.setLocationRelativeTo(null); // Center
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

Оцените статью
TechArks.Ru
Добавить комментарий