简体   繁体   English

按键与播放器 animation 发生之间的延迟(KeyListener,Java)

[英]Delay between key being pressed and player animation occuring (KeyListener, Java)

I am new to stack overflow so please excuse me if i make any mistakes.我是堆栈溢出的新手,所以如果我犯了任何错误,请原谅。

I am writing a java game with moving player which is animated, however when i press the keys to move said player (W, A, S and D), the player stops, waits a bit, then walks normally.我正在编写一个带有动画的移动玩家的 java 游戏,但是当我按下按键来移动所述玩家(W、A、S 和 D)时,玩家会停下来,稍等片刻,然后正常行走。 It is like w.....wwwwwwwwwwwwwwwwwwww where the.它就像 w .....wwwwwwwwwwwwwwwwwwwww 哪里。 means the player isnt moving.意味着玩家没有移动。

I have looked up many solutions however none of them work for some reason.我查找了许多解决方案,但是由于某种原因,它们都不起作用。 Even when i use setters to set the animation...the same thing happens.即使我使用设置器设置 animation ......同样的事情也会发生。

Is my code wrong?我的代码错了吗? Am i missing something??我错过了什么吗?

Here is the class with the player and KeyListener.这是带有播放器和 KeyListener 的 class。 Is there something wrong?有什么不对?

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

when i press the keys to move said player (W, A, S and D), the player stops, waits a bit, then walks normally.当我按下按键移动所述玩家(W、A、S 和 D)时,玩家会停下来,稍等片刻,然后正常行走。

This is because the "repeat rate" of the keyboard is controlled by a setting in your OS.这是因为键盘的“重复率”由操作系统中的设置控制。 Don't rely on the OS to generate events.不要依赖操作系统来生成事件。

Instead you should be using a Swing Timer to schedule the events.相反,您应该使用Swing Timer来安排事件。 When the key is:当关键是:

  1. pressed, you start the Timer.按下,您启动计时器。
  2. released, you stop the Timer.释放,你停止定时器。

Also you should be using "Key Bindings", not a KeyListener.此外,您应该使用“键绑定”,而不是 KeyListener。

Read the sections from the Swing tutorial on:阅读 Swing 教程中的部分:

  1. How to Use Swing Timers 如何使用 Swing 定时器
  2. How to Use Key Bindings 如何使用键绑定

for more information on these concepts.有关这些概念的更多信息。

You can also check out: Motion Using the Keyboard .您还可以查看: 使用键盘运动 The Keyboard Animation example incorporates the above two suggestions. Keyboard Animation示例包含上述两个建议。 Also, a painting method is for painting only.此外,绘画方法仅用于绘画。 You should NOT:你不应该:

  1. read the font file读取字体文件
  2. set property values设置属性值

You can't control when the paintComponent() method is called, so you should only paint the current state of your class.您无法控制何时调用 paintComponent() 方法,因此您应该只绘制 class 的当前 state。 You need other methods to change the state of your variables.您需要其他方法来更改变量的 state。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM