首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >KeyListener正在延迟

KeyListener正在延迟
EN

Stack Overflow用户
提问于 2016-09-09 16:03:27
回答 1查看 126关注 0票数 0

我正在用java做FlappyBirds,现在一切都很好。但是我被一个问题卡住了。

我有一个叫做'status‘的整型变量。当status0时,游戏运行,如果status1,则窗口将显示"game over, press s to begin“。我的KeyListener在玩游戏时效果很好。

但是当我输了游戏,status变成了1,当我再次按下s按钮时,我不得不按住这个按钮一段时间。它没有快速响应。在启动过程中,status1。当我在这段时间内按下s时,它很快就出现了,但是当我失败了,状态再次变为1时,问题就出现了。

代码语言:javascript
运行
复制
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));
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2016-09-12 17:52:16

延迟的原因肯定是计时器:

计时器连续运行,每10ms启动一次事件(即调用actionPerformed)。即使在游戏结束后,它也在运行,因此ActionEvent事件在事件队列中累积,您按下的'S‘会经历很大的延迟,直到轮到它被处理。

我推荐你:

  1. 在游戏结束后立即停止计时器。
  2. 在游戏重新启动后,立即将所有实例变量重新初始化为其初始状态。例如,实现一个名为init的私有方法,并在那里初始化xygravitytickswalls,当然还有在构造函数末尾以及让status=0.

之后的keyPressed中对take init的调用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39406711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档