码迷,mamicode.com
首页 > 其他好文 > 详细

在游戏里,我是怎样做出分身效果?

时间:2015-03-30 11:19:41      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:游戏   java   原创   


在游戏里,我是怎样做出分身效果?

 

技术分享

 

我是怎样完成了里世界,分身。

 

 

我之前已经完成了夜撩,大阳气炮,夜撩断魂,中华宝轮……后来证明,要实现是世界,分身是一件相当困难的事情,这几乎花了我两天的时间。

 

我前后想过很多办法,实现的结果不是很理想:

 

最开始,我想得很简单,就是记录一个时间差,比如只需要记住主角3秒钟前的坐标和攻击方位就行。

 

后来证明,这种想法太过幼稚。

 

不过是在实践中才得出这个结论,我这样做了,首先,我建了一个分身类,继承了我自己,省略了若干的方法,只留一个主干,其中包括绘制方法。接下来,我用几个常量记录3秒钟前的坐标和攻击方位,后来的结果是,分身几乎无法移动,即使移动也是瞬间移动。

 

所以,我想到了,用一个数组,因为我意识到,要顺滑的表现出分身的移动,分身其实就是重复我的移动,那实际上需要记录的是一系列数据,比如他是重复我3秒前的移动,那我不应该只记录3秒前我的状态,而必须记录我在3秒钟里几乎所有状态!

 

