我不能让我的2D游戏对象移动
这是我的主要代码的代码。我试着用函数创建一个包来检查键盘动作,但是它不起作用。所以,现在这两个代码都在您看到的相同文件下。到目前为止,程序打开,我可以看到圆圈,但它不会向左或向右移动。我一直在这里待3小时,相信与否。我不能让我的2D游戏对象移动
编辑:我只是意识到更新函数从名为“input”的包中获取数据。那是我把在相同的文件名都上课前,但即使当时有一个叫包中的类“gamesample.input。*,但它仍然是行不通的。
package gamesample;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
/**
* Main class for the game
*/
public class GameSample extends JFrame
{
boolean isRunning = true;
int fps = 30;
int windowWidth = 500;
int windowHeight = 500;
BufferedImage backBuffer;
Insets insets;
InputHandler input;
int x = 0;
public static void main(String[] args)
{
GameSample game = new GameSample();
game.run();
System.exit(0);
}
/**
* This method starts the game and runs it in a loop
*/
public void run()
{
initialize();
while(isRunning)
{
long time = System.currentTimeMillis();
update();
draw();
// delay for each frame - time it took for one frame
time = (1000/fps) - (System.currentTimeMillis() - time);
if (time > 0)
{
try
{
Thread.sleep(time);
}
catch(Exception e){}
}
}
setVisible(false);
}
/**
* This method will set up everything need for the game to run
*/
void initialize()
{
setTitle("Game Tutorial");
setSize(windowWidth, windowHeight);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
insets = getInsets();
setSize(insets.left + windowWidth + insets.right,
insets.top + windowHeight + insets.bottom);
backBuffer = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB);
input = new InputHandler(this);
}
/**
* This method will check for input, move things
* around and check for win conditions, etc
*/
void update()
{
if (input.isKeyDown(KeyEvent.VK_RIGHT))
{
x += 5;
}
if (input.isKeyDown(KeyEvent.VK_LEFT))
{
x -= 5;
}
}
/**
* This method will draw everything
*/
void draw()
{
Graphics g = getGraphics();
Graphics bbg = backBuffer.getGraphics();
bbg.setColor(Color.WHITE);
bbg.fillRect(0, 0, windowWidth, windowHeight);
bbg.setColor(Color.BLACK);
bbg.drawOval(x, 10, 20, 20);
g.drawImage(backBuffer, insets.left, insets.top, this);
}
}
这是键盘码
package gamesample;
import java.awt.Component;
import java.awt.event.*;
/**
* Makes handling input a lot simpler
*/
public class InputHandler implements KeyListener
{
boolean keys[];
/**
* Assigns the newly created InputHandler to a Component
* @param c Component to get input from
*/
public InputHandler(Component c)
{
c.addKeyListener(this);
}
/**
* Checks whether a specific key is down
* @param keyCode The key to check
* @return Whether the key is pressed or not
*/
public boolean isKeyDown(int keyCode)
{
if (keyCode > 0 && keyCode < 256)
{ keys = new boolean [256];
return keys[keyCode];
}
return false;
}
/**
* Called when a key is pressed while the component is focused
* @param e KeyEvent sent by the component
*/
public void keyPressed(KeyEvent e)
{ boolean keys[];
if (e.getKeyCode() > 0 && e.getKeyCode() < 256)
{ keys = new boolean [256];
keys[e.getKeyCode()] = true;
}
}
/**
* Called when a key is released while the component is focused
* @param e KeyEvent sent by the component
*/
public void keyReleased(KeyEvent e)
{ boolean keys[];
if (e.getKeyCode() > 0 && e.getKeyCode() < 256)
{ keys = new boolean [256];
keys[e.getKeyCode()] = false;
}
}
/**
* Not used
*/
public void keyTyped(KeyEvent e){}
}
Graphics g = getGraphics();
也不怎么风俗画应该做的。摇摆采用被动渲染算法,这意味着你的UI可以在任何时候重新绘制,为任意数量的原因,其中有许多你不拥有控制权Swing默认情况下也是双缓冲,所以如果你实际使用JPanel
并且覆盖它的paintComponent
方法,y你可以免费获得双倍缓冲,你会被通知任何与系统相关的绘画事件。
更多细节
见Painting in AWT and Swing和Performing Custom Painting不要使用KeyListener
,这太麻烦和键绑定API解决了自己的一切所有的问题。有关更多详细信息,请参见How to Use Key Bindings。
请记住,Swing是一个单线程框架,不是线程安全的。这意味着你不应该以任何方式阻塞事件分派线程(比如使用永无止境的循环),你应该只在EDT的上下文中更新UI。
您的“主回路”有两种危险。 JVM的本质是代码不会阻塞EDT,但这也意味着您违反了Swing的单线程本质。
有关更多详细信息,请参见Concurrency in Swing。
通常情况下,我会使用Swing Timer
进行此类工作,因为它的回调在EDT上下文中同步,但您可以使用Thread
,但您必须手动将更新重新同步到EDT。
如果你想,你应该使用BufferStrategy
在绘画过程中完全控制,见BufferStrategy
和BufferStrategy and BufferCapabilities更多细节
由于上述概念的basic example