首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KeyListener迟滞

KeyListener迟滞
EN

Stack Overflow用户
提问于 2015-03-19 18:33:07
回答 1查看 132关注 0票数 1

我正在用Java编写一个小游戏,和大多数游戏一样,我需要倾听用户的输入。我决定使用java.awt.event.KeyListener来处理输入。

以下是我的主要方法:

代码语言:javascript
复制
public static void main(String[] args){
    LevelViewer l = new LevelViewer(LevelFileIO.load());
    List<Entity> entities = l.getEntities();
    List<GameObject> gameObjects = l.getGameObjects();
    Pacman player = null;
    for (Entity e : entities){
        if (e instanceof Pacman){
            player = (Pacman)e;
            break;
        }
    }


    JFrame frame = new JFrame();
    frame.add(l);
    frame.setResizable(false);
    frame.pack();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setFocusable(true);
    frame.requestFocus();

    class Listener implements KeyListener{
        Pacman player;


        Listener(Pacman player){
            this.player = player;
        }

        @Override
        public void keyPressed(KeyEvent e) {
            switch(e.getKeyCode()){
            case KeyEvent.VK_W:
                player.up();
                break;
            case KeyEvent.VK_D:
                player.right();
                break;
            case KeyEvent.VK_S:
                player.down();
                break;
            case KeyEvent.VK_A:
                player.left();
                break;
            }


        }

        @Override
        public void keyReleased(KeyEvent e) {}

        @Override
        public void keyTyped(KeyEvent e) {}

    }
    frame.addKeyListener(new Listener(player));
    Timer timer = new Timer();
    timer.schedule(new UpdateTimer(
            entities.toArray(new Entity[entities.size()]),
            gameObjects.toArray(new GameObject[gameObjects.size()]),
            l), 0, 17);
}

这一切都很简单,当我读到关键事件时,我在玩家中调用方法,只需改变他的速度。

举个例子:

代码语言:javascript
复制
public void right(){
    this.setVelocity(new Vector2(speed, 0));
    this.setSprite(right);
}

主方法末尾的计时器只调用以下命令:

代码语言:javascript
复制
public UpdateTimer(Entity[] toUpdate, GameObject[] gameObjects, LevelViewer toRedraw){
    this.toUpdate = toUpdate;
    this.gameObjects = gameObjects;
    this.toRedraw = toRedraw;
}

@Override
public void run() {
    toRedraw.repaint();
    if (timeAtLastUpdateCall == 0){
        timeAtLastUpdateCall = System.currentTimeMillis();
        for (Entity e : toUpdate){
            e.start();
        }
        return;
    }
    long newTime = System.currentTimeMillis();
    double deltaT = ((double)(newTime - timeAtLastUpdateCall)/1000.0);
    timeAtLastUpdateCall = newTime;
    for (Entity e : toUpdate){
        for (GameObject g : gameObjects){
            if (g.touching(e)){
                e.setVelocity(e.getVelocity().multiply(-1));
                e.free(g);
            }
        }
        e.update(deltaT);
        e.getSprite().nextFrame();
    }
}

这个运行函数所做的只是一些碰撞检查,然后在每个实体中调用update方法。对于播放器,它只是计算自上次更新调用以来它应该移动多少:

代码语言:javascript
复制
public void update(double deltaT){
    this.setPosition(this.getPosition().add(velocity.multiply(deltaT)));
}

现在的问题是,当我按下一个改变玩家速度的键时,变化通常是瞬间发生的,但有时会出现明显的滞后(大约是四分之一秒,超过17毫秒)。

这是KeyListener的问题,还是我的实现的问题?

我想要修复这个有平滑的用户输入。

EN

回答 1

Stack Overflow用户

发布于 2015-03-19 23:30:39

我不认为这是KeyListener的问题。我不是一个游戏开发人员,而是一些需要考虑的事情:

  1. 您是否计时了执行TimerTask所需的时间?如果它超过17‘s,那么这可能是一个问题,特别是当您将日程安排scheduleAtFixedRate进行比较时
  2. 您可能需要使用一个适当的游戏回路,特别是如果您计划在系统上玩这个游戏,在您的控制之外。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29152390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档