哎,到底问题出在哪里?看了好久没看出来!

小牛毛 2012-04-18 10:44:39
我试着做个坦克大战游戏,但是今晚就出问题了:就是每次把鼠标单击一下界面后,程序就不受控制了,监听不到任何消息了,求大神帮忙!代码如下:
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

}
}
...全文
221 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
MiceRice 2012-04-20
  • 打赏
  • 举报
回复
mp.addKeyListener(mp); 相当于多在Mypanel1上注册了事件。

那么当你鼠标点击后,焦点就从Frame转移到了Mypanel1上,所以后续的事件全部由Mypanel1获取了。

但并没有根治问题,你如果加个Button上去,点一下后,仍然会继续大跌眼镜。
小牛毛 2012-04-20
  • 打赏
  • 举报
回复
我把this.addKeyListener(mp);

mp.addKeyListener(mp);
这两个一起用上,问题就解决了!不过原理还是不太明白![Quote=引用 6 楼 的回复:]
事件注册在mp上,然后mp.requestFocus()我测试好像是你要的结果
[/Quote]
MiceRice 2012-04-19
  • 打赏
  • 举报
回复
你4楼的这个测试程序没意义,因为根本没有东西可以去抢Smallball(JFrame)的焦点。

你在上面放个按钮,再试试看,保证你大跌眼镜。
小牛毛 2012-04-19
  • 打赏
  • 举报
回复
,我刚刚试了,不能解决啊,但我之前做了个测试程序没遇到这个问题,我把代码贴出来看看,很困扰
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

}

}


[Quote=引用 1 楼 的回复:]
//this.addKeyListener(mp);

mp.addKeyListener(mp);

启动起来要先点一点mp

测试一下感觉是点mouse的时候,焦点在mp上,再键盘mp接收到事件,而你的KeyListener是在Frame上
[/Quote]
MiceRice 2012-04-19
  • 打赏
  • 举报
回复
确实是焦点丢失的问题,你的KeyListener是在Frame上,鼠标点击后,焦点就不再Yumentank上了。

然而你没有什么方式能引用Yumentank,所以也没法进行 Yumentank.requestFocus();

需要调整下。
fnbone 2012-04-19
  • 打赏
  • 举报
回复
加上构造方法最后 mp.requestFocus();
就对了
fnbone 2012-04-19
  • 打赏
  • 举报
回复
//this.addKeyListener(mp);

mp.addKeyListener(mp);

启动起来要先点一点mp

测试一下感觉是点mouse的时候,焦点在mp上,再键盘mp接收到事件,而你的KeyListener是在Frame上
fnbone 2012-04-19
  • 打赏
  • 举报
回复
事件注册在mp上,然后mp.requestFocus()我测试好像是你要的结果

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