下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

flash游戏制作的详细步骤

作者:课课家教育     来源: http://www.kokojia.com点击数:1474发布时间: 2019-04-18 17:23:50

标签: flash游戏学习视频flash游戏视频flash游戏制作视频

这个游戏在实现是比较容易的,由于子弹在这里占据了主要地位,所以考虑以子弹为中心,即考虑构建一个粒子系统,来控制子弹的发射,发射方向的计算,以及出界的判定等。至于飞机方面,则只要有控制的部分(事件驱动,事件监听或用循环,要视具体实现环境而定),把两者结合起来,只要加上飞机与子弹间的碰撞检测即可,这里出于演示的目的,简单起见,采用球代替飞机的造型。 

 

       

 

[1b]2子弹粒子系统的运作流程[/1b]: 

 

       子弹的粒子系统要控制好子弹的发射,发射方向的计算,出界的判定以及碰撞检测. 

 

该粒子系统的总体框架并不困难,这里给出我实现过程中的总体框架:  

 

while(runFlag) 

 

       { 

 

                     For all particles 

 

                     { 

 

                            If(current particle is not lived) 

 

                            { 

 

                                          Init this particle. 

 

 

                            Else if(current particle is out of the game area) 

 

                            { 

 

                                   Current particle set to dead. 

 

 

                            Else 

 

                            { 

 

                                   Current particle move and show 

 

                                   If(current particle is collided with the plane) 

 

                                          runFlag=flase; 

 

 

 

}       这里要注意一下if….else if 中的条件判定对应的现实意义,即是否会出现实中无意义但在程序中却出现的情况,如果出现的话,这样的BUG将比较难抓出. 

 

       比如这里,如果将if及else if 中语中的条件及对应的内容作相应的交换,即: 

 

                            if(current particle is out of the game area) 

 

                            { 

 

                                   Current particle set to dead. 

 

 

                            Else if(current particle is not lived) 

 

                            { 

 

                                          Init this particle. 

 

}       在第一个if判定中,会将这样一种情况被包括进去: 

 

if(current particle is out of game area&& current is not lived)此时,将导致第二个判定永远无法到达. 

 

       所以,当条件复杂且多的时候,最好是列张真值表,看看所有可能的情况是否都如期的到达该到的判定条件处,避免在程序调试中浪费过多不避要的时间. 

 

  

 

[1b]3子弹粒子设计细节[/1b]: 

 

[1b]3.1子弹粒子的数据结构及存储方式.[/1b] 

 

粒子类以一个类的形式进行封装,里面包含了一些基本的物理属性及粒子相关的一些动作(函数)。简要的情况如下: 

 

class SPhy.CSPhyMc extends MovieClip 

 

 

       public var v :Number=0;//1 demision Velocity or together Velocity of vx ,vy 

 

       public var vx:Number=0; 

 

       public var vy:Number=0; 

 

       …… 

 

        

 

public function sETLife(lifeValue:Number):Void 

 

       { 

 

              life=lifeValue; 

 

       } 

 

        

 

       public function getLife():Number 

 

       { 

 

              return life; 

 

       } 

 

        

 

       public function isLived():Boolean 

 

       { 

 

                     return life==LIVED; 

 

       } 

 

       … … 

 

}     而在游戏中,这采用一个数组来实现粒子的群落,理由是使用方便而且快速。(当然,出于一种美学上的要求,你可能会选链表,因为它的插入和删除来的比较漂亮和干净,这就取决于你自己的喜好了) 

 

 至于子弹起始的坐标值,则是随机的散落于游戏屏幕区域外围,要写个相应的算法并不困难(详见代码部分) 

 

  

 

  

 

[1b]3.2 发射角的计算.[/1b] 

 

发射角的计算相当于一道简单的高中向量的题目: 

 

已知两点P1(x1,y1),P2(x2,y2),求P1指向P2的单位向量a. 

 

求解: 

 

a)       计算两点间的距离L=sqrt((x1-x2)^2+(y1-y2)^2) 

 

b)      求出P1P2(向量),P1P2=((x2-x1)/L,(y2-y1)/L); 

 

c)      单位化a=P1P2/(Len(P1P2))      

 

而你要做的,只是将子弹看成是P1,你自己的飞机看成是P2,即可,最后还应把起始速度去 

 

乘以所求得的单位向量a=(cos(fi),sin(fi)) 

 

              Vx=v*cos(fi) 

 

              Vy =v*sin(fi) 

 

  

 

[1b]3.3 碰撞检测[/1b] 

 

碰撞检测是个广泛而重要的话题,可以从简单到复杂,难度突破主要在计算几何上。这里针对本游戏谈两个: 

 

[1b]3.3.1[/1b]两个圆的碰撞检测,这个不用多说了,只要看两个圆的圆心的距离是否比它们的半径之和来的小就是了.

 

即圆1有:圆心O1(x1,y1),半径r1 

 

  圆2有:圆心O2(x2,y2),半径r2 

 

  则它们之间的碰撞检测可以这样来做: 

 

       

 

 If(Len(O1O2)    如果在视觉效果要求比较高的场和,尤其是不允许出现物体重叠的场和,不仿在Len(O1O2) 后加上一个偏移值。这样可以保证视觉上不会看到两个物体重叠的现像,尽管在精确的数值模型上二者并未相碰。而在数值精度要求高的场和,恐怕情况就要反一下了,图形是第二位的,数据的精准才是最重要的。具体如何去平衡图形和数据间的对应关系,还请诸位自己去斟酌了。 

 

       

 

[1b]3.3.1圆和三角形间的碰撞检测:[/1b] 

 

三角形可以用通常用一个五元组Q(P1,P2,k0,k1,k2)来表达(许多飞机的形状通常可以看成一个三角形) 

 

对于Q(P1,P2,k0,k1,k2),其中,P1,P2是三角的位于上部和左下的两个点,假设另一个点为P3,而k0是P1,P2间的斜率,k1是指P1,P3间的斜率,k2是指P2,P3间的斜率. (各字母的意义见图1) 

 

                                                         

 

您所在的用户组无法下载或查看附件:triangle.jpg。 

 

这样,三角形的三条边就可以方便的表达出来了: 

 

如直线P1P2的二维直线方程为 

 

y=k0(x-x1)+y1. 

 

         P1P3:  y=k1(x-x1)+y1 

 

         P2P3:  y=k2(x-x2)+y2这样,判定一个点是否在三解形内,就只要判断这个点是否在三条边指向三角形内的一侧.这里,如果要判的点为p(x’,y’),则根据图1的情况,有: 

 

If(k0(x’-x1)+y1>=0&&k1(x’-x1)+y1=y2)//考虑到P2P3是水平的情况 

 

 

              Collide! 

 

 

Else 

 

 

              Safe Condition. 

 

}显然,这个算法并不算得上好,因为如果三解形旋转的话,原来的某直线的左侧意味着三角形的内侧可能就会意味着外侧。这时,可以考虑再增加一个三元组,用来实时指示当前的三条直线指向三角形内侧的方面,可取的情况有以下几种: 

 

a)左侧  b)右侧  c)上侧(水平时)  d下侧(水平时) 

 

  

 

       [1b]4实现部分的关键代码(AS2)[/1b] 

 

       [1b]4.1粒子类:[/1b] 

 

       

 

 import SMotion.* 

 

