如何解决如何为我的 Java 游戏添加流畅的动作?
我的目标:在像乒乓球这样的游戏中,关键控制应该可以平稳地移动球棒。
期望:希望蝙蝠可以通过按键平滑地上下移动。 实际结果:蝙蝠像滞后或改变速度一样移动。
我尝试将速度变量与 lerp 一起使用,但它们滞后。 我尝试增加和减少 y 值,但效果更差。 我搜索过,但找不到解决方案。
我称之为矩形球棒和圆形乒乓球。 另外,这是我第一天在这里发帖。
这是通用代码:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;
public class gamePanel extends JPanel implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 6350159535293799269L;
static final int SCREEN_WIDTH = 840;
static final int SCREEN_HEIGHT = 610;
static final int PONG_SPAWN_FRAME = 50;
static final int padding = 30;
static final int pongSize = 30;
static final int batHeight = SCREEN_HEIGHT / 4;
static final int batWidth = SCREEN_WIDTH / 32;
static final int batSpeed = 4;
static final int pongSpeed = 3;
static final int scoreTextSize = 45;
boolean running = false;
int redX = padding;
int redY = SCREEN_HEIGHT / 2;
int redVelocity = 0;
int blueX = SCREEN_WIDTH - padding;
int blueY = SCREEN_HEIGHT / 2;
int blueVelocity = 0;
int redPoints = 0;
int bluePoints = 0;
int pongX = SCREEN_WIDTH / 4 - pongSize / 2;
int pongY = 0;
int pongVelocityX = pongSpeed;
int pongVelocityY = pongSpeed;
final int DELAY = 6;
Timer timer;
Random random;
gamePanel() {
random = new Random();
pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME) + PONG_SPAWN_FRAME);
if (pongVelocityY == 0) {
if (pongY > SCREEN_HEIGHT / 2 + pongSize) {
pongVelocityY = -pongSpeed;
} else {
pongVelocityY = pongSpeed;
}
}
this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
this.setBackground(Color.DARK_GRAY);
this.setFocusable(true);
this.addKeyListener(new myKeyAdapter());
startGame();
}
void startGame() {
running = true;
timer = new Timer(DELAY,this);
timer.start();
}
void restart() {
redX = padding;
redY = SCREEN_HEIGHT / 2;
redVelocity = 0;
blueX = SCREEN_WIDTH - padding;
blueY = SCREEN_HEIGHT / 2;
blueVelocity = 0;
pongX = SCREEN_WIDTH / 4 - pongSize / 2;
pongY = 0;
pongVelocityX = pongSpeed;
pongVelocityY = pongSpeed;
spawnPong();
}
void spawnPong() {
pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME * 2)) + PONG_SPAWN_FRAME;
if (pongVelocityY == 0) {
if (pongY > SCREEN_HEIGHT / 2 + pongSize) {
pongVelocityY = -pongSpeed;
} else {
pongVelocityY = pongSpeed;
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
void draw(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
g.fillOval(pongX,pongY,pongSize,pongSize);
g.setColor(Color.red);
g.fillRect(redX - batWidth / 2,redY - batHeight / 2,batWidth,batHeight);
g.setColor(Color.blue);
g.fillRect(blueX - batWidth / 2,blueY - batHeight / 2,batHeight);
g.setColor(Color.white);
g.setFont(new Font("Roman New Times",Font.PLAIN,scoreTextSize));
g.drawString(String.valueOf(redPoints),SCREEN_WIDTH / 4,scoreTextSize);
g.drawString(String.valueOf(bluePoints),SCREEN_WIDTH / 4 * 3,scoreTextSize);
}
void pongMove() {
pongX += pongVelocityX;
pongY += pongVelocityY;
}
void batMove() {
if (redY > batHeight / 2 && redVelocity < 0) {
redY += redVelocity * batSpeed;
}
if (redY < SCREEN_HEIGHT - batHeight / 2 && redVelocity > 0) {
redY += redVelocity * batSpeed;
}
blueY = pongY;
/*
* if (blueY>batHeight/2 && blueVelocity < 0) { blueY += blueVelocity *
* pongSpeed; } if (blueY<SCREEN_HEIGHT-batHeight/2 && blueVelocity > 0) { blueY
* += blueVelocity * pongSpeed; }
*/
}
void batLerp() {
redVelocity *= 0.5f;
blueVelocity *= 0.5f;
}
void checkCollision() {
if ((pongX > blueX - pongSize - batWidth / 2 && pongX < blueX - pongSize + batWidth / 2)
&& (pongY > blueY - batHeight / 2 && pongY < blueY + batHeight / 2)) {
pongVelocityX *= -1;
}
if (pongX < redX + batWidth / 2 && (pongY > redY - batHeight / 2 && pongY < redY + batHeight / 2)) {
pongVelocityX *= -1;
}
if (pongY < 0) {
pongVelocityY *= -1;
}
if (pongY > SCREEN_HEIGHT - pongSize) {
pongVelocityY *= -1;
}
if (pongX < -pongSize) {
bluePoints += 1;
restart();
}
if (pongX > SCREEN_WIDTH) {
redPoints += 1;
restart();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (running) {
checkCollision();
batMove();
batLerp();
pongMove();
}
repaint();
}
public class myKeyAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
redVelocity = -1;
break;
case KeyEvent.VK_S:
redVelocity = 1;
break;
case KeyEvent.VK_UP:
blueVelocity = -1;
break;
case KeyEvent.VK_DOWN:
blueVelocity = 1;
break;
}
}
}
}
解决方法
原答案
我修改了拨片移动,这样拨片只有在您按住按键时才会移动。为了测试,我不得不放慢游戏速度。
我无法遵循您的代码。您的 JPanel
类做的工作太多,太难理解了。我将从普通的 Java getter / setter 类创建一个 Ball
类和一个 Paddle
类来保存球和桨的字段。
这是完整的可运行代码。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ClassicPongGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ClassicPongGUI());
}
@Override
public void run() {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class GamePanel extends JPanel implements ActionListener {
private static final long serialVersionUID = 6350159535293799269L;
static final int SCREEN_WIDTH = 840;
static final int SCREEN_HEIGHT = 610;
static final int PONG_SPAWN_FRAME = 50;
static final int padding = 30;
static final int pongSize = 30;
static final int batHeight = SCREEN_HEIGHT / 4;
static final int batWidth = SCREEN_WIDTH / 32;
static final int batSpeed = 20;
static final int pongSpeed = 1;
static final int scoreTextSize = 45;
boolean running = false;
int redX = padding;
int redY = SCREEN_HEIGHT / 2;
int redVelocity = 0;
int blueX = SCREEN_WIDTH - padding;
int blueY = SCREEN_HEIGHT / 2;
int blueVelocity = 0;
int redPoints = 0;
int bluePoints = 0;
int pongX = SCREEN_WIDTH / 4 - pongSize / 2;
int pongY = 0;
int pongVelocityX = pongSpeed;
int pongVelocityY = pongSpeed;
final int DELAY = 6;
Timer timer;
Random random;
public GamePanel() {
random = new Random();
pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME) + PONG_SPAWN_FRAME);
if (pongVelocityY == 0) {
if (pongY > SCREEN_HEIGHT / 2 + pongSize) {
pongVelocityY = -pongSpeed;
} else {
pongVelocityY = pongSpeed;
}
}
this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
this.setBackground(Color.DARK_GRAY);
this.setFocusable(true);
this.addKeyListener(new myKeyAdapter());
startGame();
}
void startGame() {
running = true;
timer = new Timer(DELAY,this);
timer.start();
redX = padding;
redY = SCREEN_HEIGHT / 2;
redVelocity = 0;
}
void restart() {
blueX = SCREEN_WIDTH - padding;
blueY = SCREEN_HEIGHT / 2;
blueVelocity = 0;
pongX = SCREEN_WIDTH / 4 - pongSize / 2;
pongY = 0;
pongVelocityX = pongSpeed;
pongVelocityY = pongSpeed;
spawnPong();
}
void spawnPong() {
pongY = random.nextInt((int) (SCREEN_HEIGHT - PONG_SPAWN_FRAME * 2)) + PONG_SPAWN_FRAME;
if (pongVelocityY == 0) {
if (pongY > SCREEN_HEIGHT / 2 + pongSize) {
pongVelocityY = -pongSpeed;
} else {
pongVelocityY = pongSpeed;
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
void draw(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
g.fillOval(pongX,pongY,pongSize,pongSize);
g.setColor(Color.red);
g.fillRect(redX - batWidth / 2,redY - batHeight / 2,batWidth,batHeight);
g.setColor(Color.blue);
g.fillRect(blueX - batWidth / 2,blueY - batHeight / 2,batHeight);
g.setColor(Color.white);
g.setFont(new Font("Times New Roman",Font.PLAIN,scoreTextSize));
g.drawString(String.valueOf(redPoints),SCREEN_WIDTH / 4,scoreTextSize);
g.drawString(String.valueOf(bluePoints),SCREEN_WIDTH / 4 * 3,scoreTextSize);
}
void pongMove() {
pongX += pongVelocityX;
pongY += pongVelocityY;
}
void batMove() {
if (redY > batHeight / 2 && redVelocity < 0) {
redY += redVelocity * batSpeed;
}
if (redY < SCREEN_HEIGHT - batHeight / 2 && redVelocity > 0) {
redY += redVelocity * batSpeed;
}
blueY = pongY;
/*
* if (blueY>batHeight/2 && blueVelocity < 0) { blueY += blueVelocity *
* pongSpeed; } if (blueY<SCREEN_HEIGHT-batHeight/2 && blueVelocity > 0) { blueY
* += blueVelocity * pongSpeed; }
*/
}
void batLerp() {
redVelocity = 0;
blueVelocity = 0;
}
void checkCollision() {
if ((pongX > blueX - pongSize - batWidth / 2
&& pongX < blueX - pongSize + batWidth / 2)
&& (pongY > blueY - batHeight / 2
&& pongY < blueY + batHeight / 2)) {
pongVelocityX *= -1;
}
if (pongX < redX + batWidth / 2 && (pongY > redY - batHeight / 2
&& pongY < redY + batHeight / 2)) {
pongVelocityX *= -1;
}
if (pongY < 0) {
pongVelocityY *= -1;
}
if (pongY > SCREEN_HEIGHT - pongSize) {
pongVelocityY *= -1;
}
if (pongX < -pongSize) {
bluePoints += 1;
restart();
}
if (pongX > SCREEN_WIDTH) {
redPoints += 1;
restart();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (running) {
checkCollision();
batMove();
batLerp();
pongMove();
}
repaint();
}
public class myKeyAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
redVelocity = -1;
break;
case KeyEvent.VK_S:
redVelocity = 1;
break;
case KeyEvent.VK_UP:
redVelocity = -1;
break;
case KeyEvent.VK_DOWN:
redVelocity = 1;
break;
}
}
}
}
}
修改后的答案
我认为这会是一个有趣的项目,所以我重新编写了代码。这是 GUI 的显示方式。
W 和向上箭头键向上移动蓝色拨片。 S 和向下箭头键向下移动蓝色拨片。必须按住这些键才能继续运动。释放键停止桨运动,
空格键重新开始游戏。
当我创建 Swing GUI 时,我使用 model / view / controller (MVC) 模式。这种模式使我能够将关注点分开,一次专注于应用程序的一小部分。
对于 Swing GUI,MVC 模式定义为:
- 视图从模型中读取信息。
- 视图不会更新模型。
- 控制器更新模型并重新绘制/重新验证视图。
Swing GUI 可以有许多控制器类。我为此 Pong 游戏创建了三个控制器类。
我创建了 8 个不同的类。三个类构成应用程序模型,两个类定义视图,三个控制器类管理应用程序。
型号
我创建了一个 Ball
类来保存创建球和在屏幕上移动球所需的字段。我使用 Point
来保持中心点,使用 int
来保持球的半径。
Ball
类不是典型的 getter/setter 类。 moveBall
方法使用极坐标来计算球的新位置。将极坐标转换为笛卡尔坐标以在绘图 JPanel 上绘制球。
Paddle
类创建一个桨。我将桨的形状存储在 Rectangle
中。这是一个更典型的 Java getter/setter 类,尽管有代码来限制桨可以在 Y 轴上移动多远。
GameModel
类是应用程序模型。该类包含一个 Ball
实例和两个 Paddle
实例,以及两个分数 ints
和游戏运行的帧速率。此类的实例通过视图和控制器类传递。
查看
我创建了一个 JFrame
和一个绘图 JPanel
。绘图 JPanel
绘制球的当前位置、两个球拍和得分。时期。没有别的。
控制器类负责移动球和桨并重新绘制 JPanel
。
我使用 KeyBindings
将键盘按键设置为各种操作。使用 KeyBindings
,我不必担心绘图 JPanel
是否有焦点。
控制器
TimerListener
类为 Pong 游戏制作动画。
MovePaddleAction
类根据按下的键向上或向下移动拨片。必须按住该键才能继续运动。
RestartAction
类重新开始游戏。
代码
这是完整的可运行代码。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ClassicPongGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new ClassicPongGUI());
}
private final Dimension panelSize;
private GameModel gameModel;
private GamePanel gamePanel;
private Timer timer;
public ClassicPongGUI() {
this.panelSize = new Dimension(840,610);
this.gameModel = new GameModel(panelSize);
}
@Override
public void run() {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.gamePanel = new GamePanel(this,gameModel);
frame.add(gamePanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
setKeyBindings();
startTimer();
}
private void setKeyBindings() {
String moveUp = "moveUp";
String moveDown = "moveDown";
String restart = "restart";
InputMap inputMap = gamePanel.getInputMap(
JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = gamePanel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_W,0),moveUp);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_UP,moveUp);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_S,moveDown);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_DOWN,moveDown);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_SPACE,restart);
int increment = 15;
actionMap.put(moveUp,new MovePaddleAction(
this,gameModel,-increment));
actionMap.put(moveDown,increment));
actionMap.put(restart,new RestartAction(
this,gameModel));
}
public void startTimer() {
int delay = 1000 / gameModel.getFrameRate();
timer = new Timer(delay,new TimerListener(this,gameModel));
timer.setInitialDelay(5000);
timer.start();
}
public void stopTimer() {
if (timer != null) {
timer.stop();
}
}
public Dimension getPanelSize() {
return panelSize;
}
public void repaint() {
gamePanel.repaint();
}
public class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final GameModel model;
public GamePanel(ClassicPongGUI frame,GameModel model) {
this.model = model;
this.setBackground(Color.DARK_GRAY);
this.setPreferredSize(frame.getPanelSize());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawBall(g);
drawPaddles(g);
drawScores(g);
}
private void drawBall(Graphics g) {
Ball ball = model.getBall();
g.setColor(ball.getColor());
int radius = ball.getRadius();
int diameter = radius + radius;
Point point = ball.getCenterPoint();
g.fillOval(point.x - radius,point.y - radius,diameter,diameter);
}
private void drawPaddles(Graphics g) {
Paddle[] paddles = model.getPaddles();
for (Paddle paddle : paddles) {
g.setColor(paddle.getColor());
Rectangle r = paddle.getPaddle();
g.fillRect(r.x,r.y,r.width,r.height);
}
}
private void drawScores(Graphics g) {
int[] scores = model.getScore();
int scoreTextSize = 45;
g.setColor(Color.WHITE);
g.setFont(new Font("Times New Roman",scoreTextSize));
g.drawString(String.valueOf(scores[0]),panelSize.width / 4,scoreTextSize);
g.drawString(String.valueOf(scores[1]),panelSize.width * 3 / 4,scoreTextSize);
}
}
public class TimerListener implements ActionListener {
private final ClassicPongGUI frame;
private final GameModel model;
public TimerListener(ClassicPongGUI frame,GameModel model) {
this.frame = frame;
this.model = model;
}
@Override
public void actionPerformed(ActionEvent event) {
int frameRate = model.getFrameRate();
model.getBall().moveBall(frameRate);
Point point = model.getBall().getCenterPoint();
Paddle[] paddles = model.getPaddles();
for (int i = 0; i < paddles.length; i++) {
Rectangle p = paddles[i].getPaddle();
int y = point.y - p.height / 2;
if (i == 0) {
paddles[i].setPaddle(y);
}
model.contactsPaddle();
}
if (point.x < 0) {
model.incrementScore(1,1);
model.resetBall();
}
if (point.x > frame.getPanelSize().width) {
model.incrementScore(0,1);
model.resetBall();
}
frame.repaint();
}
}
public class MovePaddleAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final int increment;
private final ClassicPongGUI frame;
private final GameModel model;
public MovePaddleAction(ClassicPongGUI frame,GameModel model,int increment) {
this.frame = frame;
this.model = model;
this.increment = increment;
}
@Override
public void actionPerformed(ActionEvent event) {
model.getPaddles()[1].movePaddle(increment);
frame.repaint();
}
}
public class RestartAction extends AbstractAction {
private static final long serialVersionUID = 1L;
private final ClassicPongGUI frame;
private final GameModel model;
public RestartAction(ClassicPongGUI frame,GameModel model) {
this.frame = frame;
this.model = model;
}
@Override
public void actionPerformed(ActionEvent event) {
frame.stopTimer();
model.restartGame();
frame.startTimer();
frame.repaint();
}
}
public class GameModel {
private int[] score;
/** frames per second **/
private final int frameRate;
private Ball ball;
private final Dimension panelSize;
private Paddle[] paddles;
public GameModel(Dimension panelSize) {
this.panelSize = panelSize;
this.score = new int[2];
this.paddles = new Paddle[2];
this.frameRate = 50;
int ballRadius = 15;
Point centerPoint = new Point(panelSize.width / 2,panelSize.height / 2);
this.ball = new Ball(centerPoint,ballRadius,panelSize,Color.LIGHT_GRAY);
int batWidth = panelSize.width / 32;
int batHeight = panelSize.height / 4;
int padding = 30;
int x = padding;
int y = calculateCenterY(batHeight);
Rectangle r = new Rectangle(x,y,batHeight);
this.paddles[0] = new Paddle(r,panelSize.height,Color.RED);
x = panelSize.width - padding - batWidth;
r = new Rectangle(x,batHeight);
this.paddles[1] = new Paddle(r,Color.BLUE);
resetScore();
}
public void restartGame() {
int batHeight = panelSize.height / 4;
resetBall();
paddles[0].setPaddle(calculateCenterY(batHeight));
paddles[1].setPaddle(calculateCenterY(batHeight));
resetScore();
}
public void resetBall() {
ball.setCenterPoint(new Point(panelSize.width / 2,panelSize.height / 2));
}
private int calculateCenterY(int batHeight) {
return (panelSize.height - batHeight) / 2;
}
public void contactsPaddle() {
int radius = ball.getRadius();
int diameter = radius + radius;
Point point = ball.getCenterPoint();
Rectangle b = new Rectangle(point.x - radius,diameter);
for (Paddle paddle : paddles) {
if (paddle.getPaddle().intersects(b)) {
ball.reverseXDirection(frameRate);
}
}
}
public void resetScore() {
score[0] = 0;
score[1] = 0;
}
public void incrementScore(int index,int increment) {
score[index] += increment;
}
public int[] getScore() {
return score;
}
public Ball getBall() {
return ball;
}
public Paddle[] getPaddles() {
return paddles;
}
public int getFrameRate() {
return frameRate;
}
}
public class Paddle {
private final int upperBound;
private final Color color;
private Rectangle paddle;
public Paddle(Rectangle paddle,int upperBound,Color color) {
this.paddle = paddle;
this.upperBound = upperBound;
this.color = color;
}
public void movePaddle(int increment) {
paddle.y += increment;
limitMovement();
}
public void setPaddle(int y) {
paddle.y = y;
limitMovement();
}
private void limitMovement() {
paddle.y = Math.max(paddle.y,0);
int height = paddle.y + paddle.height;
height = Math.min(height,upperBound);
paddle.y = height - paddle.height;
}
public Rectangle getPaddle() {
return paddle;
}
public Color getColor() {
return color;
}
}
public class Ball {
/** Pixels per second **/
private final double velocity;
private final int radius;
private int angle;
private final Color color;
private final Dimension panelSize;
private Point centerPoint;
private Point2D.Double doubleCenterPoint;
private Random random;
public Ball(Point centerPoint,int radius,Dimension panelSize,Color color) {
this.centerPoint = centerPoint;
setDoubleCenterPoint(centerPoint);
this.radius = radius;
this.panelSize = panelSize;
this.color = color;
this.velocity = 300.0;
this.random = new Random();
setRandomAngle();
}
public void reverseXDirection(int frameRate) {
angle = bounceXAngle(angle);
angle += (angle < 0) ? 360 : 0;
moveBall(frameRate);
}
public void moveBall(int frameRate) {
double theta = Math.toRadians(angle);
double distance = velocity / frameRate;
doubleCenterPoint.x = Math.cos(theta) * distance +
doubleCenterPoint.x;
doubleCenterPoint.y = Math.sin(theta) * distance +
doubleCenterPoint.y;
if (doubleCenterPoint.y < radius) {
double adjustment = radius - doubleCenterPoint.y;
doubleCenterPoint.y += adjustment;
angle = bounceYAngle(angle);
}
if ((doubleCenterPoint.y + radius) > panelSize.height) {
double adjustment = panelSize.height -
doubleCenterPoint.y - radius;
doubleCenterPoint.y += adjustment;
angle = bounceYAngle(angle);
}
int x = (int) Math.round(doubleCenterPoint.x);
int y = (int) Math.round(doubleCenterPoint.y);
this.centerPoint = new Point(x,y);
}
private int bounceXAngle(int angle) {
return 180 - angle;
}
private int bounceYAngle(int angle) {
return 360 - angle;
}
public Point getCenterPoint() {
return centerPoint;
}
public void setCenterPoint(Point centerPoint) {
this.centerPoint = centerPoint;
setRandomAngle();
setDoubleCenterPoint(centerPoint);
}
private void setDoubleCenterPoint(Point centerPoint) {
this.doubleCenterPoint =
new Point2D.Double(centerPoint.x,centerPoint.y);
}
private void setRandomAngle() {
int[] angles = {30,150,210,330 };
this.angle = angles[random.nextInt(angles.length)];
}
public int getRadius() {
return radius;
}
public Color getColor() {
return color;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。