小游戏

  总结:
   游戏:碧奇公主历险记
   设计步骤:1   实现初界面
                          首先把每个界面的图片给ps下来(除了前面两页之外,把图片p成一个整体会方便很多),然后通过下面代码来实前两个界面:
          public class GameFrame extends JFrame{
   
  //主函数方法
         public static void main(String args[]){
          //由类创建对象
          GameFrame gf=new GameFrame();
          //对象窗体初始化
          gf.initGameFrame();
         }
         //对象窗体初始化的方法
         public void initGameFrame(){
          //设置标题和大小
          this.setTitle("小游戏");
          this.setSize(554,400);
          //设置中间面板
          JPanel center=new JPanel();
          //设置中间面板的大小
          center.setPreferredSize(new Dimension(547,377));
          //设置中间面板的颜色
          center.setBackground(Color.darkGray);
          //将中间面板加到窗体上
          this.add(center);
          //将第一张图片加到窗体上
          ImageIcon icon1=new ImageIcon("img/first.png");
         JLabel lab=new JLabel(icon1);
         center.add(lab);
          //关闭程序时退出进程
          this.setDefaultCloseOperation(3);
          //设置可见
          this.setVisible(true);
          //添加画布
          Graphics g=center.getGraphics();
         //创建监听器获取中间面板局部监听
          MouseListener mlis=new MouseAdapter(){
           public void mouseReleased(MouseEvent e) {
            //鼠标获得坐标
            int x=e.getX();
            int y=e.getY();
            
            //获得第二个界面
            if(x>=185&&x<=317&&y>=208&&y<=225){//鼠标点击这块区域时
             
             GameFrame1 gf1=new GameFrame1();
             gf1.initGameFrame1();
             
             //将第一个窗体从内存中释放
             GameFrame.this.dispose();
            }
                 if(x>=185&&x<=244&&y>=152&&y<=170){//当鼠标点击这块区域时获得另一界面
             
             GameFrame2 gf2=new GameFrame2();
             gf2.initGameFrame2();
             
             //将本窗体从内存中释放
             GameFrame.this.dispose();
            }
            
           }  
          };
          //中间面板添加鼠标监听器
          center.addMouseListener(mlis);
         }
}
      2.实现图片和人物同时分别向左和右移动
                             具体做法是   :把p好的整体图添加到界面的中心面板上, 因为人物是通过键盘监听器来完成,所以要在键盘
                             监听器里面通过人物的xc(增量)来给图片传一个变量。实现图片和人物同时移动还比较简单,但是当人物走到
                             中心面板最右端时,这时图片和人物都要跳变,即人物跳到中心面板的左边,图片  也要   跳一个中心面板的长度,
                             这个有  一定的难度,具体代码如下:
                //     人物类(把人物设置成一个线程)       
                   public void run(){
   while(lifes>0){//当人物生命值大于0时
    if(direct==-1){//direct 表示人物运动的方向    -1表示向左运动  1表示向右运动   0表示向上运动   2表示不动
     xc = -4;//人物向左的增量
    x += xc;//x表示人物的坐标

     GameFrame2.size +=xc;//定义size是用来当人物走到最右边时图片的跳变
     GameFrame2.tux -=xc; //图片的运动
    }
    if(direct==1){//人物向右运动时
      xc = 4;//人物向右的增量
     x +=xc;//坐标
     GameFrame2.size +=xc;
     GameFrame2.tux -=xc;
   
    }
    if(direct==0){//人物向上跳时
     for(int i=0;i<10;i++){//向上
      y-=yc;
     }
     try{//异常处理
     Thread.sleep(100);
     }catch(Exception e){
      e.printStackTrace();
     }
     for(int i=0;i<10;i++){//向下
      y+=yc;
     }
    
    }
    direct=2;     //默认不运动     
                            
                            
                 //主界面上的键盘监听器           
          KeyListener klis = new KeyAdapter() {
   public void keyPressed(KeyEvent e) {
    // 得到键盘码
    int t = e.getKeyCode();
    
    if (t == KeyEvent.VK_LEFT) {//左键码
     if (role.x >= 1) {//当人物向右运动时
      role.direct=-1;
     }
    }
    if (t == KeyEvent.VK_UP) {//上键码
     role.direct=0;
    }
    
    if (t == KeyEvent.VK_RIGHT) {//右键码
     
     role.direct=1;
    }

   }

  };
  //人物跳变的方法:当每过一个界面时,人物坐标跳变为0
   if (size % 496 == 0) {
    role.x = 0;
   }
   //背景跳变的方法
   if(role.x%496==0){//当role.x返回原点时,图片移动一个界面
   tux-=496;
   }
   //贴背景图片
   ImageIcon icon1 = new ImageIcon("222.png");
   //tux tuy为背景图片左上角的坐标
   gr.drawImage(icon1.getImage(), tux, tuy, null);

   if (role.xc >=0) {
    // 在背景中添加人
    gr.drawImage(role.icon.getImage(), role.x, role.y, null);
   }
   if (role.xc < 0) {
    // 在背景中添加人物
    gr.drawImage(role.icon2.getImage(), role.x, role.y, null);
   }
  
  3.实现人物按着图片上的轨迹运动,这个比较难而且麻烦,因为遍历图片轨迹的每一点,再人物的坐标比较,具体代码如下:
  //首先定义一个点类
  public class MyPoint {
 
  Point point;//点
  boolean isOk =true;//是否可以站立

//调用Point中的方法
 
     //得到图片上的x点的方法
 public double getX(){
 
  return point.x;
  
 }
 //得到图片上点y的方法
 public double getY(){
  return point.y;
 }
}
  
//将所有的点保存到队列当中
   points.add(mp);

  }

 }

 

 

 

 

 

