我的目标是:在像乒乓球这样的东西中,关键控件应该平稳地移动蝙蝠。
期望:希望蝙蝠用钥匙平稳地向上或向下移动。实际结果:蝙蝠像落后或速度变化一样移动。
我试过用速度变量和lerp,但它们滞后。我试过增加和减少y值,但效果更差。我搜索了一下,但找不到解决方案。
我叫矩形蝙蝠和圆形乒乓球。而且,这是我第一天在这里发帖。
游戏截图
以下是panal代码:
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, batWidth, 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;
}
}
}
}
我修改了桨的移动,这样桨只有在你按住键的时候才会移动。为了测试,我不得不把游戏慢一点。
我很难理解你的代码。你的J面板
类做了太多的工作,而且太难理解。我会从普通的Javagetter/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, batWidth, 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时,我使用模型/视图/控制器(MVC)模式。这种模式允许我将关注点分开,一次只关注应用程序的一小部分。
对于Swing GUI,MVC模式定义为:
一个 Swing GUI 可以有许多控制器类。我为这个Pong游戏创建了三个控制器类。
我创建了8个不同的类。三个类构成应用程序模型,两个类定义视图,三个控制器类管理应用程序。
我创建了一个<code>Ball</code>类来容纳创建球和在屏幕上移动球所需的字段。我使用点
来保持中心点,使用int
来保持球的半径。
球类不是典型的接球
手/二传手类。moveBall
方法使用极坐标来计算球的新位置。极坐标被转换为笛卡尔坐标,以在绘图JPanel上绘制球。
Paddle
类创建一个 Paddle。我将桨的形状存储在矩形
中。这是一个更典型的Java getter / setter类,尽管有代码可以限制桨在Y轴上可以行进的距离。
类
是应用程序模型。此类包含一个 Ball 实例和两个 Paddle
实例,以及两个分数整数
和游戏运行的帧速率。此类的实例通过视图类和控制器类传递。
我创建了一个JFrame
和一个绘图J面板
。绘图J面板
绘制了球的当前位置、两个桨和分数。句号。没有别的了。
控制器类负责移动球和桨以及重绘JPel
。
我使用KeyBindings
将键盘键设置为各种操作。使用KeyBindings
,我不必担心绘图JPel
是否有焦点。
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, 0), moveUp);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_S, 0), moveDown);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_DOWN, 0), moveDown);
inputMap.put(KeyStroke.getKeyStroke(
KeyEvent.VK_SPACE, 0), restart);
int increment = 15;
actionMap.put(moveUp, new MovePaddleAction(
this, gameModel, -increment));
actionMap.put(moveDown, new MovePaddleAction(
this, gameModel, 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",
Font.PLAIN, 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, batWidth, batHeight);
this.paddles[0] = new Paddle(r, panelSize.height, Color.RED);
x = panelSize.width - padding - batWidth;
r = new Rectangle(x, y, batWidth, batHeight);
this.paddles[1] = new Paddle(r, panelSize.height, 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,
point.y - radius, diameter, 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;
}
}
}
问题内容: 我在想类似的东西: 哪种Java JSON库最适合这种流畅的构建? 更新 :我包GSON,并得到几乎理想的结果...... 问题答案: 我正在使用org.json库,发现它很好并且很友好。 例: 输出:
本文向大家介绍我们如何在Java中的JSONObject中添加JSONArray?,包括了我们如何在Java中的JSONObject中添加JSONArray?的使用技巧和注意事项,需要的朋友参考一下 甲的JSONObject 可以从一个字符串解析文本以产生映射样对象和JSONArray 可以从一个字符串解析文本以产生向量样的对象。我们还可以通过首先创建一个包含很少项目的JSONArray并将这些项
我在用Java做一个2D游戏,我用KeyListener和一些布尔值来检测按键。但问题是,如果我按住一个键,玩家就不会移动半秒钟,然后开始移动。有人知道怎么修吗? public void键按下(...){PlayerX+=3;}如有任何答复,不胜感激,谢谢。
我有以下代码: 在这部分代码中: 如果存在过滤器,则将过滤器应用于流; 想要对此流进行一些偏移和限制,但这不起作用,因为“应该只对一个流进行一次操作(调用中间或终端流操作)”。 映射到dto对象并收集为列表。 如何以其他方式进行流操作skip()和limit()。提前感谢。
3点的面试等到3:30面上,然后十分钟就结束了 我发现秋招后期基本没遇到八股文问题了 1.自我介绍 2.实习内容 3.项目内容 4.是否玩过游戏 5.问工作地能否接受 6.然后面试官介绍工作内容 #校招##秋招#
问题内容: 我添加了AsyncTask来将网络操作卸载到后台线程。我需要确保UI操作位于UI线程上,因此我想在Activity中使用runOnUiThread()。 谢谢你的帮助 WifiApManager connect.java 编辑 我想在TextView中显示已处理的文本 问题答案: 我添加了AsyncTask来将网络操作卸载到后台线程。我需要确保UI操作位于UI线程上,因此我想在Acti