关于JAVA KeyPressed 按键连按延迟与加速问题

想ΚιГз念 发布于 2011/07/04 21:41
阅读 1K+
收藏 0

做的一个按键控制小球的程序,但是按键连按,他会不断加速,求解啊!

代码如下:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;
import java.awt.event.KeyAdapter;


public class shiyan3 extends JFrame{
 int x=10;
 int y=10;
 MyPanel mp=null;
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  shiyan3 shiyan3=new shiyan3();
 }

 class MyPanel extends JPanel implements KeyListener
 {
  
  private boolean flagleft = false;
  private boolean flagup = false;
  private boolean flagright = false;
  private boolean flagdown = false;
  

  public void  paint(Graphics g)
  {
   
  super.paint(g);
  g.fillOval(x, y, 10, 10);
  }

  @Override
  public void keyPressed(KeyEvent e){
    if(flagleft&&flagup&&flagright&&flagdown){//这是一个成员变量,用以查看是否按下键
     return;
    }
   
    if(e.getKeyCode()==37)
    {
     flagleft = true;
    }
     if(e.getKeyCode()==38)
    {
     flagdown = true;
    
    }
     if(e.getKeyCode()==39)
    {
     flagright = true;
    }
     if(e.getKeyCode()==40)
    {
     flagup = true;
    }
   //若没按下则处理
    if(flagleft==true)
    {
    
    new Thread(){
     public void run(){
      while(flagleft){//只要一直按着就处理:
   //添加你自己的代码:
    x=x-1;
    if(x<0)
    {
     x=400;
    
    }
    mp.repaint();
       try {
        Thread.sleep(5);//不仅可以消除延迟,还可以控制延迟时间
       } catch (InterruptedException e1) {
        e1.printStackTrace();
       }
      }
     }
    }.start();
    }
     if(flagup==true)
    {
    
    new Thread(){
     public void run(){
      while(flagup){//只要一直按着就处理:
   //添加你自己的代码:
    y=y+1;
    if(y>300)
    {
     y=0;
    
    }
    mp.repaint();
       try {
        Thread.sleep(5);//不仅可以消除延迟,还可以控制延迟时间
       } catch (InterruptedException e1) {
        e1.printStackTrace();
       }
      }
     }
    }.start();
    }
    if(flagright==true)
    {
    
    new Thread(){
     public void run(){
      while(flagright){//只要一直按着就处理:
   //添加你自己的代码:
    x=x+1;
    if(x>400)
    {
     x=0;
    
    }
    mp.repaint();
       try {
        Thread.sleep(5);//不仅可以消除延迟,还可以控制延迟时间
       } catch (InterruptedException e1) {
        e1.printStackTrace();
       }
      }
     }
    }.start();
    }
     if(flagdown==true)
    {
    
    new Thread(){
     public void run(){
      while(flagdown){//只要一直按着就处理:
   //添加你自己的代码:
    y=y-1;
    if(y<0)
    {
     y=300;
    
    }
    mp.repaint();
       try {
        Thread.sleep(5);//不仅可以消除延迟,还可以控制延迟时间
       } catch (InterruptedException e1) {
        e1.printStackTrace();
       }
      }
     }
    }.start();
    }
   }


  public void keyReleased(KeyEvent arg0) {
    if(arg0.getKeyCode()==37)
    {
     flagleft = false;
    }
     if(arg0.getKeyCode()==38)
    {
     flagdown = false;
    
    }
     if(arg0.getKeyCode()==39)
    {
     flagright =false;
    }
     if(arg0.getKeyCode()==40)
    {
     flagup = false;
    }
   
  
   
  }
  public void keyTyped(KeyEvent arg0) { 
  }

  
 
    
   
 }
  
 

 
    public shiyan3()
    {
     mp=new MyPanel();
     this.add(mp);
     this.addKeyListener(mp);
     this.setSize(400,300);
     this.setLocation(400,300);
     this.setVisible(true);
     this.setTitle("按键控制小球");
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
    }
 
}

