我用JAVA做了一个"雷电"的程序,你看一下import java.awt.*;
import java.applet.*;public class wumin1 extends Applet  
{
    carton carton_1=null;//声明一个carton类的实例.

    public void start()
    {
      if (carton_1==null)//假如未初始化
        {
            carton_1=new carton(getGraphics(),this);//初始化?
            carton_1.start();//启动?
        }
        
} public void paint(Graphics g)
{update(g);}
public void update(Graphics g)
{}
 
    public void stop()
    {
        carton_1.stop();//停止?
        carton_1=null;//释放资源?
    }    //键被按下事件的处理.
    public boolean keyDown(Event e,int key)
    {
        if (key==Event.UP)//假如是向上键被按下
            carton_1.set_direction(0);//向上的布尔变量置true
        if (key==Event.DOWN)//假如是向下键被按下
            carton_1.set_direction(1);//向下的布尔变量置true
        if (key==Event.LEFT)//假如是向左键被按下
            carton_1.set_direction(2);//向左的布尔变量true
        if (key==Event.RIGHT)//假如是向右键被按下
            carton_1.set_direction(3);//向右的布尔变量置true
if (key=='s'){
carton_1.gamerun=true;carton_1.position_x=170;carton_1.position_y=320;}
return true;
    }    //键被松开事件的处理.
    public boolean keyUp(Event e,int key)
    {
        if (key==Event.UP)//假如是向上键被松开
            carton_1.clear_direction(0);//向上的布尔变量置false
        if (key==Event.DOWN)//假如是向下键被松开
            carton_1.clear_direction(1);//向下的布尔变量置false
        if (key==Event.LEFT)//假如是向左键被松开
            carton_1.clear_direction(2);//向左的布尔变量置false
        if (key==Event.RIGHT)//假如是向右键被松开
            carton_1.clear_direction(3);//向右的布尔变量置false
if (key==32)
carton_1.fire_wanna_switch(true);
return true;
    }
}//主角所属类的描述
class carton extends Thread//从Thread类派生
{
    Graphics g,off_screen=null;//g是当前的图形设备环境,off_screen是后台缓冲区图形设备环境
    boolean up=false,down=false,left=false,right=false;//四个方向布尔变量
    boolean img_now_switch=true;//图片切换开关.
boolean fire_wanna=false;//fire_wanna是要求开枪,用户每次松开空格键就置位
    int position_x=170,position_y=320,pos_x,pos_y;//(position_x,position_y)是主角当前位置,(pos_x,pos_y)是刚才的位置
int i=0,j=0,k_left=0,k_right=0;//这些是程序中计算时的临时变量
    int bullet_amount_left=0;
int bullet_amount_right=0;//子弹总数量
    int bullet_position_left[][]=new int[301][2];
int bullet_position_right[][]=new int[301][2];//全部子弹信息纪录.每个子弹占横向三个元素.第一个是横坐标,第二个是纵坐标
int plane_died=-1;//我机被击中;
int enemy_lose=0,enemy_bullet_lose=0;//敌机损失,敌机子弹损失;
    int enemy[][]=new int[31][2];
int enemy_bullet[][]=new int[31][2];
int enemy_dx[]=new int[31];
int enemy_bullet_dx[]=new int[31];
int enemy_amount=0,enemy_bullet_amount=0;
int enemy_plane=0,enemy_ball=0;
int enemy_status[]=new int[31];
int enemy_bullet_status[]=new int[31];
Image img_center,img_right,img_left;//全部的图片
    Image img_now;//现在要显示的图片(当前图片).它会改变的
Image map;//背景图片;
Image enemy_image,enemy_bullet_image,flame,ball;
int mapposX=50,mapposY=50;//背景图片的距离
    Image bullet_left,bullet_right;//子弹的全部图片
Image off_screen_buffer=null;//后台图形缓冲
    Applet applet;
    int sleep_time=30;
    MediaTracker track;
Rectangle enemy_rect[]=new Rectangle[31];
    Rectangle enemy_bullet_rect[]=new Rectangle[31];
boolean gamerun=false;
int killtotalo=0;
    //初始化时要将各种环境准备好
    public carton(Graphics a,Applet app)
    {
        g=a;
        applet=app;
track=new MediaTracker(applet);
        //下面把所有要用的图片调入
img_center=applet.getImage(applet.getCodeBase(),"center.gif");
        img_left=applet.getImage(applet.getCodeBase(),"left.gif");
        img_right=applet.getImage(applet.getCodeBase(),"right.gif");
bullet_left=applet.getImage(applet.getCodeBase(),"bullet_left.gif");
bullet_right=applet.getImage(applet.getCodeBase(),"bullet_right.gif");
        map=applet.getImage(applet.getCodeBase(),"map.gif");
enemy_image=applet.getImage(applet.getCodeBase(),"enemy.gif");
        enemy_bullet_image=applet.getImage(applet.getCodeBase(),"ball.gif");
        flame=applet.getImage(applet.getCodeBase(),"flame.gif");
ball=applet.getImage(applet.getCodeBase(),"ball.gif");

track.addImage(img_center,0);
track.addImage(img_left,1);
track.addImage(img_right,2);
track.addImage(bullet_left,3);
track.addImage(bullet_right,4);
track.addImage(map,5);
track.addImage(enemy_image,6);
track.addImage(enemy_bullet_image,7);
track.addImage(flame,8);
    track.addImage(ball,9);

try{track.waitForAll();}
catch(InterruptedException e){}


        //设置当前图片
        img_now=img_center;        //创建后台缓冲区,并取其图形设备环境
        off_screen_buffer=applet.createImage(400,410);
        off_screen=off_screen_buffer.getGraphics();
    }    //这是主运行函数.
    public void run()
    {
while(true)//此函数一直运行;
        {
if(plane_died==-1)
   set_position();//计算我机的坐标;            select_image();//选择当前图片; bullet_processing();//处理我方子弹; set_enemy_plane();//设置敌机移动;

set_enemy_bullet();//设置敌机子弹;

draw_image();//画图
            try//标准的暂停方式
            {
                sleep(sleep_time);
            }
            catch(InterruptedException e)
            {
            }
        }
    }
    //计算主角的坐标
    public void set_position()
    {
        //首先保留当前位置坐标值
        pos_x=position_x;
        pos_y=position_y;        if(up==true && position_y>1)//假如向上的键被按下并且小方块的纵坐标大于1
            position_y-=6;//小方块向上移动
        if(down==true && position_y<350)//假如向下的键被按下并且小方块的纵坐标小于350
            position_y+=6;//小方块向下移动
        if(left==true && position_x>1)//假如向左的键被按下并且小方块的横坐标大于1
            position_x-=6;//小方块向左移动
        if(right==true && position_x<350)//假如向右的键被按下并且小方块的横坐标小于350
            position_x+=6;//小方块向右移动
    }

解决方案 »