// 把图片上所有的点保存到队列当中
 static ArrayList<MyPoint> points = new ArrayList<MyPoint>();  
  
 public GameFrame2() {
  role.start();
  int y = 257;
  // 将路径中的点保存到队列中
  for (int i = 0; i < 4878; i++) {
   // 把每一点都创建成具体对象
   MyPoint mp = new MyPoint();
   if (i <= 271) {
   //由 Point 类创建对象
    Point p = new Point(i, y);
    //将Point 类创建的对象赋给图片上的点
    mp.point = p;
    mp.isOk = true;
   } else if (i > 271 && i <= 435) {
    if (i % 4 == 0) {
     ++y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 439 && i <= 641) {
    Point p = new Point(i, y = 294);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 641 && i <= 666) {
    if (i % 4 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 666 && i <= 706) {
    if (i % 2 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 706 && i <= 748) {

    Point p = new Point(i, --y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 748 && i <= 777) {
    if (i % 2 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   }

   else if (i > 777 && i <= 1236) {
    Point p = new Point(i, y = 200);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1236 && i <= 1314) {
    if (i % 2 == 0) {
     ++y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1314 && i <= 1380) {

    Point p = new Point(i, ++y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1380 && i <= 1446) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 1446 && i <= 1465) {

    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1465 && i <= 1499) {
    if (i % 4 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1499 && i <= 1528) {

    Point p = new Point(i, --y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1528 && i <= 1598) {
    if (i % 2 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1600 && i <= 1780) {
    Point p = new Point(i, y = 200);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1780 && i <= 1844) {
    if (i % 2 == 0) {
     ++y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1844 && i <= 1918) {
    Point p = new Point(i, ++y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 1918 && i <= 1987) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 1987 && i <= 2008) {
    Point p = new Point(i, y = 296);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2008 && i <= 2077) {
    if (i % 2 == 0) {
     --y;
    }
    Point p = new Point(i, y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2077 && i <= 2139) {

    Point p = new Point(i, --y);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2139 && i <= 2403) {
    Point p = new Point(i, y = 200);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2403 && i <= 2598) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 2598 && i <= 2689) {
    Point p = new Point(i, y = 255);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2689 && i <= 2778) {
    Point p = new Point(i, y = 190);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2778 && i <= 2898) {
    Point p = new Point(i, y = 127);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 2898 && i <= 3023) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 3023 && i <= 3517) {
    Point p = new Point(i, y = 217);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 3517 && i <= 3605) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 3605 && i <= 3788) {
    Point p = new Point(i, y = 160);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 3788 && i <= 3869) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 3869 && i <= 3915) {
    Point p = new Point(i, y = 177);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 3915 && i <= 3965) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 3965 && i <= 4087) {
    Point p = new Point(i, y = 245);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 4087 && i <= 4216) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 4216 && i <= 4401) {
    Point p = new Point(i, y = 156);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 4401 && i <= 4484) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 4484 && i <= 4528) {
    Point p = new Point(i, y = 173);
    mp.point = p;
    mp.isOk = true;
   } else if (i > 4528 && i <= 4578) {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   } else if (i > 4578 && i <= 4700) {
    Point p = new Point(i, y = 243);
    mp.point = p;
    mp.isOk = true;
   } else {
    Point p = new Point(i, y = -1);
    mp.point = p;
    mp.isOk = false;
   }

 
 //人物类中的方法 
  //人物运动的方法
    public void Left(){
     // 遍历图片队列中所有的点
     for (int i = 0; i < GameFrame2.points.size(); i++) {
     //得到图片中的每一点
   MyPoint mp = GameFrame2.points.get(i);
   if(mp.isOk){
   //由点得到每点的x,y坐标
    px = (int) mp.getX();
    py = (int) mp.getY();
  //判断人物的坐标:通过在纸上画图得到role.x 和tux及px之间的关系
  if (px ==x -GameFrame2.tux +width) {//width为人物的宽度
    y = py -height;
    break;
    }
  
  }else{
   y+=yc;
  }
    }
    }
   
    public void Right(){
     
     // 遍历图片队列中所有的点
     for (int i = 0; i < GameFrame2.points.size(); i++) {
   MyPoint mp = GameFrame2.points.get(i);
   if(mp.isOk){
   px = (int) mp.getX();
     py = (int) mp.getY();
  if (px ==x -GameFrame2.tux + width) {
    y = py -height;
    break;
  }
   }else{
   yc=20;
   y+=yc;
  }
   
  
  }  
      
  4.人物发射子弹的方法:把子弹定义为一个线程,有类似抛物线的运动,因为人物随时都可以发射子弹,
  所以创建一个队列用来装子弹线程,以便可以用来清除,具体代码如下:
  public class ZidanThread extends Thread {
 // 定义子弹的属性
 int x ;
 int y ;

 // 定义宽度和高度
 int width = 15;
 int height = 12;
 // 子弹增量
  int xc = 10;
 int yc = 1;
//创建子弹图片图标
 ImageIcon icon = new ImageIcon("img/zidan.png");
 //注意:调用其他类中变量时尽量不要设置成静态的,而是像这样传入类就行
    Role role;
    public ZidanThread(Role role){
    this.role=role;
    if(role.xc>0){
     xc=15;
    }else{
     xc=-15;
    }
    //子弹的初始时的具体位置
    x=role.x+35;
    y=role.y+30;
    }
 // 调用父类的方法
 public void run() {

  change();

 }

 public void change() {
  while (true) {
   //判断子弹的路径:与图片路径的碰撞问题
              //类似于抛物线的判断方法
     if(y<role.y+role.height){
    
      x += xc;
      y += yc;
      yc++;
           
     }
     else {
       x += xc;
      yc = -yc;
      y += yc;
      yc += 1;
     }
   try {
    Thread.sleep(30);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }

 }

}
// 创建一个队列,用来装子弹
 static ArrayList<ZidanThread> zts = new ArrayList<ZidanThread>();

// 空格键的方法

    if (t == 32) {
   //由子弹类创建子弹对象的构造方法
     zt = new ZidanThread(role);
     //启动子弹线程
     zt.start();
     //将发射的子弹放到队列当中
     zts.add(zt);

    }

             5.子弹用过之后要从队列中清除------------最后在讨论
                //当子弹使用过之后从队列中清除子弹的方法
            public void test(Graphics gr) {
  for (int i = 0; i < zts.size(); i++) {

   // 从队列中取出
   ZidanThread zt = zts.get(i);
   //判断子弹清除的方法
   if (zt.yc == 0 ||(( null != zt && (yth.x - zt.x <=1)&& (yth.x - zt.x>=0)&& (yth.y - zt.y) <= 10 ))|| ((null != zt&& Math.abs(gth.x - zt.x) <=1&& Math.abs(gth.y - zt.y) <=20))) {

    zts.remove(i);

   }
   //绘制子弹图片在画布上
   gr.drawImage(zt.icon.getImage(), zt.x, zt.y, zt.width, zt.height,
     null);
  }
 }
  

          6.用子弹打怪物的方法,具体是当子弹和怪物超过一定距离时要清除子弹和怪物,具体代码如下:
          
    // 遍历乌龟队列,判断子弹有没有打到乌龟
   for (int j = 0; j < GameFrame2.yas.size(); j++) {
    //取出乌龟线程
    YaThread yth = GameFrame2.yas.get(j);
    //判断是否和子弹碰到
    if ((yth.x - this.x <=1)&&(yth.x - this.x >= 0) && (yth.y - this.y) <= 10) {
    
     //System.out.println("移除了");
     //如果碰到就从队列中移除
     GameFrame2.yas.remove(j);
     
    }

   }
   // 创建一个乌龟队列
 static ArrayList<YaThread> yas = new ArrayList<YaThread>();
 // 创建一个怪物队列
 static ArrayList<GuiwuThread> gws = new ArrayList<GuiwuThread>();
 //遍历怪物队列,判断子弹有没有打到怪物
   for(int i=0;i<GameFrame2.gws.size();i++){
   //取出所有的怪物对象
    GuiwuThread gth=GameFrame2.gws.get(i);
    //如果超过了一定的距离
    if (Math.abs((gth.x - this.x))<=1&& Math.abs(gth.y - this.y) <=20) {
     //如果碰到就从队列中移除
     GameFrame2.gws.remove(i);
    }
   }

              //重绘中的方法
   // 遍历怪物队列
   for (int k = 0; k < gws.size(); k++) {
   //从队列中取出所有的怪物对象
    GuiwuThread gth = gws.get(k);
    //在画布上画怪物的图片
    gr.drawImage(gth.icon.getImage(), gth.x + tux, gth.y, null);
   }
   //遍历乌龟队列
   for (int k = 0; k < yas.size(); k++) {
   //从队列中取出所有的乌龟对象
    YaThread ya = yas.get(k);
    //在画布上绘制乌龟的图片
    gr.drawImage(ya.icon.getImage(), ya.x + tux, ya.y, null);
   }

       
  感悟:以上是我这次做这个游戏的可以说是全部了,这次做的游戏很菜,但通过这次做游戏发现做游戏并
  不神奇,很多功能上的东东都是我们老师以前讲到过的,比如重绘,比如线程、碰撞等问题,但是还有很
  多自己不会的,比如组合键的使用,通过这次做游戏,发现自己有好多以前学的东西有些都忘了,可能是
  自己理解不够,下的功夫不够,接下来要做的就是加油了,不贪多,把每次课搞懂,熟练。
  
  
  
  
  
  
  
  
  
  
  
  
                   
                            
          
                            
                            
                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值