手机射击游戏中弹幕的开发

来源:互联网 发布:淘宝第三方推广 编辑:程序博客网 时间:2024/04/24 10:21

射击游戏中弹幕的开发

http://blog.vckbase.com/knight/archive/2005/03/29/4174.html

作者:牛阿牛     

2005-02-28

nhf_2008@hotmail.com

nhf_2003@hotmail.com

email:nhf20021166@163.com

留言:希望能给各位游戏开发一点的介绍;如有问题,请联系.

游戏射击中, boss可能是最重要的设计点!

技术角度:弹幕的组合,肢体的配合,动作的衔接.

艺术方面:绚丽的弹幕,新颖的运动,敏捷的反应.

   此处将重点放在boss的弹幕及其组合方面进行阐述.

 

追逐玩家的火龙,挥动的双钳,伸缩的双臂,总能给玩家更多新鲜感,更多的满足感!当然组合起来,就可能有更好的效果!

商家追求的是利润,策划追求的是艺术,玩家追求是满足!

我们是要将三位上帝的要求用技术来实现!

下面我们考虑一种实现方法

 

如果是强悍的boss,其弹幕一定很绚丽而又凶险,当然多变性是更重要的

 

   此处首先说明的是,接近0度或90度的正弦余弦方向步长处理,本处采取,增加子弹的移动距离属性,这样我们就可以根据总移动长度来求x,y方向的移动,不会出现,xy轴因为步长小而每次都为零的情况..

 

   我们此处也不再考虑,怎样加发射一个子弹,其实就是在链中添加一个子弹…,爆炸或者跑出屏幕,从链表中删除,链表操作,请参考链表处理一文….

子弹的数据结构:

typedef struct _CBullet   ///暂作

{

       Sprite      stSprite;

       int         nDirx;

       int         nDiry;

 

       DIR       m_nDir;   ////方向,8个方向….

 

       Point      pDest;   //目标点x,y的结构体

       Point      pSour;   //原始点

 

    BOOL       bExplore;  ////

      

 

       OBJSIZE    m_nSize; //可以分为多个类型的.

 

       WEAPON     m_nWeapon; ///武器类型了.武器的类型,主要在方向及威力,性能上起作用

 

       BYTE       m_nKillPow; ///杀伤力   

 

       BYTE       nIndex;     ///某些状态的公用状态值

 

       BYTE       nMoveDistance; //移动距离

 

       BYTE       nAngle;         //角度

 

       Explore    MeExplore;        ///暂不考虑

       Explore    MapExplore;       //暂不考虑

       PLAYERSTATUS  m_nStatus; // 子弹状态

}BULLET;

通过数学函数处理:

   对每个子弹设定运行函数即可

///////通过定时处理

1)      扇型弹幕的,可以设置速度,形成快慢两种了.

处理时定义临时变量,然后循环一定数目,每次添加子弹,当然根据方向,根据要求设置速度,,,这样就可形成扇型弹幕….

2)      螺旋型弹幕,如果每次添加的子弹时,闪开一定小角度,就可以形成块状扇型的….

通过boss里面的索引状态,然后每次重新设定起始角度,作扇型弹幕,即可,在多次定时器时即可实现螺旋型弹幕

3)      烟花型:原理类似,只要每次添加时,以公用索引角度添加,同时添加垂直和同线异向的子弹,定时器宣传,索引值变化,即可..

4)      鞭子型,,原理类似,每次只添加两个子弹,上下或者左右对称,在定时器中,修改公用索引值,在多次定时处理后,即实现鞭子型的子弹

5)      束型子弹:原理是,每次根据目标位置,确定一个角度范围,然后生成34( 随机也行)个角度范围内的子弹,定时器处理后既成为属性弹幕

6)      加激光,加敌人,就是很简单的了…..

7)      然后对上面的子弹搞一些组合,就会更加丰富

boss的弹幕有间歇,也有组合,这就要求对boss的状态进行处理

