2016-09-09 3 views
0

Я делаю FlappyBirds в java, все работает хорошо на данный момент. Но у меня проблема.KeyListener задерживается

У меня есть целочисленная переменная, называемая 'status'. Когда status - 0, игра проходит, если status - 1, тогда в окне будет указано «game over, press s to begin». Мой KeyListener хорошо подходит для игры.

Но после того, как я проиграю игру, и status становится 1, когда я снова нажимаю кнопку s, я должен удерживать кнопку на некоторое время. Он не отвечает быстро. Во время запуска status - 1. Когда я нажимаю s в течение этого времени, он приходит быстро, но когда я теряю и статус снова становится 1, возникает проблема.

package flappybirds; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import java.util.Random; 
import java.util.logging.Level; 
import java.util.logging.Logger; 


public class FlappyBirds extends JPanel implements  ActionListener,KeyListener { 
    public int WIDTH=800,HEIGHT=800,x=WIDTH/2-10,y=HEIGHT/2-10 , gravity=0,  ticks=0,status=1; 
    public static FlappyBirds flappy; 
    public boolean jump; 
    public boolean gameOver=true ; 
    public ArrayList<Rectangle>walls; 
    public Rectangle bird; 

    public Random generator; 
    public FlappyBirds(){ 
     Timer t=new Timer(10,this); 
     JFrame window=new JFrame("Flappy Birds"); 
     window.setSize(WIDTH ,HEIGHT); 
     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     window.add(this); 
     window.setVisible(true); 
     window.addKeyListener(this); 
     walls=new ArrayList<Rectangle>(); 
     generator=new Random(); 
     t.start(); 
    } 

    public static void main(String[] args) { 
     flappy=new FlappyBirds(); 
    } 

    @Override 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     bird=new Rectangle(x,y,15,15); 
     g.setColor(new Color(0,200,255)); 
     g.fillRect(0,0,WIDTH,HEIGHT); 
     g.setColor(Color.ORANGE); 
     g.fillRect(0, HEIGHT-100, WIDTH,100); 
     g.setColor(Color.GREEN); 
     g.fillRect(0,HEIGHT-110,WIDTH,10); 
     g.setColor(Color.red); 
     g.fillRect(bird.x,bird.y,bird.width,bird.height); 
     g.drawString(Integer.toString(status),200,200); 
     g.setColor(new Color(200,200,40)); 

     if(status==0){ 
      for(Rectangle rect:walls){ 
       paintWall(rect,g); 
      } 
     } 

     if(status==1){ 
      g.setFont(new Font("Arial",50,50)); 
      g.setColor(Color.RED); 
      g.drawString("Press 'S' to begin",400,400); 
     } 

