该程序工作正常,但当我按住一个键或更改键时,动作不顺畅。在变得平滑之前暂停一瞬间。我还是Java的初学者,请详细解释。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game2015
{
JFrame frame;
DrawRect mainPanel;
GridBagLayout gridbag;
GridBagConstraints constraints;
Data data;
int width;
int height;
public static void main(String[] args)
{
new Game2015();
}
public Game2015()
{
frame = new JFrame();
width = 400;
height = 500;
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
frame.setSize(width, height);
frame.setResizable(false);
data = new Data();
mainPanel = new DrawRect(data);
mainPanel.setFocusable(true);
mainPanel.setBackground(Color.WHITE);
KeyHandler keys = new KeyHandler();
mainPanel.addKeyListener(keys);
frame.add(mainPanel);
frame.validate();
frame.setLocationRelativeTo(null);
Thread thread = new Thread(new Runnable(){
public void run()
{
while(true)
{
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
});
thread.start();
}
public class KeyHandler implements KeyListener
{
public void keyReleased(KeyEvent event)
{
}
public void keyTyped(KeyEvent event)
{
}
public void keyPressed(KeyEvent event)
{
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP)
{
if(data.getY() >= data.getSpeed())
{
data.setY(data.getY() - data.getSpeed());
}
else
{
data.setY(0);
}
}
else if(event.getKeyCode() == KeyEvent.VK_S || event.getKeyCode() == KeyEvent.VK_DOWN)
{
if(data.getY() + 95 <= height - data.getSpeed())
{
data.setY(data.getY() + data.getSpeed());
}
else
{
data.setY(height - 95);
}
}
else if(event.getKeyCode() == KeyEvent.VK_A || event.getKeyCode() == KeyEvent.VK_LEFT)
{
if(data.getX() >= data.getSpeed())
{
data.setX(data.getX() - data.getSpeed());
}
else
{
data.setX(0);
}
}
else if(event.getKeyCode() == KeyEvent.VK_D || event.getKeyCode() == KeyEvent.VK_RIGHT)
{
if(data.getX() + 75 <= width - data.getSpeed())
{
data.setX(data.getX() + data.getSpeed());
}
else
{
data.setX(width - 75);
}
}
else if(event.getKeyCode() == KeyEvent.VK_ESCAPE)
{
frame.dispose();
System.exit(0);
}
}
}
}
绘制矩形的代码是:
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
public class DrawRect extends JPanel
{
BufferedImage img_player;
File file;
Data data;
public DrawRect(Data newData)
{
data = newData;
try
{
file = new File("Images\\Player.png");
img_player = ImageIO.read(file);
}
catch (Exception exception)
{
}
}
@Override
public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.drawImage(img_player, data.getX(), data.getY(), null);
}
}
并且Data类的代码是:
public class Data
{
int x, y, speed;
public Data()
{
x = 0;
y = 0;
speed = 10;
}
public void setSpeed(int new_speed)
{
speed = new_speed;
}
public int getSpeed()
{
return speed;
}
public void setX(int new_x)
{
x = new_x;
}
public int getX()
{
return x;
}
public void setY(int new_y)
{
y = new_y;
}
public int getY()
{
return y;
}
}
答案 0 :(得分:0)
这是因为有java处理事件:当你第一次按一个键时,它会触发一个事件(按下键),并且只在一小段时间之后它继续触发事件(按住键)。您可以通过每次触发事件时打印出来进行测试,并且在第一个事件和其他事件之间会有一个小的延迟。
解决这个问题的方法不是每次按一个键改变字符位置,而是改变字符的速度。
例如,而不是
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
if(data.getY() >= data.getSpeed())
{
data.setY(data.getY() - data.getSpeed());
} else {
data.setY(0);
}
} ... etc ...
它将是
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
data.setVelocityY(-data.getSpeed());
} ... etc ...
除此之外,你还需要在释放钥匙时停止速度。在keyReleased()
方法中,只需执行相同的操作,但不要将速度设置为速度,而是将其设置为0.
if(event.getKeyCode() == KeyEvent.VK_W || event.getKeyCode() == KeyEvent.VK_UP){
data.setVelocityY(0);
} ... etc ...
然后在游戏循环和方法update()
中处理计算(将速度添加到位置)
所以
public void run() {
while(true) {
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
将是
public void run() {
while(true) {
update();
mainPanel.repaint();
mainPanel.requestFocus(true);
}
}
更新方法将是
public static void update() {
data.setY(data.getY() + data.getVelocityY());
data.setX(data.getX() + data.getVelocityX());
}
你应该查阅java游戏的基础教程。例如,我总是发现this是一本很好的入门教程。