typedef enum _FIRESTATUS

{

       FIRESTATUS_PREPARE = 0, //准备阶段

       FIRESTATUS_FIRING  = 1, //射击中

    FIRESTATUS_END     = 2 //休闲中.

}FIRESTATUS;

 

至于弹幕的组合

typedef enum _FIRESTYLE

{

       FIRE_CIRCLEFAST = 0, //半圆形快速

       FIRE_CIRCLESLOW = 1 , //半圆形慢速.

       FIRE_CIRCLEBLOCK = 2 , //半园行块状.

       FIRE_BOUND       = 3 , //束状问题了.

       FIRE_BLIM        = 4 , //辫子行的.

       FIRE_FLAME       = 5 , //烟花型 .

       FIRE_LASER       = 6, //激光

       FIRE_ENEMY       = 7, //加敌人,主要指小潜艇了.

       FIRE_BLOCK       = 8,  //块状三乱行的.       

       FIRE_CIRCLEFASTSLOW =  9 ,//半圆形快慢型的.

       FIRE_CIRCLEBOUND = 10 , //半圆形夹杂 束型的.

       FIRE_CIRCLELASER = 11 ,// 半圆形夹杂激光

       FIRE_CIRCLEENEMY = 12 , // 半圆形夹杂敌人的.

       FIRE_BLIMBOUND =13 ,// 辫子型夹杂 束型的.

       FIRE_BLIMLASER = 14 ,// 辫子型夹杂激光

       FIRE_BLIMENEMY = 15 , // 辫子型夹杂敌人的.

       FIRE_FLAMEBOUND = 16 , //烟花型夹杂束型的.

       FIRE_FLAMELASER = 17,  //烟花型夹杂激光的

       FIRE_FLAMEENEMY = 18 , //烟花型夹杂敌人

}FIRESTYLE;

 

///boss的射击,将根据状态,每个状态持续多少个周期,可以固定,也可以调节

 

这里的每一个细节都要细分处理,省略不得,什么部位发射什么弹幕,

不同的部位弹幕组合,请注意难度可以调节,保证高手可以闯过

 