  1.   


       //画屏幕
        public void draw_image()
        {
    mapposX-=2;
    if (mapposX<=0) mapposX=50;
    if (left) mapposY--;
    if (right) mapposY++;
    if (mapposY<=0) mapposY=50;
    if (mapposY>50) mapposY=1;
    for (int x=0; x<=8; x++)
    for (int y=0; y<=9; y++)

    off_screen.drawImage(map,50*x-mapposY, 50*y-mapposX,applet); //在后台画背景   if(gamerun)draw_my_plane();//画我机;
    else {gameIs();plane_died=-1;position_x=1000;position_y=1000;}

    draw_bullet();//画子弹

    draw_enemy_img();//画敌机;

    draw_ball_img();//画敌机子弹;

    g.drawImage(off_screen_buffer,0,0,applet);//送到前景显示
        }
       //选择图片
        public void select_image()
        {
            //假如主角没有动
            if(position_x==pos_x && position_y==pos_y)
            {
                img_now=img_center;
            }        if(position_x==pos_x && position_y<pos_y)//主角现在的位置在刚才位置的上方
                img_now=img_center;//选择img_up去显示
            
    if(position_x==pos_x && position_y>pos_y)//主角现在的位置在刚才位置的下方
        img_now=img_center;//选择img_up去显示

            if(position_x>pos_x && position_y==pos_y)//主角现在的位置在刚才位置的右方
                img_now=img_right;//选择img_right去显示
           
            if(position_x<pos_x && position_y==pos_y)//主角现在的位置在刚才位置的左方
                img_now=img_left;//选择img_left显示
            
        }
        
