Java 而带有延迟的循环使JFrame无响应
因此,当我运行此代码时,我的JFrame将变得无响应。我设法将其追溯到gameLoop()下的while循环。不管使用delay(1000/FRAMERATE)调用其中的Thread.sleep(),它都不允许键或鼠标侦听器执行其工作 下面是完整代码,gameLoop()中存在问题Java 而带有延迟的循环使JFrame无响应,java,loops,while-loop,jframe,Java,Loops,While Loop,Jframe,因此,当我运行此代码时,我的JFrame将变得无响应。我设法将其追溯到gameLoop()下的while循环。不管使用delay(1000/FRAMERATE)调用其中的Thread.sleep(),它都不允许键或鼠标侦听器执行其工作 下面是完整代码,gameLoop()中存在问题 package me.LemmingsGame; 导入java.awt.*; 导入java.awt.event.*; 导入java.io.*; 导入javax.swing.*; 公共类游戏扩展了JFrame实现了Ke
package me.LemmingsGame;
导入java.awt.*;
导入java.awt.event.*;
导入java.io.*;
导入javax.swing.*;
公共类游戏扩展了JFrame实现了KeyListener、MouseStener{
私有世界wrld;//对当前世界的引用
私有WorldFile loader=null;//世界数据
专用int网关计数器;
private int width,height;//级别的宽度和高度
私人int mx,我的;
私人int工具=Lemming.gramb;
私有图像dbImage;私有图形dbg;//backbuffer
私有图像[]精灵;//游戏中使用的所有图像
私有旅鼠[]旅鼠;//级别中所有旅鼠的数组
private int nextLem;//从Gate类接收下一个旅鼠
private int running;//游戏状态
私有静态最终整数帧速率=180;//分配的帧速率
公共游戏(WorldFile loader){
超级(“旅鼠”);
设定位置(50,40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
可设置大小(假);
宽度=3+加载器.x*10;高度=29+加载器.y*10;
loadImages();
旅鼠=新旅鼠[loader.nolemings*loader.gates().length];
设置尺寸(宽度、高度);
setVisible(真);
addMouseListener(这个);
addKeyListener(此);
this.loader=loader;
运行=2;
dbImage=createImage(宽度、高度);
dbg=dbImage.getGraphics();
wrld=新世界(加载器、createImage(宽度、高度)、精灵、此);
gameLoop();
}
公共void loadImages(){
精灵=新图像[2];
精灵[0]=新图像图标(“Resources/toolbar.png”).getImage();
sprites[1]=newimageicon(“Resources/selector.png”).getImage();
}
公共静态无效延迟(长时间){
试一试{
睡眠(len);
}捕捉(中断异常e){
系统输出打印ln(e);
}
}
公共无效移动lemmings(){
如果(nextLem>0)
对于(int i=0;i0){
延迟(1000/帧率);
如果(运行==2){
gateconter++;
如果(门计数器>帧率*2){
wrld.cycleGates();
网关计数器=0;
}
moveLemmings();
如果(nextLem>0)
wrld.检查位置(旅鼠、nextLem);
}
重新油漆();
//绘制(getGraphics());
}
}
公共空间涂料(图g){
如果(wrld!=null){
dbg.setColor(Color.BLACK);
dbg.fillRect(0,0,宽度,高度);
工作图纸(dbg);
如果(nextLem>0)
对于(int i=0;i您正在主线程中执行Thread.sleep()
,在本例中是EDT(事件调度程序线程)。此线程负责绘制图形和侦听事件。通过执行Thread.sleep()
实际上是暂停它,因此不允许它执行其任务
您似乎希望每隔一段时间刷新GUI(至少我是这么猜的)。如果是这种情况,则需要将逻辑移动到新的单独线程,然后从生成的线程调用所需的更新方法。若要使更改可见,需要使用该方法再次调用事件调度程序线程“游戏扩展JFrame
…菜单扩展JFrame
”请参阅
package me.LemmingsGame;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class Game extends JFrame implements KeyListener, MouseListener{
private World wrld;//reference to current world
private WorldFile loader=null;//world data
private int gateCounter;
private int width,height; //width and height of level
private int mx,my;
private int tool = Lemming.CLIMB;
private Image dbImage; private Graphics dbg; //backbuffer
private Image [] sprites;//all images used in game
private Lemming[] lemmings; //array of all Lemmings in level
private int nextLem;//next Lemming to be received from Gate class
private int running;//state of game
private static final int FRAMERATE=180;//assigned framerate
public Game(WorldFile loader){
super("Lemmings");
setLocation(50,40);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
width=3+loader.x*10;height=29+loader.y*10;
loadImages();
lemmings=new Lemming[loader.noLemmings*loader.gates().length];
setSize(width,height);
setVisible(true);
addMouseListener(this);
addKeyListener(this);
this.loader=loader;
running=2;
dbImage= createImage(width,height);
dbg=dbImage.getGraphics();
wrld=new World(loader,createImage(width,height), sprites, this);
gameLoop();
}
public void loadImages(){
sprites=new Image[2];
sprites[0]=new ImageIcon("Resources/toolbar.png").getImage();
sprites[1]=new ImageIcon("Resources/selector.png").getImage();
}
public static void delay(long len){
try{
Thread.sleep(len);
}catch(InterruptedException e){
System.out.println(e);
}
}
public void moveLemmings(){
if(nextLem>0)
for(int i = 0;i<nextLem;i++)
lemmings[i].cycle();
}
public void gameLoop(){
wrld.openGates();
while(running>0){
delay(1000/FRAMERATE);
if(running==2){
gateCounter++;
if(gateCounter>FRAMERATE*2){
wrld.cycleGates();
gateCounter=0;
}
moveLemmings();
if(nextLem>0)
wrld.checkPositions(lemmings,nextLem);
}
repaint();
//paint(getGraphics());
}
}
public void paint(Graphics g){
if(wrld!=null){
dbg.setColor(Color.BLACK);
dbg.fillRect(0, 0, width, height);
wrld.draw(dbg);
if(nextLem>0)
for(int i=0;i<nextLem;i++){
lemmings[i].draw(dbg);
}
dbg.drawImage(sprites[0],0,0,null);
dbg.drawImage(sprites[1],tool-3*39,0,null);
g.drawImage(dbImage,3,29,this);
}
}
public void addLemming(Lemming lemmy) {
lemmings[nextLem]=lemmy;
lemmy.spawn();
nextLem++;
}
public void goal(){
running=0;
dispose();
new Menu();
}
public void fail(){
running=0;
dispose();
new Menu();
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void keyTyped(KeyEvent e) {}
public void mousePressed(MouseEvent e) {
System.out.println("boop");
mx=e.getX();
my=e.getY();
if(my<40)
if(mx<40)
tool=Lemming.CLIMB;
else if(mx>39&&mx<=39*2)
tool=Lemming.CHUTE;
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
System.out.println("boop2");
}
public void keyReleased(KeyEvent e) {
}
}
package me.LemmingsGame;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import javax.swing.*;
public class Menu extends JFrame implements ActionListener{
/**
*
*/
private static final long serialVersionUID = -1448646591011984524L;
private JComboBox worldList;
private JButton launch, worldEditor;
private String [] worldPaths;
private String [] worldNames;
private int currentWorld;
public Menu(){
super("Lemmings! By: Jordan and Seth");
this.setLocation(new Point(550,400));
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
File listDir[] = new File("./Worlds").listFiles();
int x=0;
for (int i = 0; i < listDir.length; i++)
if (listDir[i].isDirectory())
x++;
worldPaths=new String[x];
worldNames=new String[x];
x=0;
for (int i = 0; i < listDir.length; i++)
if (listDir[i].isDirectory()){
worldPaths[x]=listDir[i].getPath().substring(2);
worldNames[x]=worldPaths[x].substring(7);
x++;
}
worldList=new JComboBox(worldNames);
worldList.addActionListener(this);
worldEditor=new JButton("Open World Editor");
worldEditor.addActionListener(this);
launch = new JButton("Play");
launch.addActionListener(this);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(worldEditor);
cp.add(worldList);
cp.add(launch);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==worldEditor){
dispose();
new MapEditor();
}else if(e.getSource()==launch){
dispose();
try {
new Game(new WorldFile(worldPaths[currentWorld]));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else if(e.getSource()==worldList){
currentWorld=worldList.getSelectedIndex();
}
}
public static void main(String [] args){
new Menu();
}
}