if((pPart->bExist ==FALSE)||(pPart->bDestroy==TRUE)||(pPart->bFire==FALSE))

       {

              return TRUE;

       }

       else

       {

              ///////

              if(objSize==OBJ_LARGE)

              {

                     x = pMe->gBigBoss.BodyRect.x + pPart->BodyRect.x+ (pPart->BodyRect.dx>>2);

                     y = pMe->gBigBoss.BodyRect.y + pPart->BodyRect.y+ (pPart->BodyRect.dy>>1);

              }

              else

              {

                     x = pMe->gSmallBoss.BodyRect.x + pPart->BodyRect.x+ (pPart->BodyRect.dx>>2);

                     y = pMe->gSmallBoss.BodyRect.y + pPart->BodyRect.y+ (pPart->BodyRect.dy>>1);

              }

              //////////////////////////////////////////

              if(pPart->firestatus == FIRESTATUS_FIRING )

              {

                     //进行分情况处理了.ok?

                     switch(pPart->firestyle)

                     {

                     case FIRE_CIRCLESLOW:

                //if()

                            AddLeftCirCleEnemyBullet(pMe,x,y,75,0,30,1,Bullet_Speed_Slow,FALSE);

                            break;

                     case FIRE_LASER:

                            AddEnemyLaserBullet(pMe,x,y,3);

                            break;

                     case FIRE_BOUND: //

                            {

                                   nDir =GetDir(pMe,x,y);

                                   nAngle =Angle(pMe,x,y);

                                   AddBoundEnemyBullet(pMe,x,y,nDir,nAngle,1,7,0,Bullet_Speed_Slow);

                            }

                            break;

                     case FIRE_CIRCLEFAST:

                            AddLeftCirCleEnemyBullet(pMe,x,y,75,0,30,1,Bullet_Speed_Med,FALSE);

                            break;

                     case FIRE_BLIM:

                            AddLimbEnemyBullet(pMe,x,y,(BYTE)(pPart->fireIndex<<1) ,2,Bullet_Speed_Slow);

                            break;

                     case FIRE_FLAME:

                            AddFireEnemyBullet(pMe,x,y,(BYTE)(pPart->fireIndex) ,0, Bullet_Speed_Small);

                            break;

                     case FIRE_ENEMY:

                            BossAddEnemy(pMe,x,y,OBJ_SMALLSUBMARINE,OBJ_SMALL);

                            break;

                     case FIRE_BLOCK: ///

                            GETRAND(&rand,sizeof(unsigned char));

                            if(rand&0x04)

                            {

                                   AddLeftCirCleEnemyBullet(pMe,x,y,75,0,15,1,Bullet_Speed_Slow,FALSE);

                            }

                            else

                            {

                                   AddLeftCirCleEnemyBullet(pMe,x,y,75,0,30,1,Bullet_Speed_Slow,FALSE);

                            }

 

                            break;

                     case FIRE_CIRCLEFASTSLOW:

                            if(pPart->fireIndex &0x0008)

                            {

                                   AddLeftCirCleEnemyBullet(pMe,x,y,75,0,45,1,Bullet_Speed_Med,FALSE);

                            }

                            else

                            {

                                   AddLeftCirCleEnemyBullet(pMe,x,y,75,0,30,1,Bullet_Speed_Slow,FALSE);

                            }

                            break;

                     case FIRE_BLIMLASER:

                            /*

                            if(pPart->fireIndex &0x0008)

                            {

                                   AddEnemyLaserBullet(pMe,x,y,3);

                            }

                            else

                            {

                            */

                                   AddLimbEnemyBullet(pMe,x,y,(BYTE)(pPart->fireIndex<<1) ,2,Bullet_Speed_Slow);

                            //}

                           

                            break;

                     case FIRE_CIRCLEBLOCK:

                            AddLeftCirCleEnemyBullet(pMe,x,y,75,0,30,1,Bullet_Speed_Slow,TRUE);

                            break;

                     case FIRE_FLAMEBOUND:

                            if(pPart->fireIndex &0x0008)

                            {

                                   AddEnemyLaserBullet(pMe,x,y,3);

                            }

                            else//

                            {

                                   AddFireEnemyBullet(pMe,x,y,(BYTE)(pPart->fireIndex) ,0, Bullet_Speed_Small);

                            }

                           

                            break;                        

                     }

              }

 

///具体的每一种弹幕添加原理,前面已经有了

 

 

/////////////////////////添加左向半圆子弹-包括块状

BOOL AddLeftCirCleEnemyBullet(FPSApp * pMe,int x,int y,BYTE nEnd,BYTE nStart,BYTE nStep,BYTE nIndex,BYTE nSpeed,BOOL bBlock)

{

       ////

       int nBegin = 0;

       BOOL bNormal = TRUE;///

       nBegin = nEnd;

       if(!bBlock)

       {

              while(nBegin >= nStart )

              {

                     if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTUP,Cos(nBegin),Sin(nBegin),FALSE,nIndex,nSpeed,Bullet_Power))

                     {

                            bNormal=FALSE;

                            break;

                     }

                     nBegin -= nStep;

              }

              //

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTUP,Cos(0),Sin(0),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal=FALSE;      

              }

             

              nBegin = nEnd;

              while(nBegin >=nStart )

              {

                     if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTDOWN,Cos(nBegin),Sin(nBegin),FALSE,nIndex,nSpeed,Bullet_Power))

                     {

                            bNormal=FALSE;

                            break;

                     }

                     nBegin -= nStep;

              }

       }

       else /////默认数据,步长2,数量4

       {

              while(nBegin >= nStart )

              {

                     if(!AddBlockEnemyBullet(pMe,x,y,DIR_LEFTUP,(BYTE)nBegin,2,4,nIndex,nSpeed))

                     {

                            bNormal=FALSE;

                            break;

                     }

                     nBegin -= nStep;

              }

              //

              if(!AddBlockEnemyBullet(pMe,x,y,DIR_LEFTUP,0,2,4,nIndex,nSpeed))

              {

                     bNormal=FALSE;      

              }

             

              nBegin = nEnd;

              while(nBegin >=nStart )

              {

                     if(!AddBlockEnemyBullet(pMe,x,y,DIR_LEFTUP,(BYTE)nBegin,2,4,nIndex,nSpeed))

                     {

                            bNormal=FALSE;

                            break;

                     }

                     nBegin -= nStep;

              }

       }

     

       return bNormal;

}

 