     g.setColor(Color.RED); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     repaint(); 
     if(status==0){ 
      addWall(true); 
      addWall(true); 

      ticks ++; 
      if(jump){ 
       if(ticks%8==0){ 
        gravity=-10; 
       } 

      } 
      else if(ticks%8==0 && gravity<15 && jump==false){ 
       gravity+=2; 

      } 
      if(ticks==1000){ 
       ticks=0; 
      } 
      y += gravity; 

      for(Rectangle rect:walls){ 
       rect.x -=10; 
      } 

      for(int i=0;i<walls.size();i++){ 
       Rectangle r=walls.get(i); 

       if(r.x+r.width<0){ 

        addWall(false); 
       } 
      } 


      for(Rectangle column:walls){ 
       if(column.intersects(bird) || bird.y>=HEIGHT-120 ||  bird.y<=3){ 
        gameOver=true; 
        status=1; 
        if(!jump){ 
         if(y>=HEIGHT-120){ 
          y=HEIGHT-120; 
         } 
         if(column.intersects(bird)){ 
          y=HEIGHT/2-10; 
         } 
         if(bird.y<=3){ 
          y=HEIGHT/2-10; 
         } 
        }else if(jump){ 
         y=HEIGHT/2-10; 
        } 
       }else{ 
        gameOver=false; 
       } 
      } 
      collide(); 

     } 
    } 


    @Override 
    public void keyTyped(KeyEvent e) {} 

    @Override 
    public void keyPressed(KeyEvent e) { 
     int c=e.getKeyCode(); 
     if(status==0){ 
      if(c==KeyEvent.VK_SPACE){ 
       jump=true; 
      } 
     } 
     if(status==1){ 
      if(c==KeyEvent.VK_S){ 

       status=0; 
      } 
     } 
    } 
    public void collide(){ 
     if(status==0){ 
      if(gameOver){ 
       walls.clear(); 
       addWall(true); 
       addWall(true); 
       gameOver=false; 

      } 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     jump=false; 
    } 
    public void paintWall(Rectangle rect,Graphics g){ 
     g.fillRect(rect.x, rect.y, rect.width, rect.height); 
    } 
    public void paintSpace(Rectangle rect,Graphics g){ 
     g.setColor(new Color(0,200,225)); 
     g.fillRect(rect.x,rect.y,rect.width,rect.height); 
    } 
    public void addWall(boolean oldwall){ 
     int width=100; 
     final int height=350; 
     int yloc=100+generator.nextInt(150); 
     int space=100; 
     if(oldwall){ 
      if(generator.nextBoolean()){ 
       walls.add(new Rectangle(WIDTH+width+ (walls.size()*200),HEIGHT- height-yloc,width,height)); 
       walls.add(new Rectangle(WIDTH+width+(walls.size()-1)*200,- yloc, width,height- space)); 
      }else{ 
       walls.add(new Rectangle(WIDTH+width+ (walls.size()*200),HEIGHT-height+yloc,width,height)); 
       walls.add(new Rectangle(WIDTH+width+ (walls.size()-1)*200,+yloc, width,height- space)); 
      } 
     }else{ 
      if(generator.nextBoolean()){ 
       walls.add(new  Rectangle(walls.get(walls.size()-1).x+600,HEIGHT-height- yloc,width,height+space)); 
       walls.add(new Rectangle(walls.get(walls.size()-2).x+600,- yloc,width,height-space)); 
      }else{ 
       walls.add(new  Rectangle(walls.get(walls.size()-1).x+600,HEIGHT- height+yloc,width,height+space)); 
       walls.add(new  Rectangle(walls.get(walls.size()-2).x+600,yloc,width,height-space)); 
      } 
     } 
    } 
} 
+0

На самом деле информации на ваш вопрос недостаточно. Нет ничего плохого в той части кода, которую вы показывали, что означает, что проблема возникает откуда-то еще. Возможно, ваш игровой цикл занимает слишком много памяти во второй раз, или ваш код, который переключается на саму игру, достигается только после какой-то задержки или ваш прослушиватель ключей удаляется и переназначается через некоторое время, я могу продолжать и продолжать со случайными возможности, но с такой небольшой информацией, я не думаю, что это поможет. – Mark

+0

Могу ли я опубликовать весь исходный код? –

+0

Я думаю, вы могли бы, хотя это, вероятно, будет МНОГО кода для чтения, и не многие люди найдут время для этого: D Вероятно, было бы лучше, если бы вы могли попробовать немного отладить, чтобы вы могли разобраться примерно где в вашем коде ваши проблемы лежат, а затем публикуют только те части. Просто используйте отладчик своего идеала или введите какой-то тестовый результат (просто не забудьте снова его выпустить). Я бы, вероятно, начал, увидев, вызван ли метод keyPressed слишком поздно или часть кода, которая должна быть выполнена после того, как статус равен 0. – Mark

ответ

0

Определенно причиной задержки является таймер:

Таймер работает непрерывно, запуск события каждые 10 мс (то есть, ссылающегося на actionPerformed). Даже после того, как игра окончена, она запускается, поэтому события ActionEvent накапливаются в очереди событий, а нажатие кнопки «S» сильно задерживается до тех пор, пока ее очередь не будет обработана.

Я рекомендую вам:

  1. остановить таймер, как только игра закончена.
  2. Как только игра перезапускается, повторно инициализируйте все переменные экземпляра в исходное состояние. Например, выполните частный метод, называемый init, и введите там инициализацию x, y, gravity, ticks, walls, и, конечно, звонок timer.start().
  3. Звоните init в конце конструктора, а также в пределах keyPressed, после отправки status=0.
+0

Должен ли я остановить таймер в конструкторе? Я спрашиваю об этом, потому что, когда я это делаю, он не работает. –

+0

№. Таймер должен быть запущен в конструкторе и остановлен, когда вы назначаете 'gameOver = true'. –

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