首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按键和播放器动画发生之间的延迟(KeyListener、Java)

按键和播放器动画发生之间的延迟(KeyListener、Java)
EN

Stack Overflow用户
提问于 2020-04-08 00:02:23
回答 1查看 35关注 0票数 0

我是第一次接触堆栈溢出,所以如果我犯了任何错误,请原谅。

我正在写一个动画的移动玩家的java游戏,然而,当我按键移动说的玩家(W,A,S和D),玩家停止,等待一小段时间,然后正常行走。这就像w.....wwwwwwwwwwwwwwwwwwww一样。意味着玩家不会移动。

我已经查找了很多解决方案,但由于某种原因,它们都不起作用。即使我使用setter来设置animation...the,也会发生同样的事情。

我的代码是错的吗?我是不是遗漏了什么??

这是包含播放器和KeyListener的类。有什么问题吗?

代码语言:javascript
复制
import javax.swing.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;


class Play extends JPanel implements KeyListener, ActionListener{
JFrame playFrame = new JFrame("Play");

int xPos = 295;
int yPos= 215;

int xWorld = 0;
int yWorld = 0;

int worldSizeX = 640;
int worldSizeY = 480; 

boolean w, a, s, d, shift, esc, b;

Font font;

private BufferedImage[] walkingDown = {Sprite.getSprite(0,0), Sprite.getSprite(1,0), Sprite.getSprite(2,0), Sprite.getSprite(3,0)};
private BufferedImage[] walkingDownLeft = {Sprite.getSprite(0,1), Sprite.getSprite(1,1), Sprite.getSprite(2,1), Sprite.getSprite(3,1)};
private BufferedImage[] walkingDownRight = {Sprite.getSprite(0,2), Sprite.getSprite(1,2), Sprite.getSprite(2,2), Sprite.getSprite(3,2)};
private BufferedImage[] walkingUp = {Sprite.getSprite(0,5), Sprite.getSprite(1,5), Sprite.getSprite(2,5), Sprite.getSprite(3,5)};
private BufferedImage[] walkingUpLeft = {Sprite.getSprite(0,6), Sprite.getSprite(1,6), Sprite.getSprite(2,6), Sprite.getSprite(3,6)};
private BufferedImage[] walkingUpRight = {Sprite.getSprite(0,7), Sprite.getSprite(1,7), Sprite.getSprite(2,7), Sprite.getSprite(3,7)};
private BufferedImage[] walkingLeft = {Sprite.getSprite(0,3), Sprite.getSprite(1,3), Sprite.getSprite(2,3), Sprite.getSprite(3,3)};
private BufferedImage[] walkingRight = {Sprite.getSprite(0,4), Sprite.getSprite(1,4), Sprite.getSprite(2,4), Sprite.getSprite(3,4)};
private BufferedImage[] standing = {Sprite.getSprite(0,0)};

private Animation walkDown = new Animation(walkingDown, 12);
private Animation walkDownLeft = new Animation(walkingDownLeft, 12);
private Animation walkDownRight = new Animation(walkingDownRight, 12);
private Animation walkUp = new Animation(walkingUp, 12);
private Animation walkUpLeft = new Animation(walkingUpLeft, 12);
private Animation walkUpRight = new Animation(walkingUpRight, 12);
private Animation walkLeft = new Animation(walkingLeft, 12);
private Animation walkRight = new Animation(walkingRight, 12);
private Animation stand = new Animation(standing, 12);

private BufferedImage[] rollingDown = {Sprite.getSprite(0,8), Sprite.getSprite(1,8), Sprite.getSprite(2,8), Sprite.getSprite(3,8)};
private BufferedImage[] rollingDownLeft = {Sprite.getSprite(0,9), Sprite.getSprite(1,9), Sprite.getSprite(2,9), Sprite.getSprite(3,9)};
private BufferedImage[] rollingDownRight = {Sprite.getSprite(0,10), Sprite.getSprite(1,10), Sprite.getSprite(2,10), Sprite.getSprite(3,10)};
private BufferedImage[] rollingUp = {Sprite.getSprite(0,13), Sprite.getSprite(1,13), Sprite.getSprite(2,13), Sprite.getSprite(3,13)};
private BufferedImage[] rollingUpLeft = {Sprite.getSprite(0,14), Sprite.getSprite(1,14), Sprite.getSprite(2,14), Sprite.getSprite(3,14)};
private BufferedImage[] rollingUpRight = {Sprite.getSprite(0,15), Sprite.getSprite(1,15), Sprite.getSprite(2,15), Sprite.getSprite(3,15)};
private BufferedImage[] rollingLeft = {Sprite.getSprite(0,11), Sprite.getSprite(1,11), Sprite.getSprite(2,11), Sprite.getSprite(3,11)};
private BufferedImage[] rollingRight = {Sprite.getSprite(0,12), Sprite.getSprite(1,12), Sprite.getSprite(2,12), Sprite.getSprite(3,12)};

private Animation rollDown = new Animation(rollingDown, 12);
private Animation rollDownLeft = new Animation(rollingDownLeft, 12);
private Animation rollDownRight = new Animation(rollingDownRight, 12);
private Animation rollUp = new Animation(rollingUp, 12);
private Animation rollUpLeft = new Animation(rollingUpLeft, 12);
private Animation rollUpRight = new Animation(rollingUpRight, 12);
private Animation rollLeft = new Animation(rollingLeft, 12);
private Animation rollRight = new Animation(rollingRight, 12);

private Animation animation = stand;

Timer timer = new Timer(12, this);

public Play(){
    playFrame.setPreferredSize(new Dimension(640,480));
    playFrame.pack();
    playFrame.setResizable(false);
    playFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    playFrame.setLocationRelativeTo(null);

    addKeyListener(this);
    setFocusable(true);

    timer.start();

    playFrame.setVisible(true);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;

    setBackground(Color.CYAN);

    g2d.setColor(Color.GREEN);
    g2d.fillRect(xWorld,yWorld, 640,480);

    g2d.drawImage(animation.getSprite(), xPos, yPos, null);

    if(esc == true){
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0,0, 640,480);

        try{
            font = Font.createFont(Font.TRUETYPE_FONT, new File("pixelated/pixelated.ttf"));
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("pixelated/pixelated.ttf")));
        }catch(IOException|FontFormatException e){
        }

        g2d.setFont(font.deriveFont(80f));
        g2d.setColor(Color.WHITE);
        g2d.drawString("Paused", 205,80);

        g2d.setFont(font.deriveFont(30f));
        g2d.drawString("To resume, press W, A, S or D", 150,150);

        g2d.drawString("Or", 305,240);

        g2d.drawString("Press ESCAPE + B to go back to MainMenu <--", 40,320);

        if(esc == true && w == true){
            esc = false;
        }
        if(esc == true && a == true){
            esc = false;
        }
        if(esc == true && s == true){
            esc = false;
        }
        if(esc == true && d == true){
            esc = false;
        }
    }
}

