为什么我的播放器在释放箭头键后继续移动(非常慢)?

时间:2013-11-25 21:50:13

标签: java swing game-physics

我正在使用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的速度(此时任意单位)移动(向下或向右),这几乎是几个像素/秒。 我认为它与摩擦有关,但我不确定。

1 个答案:

答案 0 :(得分:2)

您永远不会重置accelXaccelY,因此不断在帧中应用加速度。你的玩家实际上应该加速,但我认为摩擦可能会以某种方式相互作用以创造缓慢的运动。