使用FLEX和 Actionscript 开发FLASH游戏(四)-1

本文介绍如何在Flash游戏中使用FLEX和Actionscript实现鼠标输入控制及动态背景更新。文章详细讲解了如何通过修改main.mxml文件来响应鼠标事件,并介绍了GameObjectManager类如何处理这些事件。

使用FLEXActionscript开发FLASH 游戏-使用输入和动态背景

 

 

在本系列第三部分我们最终得以在屏幕上画一些图形。在第四部分我们将多画图形而且使得游戏对象呈现交互性。我们还将生成一个背景级别使得游戏者可以在其上面飞行。

   大多数Flash游戏自然非常简单。它们是510分钟的小娱乐,人们在午餐时分可以玩它,或者在老板看不见的时候。这种简单性在Flash游戏的典型控制方案中反映出来:鼠标输入只使用左键单击。这是很直观的(人们抽出他们时间的几分钟来玩游戏可不想阅读一个写着复杂控制方案的帮助页面),总之Flash不会让你(简单地)使用鼠标右键。

   谢天谢地我们游戏中的俯视角射手风格非常好地适于这种简单地控制方案。游戏者仅仅在屏幕上到处移动鼠标来移动游戏者飞船,通过单击鼠标左键来发射子弹。但是在我们生成一个代表游戏者飞船的游戏对象之前我们先需要一种能探测鼠标移动到哪了鼠标何时被点击了的方法。让我们看看完成上述功能需要在main.mxml文件中做些什么改变。

main.mxml

<?xml version="1.0" encoding="utf-8"?>

<mx:Application

xmlns:mx="http://www.adobe.com/2006/mxml"

layout="absolute"

width="600"

height="400"

frameRate="100"

creationComplete="creationComplete()"

enterFrame="enterFrame(event)"

click="click(event)"

mouseDown="mouseDown(event)"

mouseUp="mouseUp(event)"

mouseMove="mouseMove(event)"

currentState="MainMenu">

    <mx:states>

        <mx:State

        name="Game"

        enterState="enterGame(event)"

        exitState="exitGame(event)"

        </mx:State>

        <mx:State name="MainMenu">

            <mx:AddChild relativeTo="{myCanvas} position="lastChild">

                <mx:Button x="525" y="368" label="Start" id="btnStart" click="startGameClicked                (event)"/>

            </mx:AddChild>

        </mx:State>

    </mx:states>

    <mx:Canvas x="0" y="0" width="100%" height="100%" id="myCanvas"/>

    <mx:Script>

    <![CDATA[

        protected var inGame:Boolean=false;

        public function creationComplete():void

        {

        }

        public function enterFrame(event:Event):void

        {

            if(inGame)

            {

                GameObjectManager.Instance.enterFrame();

                myCanvas.graphics.clear();

                myCanvas.graphics.beginBitmapFill                (GameObjectManager.Instance.backBuffer,null,false,false);

                myCanvas.graphics.drawRect(0,0,this.width,this.height);

                myCanvas.graphics.endFill();

            }

        }

        private function click(event:MouseEvent):void

        {

            GameObjectManager.Instance.click(event);

        }

        private function mouseDown(event:MouseEvent):void

        {

            GameObjectManager.Instance.mouseDown(event);

        }

        private function mouseUp(event:MouseEvent):void

        {

            GameObjectManager.Instance.mouseUp(event);

        }

        private function mouseMove(event:MouseEvent):void

        {

            GameObjectManager.Instance.mouseMove(event);

        }

        protected function startGameClicked(event:Event):void

        {

            currentState="Game";

        }

        protected function enterGame(event:Event):void

        {

            Mouse.hide();

            GameObjectManager.Instance.startup();

            Level.Instance.startup();

            inGame=true;

        }

        protected function exitGame(event:Event):void

        {

            Mouse.show();

            Level.Instance.shutdown();

            GameObjectManager.Instance.shutddown();

            inGame=false;

        }

    ]]>

    </mx:Script>

</mx:Application>

我们增加了函数来侦听四个新的事件:mouseMove,click,mouseDownmouseUpMouseMove,就如同你所希望的,在鼠标移动时被调用。它允许我们通过flash游戏窗口来监听鼠标光标的位置。相似地click在鼠标按钮被点击(即按下并且释放)时监听。当鼠标按钮被按下mouseDown作用,而当鼠标按钮被释放时mouseUp作用。我们特别地需要监听mouseDownmouseUp事件的能力(click事件与之不同,它在鼠标被点击而且接着释放时调用)因为最终用我们希望鼠标按钮被按下时游戏者开火而当鼠标按钮被释放时停止开火。

   四个新函数的事件有着同样的名称作为各自的事件,仅仅将消息传给GameObjectManager

