我有一个精灵事件的KeyEvent,可以左右移动。我只是在四处乱逛,正在为另一个我想让精灵跳的项目做准备。在我刚开始时,它不必完全现实。我所拥有的是,当按下空格键时,它将导致精灵跳跃,让我们说“ dy = -3”。因此,我有了用于keyReleased的KeyEvent,它将下降为“ dy = -2”。这不起作用,因为精灵只是继续掉下……有人可以发光吗?
完整代码:
包装碰撞;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Craft {
private String craft = "pelican.png";
private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;
private Image image;
private ArrayList missiles;
public Craft() {
ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
image = ii.getImage();
width = image.getWidth(null);
height = image.getHeight(null);
missiles = new ArrayList();
visible = true;
x = 100;
y = 300;
}
public void move() {
x += dx;
y += dy;
if (x < 1) {
x = 1;
}
if (y < 1) {
y = 1;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public ArrayList getMissiles() {
return missiles;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
}
if (key == KeyEvent.VK_V){
dx = 6;
}
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 2;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
public void fire() {
missiles.add(new Missile(x + width, y + height/2));
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_SPACE) {
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
if (key == KeyEvent.VK_UP) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}
您可能已经注意到,Im对Java以及游戏编程都是陌生的。我只想让精灵上升,然后再下降。如果有帮助,它将始终保持静止。精灵一直在跳,直到他被即将来临的障碍击中为止。我知道有其他动作的代码,但是一旦我开始下一个精灵,这些动作将被删除。
最佳答案
这是基本概念。您的实现将根据引擎的实现而改变。
基本思想是玩家有一个垂直方向的变化量,该变化量会随着时间的流逝而变化。这会影响精灵的垂直速度。
此实现还具有重新绑定的增量,该增量允许小精灵重新绑定而不是突然“停止”。重新绑定受重新绑定降级的影响,这会减少每个重新绑定上的重新绑定数量。
这模拟了一个游戏角色,因此您需要点击Space才能开始弹跳...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JumpingSprite {
public static void main(String[] args) {
new JumpingSprite();
}
public JumpingSprite() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
protected static final int SPRITE_HEIGHT = 10;
protected static final int SPRITE_WIDTH = 10;
private float vDelta; // The vertical detla...
private float rbDelta; // Rebound delta...
private float rbDegDelta; // The amount the rebound is degradation...
private int yPos; // The vertical position...
private float gDelta; // Gravity, how much the vDelta will be reduced by over time...
private Timer engine;
private boolean bounce = false;
public TestPane() {
yPos = getPreferredSize().height - SPRITE_HEIGHT;
vDelta = 0;
gDelta = 0.25f;
// This is how much the re-bound will degrade on each cycle...
rbDegDelta = 2.5f;
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "jump");
am.put("jump", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
// Can only bound when we're actually on the ground...
// You might want to add fudge factor here so that the
// sprite can be within a given number of pixels in order to
// jump again...
if (yPos + SPRITE_HEIGHT == getHeight()) {
vDelta = -8;
rbDelta = vDelta;
bounce = true;
}
}
});
engine = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int height = getHeight();
// No point if we've not been sized...
if (height > 0) {
// Are we bouncing...
if (bounce) {
// Add the vDelta to the yPos
// vDelta may be postive or negative, allowing
// for both up and down movement...
yPos += vDelta;
// Add the gravity to the vDelta, this will slow down
// the upward movement and speed up the downward movement...
// You may wish to place a max speed to this
vDelta += gDelta;
// If the sprite is not on the ground...
if (yPos + SPRITE_HEIGHT >= height) {
// Seat the sprite on the ground
yPos = height - SPRITE_HEIGHT;
// If the re-bound delta is 0 or more then we've stopped
// bouncing...
if (rbDelta >= 0) {
// Stop bouncing...
bounce = false;
} else {
// Add the re-bound degregation delta to the re-bound delta
rbDelta += rbDegDelta;
// Set the vDelta...
vDelta = rbDelta;
}
}
}
}
repaint();
}
});
engine.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth() - 1;
int xPos = (width - SPRITE_WIDTH) / 2;
g2d.drawOval(xPos, yPos, SPRITE_WIDTH, SPRITE_HEIGHT);
g2d.dispose();
}
}
}