使用FLEX和Actionscript开发FLASH 游戏-位图动画

来源:互联网 发布:淘宝怎么关联营销 编辑:程序博客网 时间:2024/05/14 11:21

使用FLEX和Actionscript开发FLASH 游戏-位图动画

   在第六部分我们增加了碰撞检测。在第七部分我们将增加动画来允许我们包含一些好的爆炸效果。  

在第六部分我们介绍了碰撞检测,它让我们能击毁屏幕上的敌机。但是敌机只是消失了,这个效果有点令人不满意。在这篇论文中我们将增加动画,这让我们增加了一些漂亮的爆炸效果。

   如果Flash有个著名的地方,那它就是动画。Flex确实允许你使用同样的基于动画的矢量图,这是Flash著名之处,然而对于我们的游戏我们将使用基于动画的历史相当悠久的帧。这么做有两个原因。第一是基于动画的帧更容易实现,更加适合我们做的游戏的风格。第二个是我不是一个美术家,不得不用我能在网络中找到的免费的材料,这里我找到了基于帧的材料。

  

   上面的图像说明了我所说的基于动画的帧的含义。这是一连串的帧,按照顺序来演示,以生成一个动画。你还在学校时在你的教科书的页角画过一些小的动画么?那是相同的概念。

   要实现动画我们首先需要给GraphicsResource类一些改变。现在让我们看看。

GraphicsResource.as

package

{

    import flash.display.*;

    public class GraphicsResource

    {

        public var bitmap:BitmapData=null;

        public var bitmapAlpha:BitmapData=null;

        public var frames:int=1;

        public var fps:Number=0;

        public function GraphicsResource(image:DisplayObject,frames:int=0,fps:Number=0)

        {

            bitmap=createBitmapData(image);

            bitmapAlpha=createAplhaBitmapData(image);

            this.frames=frames;

            this.fps=fps;

        }

        protected function createBitmapData(image:DisplayObject):BitmapData

        {

            var bitmap:BitmapData=new BitmapData(image.width,image.height);

            bitmap.draw(image);

            return bitmap;

        }

        protected function createAlphaBitmapData(image:DisplayObject):BitmapData

        {

            var bitmap:BitmapData=new BitmapData(image.width,image.height);

            bitmap.draw(image,null,null,flash.display.BlendMode.ALPHA);

            return bitmap;

        }

    }

}

   这里做的改变相当简单。我们增加了两个属性:frames和fps。Frames属性是在GraphicsResource中保存的动画图像有多少帧的一个数目。使用上面得一个爆炸的例子,frames应该被设置为7。Fps属性定义了动画在每秒中显示的帧数。

   GameObject类不知道动画。如果你使用上面的图像来初始化一个GameObject,整个图像将被显示在屏幕上,而不是一个动画序列。为了产生动画我们需要生成一个新的类:AnimatedGameObject。现在让我们看看它的代码。

AnimatedGameObject.as

package