    public void gameIs()
    {
    off_screen.setFont(new Font("",1,14));
    off_screen.setColor(Color.green);
    off_screen.drawString("Java Raiden Applet Ver 0.11",105,100);
        off_screen.drawString("press 's' to Begin",125,140);
    off_screen.drawString("SpaceBar : Fire",135,170);
    off_screen.drawString("Arrpw Key : Move",135,190);
    off_screen.drawString("Programmed by :",135,240);
    off_screen.drawString("[email protected]",135,260);
    off_screen.drawString("CopyRight (c) 2001-2002 Wang Jingfeng",50,300);
    off_screen.drawString("Special Thanks : ",135,330);
    off_screen.drawString("Xiao Qiong",153,350);
    }

    public void draw_my_plane()//画我机;
    {
    if(plane_died<=27&&plane_died>=0){

    off_screen.drawImage(flame,position_x,position_y,position_x+54,position_y+50,plane_died/3*54,0,plane_died/3*54+54,50,applet);
        plane_died++;
    }   

    else if(plane_died>=28){gamerun=false;}

    else if(plane_died==-1)
    off_screen.drawImage(img_now,position_x,position_y,applet);//在后台画主角

    }
    //在后台画子弹的方法
        public void draw_bullet()
    {
    for(i=1;i<=bullet_amount_left;i++)
    {  
    off_screen.drawImage(bullet_left,bullet_position_left[i][0],bullet_position_left[i][1],applet);
    }     
         
        for(i=1;i<=bullet_amount_right;i++)
    {  
    off_screen.drawImage(bullet_right,bullet_position_right[i][0],bullet_position_right[i][1],applet);
    }     
    }

    public void draw_enemy_img()//画敌机;
    {
      
    for(i=1;i<=enemy_amount;i++){

    if(enemy_status[i]<=27&&enemy_status[i]>=0){
     
    off_screen.drawImage(flame,enemy[i][0],enemy[i][1],enemy[i][0]+54,enemy[i][1]+50,enemy_status[i]/3*54,0,enemy_status[i]/3*54+54,50,applet);
        killtotalo++;
    enemy_status[i]++;
        

    }
      
    else if(enemy_status[i]>28){enemy_plane=i;enemy_plane_img();}

    else if(enemy_status[i]==-1){

    off_screen.drawImage(enemy_image,enemy[i][0],enemy[i][1],applet);}}
                
            off_screen.drawString("Total:"+killtotalo,20,20); 

    }

    public void draw_ball_img()
    {
    for(i=1;i<=enemy_bullet_amount;i++){
    off_screen.drawImage(ball,enemy_bullet[i][0],enemy_bullet[i][1],applet);}
    }

    //申请开枪的方法
        public void fire_wanna_switch(boolean a)
    {
    fire_wanna=a;
    }

      

  2.   