//////////////添加块状子弹,不是半圆,只是其中的一个单元

BOOL AddBlockEnemyBullet(FPSApp * pMe,int x,int y,DIR nDir,BYTE nStart,BYTE nStep,BYTE nCount,BYTE nIndex,BYTE nSpeed)

{

       //switch

       BOOL bNormal = TRUE;///

       BYTE nNum = 0;

       BYTE nBegin = nStart;

       BOOL bChangeDir = FALSE;

       DIR nRealDir = nDir; /////

 

       while(nNum<nCount)

       {

              /////

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,nRealDir,Cos(nBegin),Sin(nBegin),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal=FALSE;

                     break;

              }

              ////////////////////

              if(nDir==DIR_LEFTUP)

              {

                     if(nBegin+ nStep>=90)

                     {

                            break;

                     }

                     else

                            nBegin+=nStep;

              }

              else

              {

                     if(bChangeDir==TRUE)

                     {

                            ///////////

                            nBegin+=nStep;

                     }

                     else

                     {

                            if(nBegin < nStep)

                            {

                                   bChangeDir = TRUE;

                                   nRealDir= DIR_LEFTUP;

                                   nBegin = nStep - nBegin;

                            }

                            else

                            {

                                   nBegin -= nStep;

                            }

                     }

              }

              nNum++;

       }

       return bNormal;

}/////////

////////添加束型子弹

BOOL AddBoundEnemyBullet(FPSApp * pMe,int x,int y,DIR nDir,BYTE nStart,BYTE nStep,BYTE nCount,BYTE nIndex,BYTE nSpeed)//添加一束一束的子弹

{

       //////////////////////////////////////

       BOOL bNormal =TRUE;

       BYTE nTempAngle =0;

       BYTE nCountNum =0 ;

       /////左三,右三,角度根据nStep 来定吧.

       //自身添加了啊.

       if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,nDir,Cos(nStart),Sin(nStart),FALSE,nIndex,nSpeed,Bullet_Power))

       {

              bNormal =FALSE;

       }

 

       nTempAngle = nStart;

       nTempAngle += nStep;

       nCountNum=0;

       while(nTempAngle<=90)

       {

              if(nCountNum>=3)

                     break;

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,nDir,Cos(nStart),Sin(nStart),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;

                     break;

              }

              nCountNum++;

              nTempAngle += nStep;

       }

 

       nTempAngle = nStart;

       nTempAngle -= nStep;

       nCountNum=0;

       while(nTempAngle>=0)

       {

              if(nCountNum>=3)

                     break;

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,nDir,Cos(nStart),Sin(nStart),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;

                     break;

              }

              nCountNum++;

              nTempAngle -= nStep;

       }

       /////

       return bNormal;

}

////添加鞭子型子弹

BOOL AddLimbEnemyBullet(FPSApp * pMe,int x,int y,BYTE nAngle,BYTE nIndex,BYTE nSpeed)//辫子型的子弹

