Это моя первая графическая Java-программа, и я пытаюсь переделать простую классическую программу, в которой у меня есть несколько мячей, прыгающих в окне JFrame
.
До сих пор мне удалось получить один мяч, чтобы отскочить, используя код внутри метода run()
. Это работает для одного объекта шара, который я создаю, но теперь я хочу иметь много шариков, поэтому я пытаюсь создать метод в моем классе Ball
, который сделает каждый объект шара, который я создаю отказом в моем "мире шара" независимо.
Прямо сейчас все, о чем я забочусь, это то, что они отскакивают от стен, а не друг друга (я это выясню позже).
Проблема: В моем ballMove(int, int, int, int)
меня есть четыре параметра int
где первые два параметра - width
и height
window
, а последние два параметра - Xspeed
и Yspeed
. Когда я просматриваю свои if statements
он будет умеренно устанавливать параметры y speed
x
и y speed
на отрицательные, когда мяч попадает в правую или нижнюю стенку, но когда метод run()
ballMove(int, int, int, int)
выполняет метод ballMove(int, int, int, int)
, они возвращаются к тому, чтобы быть уверенными, и шары исчезают из окна. Я попытался использовать кучу методов getter
и setter
в моем классе шара. Я пробовал временные переменные в моем ballMove(int, int, int, int)
. Ничего, что я пробовал, работает.
Вопрос: Используя мой метод класса Ball
, как я могу запретить моим параметрам Xspeed
и Yspeed
переменные скорости экземпляра на положительные, когда мяч сталкиваются со стенами?
Поскольку я новичок в графическом программировании, мы будем очень благодарны за полезные предложения.
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
public class Main extends JFrame implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int width = 800;
private int height= 600;
private int ballRadius = 50;
private Random rand = new Random();
//Create and initialize a ball object
public Ball ball = new Ball(Color.BLUE, ballRadius, ballRadius, rand.nextInt(500), rand.nextInt(500));
//public Ball ball2 = new Ball(Color.RED, ballRadius, ballRadius, rand.nextInt(500), rand.nextInt(500));
//public Ball ball3 = new Ball(Color.GREEN, ballRadius, ballRadius, rand.nextInt(500), rand.nextInt(500));
//public Ball ball4 = new Ball(Color.ORANGE, ballRadius, ballRadius, rand.nextInt(500), rand.nextInt(500));
//public Ball ball5 = new Ball(Color.YELLOW, ballRadius, ballRadius, rand.nextInt(500), rand.nextInt(500));
//constructor
public Main(){
setSize(width, height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
//Paint the ball(s)
public void paint(Graphics g){
super.paint(g);
g.setColor(ball.getColor());
g.fillOval(ball.getBallX(), ball.getBallY(), ball.getWidth(), ball.getHeight());
//g.setColor(ball2.getColor());
//g.fillOval(ball2.getBallX(), ball2.getBallY(), ball2.getWidth(), ball2.getHeight());
//g.setColor(ball3.getColor());
//g.fillOval(ball3.getBallX(), ball3.getBallY(), ball3.getWidth(), ball3.getHeight());
//g.setColor(ball4.getColor());
//g.fillOval(ball4.getBallX(), ball4.getBallY(), ball4.getWidth(), ball4.getHeight());
//g.setColor(ball5.getColor());
//g.fillOval(ball5.getBallX(), ball5.getBallY(), ball5.getWidth(), ball5.getHeight());
}
//Run the program
public static void main(String [] args){
Main main = new Main();
main.setVisible(true);
main.run();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ball.ballMove(width, height, 20, 5);
repaint();
//ball2.ballMove(width, height, 15, 3);
//repaint();
//ball3.ballMove(width, height, 3, 20);
//repaint();
//ball4.ballMove(width, height, 10, 10);
//repaint();
//ball5.ballMove(width, height, 10, 20);
//repaint();
}
}
}
Вот мой класс Ball
import java.awt.Color;
import javax.swing.JFrame;
public class Ball extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private int width, height, ball_X, ball_Y;
private int Xspeed;
private int Yspeed;
private Color color;
public Ball(Color color, int width, int height, int ball_X, int ball_Y){
this.width = width;
this.height = height;
this.color = color;
this.ball_X = ball_X;
this.ball_Y = ball_Y;
}
public Color getColor(){
return this.color;
}
public int getWidth(){
return this.width;
}
public int getHeight(){
return this.height;
}
public int getBallX(){
return this.ball_X;
}
public int getBallY(){
return this.ball_Y;
}
public void setSpeedX(int x){
this.Xspeed = x;
}
public void setSpeedY(int x){
this.Yspeed = x;
}
public int getSpeedX(){
return this.Xspeed;
}
public int getSpeedY(){
return this.Yspeed;
}
public void setBallX(int x){
this.ball_X = x;
}
public void setBallY(int y){
this.ball_Y = y;
}
public void ballMove(int X, int Y, int xSpeed, int ySpeed){
//initialize Xspeed and Yspeed with the parameters of the function
this.setSpeedX(xSpeed);
this.setSpeedY(ySpeed);
//Moves the balls by adding the set speed to the position of the balls each time thread is executed
this.setBallX(this.getBallX() + this.getSpeedX());
this.setBallY(this.getBallY() + this.getSpeedY());
//When the balls hit the walls they are suppose to bounce back until they hit another wall.
if(this.getBallX() + 50 >= X){
this.setSpeedX(-xSpeed);
}
if(this.getBallY() + 50 >= Y){
this.setSpeedY(-ySpeed);
}
if(this.getBallX() + 25 <= 0){
this.setBallX(xSpeed);
}
if(this.getBallY() + 25 <= 0){
this.setSpeedY(ySpeed);
}
}
}
Ваша проблема прямо там:
ball.ballMove(width, height, 20, 5);
Поскольку это цикл, каждый раз, когда он называется, вы делаете его движущимся в одном направлении. Вы поворачиваете скорость в конце шара, если она попадает в стену, но это не имеет значения, потому что в следующий раз, когда вы ее назовете, мяч по-прежнему движется к +20, +5.
Мое предложение состоит в том, чтобы добавить параметры скорости, когда вы создаете свой экземпляр шара и обновляете его скорость.
ball.ballMove(width, height);
Другое предложение: поставьте свою проверку на столкновение, прежде чем перемещать мяч. Таким образом, вы можете убедиться, что вы не идете в неправильном направлении, прежде чем перемещать его.
Теперь еще одна проблема заключается в том, что в основном вы вызываете метод run()
вашего runnable. Запуск выполняется в текущем потоке. Вам нужно будет сделать что-то вроде этого:
Thread t = new Thread(main); t.start();
Выполнять чертежи и вычисления независимо от JFrame.
move()
. Это не должно принимать никаких аргументов, а просто использовать состояние BallTimer
вместоThread.sleep()
. 2) Ваша проблема вballMove()
вthis.setSpeedX(xSpeed);this.setSpeedY(ySpeed);
линий. 3) Вместо рисования наJFrame
используйтеJPanel
и методpaintComponent()