    //处理子弹的方法
        public void bullet_processing()
    {   
    //增加一颗子弹
            if(fire_wanna)//假如用户要求开枪,并且现行子弹总数小于30颗
            {
    //下面根据主角的位置设置子弹的初始坐标.
    bullet_amount_left++;
    bullet_amount_right++;
    fire_wanna=false;

    bullet_position_left[bullet_amount_left][0]=position_x+13;
    bullet_position_left[bullet_amount_left][1]=position_y+10;
        bullet_position_right[bullet_amount_right][0]=position_x+31;
    bullet_position_right[bullet_amount_right][1]=position_y+10;
     
         }
    //下面计算子弹的位置,一颗一颗处理

        for(i=1;i<=bullet_amount_left;i++)
    {
    bullet_position_left[i][0]=bullet_position_left[i][0]-2;
    bullet_position_left[i][1]=bullet_position_left[i][1]-14;
    }
          
    //下面判断是否有某颗子弹飞出了屏幕边界,有的话,去掉它,并将它后面得数组元素前移 

      k_left=0;// k 用来纪录有几颗子弹飞出了屏幕边界
        
      for(i=1;i<=bullet_amount_left;i++)
      {
    //假如子弹飞出了屏幕边界;
                if(bullet_position_left[i][0]<-10||bullet_position_left[i][0]>400||bullet_position_left[i][1]<-10||bullet_position_left[i][1]>410)
    {
    for(j=i+1;j<=bullet_amount_left;j++)//它后面所有的元素向前移占据它在数组中的位置
    {
    bullet_position_left[j-1][0]=bullet_position_left[j][0];
    bullet_position_left[j-1][1]=bullet_position_left[j][1];
    }
     k_left++;
    }
    }
    bullet_amount_left=bullet_amount_left-k_left;//现在子弹的总数量是刚才的数量减去飞出屏幕边界的子弹的数量
     
    for(i=1;i<=bullet_amount_right;i++)
    {
    bullet_position_right[i][0]=bullet_position_right[i][0]+2;
    bullet_position_right[i][1]=bullet_position_right[i][1]-14;
    }
        
    k_right=0;// k 用来纪录有几颗子弹飞出了屏幕边界

    for(i=1;i<=bullet_amount_right;i++)
    {
    //假如子弹飞出了屏幕边界
                if(bullet_position_right[i][0]<-10||bullet_position_right[i][0]>400||bullet_position_right[i][1]<-10||bullet_position_right[i][1]>410)
    {
    for(j=i+1;j<=bullet_amount_right;j++)//它后面所有的元素向前移占据它在数组中的位置
    {
    bullet_position_right[j-1][0]=bullet_position_right[j][0];
    bullet_position_right[j-1][1]=bullet_position_right[j][1];
    }
     k_right++;
    }
    }
    bullet_amount_right=bullet_amount_right-k_right;//现在子弹的总数量是刚才的数量减去飞出屏幕边界的子弹的数量;
    }  

         public void set_enemy_plane()//设置敌机出现和移动;
    {
     
    int m=enemy_amount+1; for(int i=m;i<31;i++)
    {
    if(Math.random()>0.998)
    {
    enemy[m][1]=-100;
    enemy[m][0]=(int)(Math.random()*300+25);
    enemy_dx[m]=(int)(Math.random()*5)-2;
    enemy_status[m]=-1;
    m++;
    }
    }
    enemy_amount=m-1;

    for(int i=1;i<=enemy_amount;i++)
    {
    enemy[i][0]=enemy[i][0]+enemy_dx[i];
    enemy[i][1]=enemy[i][1]+4;
    }

    enemy_lose=0;enemy_plane=0;

    for(int i=1;i<=enemy_amount;i++)
    {
      enemy_rect[i]=new Rectangle(enemy[i][0],enemy[i][1],30,30);
      
      if(enemy[i][0]<-30||enemy[i][0]>400||enemy[i][1]<-110||enemy[i][1]>410){enemy_plane=i;enemy_plane_img();}
      
      else if(enemy_rect[i].intersects(new Rectangle(position_x,position_y,40,50))&&enemy_status[i]==-1)//如果和我机相撞;
      {   
    enemy_status[i]=0;  plane_died=0; killtotalo++;//得分增加;
      }
      
      for(int z=1;z<=bullet_amount_left;z++)
      {
     if( enemy_rect[i].intersects(new Rectangle(bullet_position_left[z][0],bullet_position_left[z][1],7,13))&&enemy_status[i]==-1)
     enemy_status[i]=0;}
      
      for(int z=1;z<=bullet_amount_right;z++)
      {
     if( enemy_rect[i].intersects(new Rectangle(bullet_position_right[z][0],bullet_position_right[z][1],7,13))&&enemy_status[i]==-1)
     enemy_status[i]=0;}

    }
     }
     public void enemy_plane_img()
     {       
          enemy_lose++;
      
      for(int j=enemy_plane+1;j<=enemy_amount;j++)
      {
          enemy[j-1][0]=enemy[j][0];
          enemy[j-1][1]=enemy[j][1];
          enemy_dx[j-1]=enemy_dx[j];
      enemy_status[j-1]=enemy_status[j];
      }
              enemy_amount=enemy_amount-enemy_lose;  

     }
     