public void keyPressed(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_W) w = true;
    if(e.getKeyCode() == KeyEvent.VK_A) a = true;
    if(e.getKeyCode() == KeyEvent.VK_S) s = true;
    if(e.getKeyCode() == KeyEvent.VK_D) d = true;
    if(e.getKeyCode() == KeyEvent.VK_SHIFT) shift = true;
    if(e.getKeyCode() == KeyEvent.VK_ESCAPE) esc = true;
    if(e.getKeyCode() == KeyEvent.VK_B) b = true;

    //walking
    if(w == true){      
        yWorld = yWorld+1;

        animation = walkUp;
        animation.start();

        repaint();
    }
    if(a == true){
        xWorld = xWorld+1;

        animation = walkLeft;
        animation.start();

        repaint();
    } 
    if(s == true){
        yWorld = yWorld-1;

        animation = walkDown;
        animation.start();

        repaint();
    }
    if(d == true){
        xWorld = xWorld-1;

        animation = walkRight;
        animation.start();

        repaint();
    }

    if(w==true && a==true){
        yWorld = yWorld+1;
        xWorld = xWorld+1;

        animation = walkUpLeft;
        animation.start();
    }       
    if(w==true && d==true){
        yWorld = yWorld+1;
        xWorld = xWorld-1;

        animation = walkUpRight;
        animation.start();
    }       
    if(s==true && a==true){
        yWorld = yWorld-1;
        xWorld = xWorld+1;

        animation = walkDownLeft;
        animation.start();
    }       
    if(s==true && d==true){
        yWorld = yWorld-1;
        xWorld = xWorld-1;

        animation = walkDownRight;
        animation.start();
    }

    //rolling
    if(w==true && shift==true){
        yWorld = yWorld+5;

        animation = rollUp;
        animation.start();

        repaint();
    }
    if(a==true && shift==true){
        xWorld = xWorld+5;

        animation = rollLeft;
        animation.start();

        repaint();
    }
    if(s==true && shift==true){
        yWorld = yWorld-5;

        animation = rollDown;
        animation.start();

        repaint();
    }
    if(d==true && shift==true){
        xWorld = xWorld-5;

        animation = rollRight;
        animation.start();

        repaint();
    }

    if(w==true && a==true &&shift==true){
        yWorld = yWorld+1;
        xWorld = xWorld+1;

        animation = rollUpLeft;
        animation.start();
    }       
    if(w==true && d==true &&shift==true){
        yWorld = yWorld+1;
        xWorld = xWorld-1;

        animation = rollUpRight;
        animation.start();
    }       
    if(s==true && a==true &&shift==true){
        yWorld = yWorld-1;
        xWorld = xWorld+1;

        animation = rollDownLeft;
        animation.start();
    }       
    if(s==true && d==true &&shift==true){
        yWorld = yWorld-1;
        xWorld = xWorld-1;

        animation = rollDownRight;
        animation.start();
    }

    if(esc == true && b == true){
        esc = false;

        playFrame.setVisible(false);

        new MainMenu();
    }
}

