如何解决如何让我的跳跃动画一次全部生效?
我在让我的游戏角色跳跃时遇到了一些问题。我已将我的跳跃功能设置为空格键,但跳跃动画不会同时发生。相反,按空格会使角色每次向上移动一点,直到达到最大跳跃高度限制。然后,一旦它达到该高度,按下空间会使玩家每次向下移动一点,直到达到地面限制。按住空格键时看起来很正常,但是一旦松开,角色就会卡在松开空格键的空气中。我希望只需按一下空格键就可以一次全部发生。我已经查看了我的代码很长一段时间,并尝试更改我从 JPanel 为我的 Player 类调用“act”方法的位置。这是我的 Player 类,其中的跳跃功能旨在为其分配值:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Player {
ImageIcon movements[];
ImageIcon leftMove[];
ImageIcon move[];
ImageIcon attack;
boolean ableAttack,canJump;
int count,x,y,width,height;
int fallingSpeed = 0;
int gravity = 1;
int jumpPower = -20;
public Player(int count,int x,int y) {
this.x = x;
this.y = y;
this.count = count;
movements = new ImageIcon[8];
leftMove = new ImageIcon[8];
attack = new ImageIcon("attackRight.gif");
this.width = 80;
this.height = 130;
for (int i = 0; i < 8; i++) {
movements[i] = new ImageIcon("right_"+(i + 1) + ".png");
leftMove[i] = new ImageIcon("go_"+(i+1)+".png");
}
move = movements.clone();
}
public void act() {
if (isOnGround()) {
canJump = true;
jump();
} else {
canJump = false;
fall();
}
}
public void jump() {
fallingSpeed = jumpPower;
fall();
}
public void fall() {
y += fallingSpeed;
fallingSpeed = fallingSpeed + gravity;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public boolean isOnGround() {
if (y > 410)
return true;
return false;
}
public void setAttack(boolean attack) {
ableAttack = attack;
}
public void setimageArrLeft() {
move = leftMove.clone();
attack = new ImageIcon("attack.gif");
}
public void setimageArrRight() {
move = movements.clone();
attack = new ImageIcon("attackRight.gif");
}
public void increaseCount() {
count++;
}
public void myDraw(Graphics g) {
if (ableAttack) {
g.drawImage(attack.getimage(),width + 30,height + 10,null);
}
else {
g.drawImage(move[count % 8].getimage(),height,null);
}
}
}
然后,在我的 JPanel 类中,我在 keypressed 方法下调用 Player 类中的 act() 方法,从 KeyListener 接口检查 VK_ENTER:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class MyPanel extends JPanel implements ActionListener,MouseListener,MouseMotionListener,KeyListener{
int mouseX,mouseY,x = 100,y = 420;
Timer timer;
ImageIcon background = null;
Player p;
public MyPanel() {
timer = new Timer(60,this);
p = new Player((int)(Math.random() * 8),y);
background = new ImageIcon("battlefield1.png");
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getimage(),1375,750,null);
p.myDraw(g);
repaint();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==timer) {
}
}
public void mouseClicked(MouseEvent me) {}
public void mouseEntered(MouseEvent me) {}
public void mouseExited(MouseEvent me) {}
public void mousepressed(MouseEvent me) {}
public void mouseReleased(MouseEvent me) {}
public void mouseDragged(MouseEvent me) {}
public void mouseMoved(MouseEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keypressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
p.increaseCount();
if (x < 1300)
x += 10;
p.setX(x);
p.setimageArrRight();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
p.increaseCount();
if (x > 0)
x -= 5;
p.setX(x);
p.setimageArrLeft();
}
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
p.setAttack(true);
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
p.act();
}
}
@Override
public void keyreleased(KeyEvent e) {
// Todo Auto-generated method stub
p.setAttack(false);
}
}
解决方法
您需要更好地理解动画(一般)和游戏循环。
Swing 使用被动渲染方法,因此您需要设置一个“游戏循环”来更新游戏状态,考虑用户提供的任何输入,然后安排重绘。
这意味着,您不能在 KeyListener
中更新玩家的状态,而是需要设置一个允许“游戏循环”更新整体状态的状态。
这是一个非常基本的例子...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MyPanel extends JPanel implements ActionListener,MouseListener,MouseMotionListener,KeyListener {
int mouseX,mouseY,x = 100,y = 420;
Timer timer;
Player p;
public MyPanel() {
timer = new Timer(60,this);
p = new Player((int) (Math.random() * 8),x,y);
setBackground(Color.BLUE);
addKeyListener(this);
setFocusable(true);
}
@Override
public void addNotify() {
super.addNotify();
timer.start();
}
@Override
public void removeNotify() {
super.removeNotify();
timer.stop();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(800,800);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
p.myDraw(g);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == timer) {
p.update();
repaint();
}
}
public void mouseClicked(MouseEvent me) {
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
}
public void mouseReleased(MouseEvent me) {
}
public void mouseDragged(MouseEvent me) {
}
public void mouseMoved(MouseEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
p.increaseCount();
if (x < 1300) {
x += 10;
}
p.setX(x);
p.setImageArrRight();
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
p.increaseCount();
if (x > 0) {
x -= 5;
}
p.setX(x);
p.setImageArrLeft();
}
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
p.setAttack(true);
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
p.act();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
p.setAttack(false);
}
}
public class Player {
boolean ableAttack,canJump;
int count,y,width,height;
int fallingSpeed = 0;
int gravity = 1;
int jumpPower = -20;
private boolean isJumping = false;
public Player(int count,int x,int y) {
this.x = x;
this.y = y;
this.count = count;
width = 10;
height = 10;
}
public void act() {
if (isOnGround()) {
jump();
// canJump = true;
// jump();
//
// } else {
// canJump = false;
// fall();
}
}
public void jump() {
isJumping = true;
fallingSpeed = jumpPower;
fall();
}
public void fall() {
y += fallingSpeed;
fallingSpeed = fallingSpeed + gravity;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public boolean isOnGround() {
if (y > 410) {
return true;
}
return false;
}
public void setAttack(boolean attack) {
ableAttack = attack;
}
public void setImageArrLeft() {
}
public void setImageArrRight() {
}
public void increaseCount() {
count++;
}
public void update() {
if (isJumping) {
if (!isOnGround()) {
fall();
} else {
isJumping = false;
}
}
}
public void myDraw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x,height);
}
}
}
就我个人而言,我会使用 Key Bindings 而不是 KeyListener
,因为它将解决键盘焦点的直接问题并提供更可配置的方法。
这意味着“输入状态”将独立于玩家,游戏循环将负责根据游戏状态控制玩家状态变化
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。