今天抽空整理了一下資料,周末繼續奮鬥。 頁遊裡面的角色是遊戲裡面核心模組之一,由於一直做模組,沒有動手寫一個來玩,這次我嘗試寫一個傻瓜的demo,嘗試去做一個非常簡單的實驗。
下面是今天早上的一個實驗過程,這個過程當中包括一些沒有解決的問題的思考記錄。
一、區分動作類型,進行打包分類
遇到的問題:打包資源動作過多不知道怎樣組合
打包一個 還是分開打包好?
在打包swf 寫上動作的幀,最大值是多少,方便進行播放?怎樣使用時間來合理過渡每一幀之間的時間?
二、嘗試播放四個常規的動作
遇到的問題,播放速度比較快?應該怎樣調整好?
三、改變速率進行播放
應該怎樣做到?
三 、嘗試基於時間的播放
/怎樣做到基於時間播放?
實驗進行中,由於沒有素材,於是我在一些遊戲網站裡面下載了一些緩衝的swf。
下載了swf資源後,我嘗試將動作區分開來,這次實驗盡量的保持簡單原則,只是選擇了8個方向來實驗。至於攻擊動作,受創等就不嘗試加入去。避免過於複雜。
把這些素材下載後,整理命名,我們將其打包成一個swf來載入。鑒於實驗,所以大小那些我就不考慮太多,只管實現成功即可。
註:下載下來的素材基本的動作都是6-8幀,我將每個動作都帶首碼區分下來
按上下左右進行對資源命名
如:up_1....up_8
down_1 ....down_8
下面到了編程的時候,寫一個簡單的方式對其進行實現。
載入後我們打包的swf資源,我將其命名為101.swf,加入域裡面去,選擇80毫秒播放一下。
package {import flash.display.Sprite;import flash.events.Event;import flash.net.URLLoader;import flash.display.Loader;import flash.net.URLRequest;import flash.system.LoaderContext;import flash.system.ApplicationDomain;import flash.display.BitmapData;import flash.display.Bitmap;import flash.events.KeyboardEvent;import flash.ui.Keyboard;import flash.utils.getTimer;public class Main extends Sprite{private var avatarActionType:int = 2;private var avatar:Avatar;private var circleButton:CircleButton;public function Main(){init();}private function init():void{var loader:Loader=new Loader();loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadCompleteHandler);loader.load(new URLRequest("101.swf"),new LoaderContext(false,ApplicationDomain.currentDomain));addEventListener(Event.ENTER_FRAME,onRender);stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDownHandler);circleButton=new CircleButton();circleButton.updateFun=updateAction;addChild(circleButton);circleButton.x=260;circleButton.y=200;} private function updateAction():void{avatarActionType=circleButton.curDir;}private function onKeyDownHandler(event:KeyboardEvent):void{switch (event.keyCode){case Keyboard.UP :avatarActionType = 1;break;case Keyboard.DOWN :avatarActionType = 2;break;case Keyboard.LEFT :avatarActionType = 3;break;case Keyboard.RIGHT :avatarActionType = 4;break;}}private function onLoadCompleteHandler(event:Event):void{event.currentTarget.removeEventListener(Event.COMPLETE,onLoadCompleteHandler);avatar=new Avatar();addChild(avatar);avatar.x = 250;avatar.y = 180;}//進行輪播private var oldTime:int;private function onRender(event:Event):void{if (! avatar){return;}var curTime:int = getTimer(); if (curTime-oldTime>80){oldTime = getTimer(); avatar.play(avatarActionType);} }}}
角色部分提供一個簡單的身體對其進行位元影像設計。在渲染的時候,不停地切換下一幀。為了省資源,處理反向的資源,採用scaleX =-1的方式進行處理。
package {import flash.display.Sprite;import flash.display.Bitmap;public class Avatar extends Sprite{private var body:Bitmap;//身體public var curFrame:int = 0;public var curFrameLabel:String;public function Avatar():void{body = new Bitmap();addChild(body);}public function play(avatarActionType:int):void{curFrame++;if (avatarActionType == ActionType.UP){if ((curFrame > 6)){curFrame = 1;}curFrameLabel = "up_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX = 1;}else if (avatarActionType == ActionType.DOWN){if (curFrame > 8){curFrame = 1;}curFrameLabel = "down_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX = 1;}else if (avatarActionType == ActionType.LEFT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "right_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX = -1;}else if (avatarActionType == ActionType.RIGHT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "right_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX = 1;}else if (avatarActionType == ActionType.UP_RIGHT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "upRight_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX = 1;}else if (avatarActionType == ActionType.UP_LEFT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "upRight_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX =-1 ;}else if (avatarActionType == ActionType.DWON_LEFT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "rightDown_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);body.x = - width / 2;body.y = - height / 2;this.scaleX =-1 ;}else if (avatarActionType == ActionType.DWON_RIGHT){if (curFrame > 8){curFrame = 1;}curFrameLabel = "rightDown_" + curFrame;body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);trace(body.bitmapData);body.x = - width / 2;body.y = - height / 2;this.scaleX =1 ;}}}}
定義一組簡單的動作類型。
package {//方向8個,資源需要5個public class ActionType{public static const UP:int = 1;//向上炮public static const DOWN:int = 2;//向下跑public static const LEFT:int = 3;//向左跑public static const RIGHT:int = 4;//向右跑public static const UP_LEFT:int = 5;//左上跑public static const UP_RIGHT:int = 6;//右上跑public static const DWON_LEFT:int = 7;//左下跑public static const DWON_RIGHT:int = 8;//右下跑public static const UP_STAND:int = 9;//向上站立public static const UP_LEFT_STAND:int = 10;//向左站立public static const UP_RIGHT_STAND:int = 11;//向右站立public static const DOWN_STAND:int = 12;//向下站立public static const DOWN_LEFT_STAND:int = 13;//向左下站立public static const DOWN_RIGHT_STAND:int = 14;//向右下站立}}
資源集區,這裡可以不用這樣設計,鑒於實驗。
package {import flash.display.BitmapData;import flash.system.ApplicationDomain;import flash.utils.Dictionary;public class BitmapPool{private static var pool:Dictionary=new Dictionary();public function BitmapPool(){}public static function getBitmapData(name:String):BitmapData{var myCls:Class;if (pool[name] == null){myCls = getClass(name) as Class;if (myCls){return new myCls();}}else{return pool[name];}return null;}public static function getClass(clsName:String):*{if (ApplicationDomain.currentDomain.hasDefinition(clsName)){return ApplicationDomain.currentDomain.getDefinition(clsName);}return null;}}}
package {import flash.display.Sprite;import flash.events.MouseEvent;import flash.filters.GlowFilter;import flash.text.TextField;public class CircleButton extends Sprite{ public var curDir:int;public var updateFun:Function;public function CircleButton(){ var perAngle:Number=2*Math.PI/8;var dirArr:Array=[ActionType.RIGHT,ActionType.DWON_RIGHT,ActionType.DOWN,ActionType.DWON_LEFT,ActionType.LEFT, ActionType.UP_LEFT,ActionType.UP,ActionType.UP_RIGHT]; for (var i:int=0; i<8; i++){var shape:Sprite=new Sprite();addChild(shape);shape.graphics.beginFill(0xffffff);shape.graphics.drawCircle(0,0,12);shape.graphics.endFill();shape.buttonMode=true;var msg:TextField=new TextField();shape.addChild(msg);msg.autoSize="left";msg.mouseEnabled=false;msg.x=-5;msg.y=-8msg.text=dirArr[i].toString();shape.x = Math.cos(i*perAngle) * 140;shape.y = Math.sin(i*perAngle) * 140;shape.name = dirArr[i].toString();shape.filters=[new GlowFilter(0x33333)];shape.addEventListener(MouseEvent.CLICK,onClick);}}private function onClick(event:MouseEvent):void{ curDir=int(event.currentTarget.name);if(updateFun!=null){updateFun.apply(null,null);}} }}
大體的工作已經完成了。其實我們在EnterFrame 事件觸發後,處理幀的播放就能看到不同的切片。這裡要是做到更多的功能還需要考慮更多事情,如載入,鏈
接處理,不同部位i的等方式,一大堆亂七八糟的東西煩著你。這裡 基本思路,就是要怎樣解決輪播圖片的問題,可以參考(D5power 也有相關引擎製作案例),個
人感覺開源裡面也很不錯,學習起來。
很多功能對角色製作工藝有不一樣的,這裡更多要嘗試去分解他們資源進行學習。畢竟這些東西也不是一兩天能夠吃套的東西。作為一個簡單demo 拿來無聊的時
候寫寫代碼就好了。