所以我试图在java中制作流行的游戏。我已经制作了播放器矩形并设置了动作监听器,所以我准备在屏幕上上下移动播放器。但我遇到了一个问题。当我移动播放器时,我可以选择每次移动移动X像素。
但是,如果我将X像素设置为移动,则说1.然后播放器移动速度太慢。如果我将X像素设置为10,那么他会跳过9个像素,动画看起来很粗糙。如何平滑动画并仍然快速移动?
这里有一些代码:
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == keyUp){
playerYCordinate -= 10;
}else if(e.getKeyCode() == keyDown){
playerYCordinate += 10;
}
repaint();
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == keyUp){
}else if(e.getKeyCode() == keyDown){
}
repaint();
}
答案 0 :(得分:4)
不要依赖系统提供的按键重复功能。它们可能以低速率发生(这会导致您描述的问题)并依赖于系统键盘设置。
我建议您使用keyPressed
来启动Timer
和keyReleased
来停止它。
计时器可以安排每20秒左右执行TimerTask
,这可以更新坐标并调用repaint()
。 (不要担心过于频繁地调用repaint()
。如果EDT无法跟上,它会折叠连续调用以重新绘制为单个颜色。)
答案 1 :(得分:2)
如何使动画平滑并且仍能快速移动?
一种技术是沿每条移动步进较少像素的路径绘制移动物体的半透明版本。
E.G。对于10像素的移动,为移动的第一个像素绘制10%不透明度的版本,为第二个像素绘制20%的等级。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MovingBlock {
MovingBlock() {
final JPanel gui = new JPanel() {
private static final long serialVersionUID = 1L;
int x = 0;
int step = 60;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
x+=10;
Color fg = getForeground();
for (int ii=x-step; ii<x; ii+=4) {
double transparency = (double)(x-ii)/(double)step;
Color now = new Color(
fg.getRed(),
fg.getGreen(),
fg.getBlue(),
(int)(255*(1-transparency)));
g2.setColor(now);
g2.fillRect(ii, 3, 5, 10);
}
if (x>getWidth()) {
x=0;
}
}
};
gui.setBackground(Color.BLACK);
gui.setForeground(Color.GREEN.darker());
gui.setPreferredSize(new Dimension(400,16));
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
gui.repaint();
}
};
Timer timer = new Timer(20, listener);
timer.start();
JFrame f = new JFrame("Moving Block");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(gui);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MovingBlock();
}
});
}
}
答案 2 :(得分:2)
在游戏中,传统上使用游戏循环来控制应用程序,而不是驱动Swing的事件驱动系统。
你可以有一个存储划桨移动的变量,例如包含UP
,DOWN
和STATIONARY
的枚举。您的关键监听器将设置此变量的值,然后游戏循环将检查变量并相应地更新换档位置。
此技术将应用程序的速度与其运行环境的速度分离。
答案 3 :(得分:1)
请勿KeyListener
使用Swing JComponents
将KeyBinding用于Swing JComponents
不要画到JFrame
放在那里JPanel
并使用方法paintComponent()
代替paint()
,你的动作将是流畅自然的< / p>
答案 4 :(得分:0)
只要你依靠按键来控制你的矩形,你就可以像keyrepeat事件一样快地移动(或者跟用户输入的速度一样快)。要么倾听鼠标移动等其他内容,要么将键盘配置为更高的重复率。