加载中
0
鬼经

你好。  我初步分析原因是这样的。

你用了新建线程的方式来改变X  Y的值, 当你连续按键或一直按住时,会不停的new新的线程出来,而new新线程的速度大于paint()方法执行的速度,所以会有越来越多的线程改变X Y的值,这样相当于同一时间里X  Y值变化越来越大。。 所以会出现加速的问题。。

0
想ΚιГз念

嗯,我觉得你说的有道理,我程序重新改了下,新建了个线程来专门执行移动操作,而按键判断放在主线程里面,改变新线程的执行。

程序如下:

package main;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

 

import javax.swing.*;

import java.awt.event.KeyAdapter;

 

 

public class key extends JFrame{

public static int x=10;

public  static int y=10;

public static MyPanel mp=null;

 public static void main(String[] args) {

  // TODO Auto-generated method stub

 key key=new key();

 }

 

 class MyPanel extends JPanel implements KeyListener

 {

  

  

 

  public void  paint(Graphics g)

  {

   

  super.paint(g);

  g.fillOval(x, y, 10, 10);

  }

 

  @Override

  public void keyPressed(KeyEvent e){

  

    

    if(e.getKeyCode()==37)

    {

     move.left = true;

      System.out.println(move.left);

    }

     if(e.getKeyCode()==38)

    {

      move.down = true;

     

    }

     if(e.getKeyCode()==39)

    {

      move.right = true;

    }

     if(e.getKeyCode()==40)

    {

      move.up = true;

    }

   //若没按下则处理

   }

 

 

  public void keyReleased(KeyEvent arg0) {

    if(arg0.getKeyCode()==37)

    {

     move.left = false;

    }

     if(arg0.getKeyCode()==38)

    {

      move.down = false;

     

    }

     if(arg0.getKeyCode()==39)

    {

      move.right =false;

    }

     if(arg0.getKeyCode()==40)

    {

      move.up = false;

    }

   

  

   

  }

  public void keyTyped(KeyEvent arg0) { 

  }

 

 }

  

 

 

    public key()

    {

     mp=new MyPanel();

     

     this.add(mp);

     this.addKeyListener(mp);

     this.setSize(400,300);

     this.setLocation(400,300);

     this.setVisible(true);

     this.setTitle("按键控制小球");

     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     

     move move=new move();

     move.run();

    }

 

}

 

class move implements Runnable{

public static boolean left=false;

public static boolean right=false;

public static boolean up=false;

public static boolean down=false;

@Override

public void run() {

// TODO Auto-generated method stub

while(true)

{

    if(left==true)

    {

     System.out.println("left");

     key.x=key.x-1;

    if(key.x<0)

    {

     key.x=400;

     

    }

    key.mp.repaint();

    

        try {

Thread.sleep(5);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//不仅可以消除延迟,还可以控制延迟时间

   

       }

      

     

  

    

     if(up==true)

    {

      System.out.println("up");

      key.y=key.y+1;

    if(key.y>300)

    {

     key.y=0;

     

    }

    key.mp.repaint();

     

        try {

Thread.sleep(5);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//不仅可以消除延迟,还可以控制延迟时间

    

      

     }

   

    if(right==true)

    {

      System.out.println("right");

     key.x=key.x+1;

    if(key.x>400)

    {

     key.x=0;

     

    }

    key.mp.repaint();

          try {

Thread.sleep(5);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//不仅可以消除延迟,还可以控制延迟时间

      

      

       }

      

   

    

     if(down==true)

    {

      System.out.println("down");

      key.y=key.y-1;

    if(key.y<0)

    {

     key.y=300;

     

    }

    key.mp.repaint();

   

        try {

Thread.sleep(5);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//不仅可以消除延迟,还可以控制延迟时间

      

       }

      }

   

    }

}


0
想ΚιГз念

这样就消除了。

此方法无我提出的那种 按键持续按下加速问题。

返回顶部
顶部