关于对FLASH开发,starling、starling feathers、starling MVC框架的理解
說在前頭:樓主之前沒有不論什么flash開發經驗,僅僅是從一次嘗試中總結自己的理解和經驗而已。假設有寫的不正確的地方,歡迎大家指正。
前一段時間嘗試想用flash(as3)又一次制作一下之前做的一個游戲,作為從來沒有接觸過flash開發的我來說,花了一些時間研究現有的一些框架。
盡管如今我已經放棄了使用flash來開發(后面會說原因),但我認為還是有必要總結一下這個過程中對于flash、starling、starling mvc的一些理解。
由于一開始我是使用silverlight開發游戲的,它有一個極大的便利是微軟提供了強大好用的Microsoft Blend Expression。能夠非常好的、所見即所得用它來制作UI。自然而然,我非常想在flash的開發環境下找一個替代品。
但非常遺憾,最后我自己得出的結論是:沒有。
1、flex和blend有點像,但flex(后來叫flash builder)貌似某個版本號以后就不提供圖形編輯器了。而且通過網上大家的討論得出,flex性能特別差,差點兒無法在手機上執行。果斷棄坑。
2、flash cs能夠制作游戲UI,但給我的感覺是提供的功能特別基礎,也不甚符合程序猿的邏輯思維。
3、另一些其它的第三方或者個人提供的UI庫、編輯工具,如flexlite等——不敢用,怕有大坑。并且翻了一下代碼更新日志,也是好久都沒動過了——更加怕。
4、starling貌似是大家比較推崇的flash移動端解決方式,大概看了一下。從原理上來說肯定是性能比傳統的flash要好得多。
通過一番調研,決定用starling試試。
非常自然的,游戲須要比較好的擴展性的話。我們須要一個好的代碼框架。找了一圈找到starling MVC。大概看了一下功能介紹,感覺和j2ee的spring MVC有一點像。
starling MVC是一個IOC框架,提供下面特性:
- 依賴注入(DI)/控制反轉(IOC)
- 視圖仲裁(View Mediation)
- 事件處理
- 不影響原生的Starling游戲代碼
- 簡易配置
- 易擴展
- 提供一些有用工具
我到網上翻了一些關于starling MVC編寫的游戲例程。怎么說呢。我感覺是沒一個靠譜的。。大部分人都是淺嘗輒止,并且都是生搬硬套。想把游戲邏輯拼命的塞到starling MVC中,而不是真正的用它來做代碼的整理、規劃,沒有理解MVC、IOC、DI等思想,于是我索性自己開始琢磨。
我整理的starling MVC的調用邏輯關系例如以下:
1、啟動時初始化各個bean(包含model、mediator、controller、view我覺得都應該實例化為bean)
2、starling MVC提供方法將bean依賴注入([Inject]等標簽)
3、MVC的連接方式為:
- controller中注冊EventHandler。接收消息。
然后直接調用ViewManager的addView/removeView方法。來改動元素。
- 調用了addView/removeView實際上會被相關的Mediator攔截到,在Mediator中編寫界面展示的邏輯。
(調用view的改動方法,調用Model的邏輯)
- Model中提供業務邏輯方法
- View中定義界面元素
開發過程中邏輯還是比較順暢的。只是后來我一直沒去搞清楚比方要實現場景切換的過渡特效,在starling MVC中怎么實現……由于每次都是直接addView、removeView,木有一個中間狀態啊。只是還沒等我去研究,我就棄坑了……呵呵呵呵呵呵……
另外提一下starling feathers這個東東。
starling沒有可視化的UI開發工具(拖界面的工具),那么意味著你須要手動在代碼里去寫x、y坐標。寫width、height等屬性(我了個擦。坑爹啊!
)——當然。假設你說你能夠自己開發一個可視化的工具。那么,我僅僅能說:祝你好運……
OK,那么我先硬著頭皮寫一下用代碼來布局的UI吧……
var stateBackground : ImageLoader = new ImageLoader();stateBackground.source = assets.getTexture("nick");stateBackground.x = 0;stateBackground.y = -12;stateBackground.width = 200;stateBackground.height = 70;stateCanvas.addChild(stateBackground);_nickLabel = ComponentFactory.getSmallFontLabel("初出茅廬", 0xEF5E00, true, 20);_nickLabel.x = 62;_nickLabel.y = -4;stateCanvas.addChild(_nickLabel);_gameModeLabel = ComponentFactory.getSmallFontLabel("難度:普通", 0xFFFFFF, true, 12);_gameModeLabel.x = 61;_gameModeLabel.y = 24;stateCanvas.addChild(_gameModeLabel);_zhujueHead = new ImageLoader();_zhujueHead.x = 4;_zhujueHead.y = -4;_zhujueHead.width = 40;_zhujueHead.height = 49;_zhujueHead.source = assets.getTexture("zhujue");stateCanvas.addChild(_zhujueHead); _descCanvas = new Sprite();_descCanvas.x = 100;_descCanvas.y = 100;_descCanvas.visible = false;this.addChild(_descCanvas);//提示框var descBackground : Scale9Image = ComponentFactory.getScale9Image("info", new Rectangle(7,9,360,87));descBackground.x = 0;descBackground.y = 0;descBackground.width = 377;descBackground.height = 103;descBackground.alpha = 0.8;_descCanvas.addChild(descBackground);_descImage = new ImageLoader();_descImage.x = 14;_descImage.y = 14;_descImage.width = 80;_descImage.height = 80;_descImage.maintainAspectRatio = false;_descCanvas.addChild(_descImage);_descLocationLabel = ComponentFactory.getSmallFontLabel("", 0xffffff, true, 18);_descLocationLabel.x = 104;_descLocationLabel.y = 6;_descLocationLabel.filter = BlurFilter.createDropShadow(4,0.7,0x000000,0.8,0.5,1);_descCanvas.addChild(_descLocationLabel);_descInfoLabel = ComponentFactory.getSmallFontLabel("", 0xffffff, false, 12);_descInfoLabel.x = 104;_descInfoLabel.y = 40;_descInfoLabel.width = 250;_descInfoLabel.height = 56;_descInfoLabel.filter = BlurFilter.createDropShadow(2,0.7,0x000000,0.8,0.5,1);_descCanvas.addChild(_descInfoLabel);
上面這一段截取于我剛開始寫的一個布局view,實在是蛋疼至極有木有!!! 于是樓主憤慨的自己寫了一個布局基類,能夠實現成以下這種寫法了……
this.initComponents([{type:Scale9Image, source:"UI-kuang", rect:new Rectangle(15,40,315,328), width:500, height:585},{type:RoleUI, id:"roleUI", x:80, id:"roleUI"},{type:Label, text:"當前隊伍", color:0xffffff, fontSize:14, width:110, x:25, y:73},{type:ScrollContainer, width:80, height:435, x:25, y:108, id:"teamlist" },{type:ImageLoader, source:"back", width:20, height:20, x:470, y:5, id:"close"},]);
自己感覺好多了……但還是非常蛋疼有木有
這里奉上基類BaseUI,有興趣拿走~
package cn.hanjiasongshu.jygame.views.components {import com.creativebottle.starlingmvc.views.ViewManager;import flash.geom.Rectangle;import flash.utils.Dictionary;import cn.hanjiasongshu.jygame.core.assets.Assets;import cn.hanjiasongshu.jygame.views.factorys.ComponentFactory;import feathers.controls.ImageLoader;import feathers.controls.Label;import feathers.controls.ScrollContainer;import feathers.core.FeathersControl;import feathers.display.Scale9Image;import feathers.textures.Scale9Textures;import feathers.dragDrop.DragDropManager;import starling.display.Sprite;import starling.textures.Texture;/*** UI基類* @author cg* */public class BaseUI extends FeathersControl{private static const ANONYMOUS_PREFIX:String = "__";public function BaseUI(){_components = new Dictionary();_autoId = 0;}public function get assets():Assets{return Assets.instance;}/*** 初始化組件 * @param componentsArray* */protected function initComponents(componentsArray:Object):void{this.addComponents(componentsArray, this);}/*** 為一個組件加入孩子 * @param componentsArray* @param parent* */private function addComponents(componentsArray:Object, parent:Sprite):void{for each(var c:Object in componentsArray){if(c.type == null){trace("[error]undefined component type:" + c);continue;}var type:String = c.type;var id:String = "";if(c.id != null){id = c.id;}else{id = String(ANONYMOUS_PREFIX + _autoId + ":" + String(c.type));_autoId++;}var component:Sprite = null;switch(c.type){case Label:var text:String = c.text==null?"":c.text;var color:int = c.color==null?0:c.color;var bold:Boolean = c.bold==null?true:c.bold;var fontSize:int = c.fontSize==null?11:c.fontSize;if(c.align != null && c.align == "center"){component = ComponentFactory.getCenterAlignedFontLabel(text,color,bold,fontSize);}else{component = ComponentFactory.getSmallFontLabel(text,color,bold,fontSize);}break;case ImageLoader:var tmp:ImageLoader = new ImageLoader();tmp.maintainAspectRatio = false;var source:String = c.source==null?"":c.source;tmp.source = c.source==null?
"":assets.getTexture(source); component = tmp; break; case Scale9Image: component = ComponentFactory.getScale9Image(c.source, c.rect); break; case ScrollContainer: component = ComponentFactory.generateVerticalScrollContainer(c.layout, c.backgroundSkin); break; case ToolTipUI: component = new ToolTipUI(parent); break; default: var clz:Class = c.type; var instance:Object = new clz(); if(instance is Sprite) { component = instance as Sprite; } else { trace("[error]invalid component type:" + c.type); } break; } if(component != null) { this.setIfExist(c, component, ["x","y","width","height","visible"]); _components[id] = component; parent.addChild(component); if(c.children != null) //遍歷孩子組件 { this.addComponents(c.children, component); } } } } /** * 通過ID獲取組件 * @param id * @return * */ public function getComponentById(id:String):Sprite { if(_components[id] == null) { trace("[error]get undefined component id:"+id); return null; } return _components[id]; } public function getLabel(id:String):Label { return this.getComponentById(id) as Label; } public function getImageLoader(id:String):ImageLoader { return this.getComponentById(id) as ImageLoader; } private function setIfExist(dataSource:Object, obj:Sprite, params:Array):void { for each(var p:String in params) { if(dataSource[p]!=null) obj[p]=dataSource[p]; } } private var _components:Dictionary; private var _autoId:int; public override function dispose():void { for each(var key:String in _components) { var sprite:Sprite = _components[key] as Sprite; sprite.removeFromParent(true); } _components = null; } } }
你能夠改動addComponent函數來自己加入控件類型,支持控件的組合等等。
啰啰嗦嗦說了這么多,發幾個終于做出來的效果的圖吧……還是非常丑……
算是寫了一些代碼,但越做越不正確頭,由于UI這東西還真不是寫寫控件布局就能做好的,沒有一個非常好的可視化的編輯工具。我也越來越力不從心。 之后出于多方考慮。還是棄坑投入了unity3d的懷抱。
最后總結一下吧:
1、用starling這一系列東西開發的過程中到是沒遇到太多框架性的BUG,已有的特性和功能都能夠用。 2、starling等提供的功能還是比較原始。我認為用來開發小游戲可能還不錯。規模略微大一點,就須要好好考量了。 3、PC上性能還OK。但最后貌似我也沒上手機真機調試。這個我沒有發言權。 4、as3還是比較靈活,寫代碼也有挺爽快的感覺。給我留下的印象僅次于c#。假設以后有機會開發flash游戲。我還是挺樂觀的。 5、Adobe對于這塊的投入貌似非常萎縮,flash開發人員們以及社區都不夠繁榮。 6、開發手機游戲的話,還是用專業的引擎吧。
總結
以上是生活随笔為你收集整理的关于对FLASH开发,starling、starling feathers、starling MVC框架的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 书写神器——markdown
- 下一篇: 完整项目基础架构精简版-实现权限管理