import SColDet.* 

 

  

 

class SPhy.CSPhyMc extends MovieClip 

 

 

       public var m:Number=0;//mass 

 

        

 

       public var g:Number=0;//gravity 

 

        

 

       public var pF:Number=0;//Positive forces,attention here UpCase!!!!!!! 

 

       //Because the compiler was not so perfect as you think ,add a p here to prepare for the case. 

 

       public var r:Number =0;//when it become a ball---radius. 

 

        

 

       public var v :Number=0;//1 demision Velocity or together Velocity of vx ,vy 

 

       public var vx:Number=0; 

 

       public var vy:Number=0; 

 

        

 

       public var f :Number=0;//fraction forces. 

 

       public var fx:Number=0; 

 

       public var fy:Number=0; 

 

        

 

       public var a :Number=0;//acclerate v 

 

       public var ax:Number=0; 

 

       public var ay:Number=0; 

 

        

 

       //plane game use; 

 

       public var bigFire:Number=0; 

 

        

 

       private static var DEAD:Number=0; 

 

       private static var LIVED:Number=1; 

 

       private var life:Number; 

 

        

 

       private var mMotionCom:RCSMove; 

 

       private var mColDetCom:RCSColDet; 

 

        

 

       private static var thisP:Object; 

 

               

 

       public function setLife(lifeValue:Number):Void 

 

       { 

 

              life=lifeValue; 

 

       } 

 

        

 

       public function getLife():Number 

 

       { 

 

              return life; 

 

       } 

 

        

 

       public function isLived():Boolean 

 

       { 

 

                     return life==LIVED; 

 

       } 

 

        

 

       public function init():Void 

 

       { 

 

              thisP=this;       

 

              this.vx=0; 

 

              this.vy=0; 

 

              this.v=3+random(3); 

 

               

 

              this._width=10; 

 

    this._height=10; 

 

              this.r=5; 

 

               

 

              this.initCom(); 

 

       } 

 

        

 

        

 

        

 

       public function initPos(targetPlane:CSPhyMc):Void 

 

       { 

 

                 var randNum:Number=random(100); 

 

                 //set init positoin:down,left,up,right 

 

                 if(randNum[1b]4.2游戏主调度类[/1b] 

 

class ChaseAim 

 

{       

 

       static private var thisP:Object; 

 

       private var staturs:Number;//gaming 1,failure 0 

 

      private var speed:Number; 

 

       private var bulletNum:Number=20; 

 

       private var start:Number=0; 

 

       private var end:Number=0; 

 

       public function init():Void 

 

       {   thisP=this; 

 

            staturs=1; 

 

            speed=3; 

 

           bulletNum=20; 

 

            for(var i=0;i510||tmpMc._y410) 

 

                          return true; 

 

              else      return false; 

 

       } 

 

       private  function TwoBallCol(ball1:CSPhyMc,ball2:CSPhyMc):Boolean 

 

       {    

 

              if(Math.sqrt((ball1._x-ball2._x)*(ball1._x-ball2._x)+(ball1._y-ball2._y)*(ball1._y-ball2._y))[1b]5实验结论:[/1b] 

 

       通过该模型,实现了一个粒子系统的基本运作模式,该运作模式同样适用于其它的粒子系统,只要在最关键的运动及显示部分加以变换即可 

赞(0)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程