使用FLEX和 Actionscript 开发FLASH游戏(五)

来源:互联网 发布:瞻博网络的老板 编辑:程序博客网 时间:2024/05/16 19:31

使用FLEX和Actionscript开发FLASH 游戏-增加武器

在本系列的第四部分我们增加了用户输入,还生成了一个滚动的背景来模仿海面上空的飞行。第五部分我们将增加一些敌机和游戏者武器。
本系列到现在已经实现了足够的底层代码使得为游戏增加新的元素非常的容易。通过使用GameObjectManager和GameObject类处理绘制和更新游戏元素的工作以及用Level类实际生成新的元素,实现新的游戏元素就仅仅只需要很少量的代码了。我们将利用这个来给游戏增加一些敌机,并且给游戏者增加战斗用的武器。
首先,让我们看看在Level类中做的一些改变。
Level.as
package
{
    import flash.events.*;
    import flash.geom.*;
    import flash.media.*;
    import flash.net.*;
    import flash.utils.*;
    import mx.collections.ArrayCollection;
    import mx.core.*;
    public class Level
    {
        protected static var instance:Level=null;
        protected static const TimeBetweenLevelElements:Number=2;
        protected static const TimeBetweenEnemies:Number=3;
        protected static const TimeBetweenClouds:Number=2.5;
        protected var timeToNextLevelElement:Number=0;
        protected var levelElementGraphics:ArrayCollection=new ArrayCollection();
        protected var timeToNextEnemy:Number=0;
        protected var enemyElementGraphics:ArrayCollection=new ArrayCollection();
        protected var timeToNextCloud:Number=0;
        static public function get Instance():Level
        {
            if(instance==null)
                instance=new Level();
            return instance;
        }
        public function Level(caller:Function=null)
        {
            if(Level.instance!=null)
                throw new Error("Only one Singleton instance should be instantiated");
            levelElementGraphics.addItem(ResourceManager.SmallIslandGraphics);
            levelElementGraphics.addItem(ResourceManager.BigIslandGraphics);
            levelElementGraphics.addItem(ResourceManager.VolcanoIslandGraphics);
            enemyElementGraphics.addItem(ResourceManager.SmallBluePlaneGraphics);
           enemyElementGraphics.addItem(ResourceManager.SmallGreenPlaneGraphics);
            enemyElementGraphics.addItem(ResourceManager.SmallWhitePlaneGraphics);
        }
        public function startup():void
        {
            timeToNextLevelElement=0;
            new Player().startupPlayer();
        }
        public function shutdown():void
        {
        }
        public function enterFrame(dt:Number):void
        {
            //add a background element
            timeToNextLevelElement-=dt;
            if(timeToNextLevelElement<=0)
            {
                timeToNextLevelElement=TimeBetweenLevelElements;
                var graphics:GraphicsResource=levelElementGraphics.getItemAt                                (MathUtils.randomInteger(0,levelElementGraphics.length)) as GraphicsResource;
                var backgroundLevelElement:BackgroundLevelElement=
                BackgroundLevelElement.pool.ItemFromPool as BackgroundLevelElement
                backgroundLevelElement.startupBackgroundLevelElement(graphics,new Point         (Math.random()*Application.applilcation.width,
-ZOrders.BackgroundZOrder,50);
            }
            //add an enemy
            timeToNextEnemy-=dt;
            if(timeToNextEnemy<=0)
            {
                timeToNextEnemy=TimeBetweenEnemies;
                var enemygraphics:GraphicsResource=enemyElementGraphics.getItemAt                (MathUtils.randomInteger(0,enemyElementGraphics.length))as GrahpicsResource;
                var enemy:Enemy=Enemy.pool.ItemFromPool as Enemy;
                enemy.startupBasicEnemy(
                new Point(Math.random()*Application.application.width,-                enemygraphics.bitmap.height),55);
            }
            //add cloud
            timeToNextCloud-=dt;
            if(timeToNextCloud<=dt)
            {
                timeToNextCloud=TimeBetweenClouds;
                var cloudBackgroundLevelElement:BackgroundLevelElement=
                BackgroundLevelElement.pool.ItemFromPool as BackgroundLevelElement;
                cloudBackgroundLevelElement.startupBackgroundLevelElement(
                ResourceManager.CloudGraphics,new Point(Math.random()                *Application.application.width,-                ResourceManager.CloudGraphics.bitmap.height),ZOrders.CloudsBelowZOrder,75);
            }
        }
    }
}
timeToNextEnemy/TimeBetweenEnemies 和timeToNextCloud/TimeBetweenClouds属性对和timeToNextLevelElement/TimeBetweenLevelElements 属性对(在第四部分详细描述的)是一样的作用,除了它们是各自用来增加敌机和云朵。enemyElementGraphics属性同levelElementGraphics(也在第四部分详细描述过)是一样的作用,除了这里它用来提供生成敌机的图像资源。
我们还在enterFrame函数里增加了两个新的代码块来生成敌机和云朵。这些代码几乎和生成BackgroundLevelElement的代码块完全一样。
云朵是作为一个BackgroundLevelElement来实现的,除了使用了稍快些的滚动速度和更高级别的zOrder。这让它们看起来处在更高的海拔高度。
一个新的类,敌机,被生成来代表敌人。现在让我们看看代码。
Enemy.as
package
{
    import flash.geom.Point;
    import mx.core.*;
    public class Enemy extends GameObject
    {
        static public var pool:ResourcePool=new ResourcePool(NewEnemy);
        protected var logic:Function=null;
        protected var speed:Number=0;
        static public function NewEnemy():Enemy
        {
            return new Enemy();
        }
        public function Enemy()
        {
            super();
        }
        public function startupBasicEnemy(graphics:GraphicsResource,position:Point,speed:Number):void
        {
            super.startupGameObject(graphics,position,ZOrders.PlayerZOrder);
            logic=basicEnemyLogic;
            this.speed=speed;
        }
        override public function shutdown():void
        {
            super.shutdown();
            logic=null;
        }
        override public function enterFrame(dt:Number):void
        {
            if(logic!=null)
                logic(dt);
        }
        protected function basicEnemyLogic(dt:Number):void
        {
            if(position.y>Application.application.height+graphics.bitmap.height)
                this.shutdown();
            position.y+=speed*dt;
        }
    }
}
代码和BackgroundElement代码非常相似。实际上唯一的差别是我们把敌机的逻辑部分分离到它自己的basicEnemyLogic 函数里。我们在逻辑属性里保留了一个basicEnemyLogic函数的引用(更像我们在ResourcePool里的NewEnemy函数的引用)。这看起来可能多余,但将在以后让我们通过生成新的逻辑函数实现敌机的新种类。startupBasicEnemy函数被用来初始化底层的GameObject而且安装指定logic属性给basicEnemyLogic函数,这将在绘制循环里被依次调用。(即enterFrame函数)
通过这些简单的改变我们现在可以在游戏中以一定的时间间隔生成敌机。下一步将生成游戏者能够用来使用的武器。这么做我们需要生成武器类。让我们看看它的代码。
   Weapon.as
package
{
    import flash.geom.*;
    public class Weapon extends GameObject
    {
        static public var pool:ResourcePool=new ResourcePool(NewWeapon);
        protected var logic:Function=null
        protected var speed:Number=0;
        static public function NewWeapon():Weapon
        {
            return new Weapon();
        }
        public function Weapon()
        {
            super();
        }
        public function startupBasicWeapon(graphics:GraphicsResource,position:Point,speed:Number):void
        {
            super.startupGameObject(graphics,position,ZOrders.PlayerZOrder);
            logic=basicWeaponLogic;
            this.speed=speed;
        }
        override public function shutdown():void
        {
            super.shutdown();
            logic=null;
        }
        override public function enterFrame(dt:Number):void
        {
            if(logic!=null)
                logic(dt);
        }
        protected function basicWeaponLogic(dt:Number):void
        {
            if(position.y<-graphics.bitmap.height)
                this.shutdown();
            position.y-=speed*dt;
        }
    }
}

这个代码和Enemy类的代码非常相似,除了在basicWeaponLogic函数里是把对象在屏幕里向上移动而不是向下移动。到这时你可能会觉得奇怪为什么我们需要把互相相似得如同彼此的拷贝的类给分离开。我们这么做的原因是最终敌机和武器将有许多专门的逻辑例程。虽然这两个类可能能归为一个类,但是把这两个类分离开来可以让代码更有易读性。最后的改变在游戏者类里,这将监视鼠标点击来开火。
Play.as
package
{
    import flash.events.*;
    import flash.geom.*;
    import mx.core.*;
    public class Player extends GameObject
    {
        protected static const TimeBetweenShots:Number=0.25;
        protected var shooting:Boolean=false;
        protected var timeToNextShot:Number=0;
        public funtion Player()
        {
        }
        public function startupPlayer():void
        {
            startupGameObject(ResourceManager.BrownPlaneGraphics,new Point
            (Application.application.width/2,Application.application.height/2),ZOrder.PlayerZOrder);
            shooting=false;
            timeToNextShot=0;
        }
        override public function shutdown():void
        {
            super.shutdown();
        }
        override public function enterFrame(dt:Number):void
        {
            super.enterFrame(dt);
            timeToNextShot-=dt;
            if(timeToNextShot<=0&&shooting)
            {
                timeToNextShot=TimeBetweenShots;
                var weapon:Weapon=Weapon.pool.ItemFromPool as Weapon;
                weapon.startupBasicWeapon(ResourcManager.TwoBulletsGraphics,new Point(
                position.x+graphics.bitmap.width/2-ResourceManager.TwoBulletsGraphics.bitmap.width/2,
                position.y-graphics.bitmap.height+ResourceManager.TwoBulletsGraphics.bitmap.height*2),
                150);
            }
        }   
        override public function mouseMove(event:MouseEvent):void
        {
            //move player to mouse position
            position.x=event.stageX;
            position.y=event.stageY;
            //keep player on the screen
            if(position.x<0)
                position.x=0;
            if(position.x>Application.application.width-graphics.bitmap.width)
                position.x=Application.application.width-graphics.bitmap.width;
            if(position.y<0)
                postion.y=0;
            if(position.y>Application.application.height-graphics.bitmap.height)
                position.y=Application.application.height-graphics.bitmap.height;
        }
        override public function mouseDown(event:MouseEvent):void
        {
            shooting=true;
        }
        override public function mouseUp(event:MouseEvent):void
        {
            shooting=false;
        }
    }
}   


我们已经增加了shooting属性。当被设置为真时(在mouseDown函数里,此函数在鼠标左键被按下时调用)游戏者周期性地增加生成新的武器类实例。mouseUp(当鼠标按钮被释放时调用)将设置shooting 为假,而且Player停止生成新的武器。timeToNextShot/TimeBetweenShots属性对被用来生成新的武器对象。

通过生成这两个新的类(武器和敌机),在Level和Player类中增加了一些小小的改变我们几乎到此时有了一个可以玩的游戏了。你将发现实际上你还不能向敌人射击。那需要我们在第六部分增加一些东西:冲突检测。
在http://flexfighters.sourceforge.net/flexfighters5.html处可查看最终效果,从https://sourceforge.net/project/showfiles.php?group_id=241490&package_id=293860&release_id=632324处可下载资源。
图片

 


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

原创粉丝点击