按键被按下和玩家动画发生之间的延迟(KeyListener,Java)

huangapple go评论123阅读模式
英文:

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

问题

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)};
    // ... (similar lines for other sprite arrays)

    private Animation walkDown = new Animation(walkingDown, 12);
    // ... (similar lines for other animations)
    
    private Animation animation = stand;
    
    Timer timer = new Timer(12, this);
    
    public Play(){
        // ... (constructor code)
    }
            
    public void paintComponent(Graphics g){
        // ... (paintComponent code)
    }
    
    public void keyPressed(KeyEvent e){
        // ... (keyPressed code)
    }
    
    public void keyReleased(KeyEvent e){
        // ... (keyReleased code)
    }
    
    public void keyTyped(KeyEvent e){
    }
    
    public void actionPerformed(ActionEvent e){
        // ... (actionPerformed code)
    }
}

(Note: The code you provided appears to be a Java program related to game development, with various sprite animations and key event handling. Since you requested that I only return the translated code, I've provided the translated Java code based on your input. Please ensure that the logic and functionality of the code remain intact after translation.)

英文:

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. It is like w.....wwwwwwwwwwwwwwwwwwww where the . 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.

Is my code wrong? Am i missing something??

Here is the class with the player and KeyListener. 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;	
}
}
}

答案1

得分: 1

当我按下移动玩家的键(W、A、S和D)时,玩家会停下来,等待片刻,然后正常行走。

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

相反,你应该使用Swing定时器来安排事件。当按键:

  1. 被按下时,你启动定时器。
  2. 被释放时,你停止定时器。

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

阅读Swing教程中有关以下概念的部分:

  1. 如何使用Swing定时器
  2. 如何使用键绑定

获取有关这些概念的更多信息。

你还可以查看:使用键盘进行运动Keyboard Animation示例结合了上述两个建议。
另外,绘图方法仅用于绘图。你不应该:

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

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

英文:

> when i press the keys to move said player (W, A, S and D), the player stops, waits a bit, then walks normally.

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. 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.

Read the sections from the Swing tutorial on:

  1. How to Use Swing Timers
  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.
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. You need other methods to change the state of your variables.

huangapple
  • 本文由 发表于 2020年4月8日 00:02:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/61084288.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定