平滑过渡的战争迷雾(二) 实现:真正的迷雾来了

转载:
http://blog.csdn.net/u011371356/article/details/9712321


这两天不少朋友留言提出了一些问题,但是由于雾央家里网络出了点问题,所以这两天都上不了网,没有及时回答大家,关注了雾央微博的朋友就知道这件事,抱歉了。

      另外,欢迎转载文章,雾央会把它当成对自己的认可~(@^_^@)~,但是请不要删除第一段话或者注明一下原文地址,好吗?请尊重一下作者的劳动。


一、原理回顾

      

      今天继续来说战争迷雾,上一节介绍了一下战争迷雾的原理,不知道大家清楚了没?如果没清楚,也不要紧,现在再来啰嗦几句哈。

      我们的素材是下面这张图

     

      我们还是图解吧,这样应该更形象,先给它编上号。

    

      用鼠标点击一下,散开一片迷雾,大家可以看到上面标示的数字,左上角是4,右上角是8,左下角是1,右下角是2

      

     在右边再点一下,我们可以看到两片迷雾叠加起来了,过渡的很自然。大家注意一下数字,两片迷雾中间的数字变成了12=4+8,3=2+1

     

     继续点,同理

 


     看了上面的图,大家应该清楚了吧,雾央假定大家都清楚了~(@^_^@)~,如果有问题的朋友可以留言或者微博@七十一雾央。

     我们每次点击游戏窗口的时候,驱散一个圆形的迷雾,这个圆形就只需要1+2+4+8号图元拼接起来就可以了,当同一个Tile内有多个图元时,将它们的数字相加,用新数字的图元替换掉即可。

 

二、实现步骤

      

      我们知道,把上面的鼠标换成人物,就可以营造出游戏中的战争迷雾效果:随着人物的走动,迷雾散开,合理的方式应该是以人物为中心散开迷雾,就像魔兽那样。但是雾央简化了一下问题,采用的是以鼠标为左上角散开迷雾。以鼠标为中心散开留给大家完成,也就是加个判断,找出鼠标附近的四个方块。

       如果大家看过了上上一节,即战争迷雾的初步实现,那么就容易多了,因为区别只存在于两个地方:绘图函数和更新函数。

       这次雾央用了一个大一点的地图1280*640,为了多点几下,呵呵。我们的图元方块是128*128的,那么网格就是10*5个。

       现在大家都清楚了每个网格要贴它的数字的图,那么我们怎么找到数字为n的图元的起始坐标呢?

       大家观察一下下面的图,找找规律

      

       大家发现了没有?每一列的数字除以4得到的商是相同的,分别为0,1,2,3;每一行的数字对4取余得到的结果也是相同的,分别是0,1,2,3!

       那么问题就简单了,编号为n的图元的起始坐标

      

[cpp] view plain copy
  1. x=(n/4)*128,  
  2. y=(n%4)*128  

      那么我们绘制战争迷雾的函数就可以修改成下面这样了

 

[cpp] view plain copy
  1. //绘制战争迷雾  
  2. void CScene::DrawFog(CDC &cDC)  
  3. {  
  4.     for(int i=0;i<10;i++)  
  5.         for(int j=0;j<5;j++)  
  6.             m_black[m_mode].Draw(cDC,i*128,j*128,128,128,(m_fogArray[i][j]/4)*128,(m_fogArray[i][j]%4)*128,128,128);  
  7. }  

      接下来要处理的就是更新迷雾区域的函数了

      我们首先计算出鼠标点击的格子编号

 

[cpp] view plain copy
  1. //首先计算出鼠标所在的格子  
  2. int xPosBox=x/128;  
  3. int yPosBox=y/128;  

      如果这个格子没有被点击过,那么就展开迷雾,并进行数值叠加,注意如果数字达到了15以上,就保持15,因为15已经是全开的状态了,在上一节雾央提过,如果是用于地形拼接的话,那么就可以在几种铺满状态的草地图案随机选择,造成丰富的地形效果。另外,雾央偷懒了,没有进行数组边界判断!但是呢,为了防止数组越界导致的错误,雾央就把数组扩大了一点,变成11*6的数组,这样就不会有越界错误了。

 

[cpp] view plain copy
  1. void Add(int fogArray[][6],int i,int j,int num)  
  2. {  
  3.     fogArray[i][j]+=num;  
  4.     if(fogArray[i][j]>15)  
  5.         fogArray[i][j]=15;  
  6. }  
  7. //更新迷雾区域  
  8. void CScene::UpdateFogArea(int x,int y)  
  9. {  
  10.     //首先计算出鼠标所在的格子  
  11.     int xPosBox=x/128;  
  12.     int yPosBox=y/128;  
  13.   
  14.     if(m_clickArray[xPosBox][yPosBox]==0)  
  15.     {  
  16.         //左上+4,右上+8,左下+1,右下+2  
  17.         Add(m_fogArray,xPosBox,yPosBox,4);  
  18.         Add(m_fogArray,xPosBox+1,yPosBox,8);  
  19.         Add(m_fogArray,xPosBox,yPosBox+1,1);  
  20.         Add(m_fogArray,xPosBox+1,yPosBox+1,2);  
  21.         //点过的地方已经散开过一次了,就不再叠加  
  22.         m_clickArray[xPosBox][yPosBox]=1;  
  23.     }  
  24. }  

你可能感兴趣的:(游戏开发技巧)