【发布时间】:2022-01-05 10:30:00
【问题描述】:
我试图复制吃豆人游戏,我想出了玩家动画,然后根据需要转身并循环打开和关闭嘴巴。我编写了代码,它可以根据需要正常工作。只是当我按住按键(W、A、S、D)时它会张开和合上嘴,但并非总是如此。我不明白错误在哪里..这是我现在的代码:
package playerAnimation;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Animation extends JPanel implements ActionListener, KeyListener {
Timer tm = new Timer(1,this);
private String playerDirection="Right";
private int playerX;
private int playerY;
private int playerSpeedX;
private int playerSpeedY;
private int spriteCounter = 0;
private int spriteNum = 1;
public BufferedImage playerUp, playerDown, playerLeft, playerRight, playerClosedMouth;
public BufferedImage imagePlayer = null;
public void getPlayerImage() {
try {
playerUp = ImageIO.read(getClass().getResourceAsStream("/player/imageUp.png"));
playerDown = ImageIO.read(getClass().getResourceAsStream("/player/imageDown.png"));
playerLeft = ImageIO.read(getClass().getResourceAsStream("/player/imageLeft.png"));
playerRight = ImageIO.read(getClass().getResourceAsStream("/player/imageRight.png"));
playerClosedMouth = ImageIO.read(getClass().getResourceAsStream("/player/closed.png"));
}catch(IOException e ) {
e.printStackTrace();
}
}
Timer timer = new Timer(1,this);
public Animation() {
getPlayerImage();
tm.start();
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imagePlayer,playerX,playerY,null);
}
public void actionPerformed(ActionEvent e) {
playerX=playerX+playerSpeedX;
playerY=playerY+playerSpeedY;
repaint();
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W) {
if(spriteNum==1) {
imagePlayer=playerUp;
}
if(spriteNum==2) {
imagePlayer=playerClosedMouth;
}
playerSpeedX=0;
playerSpeedY=-1;
}
if(e.getKeyCode() == KeyEvent.VK_D) {
if(spriteNum==1) {
imagePlayer=playerRight;
}
if(spriteNum==2) {
imagePlayer=playerClosedMouth;
}
playerSpeedX=1;
playerSpeedY=0;
}
if(e.getKeyCode() == KeyEvent.VK_A) {
if(spriteNum==1) {
imagePlayer=playerLeft;
}
if(spriteNum==2) {
imagePlayer=playerClosedMouth;
}
playerSpeedX=-1;
playerSpeedY=0;
}
if(e.getKeyCode() == KeyEvent.VK_S) {
if(spriteNum==1) {
imagePlayer=playerDown;
}
if(spriteNum==2) {
imagePlayer=playerClosedMouth;
}
playerSpeedX=0;
playerSpeedY=1;
}
spriteCounter++;
if(spriteCounter>10) {
if(spriteNum==1) {
spriteNum=2;
}
else if(spriteNum==2) {
spriteNum=1;
}
spriteCounter=0;
}
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
还有主要的:
package playerAnimation;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
Animation player = new Animation();
JFrame Window = new JFrame();
Window.setTitle("playerAnimation");
Window.setSize(600,400);
Window.setVisible(true);
Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Window.add(player);
}
}
这是照片:
【问题讨论】:
-
1) 绘制方法应该只绘制类的当前状态,而不是改变状态。您当前的逻辑是更改要绘制的图像。该逻辑应移至侦听器类。所以基本上不需要“playerDirection”变量。相反,您只需在处理 KeyEvent 时设置“imagePlayer”变量。绘画方法然后只是绘画图像。 2) 你的定时器启动太快了。 1ms 不实用。也许它触发得太快并且重绘结果合并为一个,因此您看不到图像发生变化。尝试使用 1000 看看是否有效。
-
我照你说的做了。在paintComponent 方法中,我只留下了 g.drawImage (imagePlayer, playerX, playerY, null);相反,在 keyPressed 方法中,我在按下键的每个条件中放置了两个 if,例如(如果 spriteNum == 1)playerImage 变为 playerUp,并且(如果 spriteNum == 2)playerImage 变为 playerClosedMouth。这与密钥检测的所有条件有关。不幸的是,没有任何改变。只有按住按键时才会出现嘴部动画。
-
请包含图像或从 URL 热链接它们,这样我们也可以测试代码。并根据 camickr 提出的建议发布编辑后的代码
-
完成。我添加了照片并使用 camickr 所做的更正编辑了代码
-
Timer timer从未使用过