GameObjectManager.as

package

{

    import flash.display.*;

    import flash.events.*;

    import mx.collections.*;

    import mx.core.*;

    public class GameObjectManager

    {

        //double buffer

        public var backBuffer:BitmapData;

        //colour to use to clear backbuffer with

        public var clearColor:uint=0xFF0043AB;

        //static instance

        protected static var instance:GameObjectManager=null;

        //the last frame time

        protected var lastFrame:Date;

        //a collection of the GameObjects

        protected var gameObjects:ArrayCollection=new ArrayCollection();

        //a collection of the GameObjects are placed,to avoid adding items

        //to gameObjects while in the gameObjects collection while it is in a loop

        protected var newGameObjects:ArrayCollection=new ArrayCollection();

        //a collection where removed GameObjects are placed,to avoid removing items

        //to gameObjects while in the gameObjects collection while it is in a loop

        protected var removedGameObjects:ArrayCollection=new ArrayCollection();

        static public function get Instance():GameObjectManager

        {

            if(instance==null)

                instance==new GameObjectManager();

            return instance;

        }

        public function GameObjectManager()

        {

            if(instance!==null)

                throw new Error("Only one Singleton instance shoule be instantiated");

            backBuffer=new BitmapData            (Appliction.application.width,Application.application.height,false);

        }

        public function startup():void

        {

            lastFrame=new Date();

        }

        public function shutdown():void

        {

            shutdownAll();

        }

        public function enterFrame():void

        {

            //Calculate the time since the last frame

            var thisFrame:Date=new Date();

            var seconds:Number=(thisFrame.getTime()-lastFrame.getTime())/1000.0;

            lastFrame=thisFrame;

            removeDeletedGameObjects();

            insertNewGameObjects();

            Level.Instance.enterFrame(seconds);

            //now allow objects to update themselves

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.enterFrame(seconds);

            }

            drawObjects();

        }

        public function click(event:MouseEvent):void

        {

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.click(event);

            }

        }

        public function mouseDown(event:MouseEvent):void

        {

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.mouseDown(event);

            }

        }

        public function mouseUp(event:MouseEvent):void

        {

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.mouseUp(event);

            }

        }

        public function mouseMove(event:MouseEvent):void

        {

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.mouseMove(event);

            }

        }

        protected function drawObject():void

        {

            backBuffer.fillRect(backBuffer.rect,clearColor);

            //draw the objects

            for each(var gameObject:GameObject in gameObjects)

            {

                if(gameObject.inuse)

                    gameObject.copyToBackBuffer(backBuffer);

            }

        }

        public function addGameObject(gameObject:GameObject):void

        {

            newGameObjects.addItem(gameObject);

        }

        public function removeGameObject(gameObject:GameObject):viod

        {

            removeGameObjects.addItem(gameObject);

        }

        protected function shutdownAll():void

        {

            //don't dispose objects twice

            for each(var gameObject:GameObject in gameObjects)

            {

                var found:Boolean=false;

                for each(var removedObject:GameObject in removedGameObjects)

                {

                    if(removedObject==gameObject)

                    {

                        found==true;

                        break;

                    }

                }

                if(!found)

                    gameObject.shutdown();

            }

        }

        protected function insertNewGameObjects():void

        {

            for each(var gameObject:GameObject in newGameObjects)

            {

                for(var i:int=0;i<gameObjects.length;++i)

                {

                    if(gameObjects.getItemAt(i).zOrder>gameObject.zOrder||gameObject.getItemAt(i).zOrder==-1)

                        break;

                }

                gameObjects.addItemAt(gameObject,i);

            }

            newGameObjects.removeAll();

        }        

        protected function removeDeletedGameObjects():void

        {

            //insert the object acording to it's z position

            for each(var removedObject:GameObject in removedGameObjects)

            {

                var i:int=0;

                for (i=0;i<gameObjects.length;++i)

                {

                    if(gameObjects.getItemAt(i)==removedObject)

                    {

                        gameObjects.removedItemAt(i);

                        break;

                    }

                }

            }

            removedGameObjects.removedAll();

        }

    }

}

正如你所看见的GameObjectManager有了4个新的函数来反映应用程序对象里的4个新的鼠标事件。GameObjectManager依次在gameObjects集合上循环给当前处于活动状态的任何GameObject传递消息。

<本系列前一篇文章 | 页面:1 2 | 下一页>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值