{

       import flash.display.*;

       import flash.geom.*;

       import mx.collections.*;

 

       public class AnimatedGameObject extends GameObject

       {

              static public var pool:ResourcePool = new ResourcePool(NewAnimatedGameObject);

              protected var frameTime:Number = 0;

              protected var currentFrame:int = 0;

              protected var frameWidth:int = 0;

              protected var playOnce:Boolean = false;

             

              static public function NewAnimatedGameObject():AnimatedGameObject

              {

                     return new     AnimatedGameObject();

              }

                           

              public function AnimatedGameObject()

              {

                                         

              }

             

              public function startupAnimatedGameObject(graphics:GraphicsResource, position:Point, z:int = 0, playOnce:Boolean = false):void

              {                  

                     this.playOnce = playOnce;                  

                     this.frameWidth = graphics.bitmap.width / graphics.frames;

                    

                     startupGameObject(graphics, position, z);

              }

             

              override public function enterFrame(dt:Number):void

              {

                     if (inuse)

                     {

                            frameTime += dt;

                            if (graphics.fps != -1)

                            {

                                   while (frameTime > 1/graphics.fps)

                                   {

                                          frameTime -= 1/graphics.fps;

                                          currentFrame = (currentFrame + 1) % graphics.frames;

                                          if (currentFrame == 0 && playOnce)

                                          {

                                                 shutdown();

                                                 break;

                                          }

                                   }

                            }

                     }

              }

             

              override public function copyToBackBuffer(db:BitmapData):void

              {

                     if (inuse)

                     {

                            var drawRect:Rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, graphics.bitmap.height);

                            db.copyPixels(graphics.bitmap, drawRect, position, graphics.bitmapAlpha, new Point(drawRect.x, 0), true);

                     }

              }

             

              override protected function setupCollision():void

              {

                     collisionArea = new Rectangle(0, 0, frameWidth, graphics.bitmap.height);

              }

       }

      

}

   就像其它任何游戏资源一样,AnimatedGameObject类是从GameObject类继承来的。为了显示一个动画我们覆盖了GameObjects类的三种函数:enterFrame,copyToBackBuffer和setupCollision。

   在enterFrame函数里AnimatedGameObject保留了一个轨迹来保存上一帧被演示后过了多久时间。一旦这个时间超过了在GraphicsResource中fps定义的值AnimatedGameObject就移到下一帧。这里也有一个playOnce属性,如果设置为真那么一个完整的动画被显示后将触发AnimatedGameObject来移除自身。这对于生成特效(比如爆炸)是很有用的,因为显示一次就消失了。它将让你作为一个编码者能在游戏中生成一种初始化后就不用干预的对象来清除它自身。

   copyToBackBuffer仅仅在GameObject类的同一代码上做了小小的改动来让它仅仅拷贝graphics属性引用的图形的一部分。这部分同当前的帧有关系,是当我们在屏幕上演示一个动画时从左到右的显示的一帧。

   最后我们覆盖了setupCollision函数来定义collisionArea,它是动画中一帧的大小,而不是整个图片的大小。

   这里其余的代码(比如资源池和开始/结束函数)在前面章节已经讨论过,它们在此处的应用还是一样。

   我们也需要给ResourceManager做些改变来适应动画需要的特别的信息。现在让我们看看它的代码。

ResourceManager.as
package
{
       import flash.display.*;

       public final class ResourceManager
       {
              [Embed(source="/media/brownplane.png")]
              public static var BrownPlane:Class;
              public static var BrownPlaneGraphics:GraphicsResource = new GraphicsResource(new BrownPlane(), 3, 20);

              [Embed(source="/media/smallgreenplane.png")]
              public static var SmallGreenPlane:Class;
              public static var SmallGreenPlaneGraphics:GraphicsResource = new GraphicsResource(new SmallGreenPlane(), 3, 20);

              [Embed(source="/media/smallblueplane.png")]
              public static var SmallBluePlane:Class;
              public static var SmallBluePlaneGraphics:GraphicsResource = new GraphicsResource(new SmallBluePlane(), 3, 20);

              [Embed(source="/media/smallwhiteplane.png")]
              public static var SmallWhitePlane:Class;
              public static var SmallWhitePlaneGraphics:GraphicsResource = new GraphicsResource(new SmallWhitePlane(), 3, 20);

              [Embed(source="/media/bigexplosion.png")]
              public static var BigExplosion:Class;
              public static var BigExplosionGraphics:GraphicsResource = new GraphicsResource(new BigExplosion(), 7, 20);

              [Embed(source="/media/smallisland.png")]
              public static var SmallIsland:Class;
              public static var SmallIslandGraphics:GraphicsResource = new GraphicsResource(new SmallIsland());

              [Embed(source="/media/bigisland.png")]
              public static var BigIsland:Class;
              public static var BigIslandGraphics:GraphicsResource = new GraphicsResource(new BigIsland());

              [Embed(source="/media/volcanoisland.png")]
              public static var VolcanoIsland:Class;
              public static var VolcanoIslandGraphics:GraphicsResource = new GraphicsResource(new VolcanoIsland());

              [Embed(source="/media/twobullets.png")]
              public static var TwoBullets:Class;
              public static var TwoBulletsGraphics:GraphicsResource = new GraphicsResource(new TwoBullets());

              [Embed(source="/media/cloud.png")]
              public static var Cloud:Class;
              public static var CloudGraphics:GraphicsResource = new GraphicsResource(new Cloud());
       }
}
就如你所见的我们所做的只是在将显示动画的那些图像的GraphicsResource构造器中增加帧和帧速率的值。
最后一步是改变将产生动画的游戏元素,这些元素现在继承AnimatedGameObject类而不是GameObject类,当我们在击毁一架飞机时产生爆炸动画。
   Player和Enemy类都将被动画化,两个在击毁时都将产生爆炸。这两个类的需改变的代码都一样,所以我仅仅列出新的Enemy类。你可以下载本论文结尾处的源代码,看看Player类做了哪些改变。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/literza/archive/2009/06/05/4241599.aspx