{

       BOOL bNormal =TRUE;

      

       if(nAngle>180)

              nAngle= 180;

       ////////

       if(nAngle>90)

       {

              //////

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTUP,Cos(180-nAngle),Sin(180-nAngle),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTDOWN,Cos(180-nAngle),Sin(180-nAngle),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

       }

       else

       {

              //////

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_RIGHTUP,Cos(nAngle),Sin(nAngle),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

              if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_RIGHTDOWN,Cos(nAngle),Sin(nAngle),FALSE,nIndex,nSpeed,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

       }

       return bNormal;

}

////////添加螺旋型单元子弹

BOOL AddFireEnemyBullet(FPSApp * pMe,int x,int y,BYTE nStart,BYTE nIndex,BYTE nSpeed)//

{

       BOOL bNormal =TRUE;

 

       if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTUP,Cos(nStart),Sin(nStart),FALSE,nIndex,nSpeed,Bullet_Power))

       {

              bNormal =FALSE;                   

       }

       if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_RIGHTUP,Cos(90-nStart),Sin(90-nStart),FALSE,nIndex,nSpeed,Bullet_Power))

       {

              bNormal =FALSE;                   

       }

       /////

       if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_RIGHTDOWN,Cos(nStart),Sin(nStart),FALSE,nIndex,nSpeed,Bullet_Power))

       {

              bNormal =FALSE;                   

       }

       /////

       if(!AddEnemyBullet(pMe,WEAPON_ORANGE,x,y,DIR_LEFTDOWN,Cos(90-nStart),Sin(90-nStart),FALSE,nIndex,nSpeed,Bullet_Power))

       {

              bNormal =FALSE;                   

       }

       return bNormal;

}

///添加激光子弹

BOOL AddEnemyLaserBullet(FPSApp * pMe,int x,int y,BYTE nCount)

{

       BOOL bNormal = FALSE;

       switch(nCount)

       {

       case 1:

              {

                     if(!AddEnemyBullet(pMe,WEAPON_LASER,x,y,DIR_LEFTDOWN,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

                     {

                            bNormal =FALSE;                   

                     }

              }

              break;

       case 2:

              {

                     if(!AddEnemyBullet(pMe,WEAPON_LASER,x-CELL_W,y-8,DIR_LEFTDOWN,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

                     {

                            bNormal =FALSE;                   

                     }

                     if(!AddEnemyBullet(pMe,WEAPON_LASER,x-CELL_W,y+8,DIR_LEFTDOWN,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

                     {

                            bNormal =FALSE;                   

                     }

              }

              break;

       case 3:

              if(!AddEnemyBullet(pMe,WEAPON_LASER,x-CELL_W,y-CELL_H,DIR_LEFT,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

              if(!AddEnemyBullet(pMe,WEAPON_LASER,x-CELL_W,y,DIR_LEFT,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

              if(!AddEnemyBullet(pMe,WEAPON_LASER,x-CELL_W,y+CELL_H,DIR_LEFT,Cos(0),Sin(0),FALSE,0,Bullet_Speed_Med,Bullet_Power))

              {

                     bNormal =FALSE;                   

              }

              break;

       }

       return bNormal;

}

////////////////////////添加自杀式敌人,此处小潜艇而已

BOOL BossAddEnemy(FPSApp * pMe,int x,int y,OBJECT obj,OBJSIZE size)

{

       BOOL bNormal = FALSE;

 

       if(!AddSubMarine(pMe,OBJ_SMALL,y-8))

       {

              bNormal = FALSE;

       }

 

       /////

       if(y+CELL_H< pMe->stWorldRect.dy-CELL_H)

       {

              if(!AddSubMarine(pMe,OBJ_SMALL,y+CELL_H-8))

              {

                     bNormal = FALSE;

              }

       }

       if(y-CELL_H< 48)

       {

              if(!AddSubMarine(pMe,OBJ_SMALL,y-CELL_H-8))

              {

                     bNormal = FALSE;

              }

       }

       return bNormal;

}

 

原创粉丝点击