2012-06-11 3 views
0

Итак, мой JFrame становится неактуальным, когда я запускаю этот код. Мне удалось проследить его до цикла while в gameLoop(). Независимо от использования задержки (1000/FRAMERATE), которая вызывает в нем Thread.sleep(), она не позволит слушателям Key или Mouse выполнять свою работу.Хотя цикл с задержкой делает JFrame невосприимчивым

Полный код ниже, существует проблема в gameLoop()

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(); 
    } 
} 

Вероятно, не имеет значения, но вот плагин к github repo https://github.com/cybnetsurfe3011/Lemmings-Computer-Science/

+0

* «Игра расширяет JFrame' ...« Меню расширяет JFrame' »* См. [Использование нескольких JFrames, Good/Bad Practice?] (Http://stackoverflow.com/a/9554657/418556) –

ответ

2

Вы вносите Thread.sleep() в свой основной поток, который в этом случае является EDT (Event Dispatcher Thread). Этот поток отвечает за рисование графики и прослушивание событий. Выполняя Thread.sleep(), вы, по сути, приостанавливаете его, тем самым не позволяя ему выполнять свою работу.

Кажется, что вы хотите обновить свой графический интерфейс с интервалом (по крайней мере, это то, что я угадываю). Если это так, вам нужно будет переместить вашу логику в новый отдельный поток, а затем вызвать любые методы обновления, которые вам понадобятся, из потока, который вы отложили. Чтобы изменения были видимыми, вам нужно будет снова вызвать поток диспетчера событий, используя метод SwingUtilities.invokeLater().

Смежные вопросы