OK,现在开始做,我做了如下改进:我用一个二维数组,比如a[][],第一个下标代表3秒内的每一帧,第二个下标取值为0-2,记录3个数据,x坐标, y坐标,攻击方向。那从现在(假设已经是3秒后往前推,a[0][0]就带表3秒前第一帧的x坐标,a[100][2]代表大概1秒前的攻击方向。

 

我把这些数据传递给我的分身,我在分身里定义了相应的3个静态常量,之所以要静态的,是为了方便赋值,因为这些常量我只需要一份,因为同一个分身不可能有多个实例。这时,我想到的是我做一个分身就行了,所以,比如x,y坐标和攻击方向,我只需要一份(当然你也看到了,实际上我做出了多个分身的效果)

 

但是,现在问题来了,主要问题有两个:

1、  攻击方向我是定义的一个枚举常量,数组中无法同时传递int 枚举数据;

2、  最关键的,数组的大小是固定的,我该要定义多大的数组?我也许试过a[10000][3],很显然,我需要分身战斗200秒,每秒假设绘制50帧,那数组可能越界,而且这样会很耗内存,因为内存得不到释放。

 

所以我必须改变,要同时解决上面两个问题,我思考后,改进为:

 

我先定义了一个内部类(他们就是最后我完成的方式了,现在我可以粘贴一些代码了):

    class Date {

       int dx;

       int dy;

       Directionddir;

 

       public Date(int dxint dy, Direction ddir) {

           this.dx = dx;

           this.dy = dy;

           this.ddir = ddir;

       }

    }

 

短短几行,却包含了足够信息。

 

完后,该是一个集合来盛放这些Date对象了,当然LIST和内部类简直是完美的搭配。代码如下:

 

List<Date> s;

 

我曾今考虑过这里用一个链表来装这个集合,因为这里不涉及到很多的随机读取,不过考虑到实际实现他后,list 的长度也只有不到20(通常情况下永远不会超过30,后面我会讲实现),所以我只是用了一个ArrayList轻松搞定。

 

在按下分身键后,一系列的计算开始了:(这就是说不按分身时是不需要去计算和保存list滴)

 

           if (dir != Direction.stop) {    //如果我在移动,才放入我的状态Date

              if (fs1 > 0) {       //fs1代表我随机出几个分身,最多4个,我不想要再多了

                  // if(ap)

                  a++;       //ab决定了分身跟我的位置。

                  Dated = new Date(xydir);   //每一次,只要我在移动,记录我的状态到一个Date里,很重要的,必须要移动才记录,否则结果会很尴尬,这是我试出来的,同时这个也保证list  size不会太大。

                  if (s == null)    //因为按下分身后,是一个TimerTask 在记录分身时间,到时则要清理相关的a,b,s等所有信息,释放内存资源,并避免下一次激活分身冲突。

                     s = newArrayList<Date>();

                  if (Unit.Dfs) { //工具类,如果为真打印调试信息,毕竟项目有些大了。

                     System.out.println(b + "    a=   "a + "  " + ",g24.size=   "t.g24.size() + "   " + ",s.size=   "s.size());

                  }

                  s.add(d);

                  if (fs1 == 1) {   //如果有一个分身,至少有一个。

                     if (a > b) {//ab决定了分身跟我的位置。b是每一次timer.cancel时计算的随机值,以供下次激活分身使用。a是每帧自增长而是固定不变,比如当17,这个算式代表了,将会在17帧后执行下面得操作。

                         // ap=false;

                         Funk24.x = s.get(0).dx;  //Funk24为分身类

                         Funk24.y = s.get(0).dy;

                         Funk24.dir = s.get(0).ddir;

                         s.remove(0);      //非常关键的,由s.remove(0)s.get(0).dx;组合成了一个记录,实现机器,并且保证了整个list的大小不会超过的大小。

                     }

                  }

 

                  if (fs1 == 2) {//如果有2个分身,第一个的出现是必然的,但第二个可能有3种情况,这里是因为我设计了4个不同的分身,而且为他们每一个都设计了单独的类,这是我塑造分身性格的一部分,在我的游戏里,分身是具备不同性格的,也有一些随机性。

                     if (a > b + Unit.UF1) {  // Unit.UF1这里等于5,实际上代表了2个分身之间的距离,当然也可以是随机数,我这里用到工具类,可以方便的进行修改。

                         Funk24.x = s.get(Unit.UF1).dx;

                         Funk24.y = s.get(Unit.UF1).dy;

                         Funk24.dir = s.get(Unit.UF1).ddir;

                         s.remove(0);      //非常重要的,一定要在list最大的哪种if情形下remove0),其他情形不用 remove

                     }

                     if (a > b) {// Funk241- Funk243 Funk24是所有的4个分身类

                         if (Funk241.g241 == 1) {// Funk241.g241 == 1就是说Funk241 被实例化了

                            Funk241.x = s.get(0).dx;

                            Funk241.y = s.get(0).dy;

                            Funk241.dir = s.get(0).ddir;

                         }

                         if (Funk242.g242 == 1) {

                            Funk242.x = s.get(0).dx;

                            Funk242.y = s.get(0).dy;

                            Funk242.dir = s.get(0).ddir;

                         }

                         if (Funk243.g243 == 1) {

                            Funk243.x = s.get(0).dx;

                            Funk243.y = s.get(0).dy;

                            Funk243.dir = s.get(0).ddir;

                         }

                     }

                  }

 

                  if (fs1 == 3) {//如果有3个分身,组合的可能最多,最复杂,但实际也不复杂,有规律

                     if (a > b + Unit.UF2) {// Unit.UF2同理是第三个跟第一个的距离

                         Funk24.x = s.get(Unit.UF2).dx;

                         Funk24.y = s.get(Unit.UF2).dy;

                         Funk24.dir = s.get(Unit.UF2).ddir;

                         s.remove(0); // b + Unit.UF2无疑是list最大情形,所以在这里s.remove(0).

                     }

                     if (Funk241.g241 == 1 && Funk242.g242 == 1) {// Funk241.g241 == 1就是说Funk241 被实例化了

 

                         if (a > b + Unit.UF1) {

                            Funk241.x = s.get(Unit.UF1).dx;

                            Funk241.y = s.get(Unit.UF1).dy;

                            Funk241.dir = s.get(Unit.UF1).ddir;

                         }

                         if (a > b) {

                            Funk242.x = s.get(0).dx;

                            Funk242.y = s.get(0).dy;

                            Funk242.dir = s.get(0).ddir;

                         }

                     }

                     if (Funk241.g241 == 1 && Funk243.g243 == 1) {

                         if (a > b + Unit.UF1) {

                            Funk241.x = s.get(Unit.UF1).dx;

                            Funk241.y = s.get(Unit.UF1).dy;

                            Funk241.dir = s.get(Unit.UF1).ddir;

                         }

                         if (a > b) {

                            Funk243.x = s.get(0).dx;

                            Funk243.y = s.get(0).dy;

                            Funk243.dir = s.get(0).ddir;

                         }

                     }

                     if (Funk243.g243 == 1 && Funk242.g242 == 1) {

                         if (a > b + Unit.UF1) {

                            Funk242.x = s.get(Unit.UF1).dx;

                            Funk242.y = s.get(Unit.UF1).dy;

                            Funk242.dir = s.get(Unit.UF1).ddir;

                         }

                         if (a > b) {

                            Funk243.x = s.get(0).dx;

                            Funk243.y = s.get(0).dy;

                            Funk243.dir = s.get(0).ddir;

                         }

                     }

 

                  }

                  if (fs1 == 4) {//如有4个分身,Unit.UF3是第4个跟第一个的距离,这种情形很简单,同时也可以很清楚的看出整个计算流程。

                     if (a > b + Unit.UF3) {

                         Funk24.x = s.get(Unit.UF3).dx;

                         Funk24.y = s.get(Unit.UF3).dy;

                         Funk24.dir = s.get(Unit.UF3).ddir;

                         s.remove(0);

                     }

                     if (a > b + Unit.UF2) {

                         Funk241.x = s.get(Unit.UF2).dx;

                         Funk241.y = s.get(Unit.UF2).dy;

                         Funk241.dir = s.get(Unit.UF2).ddir;

                     }

                     if (a > b + Unit.UF1) {

                         Funk242.x = s.get(Unit.UF1).dx;

                         Funk242.y = s.get(Unit.UF1).dy;

                         Funk242.dir = s.get(Unit.UF1).ddir;

                     }

                     if (a > b) {

                         Funk243.x = s.get(0).dx;

                         Funk243.y = s.get(0).dy;

                         Funk243.dir = s.get(0).ddir;

                     }

                  }

 

                  if (Unit.Ds11) {

                     System.out.println(s.size());//s从未超过过30.

                  }

              }

           }

 

 

以上就是实现分身的主要代码,除开建立类之外也只有他们了,他们并没有增加很多运算复杂程度。最后press分身键时。

       case KeyEvent.VK_Q:

           if (fss > 0) { // 能放几炮

              if (!fs) { // 是否已经放出

                  fs1++; // 一个分身加一

                  Funk24g = new Funk24(xydirt, Unit.color3);

                  t.g24.add(g);     //分身有专门的队列g24.

                  fss -= 1;

                  fs = true;

                  if (r.nextInt(2) == 1) { //除了第一个分身,234个分身出现都是有一定几率的。

                     fs1++;

                     Funk241g1 = new Funk241(xydirt, Unit.color4);

                     t.g24.add(g1);

                  }

                  if (r.nextInt(2) == 1) {

                     fs1++;

                     Funk242g2 = new Funk242(xydirt, Unit.color5);

                     t.g24.add(g2);

                  }

                  if (r.nextInt(2) == 1) {

                     fs1++;

                     Funk243g3 = new Funk243(xydirt, Unit.color6);

                     t.g24.add(g3);

                  }

 

                  // timer = new Timer(); 千万不要每次都new Timer !

                  timer.schedule(new TimerTask() {

                     public void run() {

                         if (!FunkD.pas) {

                            if (FunkD.restart) {

                                t.g24.clear();

                                s = null;

                                a = 0;

                                fs1 = 0;

                                b = r.nextInt(17);

                                cancel();

                                System.out.println("1========================");

                            }

                            fse++; // 计时

                            if (fse == 10) {

                                fs = false;

                                fse = 0;

                                if (t.g24.size() > 0) {

                                   t.g24.clear();

                                }

                                s = null;

                                a = 0;

                                fs1 = 0;

                                b = r.nextInt(17);

                                cancel();

                                System.out.println("1========================");

                            }

                         }

                     }

                  },0, 1000); // 40秒等待

              }

           }

           break;

 

最后,我正在尝试不使用任何开发包,不使用任何工具,用最原始的java代码来开发一个游戏。那是一个很火爆的游戏:


技术分享



在游戏里,我是怎样做出分身效果?

标签:游戏   java   原创   

原文地址:http://blog.csdn.net/cnmm22/article/details/44747783

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!