我试着做个坦克大战游戏,但是今晚就出问题了:就是每次把鼠标单击一下界面后,程序就不受控制了,监听不到任何消息了,求大神帮忙!代码如下:import java.awt.Color;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;import javax.swing.*;
public class Yumentank extends JFrame{
Mypanel1 mp=null;
Yumentank()
{
mp=new Mypanel1();
this.addKeyListener(mp);

this.add(mp);
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   this.setSize(500,400);
   this.setVisible(true);
}

public static void main(String[] args) {
// TODO Auto-generated method stub
Yumentank mytank=new Yumentank();
}}
//坦克基类
class Tank{
int x;
int y;
int direction;
int speed=1;
Tank(int x,int y)
{
this.x=x;
this.y=y;
}
public void setX(int x)
{
this.x=x;
}
public void setY(int y)
{
this.y=y;
}
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
public void setDirction(int n)
{
direction=n;
}
public int getDirection()
{
return direction;
}
}
//我的坦克
class Mytank extends Tank
{
Mytank(int x,int y)
{
super(x,y);
speed=3;
}
public void goUp()
{
direction=0;
y-=speed;
}
public void goDown()
{
direction=1;
y+=speed;
}

public void goLeft()
{
direction=2;
x-=speed;
}
public void goRight()
{
direction=3;
x+=speed;
}
}//面板
class Mypanel1  extends Panel implements KeyListener
{

Mytank tank;
Mypanel1(){
tank=new Mytank(0,0);
}
public void paint(Graphics g)

super.paint(g);
this.drawTank(g, tank.getX(), tank.getY(),0,tank.getDirection());


}
public void drawTank(Graphics g,int x,int y,int type,int direct)
{
switch(direct)//go up
{
case 0:
{
g.setColor(Color.DARK_GRAY);
g.fill3DRect(0, 0, 500, 400, false);
g.setColor(Color.blue);
g.fill3DRect(x, y, 10, 40,false);
g.fill3DRect(x+30, y, 10, 40,false);

g.fill3DRect(x+10, y+10, 20, 20,false);
g.setColor(Color.lightGray);
g.fillOval(x+10, y+13, 20, 15);
g.fill3DRect(x+18, y, 3, 20,false);
break;
}
case 1://gou down
{
g.setColor(Color.DARK_GRAY);
g.fill3DRect(0, 0, 500, 400, false);
g.setColor(Color.blue);
g.fill3DRect(x, y, 10, 40,false);
g.fill3DRect(x+30, y, 10, 40,false);

g.fill3DRect(x+10, y+10, 20, 20,false);
g.setColor(Color.lightGray);
g.fillOval(x+10, y+13, 20, 15);
g.fill3DRect(x+18, y+20, 3, 20,false);
break;
}
case 2: //go left
{
g.setColor(Color.DARK_GRAY);
g.fill3DRect(0, 0, 500, 400, false);
g.setColor(Color.BLUE);
g.fill3DRect(x, y, 40, 10,false);
g.fill3DRect(x, y+30, 40, 10,false);

g.fill3DRect(x+10, y+10, 20, 20,false);
g.setColor(Color.lightGray);
g.fillOval(x+12, y+11, 15, 20);
g.fill3DRect(x, y+20, 20, 3,false);
break;
}
case 3://go right
{
g.setColor(Color.DARK_GRAY);
g.fill3DRect(0, 0, 500, 400, false);
g.setColor(Color.BLUE);
g.fill3DRect(x, y, 40, 10,false);
g.fill3DRect(x, y+30, 40, 10,false);

g.fill3DRect(x+10, y+10, 20, 20,false);
g.setColor(Color.lightGray);
g.fillOval(x+12, y+11, 15, 20);
g.fill3DRect(x+20, y+20, 20, 3,false);
break;
}
}
}
@Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getKeyCode()==KeyEvent.VK_UP)
{
this.tank.direction=0;
this.tank.goUp();
//System.out.println("go up");

}
else if(arg0.getKeyCode()==KeyEvent.VK_DOWN)
{
this.tank.direction=1;
this.tank.goDown();
}
else if(arg0.getKeyCode()==KeyEvent.VK_LEFT)
{
this.tank.direction=2;
this.tank.goLeft();
}
else if(arg0.getKeyCode()==KeyEvent.VK_RIGHT)
{
this.tank.direction=3;
this.tank.goRight();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub

}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub

}
}

解决方案 »

  1.   

     //this.addKeyListener(mp);    mp.addKeyListener(mp);启动起来要先点一点mp测试一下感觉是点mouse的时候,焦点在mp上,再键盘mp接收到事件,而你的KeyListener是在Frame上
      

  2.   

    加上构造方法最后  mp.requestFocus();
    就对了
      

  3.   

    确实是焦点丢失的问题,你的KeyListener是在Frame上,鼠标点击后,焦点就不再Yumentank上了。然而你没有什么方式能引用Yumentank,所以也没法进行 Yumentank.requestFocus();需要调整下。
      

  4.   

    ,我刚刚试了,不能解决啊,但我之前做了个测试程序没遇到这个问题,我把代码贴出来看看,很困扰
    import javax.swing.*;import java.awt.*;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    public class Smallball extends JFrame {
    Ballpanel ball=null;
    Smallball()
    {
    ball=new Ballpanel();
    this.addKeyListener(ball);//监听
       this.add(ball);
       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       this.setSize(300,200);
       this.setVisible(true);
    }
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Smallball ba=new Smallball();
    }}class Ballpanel extends JPanel implements KeyListener//实现接口
    {
    int x=0,y=0;
    public void paint(Graphics g)
    {
    super.paint(g);//画一个小球
    this.draw(g);
    }
    public void draw(Graphics g)
    {
    g.fillOval(x, y,10, 10);
    }

    @Override
    public void keyPressed(KeyEvent arg0) {//实现键盘功能
    // TODO Auto-generated method stub
    if(arg0.getKeyCode()==KeyEvent.VK_DOWN)
    {
    y+=5;
    System.out.println("向下运动!");
    }
    else if(arg0.getKeyCode()==KeyEvent.VK_UP)
    {
    y-=5;
    System.out.println("向上运动!");
    }
    else if(arg0.getKeyCode()==KeyEvent.VK_LEFT)
    {
    x-=5;
    System.out.println("向左运动!");
    }
    else if(arg0.getKeyCode()==KeyEvent.VK_RIGHT)
    {   x+=5;
    System.out.println("向右运动!");
    }
    this.repaint();//重绘
    } @Override
    public void keyReleased(KeyEvent arg0) {
    // TODO Auto-generated method stub

    } @Override
    public void keyTyped(KeyEvent arg0) {
    // TODO Auto-generated method stub

    }

    }
      

  5.   

    你4楼的这个测试程序没意义,因为根本没有东西可以去抢Smallball(JFrame)的焦点。你在上面放个按钮,再试试看,保证你大跌眼镜。
      

  6.   

    事件注册在mp上,然后mp.requestFocus()我测试好像是你要的结果
      

  7.   

    我把this.addKeyListener(mp);  mp.addKeyListener(mp);
    这两个一起用上,问题就解决了!不过原理还是不太明白!
      

  8.   

    mp.addKeyListener(mp); 相当于多在Mypanel1上注册了事件。那么当你鼠标点击后,焦点就从Frame转移到了Mypanel1上,所以后续的事件全部由Mypanel1获取了。但并没有根治问题,你如果加个Button上去,点一下后,仍然会继续大跌眼镜。