        public void set_enemy_bullet()//设置敌机的子弹;
    {
     
    int m=enemy_bullet_amount;

    for(int i=1;i<=enemy_amount;i++)
    {
    if(Math.random()>0.97&&enemy_bullet_amount<29&&enemy_status[i]==-1)
    {
    m++;
    enemy_bullet[m][1]=enemy[i][1]+20;
    enemy_bullet[m][0]=enemy[i][0]+10;//子弹的初始坐标
    enemy_bullet_dx[m]=(int)(Math.random()*20)-10;
    enemy_bullet_status[m]=-1;
    }
    }
    enemy_bullet_amount=m;//敌机打出子弹的总和;



    for(int i=1;i<=enemy_bullet_amount;i++)
    {
    enemy_bullet[i][0]=enemy_bullet[i][0]+enemy_bullet_dx[i];
    enemy_bullet[i][1]=enemy_bullet[i][1]+12;//子弹的轨迹;
    }
    enemy_bullet_lose=0;enemy_ball=0;

     for(int i=1;i<=enemy_bullet_amount;i++)
    {
    enemy_bullet_rect[i]=new Rectangle(enemy_bullet[i][0],enemy_bullet[i][1],8,8);
      
        if(enemy_bullet[i][0]<-20||enemy_bullet[i][0]>400||enemy_bullet[i][1]<-110||enemy_bullet[i][1]>410){enemy_ball=i;enemy_ball_img();}
      
        else if(enemy_bullet_rect[i].intersects(new Rectangle(position_x,position_y,40,50)))
        {   
    enemy_bullet_status[i]=0;enemy_ball=i;enemy_ball_img(); plane_died=0;
        }
    }
        enemy_bullet_amount=enemy_bullet_amount-enemy_bullet_lose; 
    }

          public void enemy_ball_img()
     {       
          enemy_bullet_lose++;
      
      for(int j=enemy_ball+1;j<=enemy_bullet_amount;j++)
      {
          enemy_bullet[j-1][0]=enemy_bullet[j][0];
          enemy_bullet[j-1][1]=enemy_bullet[j][1];
          enemy_bullet_dx[j-1]=enemy_bullet_dx[j];
      enemy_bullet_status[j-1]=enemy_bullet_status[j];
      }
         
          
     }

    //表示主角移动方向的布尔变量的置位方法
        public void set_direction(int direction_)
        {
            switch(direction_)
            {
                case(0)://向上键被按下则向上的布尔变量置true
                    up=true;
                    break;
                case(1)://向下键被按下则向下的布尔变量true
                    down=true;
                    break;
                case(2)://向左键被按下则向左的布尔变量true
                    left=true;
                    break;
                case(3)://向右键被按下则向右的布尔变量置true
                    right=true;
                    break;
                default:
                    break;
            }
        }    //表示主角移动方向的布尔变量的清零方法
        public void clear_direction(int direction_)
        {
            switch(direction_)
            {
                case(0)://向上键被松开则向上的布尔变量置false
                    up=false;
                    break;
                case(1)://向下键被松开则向下的布尔变量置false
                    down=false;
                    break;
                case(2)://向左键被松开则向左的布尔变量置false
                    left=false;
                    break;
                case(3)://向右键被松开则向右的布尔变量置false
                    right=false;
                    break;
                default:
                    break;
            }
        }
    }
      

  3.   

    太感谢了!能不能再把class,htm和图片也发给我?
    [email protected]
      

  4.   

    据我所知只能够判断出ctrl、alt、shift这些功能键是否按下,其他的键是否会有同时按下的说法恐怕不容易啊,楼主应该是通过记录两次时间来判断的吧,可能就这个方法
      

  5.   

    在keyRelease事件里面进行处理,放掉键为左时修改一下方向