我在一个小项目上工作,遇到了一些我不知道如何解决的问题。我试着查看线程,看看这是不是问题,但找不到任何帮助我的东西。问题是每当我点击框架,键输入,动画等都冻结。
这是主类的代码:(如果您需要来自任何其他类的代码,请告诉我,但我认为问题在于此处)
package me.runeglaive.main;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import me.runeglaive.gamestate.GameStateManager;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
public static int height = 360;
public static int width = height * 16 / 9;
public static int scale = 2;
private JFrame frame;
private Graphics g;
private boolean running = true;
GameStateManager gsm;
public Game(){
frame = new JFrame("Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setSize(width * scale, height * scale);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
gsm = new GameStateManager();
init();
MouseListener ml = new MouseListener(){
public void mousePressed(MouseEvent e) {
gsm.mousePressed(e);
}
public void mouseReleased(MouseEvent e) {
gsm.mouseReleased(e);
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
};
KeyListener kl = new KeyListener(){
public void keyPressed(KeyEvent k) {
gsm.keyPressed(k);
}
public void keyReleased(KeyEvent k) {
gsm.keyReleased(k);
}
public void keyTyped(KeyEvent k) {
}
};
frame.addKeyListener(kl);
frame.addMouseListener(ml);
frame.setFocusable(true);
}
public void init(){
}
public void update(double delta){
gsm.update(delta);
}
public void render(){
//double buffering
BufferStrategy bs = getBufferStrategy();
if (bs == null){
createBufferStrategy(2);
return;
}
g = bs.getDrawGraphics();
//clear screen
g.clearRect(0, 0, getWidth(), getHeight());
//Draw gameState
gsm.render(g);
g.dispose();
bs.show();
}
public synchronized void start(){
running = true;
new Thread(this).start();
}
public synchronized void stop(){
running = false;
}
public void run() {
//initialize time loop variables
long lastLoopTime = System.nanoTime();
final int TARGET_FPS = 60;
final long OPTIMAL_TIME = 1000000000 / TARGET_FPS;
double lastFpsTime = 0;
while(running)
{
//Calculate since last update
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
double delta = updateLength / ((double)OPTIMAL_TIME);
//update frame counter
lastFpsTime += updateLength;
//update FPS counter
if(lastFpsTime >= 1000000000)
{
lastFpsTime = 0;
}
//game updates
update(delta);
//graphics (gameState)
render();
try{
Thread.sleep((Math.abs(lastLoopTime - System.nanoTime() + OPTIMAL_TIME)/1000000));
}catch(InterruptedException e){
System.out.println("Error in sleep");
}
}
}
public static void main(String args[]){
new Game().start();
}
}
Heres the Game State Manager:
package me.runeglaive.gamestate;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
public class GameStateManager {
private ArrayList<GameState> states;
private int currentState;
public static final int MENUSTATE = 0;
public static final int MAINSTATE = 1;
public GameStateManager(){
states = new ArrayList<GameState>();
states.add(new MenuState(this));
states.add(new MainState(this));
setState(MAINSTATE);
}
public void setState(int state){
currentState = state;
states.get(state).init();
}
public int getCurrentState(){
return currentState;
}
public void update(double delta){
states.get(currentState).update(delta);
}
public void render(Graphics g){
states.get(currentState).render(g);
}
public void keyPressed(KeyEvent k){
states.get(currentState).keyPressed(k);
}
public void keyReleased(KeyEvent k){
states.get(currentState).keyReleased(k);
}
public void mousePressed(MouseEvent e){
states.get(currentState).mousePressed(e);
}
public void mouseReleased(MouseEvent e){
states.get(currentState).mouseReleased(e);
}
}
答案 0 :(得分:0)
gsm.mousePressed(e)的代码是什么;和gsm.mouse发布(e)好吗? :)
你在滥用Java Swing。您不应创建自己的线程并以编程方式重绘场景,因为这会干扰输入队列的线程模型。
如果你正在使用swing,那么不要启动自己的线程,而是启动一个swing计时器。从计时器的事件侦听器调用更新。而不是调用渲染,在帧上发出repaint()并覆盖帧的绘制代码,如果你想玩得好。 http://www.oracle.com/technetwork/java/painting-140037.html
在AWT的情况下,有系统触发的绘画和应用程序触发的绘制。
你正在做的代码是一个完全有效的蛮力游戏编码器思考 - 如果你在屏幕上有完全控制权,则完全有效。在Swing的情况下,情况并非如此,因为Swing确实需要处理更多事情。如果你和Mr.Swing搞混乱,它迟早会咬你; - )
如果您更喜欢更认真地对待这个游戏开发,那么请寻找Java 2D游戏引擎或Java 3D游戏引擎(例如jMonkey)来处理所有细节并提供工作垂直回扫同步 - 这是不可避免的流畅的动作。请注意,您的BufferStrategy 不会照顾它,这个主题更复杂。