2013-11-25 61 views
1

我正在使用Swing開發我的第一個2D Java遊戲,並且遇到了一個奇怪的bug。 下面是相關的代碼,首先:爲什麼我的播放器在釋放箭頭鍵後繼續移動(非常緩慢)?

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; 
    } 

} 

(請原諒馬虎的代碼)。 小紅方玩家移動精,但是當我釋放箭頭鍵時,播放器以20(此時爲任意單位)的速度移動(向下或向右),其速度爲幾個像素/秒。 我認爲這與摩擦有關,但我不確定。

回答

2

你永遠不會重置accelXaccelY,所以加速度連續地跨幀應用。你的球員實際上應該在加速,但我認爲這種摩擦可能以某種方式相互作用,從而造成慢速移動。

相關問題