public void keyReleased(KeyEvent e){
    if(e.getKeyCode() == KeyEvent.VK_W) w = false;
    if(e.getKeyCode() == KeyEvent.VK_A) a = false;
    if(e.getKeyCode() == KeyEvent.VK_S) s = false;
    if(e.getKeyCode() == KeyEvent.VK_D) d = false;
    if(e.getKeyCode() == KeyEvent.VK_SHIFT) shift = false;
    if(e.getKeyCode() == KeyEvent.VK_B) b = false;

    if(w == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(a == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(s == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(d == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }

    if(shift == false){
        animation.stop();
        animation.reset();
        animation = stand;
    }
}

public void keyTyped(KeyEvent e){
}

public void actionPerformed(ActionEvent e){     
    animation.update();

    if(yPos < yWorld){
        yWorld = yPos;
        yPos = yWorld;
    }
    if(xPos < xWorld){
        xWorld = xPos;
        xPos = xWorld;
    }       
    if((yPos+64) > (yWorld+worldSizeY)){
        yWorld = yPos-worldSizeY+64;
        yPos = (yWorld+worldSizeY)-64;
    }
    if((xPos+64) > (xWorld+worldSizeX)){
        xWorld = xPos-worldSizeX+64;
        xPos = (xWorld+worldSizeX)-64;  
    }
  }
}
EN

回答 1

Stack Overflow用户

发布于 2020-04-08 05:50:13

当我按下键移动所述播放器(W,A,S和D)时,播放器停止,稍等片刻,然后正常行走。

这是因为键盘的“重复频率”是由操作系统中的设置控制的。不要依赖操作系统来生成事件。

相反,您应该使用Swing Timer来安排事件。当密钥为:

按下

  1. ,启动计时器。
  2. 释放,你停止计时器。

此外,您应该使用“键绑定”,而不是KeyListener。

阅读Swing教程中有关以下内容的部分:

  1. How to Use Swing Timers
  2. How to Use Key Bindings

有关这些概念的详细信息,请参阅。

你也可以查看:Motion Using the KeyboardKeyboard Animation示例合并了上述两个建议。此外,绘制方法仅用于绘制。您不应该:

  1. 读取字体文件
  2. 设置属性值

您无法控制何时调用paintComponent()方法,因此您应该只绘制类的当前状态。您需要其他方法来更改变量的状态。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61084288

复制
相关文章

相似问题

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