我正在使用Swing开发我的第一个2D Java游戏,我遇到了一个奇怪的错误。 这是相关的代码,首先是:
GamePanel.java
public class GamePanel extends JPanel implements KeyListener {
public GamePanel() {
setPreferredSize(new Dimension(STAGE_WIDTH, STAGE_HEIGHT));
Thread runner = new Thread(new Runnable() {
@Override
public void run() {
begin();
long lastUpdate = System.currentTimeMillis();
while (true) {
long elapsed = System.currentTimeMillis() - lastUpdate;
repaint();
if (elapsed < 16) {
try {
Thread.sleep(20 - elapsed);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
update((System.currentTimeMillis() - lastUpdate) / 1000.0);
lastUpdate = System.currentTimeMillis();
}
}
});
runner.start();
}
//variables
int bulletVelocity = 10;
final int STAGE_HEIGHT = 600;
final int STAGE_WIDTH = 800;
int playerWidth = 50;
int playerHeight = 50;
//lists
List<Bullet> bulletList = new ArrayList<>();
List<Enemy> enemyList = new ArrayList<>();
//objects
Player player = new Player((STAGE_WIDTH - playerWidth) / 2, (STAGE_HEIGHT - playerHeight) / 2, 0, 0, playerWidth, playerHeight);
public void begin() {
}
public void update(double delta) {
player.update(delta);
//System.out.println(delta);
for (Bullet bullet : bulletList) {
bullet.update();
}
for (Enemy enemy : enemyList) {
enemy.update(player.getXPos(), player.getYPos());
}
}
@Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
g.fillRect((int) player.getXPos(), (int) player.getYPos(), player.getWidth(), player.getHeight());
g.setColor(Color.BLUE);
for (Bullet bullet : bulletList) {
g.fillRect((int) bullet.getXPos(), (int) bullet.getYPos(), 10, 10);
}
g.setColor(Color.GREEN);
for (Enemy enemy : enemyList) {
g.fillOval((int) enemy.getXPos(), (int) enemy.getYPos(), enemy.getWidth(), enemy.getHeight());
}
}
@Override
public void keyTyped(KeyEvent e) {
}
private Set<Integer> keysDown = new HashSet<Integer>();
@Override
public void keyPressed(KeyEvent e) {
if (keysDown.contains(e.getKeyCode())) {
return;
}
keysDown.add(e.getKeyCode());
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
player.addAccelX(-1);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.addAccelX(1);
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
player.addAccelY(-1);
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
player.addAccelY(1);
} else if (e.getKeyCode() == KeyEvent.VK_SPACE) {
Bullet bullet = new Bullet(player.getXPos() + (player.getWidth() / 2), player.getYPos(), bulletVelocity - (player.getYVel() / 4));
bulletList.add(bullet);
} else if (e.getKeyCode() == KeyEvent.VK_E) {
Enemy enemy = new Enemy(100, 100, Math.random() * 3 + .5, 10, 10);
enemyList.add(enemy);
} else if (e.getKeyCode() == KeyEvent.VK_A) {
System.out.println(toDegrees(atan2(player.getYPos() - 0, player.getXPos() - 0)));
}
}
@Override
public void keyReleased(KeyEvent e) {
keysDown.remove(e.getKeyCode());
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
player.addAccelX(1);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
player.addAccelX(-1);
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
player.addAccelY(1);
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
player.addAccelY(-1);
}
}
}
Player.java
public class Player {
private final double MAX_VELOCITY = 500;
private final double ACCELERATION = 3000.0;
//friction is % ? Add that later
private final double FRICTION = 400.0;
private double mass = 10.0;
private double xPos = 400;
private double yPos = 200;
private double xVel = 0.0;
private double yVel = 0.0;
private int width = 100;
private int height = 100;
private int xDir = 0;
private int yDir = 0;
private boolean moving = false;
private double accelX = 0.0;
private double accelY = 0.0;
public Player() {
}
public Player(double xPos, double yPos, double xVel, double yVel, int width, int height) {
this.xPos = xPos;
this.yPos = yPos;
this.xVel = xVel;
this.yVel = yVel;
this.width = width;
this.height = height;
}
public void update(double delta) {
this.xVel += accelX * delta;
this.yVel += accelY * delta;
if(abs(xVel) > MAX_VELOCITY){xVel = MAX_VELOCITY * xDir;}
if(abs(yVel) > MAX_VELOCITY){yVel = MAX_VELOCITY * yDir;}
if(xVel > 0) xVel += -FRICTION / mass;
if(xVel < 0) xVel += FRICTION / mass;
//debugging
//System.out.println(yVel);
if(yVel > 0) yVel += -FRICTION / mass;
if(yVel < 0) yVel += FRICTION / mass;
//System.out.println(yVel);
//if(!moving){xVel = 0; yVel = 0;}
this.xPos += this.xVel * delta;
this.yPos += this.yVel * delta;
}
public void setMoving(boolean moving){
this.moving = moving;
}
public void move(double delta) {
/*
* Acceleration = Force / Mass
* Velocity += Acceleration * ElapsedTime (delta)
* Position += Velocity * ElapsedTime (delta)
*/
}
public double getAccel(){
return ACCELERATION;
}
public void addAccelX(int dir) {
this.accelX += ACCELERATION * dir;
//this.xDir = dir;
}
public void addAccelY(int dir) {
this.accelY += ACCELERATION * dir;
//this.yDir = dir;
}
public double getXPos() {
return this.xPos;
}
public double getYPos() {
return this.yPos;
}
public double getXVel() {
return this.xVel;
}
public double getYVel() {
return this.yVel;
}
public int getHeight() {
return this.height;
}
public int getWidth() {
return this.width;
}
public void addXPos(int delta) {
this.xPos += delta;
}
public void addYPos(int delta) {
this.yPos += delta;
}
public void addXVel(int delta) {
this.xVel += delta;
}
public void addYVel(int delta) {
this.yVel += delta;
}
}
(请原谅邋code的代码。) 小红方播放器移动很好,但是当我释放箭头键时,播放器以20的速度(此时任意单位)移动(向下或向右),这几乎是几个像素/秒。 我认为它与摩擦有关,但我不确定。
答案 0 :(得分:2)
您永远不会重置accelX
和accelY
,因此不断在帧中应用加速度。你的玩家实际上应该加速,但我认为摩擦可能会以某种方式相互作用以创造缓慢的运动。