├── .actionScriptProperties
├── .flexProperties
├── .gitignore
├── .project
├── .settings
└── org.eclipse.core.resources.prefs
├── Animator.exe
├── README.md
├── guide_make_transition.gif
├── libs
└── ui.swc
└── src
├── Animator-app.xml
├── Animator.mxml
├── assets
├── +.png
├── -.png
├── icon128.png
├── icon16.png
├── icon32.png
└── icon48.png
└── com
└── wonder
├── AnimState.as
├── AnimTransition.as
├── Condition.as
├── DataParser.as
├── DragSprite.as
├── EditController.as
└── Parameter.as
/.actionScriptProperties:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/.flexProperties:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin-debug/Animator-app.xml
2 | bin-debug/Animator.swf
3 | /bin-debug
4 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Animator
4 |
5 |
6 |
7 |
8 |
9 | com.adobe.flexbuilder.project.flexbuilder
10 |
11 |
12 |
13 |
14 | com.adobe.flexbuilder.project.apollobuilder
15 |
16 |
17 |
18 |
19 |
20 | com.adobe.flexbuilder.project.apollonature
21 | com.adobe.flexbuilder.project.flexnature
22 | com.adobe.flexbuilder.project.actionscriptnature
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | #Sat Mar 28 18:13:06 CST 2015
2 | eclipse.preferences.version=1
3 | encoding/=utf-8
4 |
--------------------------------------------------------------------------------
/Animator.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/Animator.exe
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Animator
2 | A Visual FSM Editor like Unity Mecanim System
3 |
4 | Project
5 | =======
6 | * A Flex project
7 | * IDE: FlashBuilder
8 | * can be published as desktop application for Windows and Mac OS
9 |
10 | Feature
11 | =======
12 | * export *.json file
13 | * support dragonBones skeleton file for Egret Engine(http://www.egret-labs.org/dragonbones)
14 |
15 | Guide
16 | =====
17 | 
18 |
19 | 工程
20 | ====
21 | * Flex工程
22 | * IDE: FlashBuilder
23 | * 可以发布为桌面应用程序(支持Windows和Mac)
24 |
25 | 功能
26 | ====
27 | * 将编辑过的状态机导出为json文件供程序解析
28 | * 支持dragonBones导出的Egret白鹭引擎格式skeleton.json文件,点击open打开或直接拖拽到视窗内(支持多文件)
29 | * 主要操作方式可搜索参考Unity的Mecanim,不再赘述(=。。=)
30 |
--------------------------------------------------------------------------------
/guide_make_transition.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/guide_make_transition.gif
--------------------------------------------------------------------------------
/libs/ui.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/libs/ui.swc
--------------------------------------------------------------------------------
/src/Animator-app.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
18 | Animator
19 |
20 |
21 | Animator
22 |
23 |
25 | Animator
26 |
27 |
30 | 1.0.0
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | [此值将由 Flash Builder 在输出 app.xml 中覆盖]
50 |
51 |
52 | AnimatorEditor
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | 960
74 |
75 |
76 | 480
77 |
78 |
79 | 0
80 |
81 |
82 | 0
83 |
84 |
85 | 960 480
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | false
109 | false
110 | false
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
128 |
129 | assets/icon16.png
130 | assets/icon32.png
131 |
132 | assets/icon48.png
133 |
135 | assets/icon128.png
136 |
137 |
138 |
141 |
142 |
143 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
192 |
193 |
194 |
195 |
196 |
218 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/src/Animator.mxml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
12 |
14 |
15 |
17 |
18 |
19 |
20 |
23 |
25 |
26 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
38 |
41 |
42 |
43 |
45 |
47 |
48 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
63 |
65 |
66 |
69 |
70 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
242 |
243 |
244 |
--------------------------------------------------------------------------------
/src/assets/+.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/+.png
--------------------------------------------------------------------------------
/src/assets/-.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/-.png
--------------------------------------------------------------------------------
/src/assets/icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/icon128.png
--------------------------------------------------------------------------------
/src/assets/icon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/icon16.png
--------------------------------------------------------------------------------
/src/assets/icon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/icon32.png
--------------------------------------------------------------------------------
/src/assets/icon48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wonderyue/Animator/33e55bbe742d9c0d7151c590ff91b8503dceead3/src/assets/icon48.png
--------------------------------------------------------------------------------
/src/com/wonder/AnimState.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | import flash.display.SimpleButton;
4 | import flash.display.Sprite;
5 | import flash.events.ContextMenuEvent;
6 | import flash.events.MouseEvent;
7 | import flash.filters.DropShadowFilter;
8 | import flash.filters.GlowFilter;
9 | import flash.text.TextField;
10 | import flash.text.TextFormat;
11 | import flash.ui.ContextMenu;
12 | import flash.ui.ContextMenuItem;
13 |
14 | import flashx.textLayout.formats.TextAlign;
15 |
16 | public class AnimState extends DragSprite
17 | {
18 | public static var ANYSTATE_ID:String = "anyState";
19 | private static var DEFAULT_COLOR:int = 0xFFD700;
20 | private static var NORMAL_COLOR:int = 0xD3D3D3;
21 | private static var ANYSTATE_COLOR:int = 0x66CDAA;
22 | private var m_isDefaultState:Boolean = false;
23 | private var m_isSelected:Boolean = false;
24 |
25 | private var m_textField:TextField;
26 | private var m_bg:Sprite;
27 | private var m_btn:SimpleButton;
28 | private var m_id:String;
29 | private var m_animation:String;
30 |
31 | public function AnimState(id:String)
32 | {
33 | super();
34 | m_animation = m_id = id;
35 | initSkin();
36 | initMenu();
37 | }
38 |
39 | public function set id(value:String):void
40 | {
41 | m_id = value;
42 | m_textField.text = m_id;
43 | }
44 |
45 | public function get id():String{
46 | return m_id;
47 | }
48 |
49 | public function get animation():String
50 | {
51 | return m_animation;
52 | }
53 |
54 | public function set animation(value:String):void
55 | {
56 | m_animation = value;
57 | }
58 |
59 | public function get isDefaultState():Boolean
60 | {
61 | return m_isDefaultState;
62 | }
63 |
64 | public function set isDefaultState(value:Boolean):void
65 | {
66 | if(m_isDefaultState == value) {
67 | return;
68 | }
69 | if (value) {
70 | m_bg.graphics.clear();
71 | m_bg.graphics.beginFill(DEFAULT_COLOR);
72 | m_bg.graphics.drawRoundRect(0,0,150,40,18,18);
73 | m_bg.graphics.endFill();
74 | } else {
75 | m_bg.graphics.clear();
76 | m_bg.graphics.beginFill(NORMAL_COLOR);
77 | m_bg.graphics.drawRoundRect(0,0,150,40,18,18);
78 | m_bg.graphics.endFill();
79 | }
80 | m_isDefaultState = value;
81 | }
82 |
83 | public function get isAnyState():Boolean
84 | {
85 | return id == ANYSTATE_ID;
86 | }
87 |
88 | private function initSkin():void{
89 | m_bg = new Sprite();
90 | m_bg.graphics.clear();
91 | m_bg.graphics.beginFill(isAnyState?ANYSTATE_COLOR:NORMAL_COLOR);
92 | m_bg.graphics.drawRoundRect(0,0,150,40,18,18);
93 | m_bg.graphics.endFill();
94 | addChild(m_bg);
95 | m_bg.filters = [new DropShadowFilter(2,90,0,0.8)];
96 |
97 | m_textField = new TextField();
98 | m_textField.selectable = false;
99 | var textFormat:TextFormat = new TextFormat();
100 | textFormat.font = "Arial";
101 | textFormat.size = 20;
102 | m_textField.textColor = 0x000000;
103 | textFormat.align = TextAlign.CENTER;
104 | m_textField.defaultTextFormat = textFormat;
105 | m_textField.text = m_id;
106 | m_textField.width = m_bg.width;
107 | m_textField.height = m_bg.height;
108 | addChild(m_textField);
109 | }
110 |
111 | private function initMenu():void
112 | {
113 | var contextMenu:ContextMenu = new ContextMenu();
114 | var contextItem1:ContextMenuItem = new ContextMenuItem("Make Transition");
115 | var contextItem2:ContextMenuItem = new ContextMenuItem("Set As Default");
116 | var contextItem3:ContextMenuItem = new ContextMenuItem("Copy");
117 | var contextItem4:ContextMenuItem = new ContextMenuItem("Delete");
118 | var self:AnimState = this;
119 | contextItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void{
120 | EditController.getInstance().makeTransition(self);
121 | });
122 | contextItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void{
123 | EditController.getInstance().setDefaultState(self);
124 | });
125 | contextItem3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void{
126 | var state:AnimState = EditController.getInstance().addState(self.id + "(copy)", x + 30, y + 30);
127 | state.animation = self.animation;
128 | });
129 | contextItem4.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void{
130 | EditController.getInstance().removeState(self);
131 | });
132 | contextMenu.customItems.push(contextItem1);
133 | if (!isAnyState)
134 | {
135 | contextMenu.customItems.push(contextItem2);
136 | contextMenu.customItems.push(contextItem3);
137 | contextMenu.customItems.push(contextItem4);
138 | }
139 | contextMenu.hideBuiltInItems();
140 | this.contextMenu = contextMenu;
141 | }
142 |
143 | public function get isSelected():Boolean
144 | {
145 | return m_isSelected;
146 | }
147 |
148 | public function set isSelected(bool:Boolean):void
149 | {
150 | if (bool)
151 | {
152 | var filter:Array = [new GlowFilter(0x000ff0, 1.0, 2.0, 2.0, 20, 1, true, false)];
153 | this.filters = filter;
154 | } else {
155 | this.filters = null;
156 | }
157 | m_isSelected = bool;
158 | }
159 |
160 | override protected function onIn(e:MouseEvent):void
161 | {
162 | if (!EditController.getInstance().hasDragState())
163 | {
164 | super.onIn(e);
165 | }
166 | }
167 |
168 | override protected function onMove(e:MouseEvent):void
169 | {
170 | super.onMove(e);
171 | EditController.getInstance().updateArrow(this);
172 | }
173 |
174 | override protected function onMouseUp(e:MouseEvent):void
175 | {
176 | super.onMouseUp(e);
177 | EditController.getInstance().updateArrow(this);
178 | EditController.getInstance().curState = this;
179 | }
180 |
181 | public function destroy():void
182 | {
183 | if (parent)
184 | {
185 | parent.removeChild(this);
186 | }
187 | }
188 | }
189 | }
--------------------------------------------------------------------------------
/src/com/wonder/AnimTransition.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | import flash.display.Sprite;
4 | import flash.events.ContextMenuEvent;
5 | import flash.events.Event;
6 | import flash.events.MouseEvent;
7 | import flash.filters.GlowFilter;
8 | import flash.geom.Point;
9 | import flash.ui.ContextMenu;
10 | import flash.ui.ContextMenuItem;
11 |
12 | public class AnimTransition
13 | {
14 | private var m_from:AnimState;
15 | private var m_to:AnimState;
16 | private var m_arrow:Sprite;
17 | private var m_isSelected:Boolean = false;
18 | private var m_conditionArray:Array;
19 |
20 | public function AnimTransition(from:AnimState)
21 | {
22 | super();
23 | m_from = from;
24 | m_arrow = new Sprite();
25 | EditController.getInstance().arrowContainer.addChild(m_arrow);
26 | m_arrow.addEventListener(MouseEvent.CLICK,onMouseClick);
27 | m_arrow.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
28 | m_arrow.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
29 | m_arrow.addEventListener(Event.REMOVED_FROM_STAGE,onDestroy);
30 | m_conditionArray = new Array();
31 | initMenu();
32 | }
33 |
34 | private function initMenu():void
35 | {
36 | var contextMenu:ContextMenu = new ContextMenu();
37 | var contextItem1:ContextMenuItem = new ContextMenuItem("Delete");
38 | var self:AnimTransition = this;
39 | contextItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void{
40 | EditController.getInstance().removeTransition(self);
41 | EditController.getInstance().curArrow = null;
42 | });
43 | contextMenu.customItems.push(contextItem1);
44 | contextMenu.hideBuiltInItems();
45 | m_arrow.contextMenu = contextMenu;
46 | }
47 |
48 | public function get conditionArray():Array
49 | {
50 | return m_conditionArray;
51 | }
52 |
53 | public function addCondition():Condition
54 | {
55 | var condition:Condition = new Condition(new Parameter(Parameter.COMPLETE_ID, Parameter.TYPE_COMPLETE));
56 | m_conditionArray.push(condition);
57 | return condition;
58 | }
59 |
60 | public function removeCondition(condition:Condition):void
61 | {
62 | for (var i:int = 0; i < m_conditionArray.length; i++)
63 | {
64 | var element:Condition = m_conditionArray[i] as Condition;
65 | if (element == condition)
66 | {
67 | m_conditionArray.splice(i,1);
68 | return;
69 | }
70 | }
71 | }
72 |
73 | public function get from():AnimState
74 | {
75 | return m_from;
76 | }
77 |
78 | public function get to():AnimState
79 | {
80 | return m_to;
81 | }
82 |
83 | public function set to(value:AnimState):void
84 | {
85 | m_arrow.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
86 | m_to = value;
87 | }
88 |
89 | private function onDestroy(e:Event):void
90 | {
91 | m_arrow.removeEventListener(MouseEvent.CLICK,onMouseClick);
92 | m_arrow.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
93 | m_arrow.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
94 | }
95 |
96 | public function destroy():void
97 | {
98 | if (m_arrow.parent)
99 | {
100 | m_arrow.parent.removeChild(m_arrow);
101 | }
102 | }
103 |
104 | public function get isSelected():Boolean
105 | {
106 | return m_isSelected;
107 | }
108 |
109 | public function set isSelected(bool:Boolean):void
110 | {
111 | if (bool)
112 | {
113 | var filter:Array = [new GlowFilter(0xff0000, 1.0, 2.0, 2.0, 20, 1, true, false)];
114 | m_arrow.filters = filter;
115 | } else {
116 | m_arrow.filters = null;
117 | }
118 | m_isSelected = bool;
119 | }
120 |
121 | public function draw():void
122 | {
123 | var fromCenter:Point = new Point(m_from.x + m_from.width / 2, m_from.y + m_from.height / 2);
124 | var toCenter:Point;
125 | if(m_to){
126 | toCenter = new Point(m_to.x + m_to.width / 2, m_to.y + m_to.height / 2);
127 | }else{
128 | toCenter = new Point(m_arrow.stage.mouseX, m_arrow.stage.mouseY);
129 | toCenter = m_arrow.parent.globalToLocal(toCenter);
130 | }
131 | m_arrow.graphics.clear();
132 | m_arrow.graphics.lineStyle(3,0x000000,0.7);
133 | var len:int = 10;//箭头长度
134 | var _a:int = 8;//箭头与直线的夹角
135 | var angle:int = Math.atan2((fromCenter.y-toCenter.y), (fromCenter.x-toCenter.x))*(180/Math.PI);
136 | //防止双向Transition重合,重新确定端点
137 | var begin:Point = fromCenter;
138 | var end:Point = toCenter;
139 | if(m_to){
140 | begin = new Point(fromCenter.x + 5*Math.cos((angle+90)*(Math.PI/180)), fromCenter.y + 5*Math.sin((angle+90)*(Math.PI/180)));
141 | end = new Point(toCenter.x + 5*Math.cos((angle+90)*(Math.PI/180)), toCenter.y + 5*Math.sin((angle+90)*(Math.PI/180)));
142 | }
143 | var arrowPt:Point = new Point((begin.x+end.x)/2, (begin.y+end.y)/2);
144 | m_arrow.graphics.moveTo(arrowPt.x, arrowPt.y);
145 | m_arrow.graphics.lineTo(arrowPt.x+len*Math.cos((angle-_a)*(Math.PI/180)), arrowPt.y+len*Math.sin((angle-_a)*(Math.PI/180)));
146 | m_arrow.graphics.moveTo(arrowPt.x, arrowPt.y);
147 | m_arrow.graphics.lineTo(arrowPt.x+len*Math.cos((angle+_a)*(Math.PI/180)), arrowPt.y+len*Math.sin((angle+_a)*(Math.PI/180)));
148 | m_arrow.graphics.moveTo(begin.x,begin.y);
149 | m_arrow.graphics.lineTo(end.x,end.y);
150 | }
151 |
152 | private function onMouseMove(e:MouseEvent):void
153 | {
154 | draw();
155 | }
156 |
157 | private function onMouseUp(e:MouseEvent):void
158 | {
159 | var state:AnimState = EditController.getInstance().getStateByMouse(new Point(m_arrow.stage.mouseX, m_arrow.stage.mouseY));
160 | if(state && !to && !state.isAnyState){
161 | to = state;
162 | draw();
163 | EditController.getInstance().checkTransitionExist(this);
164 | }
165 | }
166 |
167 | private function onMouseClick(e:MouseEvent):void
168 | {
169 | if(m_to){
170 | EditController.getInstance().curArrow = this;
171 | }
172 | }
173 | }
174 | }
--------------------------------------------------------------------------------
/src/com/wonder/Condition.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | public class Condition
4 | {
5 | private var m_parameter:Parameter;
6 | private var m_value:int = 0;
7 | private var m_logic:int = 0;
8 |
9 | public static var LOGIC_EQUAL:int = 0;
10 | public static var LOGIC_GREATER:int = 1;
11 | public static var LOGIC_LESS:int = 2;
12 | public static var LOGIC_NOTEQUAL:int = 3;
13 |
14 | public function Condition(param:Parameter)
15 | {
16 | parameter = param;
17 | }
18 |
19 | public function get parameter():Parameter
20 | {
21 | return m_parameter;
22 | }
23 |
24 | public function set parameter(value:Parameter):void
25 | {
26 | m_parameter = value;
27 | }
28 |
29 | public function get id():String
30 | {
31 | return m_parameter.id;
32 | }
33 |
34 | public function set id(value:String):void
35 | {
36 | m_parameter.id = value;
37 | }
38 |
39 | public function get type():int
40 | {
41 | return m_parameter.type;
42 | }
43 |
44 | public function set type(value:int):void
45 | {
46 | m_parameter.type = value;
47 | }
48 |
49 | public function get value():int
50 | {
51 | return m_value;
52 | }
53 |
54 | public function set value(value:int):void
55 | {
56 | m_value = value;
57 | }
58 |
59 | public function get logic():int
60 | {
61 | return m_logic;
62 | }
63 |
64 | public function set logic(value:int):void
65 | {
66 | m_logic = value;
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/src/com/wonder/DataParser.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | import flash.events.Event;
4 | import flash.events.FileListEvent;
5 | import flash.filesystem.File;
6 | import flash.filesystem.FileMode;
7 | import flash.filesystem.FileStream;
8 | import flash.net.FileFilter;
9 |
10 | public class DataParser
11 | {
12 | private static var FILETYPE_SKELETON:int = 1;
13 | private static var FILETYPE_FSM:int = 2;
14 |
15 | private static function generateJson(stateArr:Array,transitionArr:Array,paramArr:Array,armatureInfo:Object):String
16 | {
17 | var output:String = "";
18 | var stateJsonArr:Array = new Array();
19 | for each (var state:AnimState in stateArr)
20 | {
21 | var stateObj:Object = new Object();
22 | stateObj["state"] = state.id;
23 | stateObj["animation"] = state.animation;
24 | stateObj["transition"] = new Array();
25 | stateObj["x"] = state.x;
26 | stateObj["y"] = state.y;
27 | if (state.isDefaultState)
28 | {
29 | stateObj.default = true;
30 | }
31 | for each (var transition:AnimTransition in transitionArr)
32 | {
33 | if (transition.from == state)
34 | {
35 | var transitionObj:Object = new Object();
36 | transitionObj["nextState"] = transition.to.id;
37 | transitionObj.condition = new Array();
38 | for each (var condition:Condition in transition.conditionArray)
39 | {
40 | if (condition.type == Parameter.TYPE_COMPLETE)
41 | {
42 | condition.id = Parameter.COMPLETE_ID;
43 | }
44 | if (condition.id)
45 | {
46 | var conditionObj:Object = new Object();
47 | conditionObj["id"] = condition.id;
48 | conditionObj["type"] = condition.type;
49 | conditionObj["logic"] = condition.logic;
50 | conditionObj["value"] = condition.value;
51 | transitionObj.condition.push(conditionObj);
52 | }
53 | }
54 | stateObj.transition.push(transitionObj);
55 | }
56 | }
57 | stateJsonArr.push(stateObj);
58 | }
59 | var paramJsonArr:Array = new Array();
60 | for each (var param:Parameter in paramArr)
61 | {
62 | paramJsonArr.push({"id":param.id, "type":param.type});
63 | }
64 | return JSON.stringify({"state":stateJsonArr, "parameter":paramArr, "armatureInfo":armatureInfo});
65 | }
66 |
67 | private static function saveFile(fileName:String, content:String):void
68 | {
69 | var fileToSave:File = File.documentsDirectory;
70 | fileToSave = fileToSave.resolvePath(fileName);
71 | fileToSave.browseForSave("Select Directory");
72 | fileToSave.addEventListener(Event.SELECT, directorySelected);
73 |
74 | function directorySelected(event:Event):void
75 | {
76 | var file:File = event.target as File;
77 | var fileStream:FileStream = new FileStream();
78 | fileStream.open(file, FileMode.WRITE);
79 | fileStream.writeUTFBytes(content);
80 | }
81 | }
82 |
83 | public static function browseForOpenFile():void
84 | {
85 | var fileToSave:File = File.documentsDirectory;
86 | fileToSave.browseForOpenMultiple("Select Directory",[new FileFilter("Text", "*.json")]);
87 | fileToSave.addEventListener(FileListEvent.SELECT_MULTIPLE, onFileSelect);
88 | function onFileSelect(event:FileListEvent):void
89 | {
90 | parseFiles(event.files);
91 | }
92 | }
93 |
94 | public static function parseFiles(files:Array):void
95 | {
96 | if(files.length == 1){
97 | parseSingleFile(files[0]);
98 | }else{
99 | for (var i:int = 0; i < files.length; i++)
100 | {
101 | var file:File = files[i];
102 | parseSingleFile(file);
103 | }
104 | }
105 | }
106 |
107 | private static function parseSingleFile(file:File):void
108 | {
109 | var fs:FileStream = new FileStream();
110 | fs.open(File(file),FileMode.READ);
111 | var content:String = fs.readUTFBytes(fs.bytesAvailable);
112 | fs.close();
113 |
114 | var type:int;
115 | if (file.name.indexOf("fsm.json") != -1)
116 | {
117 | type = FILETYPE_FSM;
118 | }
119 | else if (file.name.indexOf("skeleton.json") != -1)
120 | {
121 | type = FILETYPE_SKELETON;
122 | }
123 |
124 | switch(type)
125 | {
126 | case FILETYPE_SKELETON:
127 | {
128 | var obj:Object = JSON.parse(content);
129 | var stateStrArr:Array = new Array();
130 | var animationArr:Array = new Array();
131 | for each (var ani:Object in obj["armature"][0]["animation"])
132 | {
133 | stateStrArr.push({"state":ani["name"],"animation":ani["name"]});
134 | if (animationArr.indexOf(ani["name"]) == -1)
135 | {
136 | animationArr.push(ani["name"]);
137 | }
138 | }
139 | EditController.getInstance().addStates(stateStrArr);
140 | EditController.getInstance().armatureInfo[obj["armature"][0]["name"]] = animationArr;
141 | break;
142 | }
143 | case FILETYPE_FSM:
144 | {
145 | var contentObj:Object = JSON.parse(content);
146 | var stateArr:Array = contentObj["state"];
147 | var paramArr:Array = contentObj["parameter"];
148 | var armatureInfo:Object = contentObj["armatureInfo"];
149 | var stateStrArray:Array = new Array();
150 | for each (var oneStateObj:Object in stateArr)
151 | {
152 | if (oneStateObj["state"] != AnimState.ANYSTATE_ID)
153 | {
154 | stateStrArray.push({"state":oneStateObj["state"],"animation":oneStateObj["animation"],"default":oneStateObj["default"]});
155 | }
156 | }
157 | EditController.getInstance().initStates(stateStrArray,file.name.split(".")[0]);
158 | for each (var state:AnimState in EditController.getInstance().stateArray)
159 | {
160 | for each (var stateObj:Object in stateArr)
161 | {
162 | if (stateObj["state"] == state.id)
163 | {
164 | state.x = stateObj["x"];
165 | state.y = stateObj["y"];
166 | for each (var transitionObj:Object in stateObj["transition"])
167 | {
168 | var transition:AnimTransition = EditController.getInstance().makeTransition(state,false);
169 | transition.to = EditController.getInstance().getStateById(transitionObj["nextState"]);
170 | for each (var conditionObj:Object in transitionObj.condition)
171 | {
172 | var condition:Condition = transition.addCondition();
173 | condition.id = conditionObj["id"];
174 | condition.type = conditionObj["type"];
175 | condition.logic = conditionObj["logic"];
176 | condition.value = conditionObj["value"];
177 | }
178 | }
179 | }
180 | EditController.getInstance().updateArrow(state);
181 | }
182 | }
183 | for each (var oneParamObj:Object in paramArr)
184 | {
185 | EditController.getInstance().addParam(new Parameter(oneParamObj["id"], oneParamObj["type"]));
186 | }
187 | EditController.getInstance().armatureInfo = armatureInfo;
188 | break;
189 | }
190 | default:
191 | {
192 | break;
193 | }
194 | }
195 | }
196 |
197 | public static function saveFsmJson(fileName:String,stateArr:Array,transitionArr:Array,paramArr:Array,armatureInfo:Object):void
198 | {
199 | saveFile(fileName+(fileName.indexOf("fsm") == -1?"_fsm.json":".json"),generateJson(stateArr,transitionArr,paramArr,armatureInfo));
200 | }
201 | }
202 | }
--------------------------------------------------------------------------------
/src/com/wonder/DragSprite.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | import flash.display.Sprite;
4 | import flash.display.StageQuality;
5 | import flash.events.Event;
6 | import flash.events.MouseEvent;
7 | import flash.geom.Rectangle;
8 |
9 | public class DragSprite extends Sprite
10 | {
11 | private var m_isDrag:Boolean;
12 | private var m_border:int = 5;
13 | public function DragSprite()
14 | {
15 | addEventListener(Event.ADDED_TO_STAGE,onAdd);
16 | addEventListener(Event.REMOVED_FROM_STAGE,onRemoveEvent);
17 | }
18 |
19 | public function get isDrag():Boolean
20 | {
21 | return m_isDrag;
22 | }
23 |
24 | protected function onAdd(event:Event):void
25 | {
26 | removeEventListener(Event.ADDED_TO_STAGE,onAdd);
27 | addEventListener(MouseEvent.MOUSE_OVER,onIn);
28 | }
29 |
30 | protected function onRemoveEvent(e:Event=null):void
31 | {
32 | removeEventListener(MouseEvent.MOUSE_OVER,onIn);
33 | onOut();
34 | }
35 |
36 | protected function onIn(event:MouseEvent):void
37 | {
38 | addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
39 | addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
40 | addEventListener(MouseEvent.MOUSE_MOVE,onMove);
41 | addEventListener(MouseEvent.MOUSE_OUT,onOut);
42 | addEventListener(MouseEvent.RIGHT_MOUSE_DOWN,onOut);
43 | }
44 |
45 | protected function onRelease(event:MouseEvent = null):void
46 | {
47 | m_isDrag = false;
48 | }
49 |
50 | protected function onOut(event:MouseEvent = null):void
51 | {
52 | m_isDrag = false;
53 | removeEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
54 | removeEventListener(MouseEvent.MOUSE_UP,onMouseUp);
55 | removeEventListener(MouseEvent.MOUSE_MOVE,onMove);
56 | removeEventListener(MouseEvent.MOUSE_OUT,onOut);
57 | removeEventListener(MouseEvent.RIGHT_MOUSE_DOWN,onOut);
58 | removeEventListener(Event.REMOVED_FROM_STAGE,onRemoveEvent);
59 | }
60 |
61 | protected function onMove(e:MouseEvent):void
62 | {
63 | if(m_isDrag){
64 | this.startDrag(false);
65 | if(stage)stage.quality = StageQuality.LOW;
66 | }
67 | e.stopImmediatePropagation();
68 | }
69 |
70 | protected function onMouseUp(e:MouseEvent):void
71 | {
72 | m_isDrag = false;
73 | this.stopDrag();
74 | x = int(x);
75 | y = int(y);
76 | if(stage)stage.quality = StageQuality.BEST;
77 | }
78 |
79 | protected function onMouseDown(e:MouseEvent):void
80 | {
81 | m_isDrag = true;
82 | e.stopImmediatePropagation();
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/src/com/wonder/EditController.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | import flash.display.Sprite;
4 | import flash.events.MouseEvent;
5 | import flash.geom.Point;
6 | import flash.geom.Rectangle;
7 |
8 | import mx.collections.ArrayCollection;
9 | import mx.controls.Alert;
10 |
11 | import spark.components.Button;
12 | import spark.components.DropDownList;
13 | import spark.components.HGroup;
14 | import spark.components.Image;
15 | import spark.components.Panel;
16 | import spark.components.Scroller;
17 | import spark.components.TextInput;
18 | import spark.components.VGroup;
19 | import spark.components.supportClasses.SkinnableComponent;
20 | import spark.events.IndexChangeEvent;
21 | import spark.events.TextOperationEvent;
22 | import spark.layouts.VerticalAlign;
23 |
24 | public class EditController
25 | {
26 | private static var _instance:EditController;
27 | private var m_editLayer:Sprite;
28 | private var m_inspector:VGroup;
29 | private var m_stateInputer:TextInput;
30 | private var m_animationInputer:TextInput;
31 | private var m_stateArray:Array;
32 | private var m_transitionArray:Array;
33 | private var m_paramArray:Array;
34 | private var m_defaultState:AnimState = null;
35 | private var m_arrowContainer:Sprite;
36 | private var m_curArrow:AnimTransition = null;
37 | private var m_skeletonName:String;
38 | private var m_curState:AnimState = null;
39 | private var INPUT_ID:String = "input";
40 | private var LOGIC_ID:String = "logic";
41 | private var VALUE_ID:String = "value";
42 | private var REMOVE_ID:String = "remove";
43 | private var m_paramList:VGroup;
44 | private var m_paramScroller:Scroller;
45 | private var m_paramPanel:Panel;
46 | private var m_armatureInfo:Object;
47 |
48 | public static function getInstance():EditController
49 | {
50 | return _instance;
51 | }
52 |
53 | public function EditController(main:Animator)
54 | {
55 | m_editLayer = main.editLayer;
56 | m_inspector = main.transitionInspector;
57 | m_stateInputer = main.stateIdInputer;
58 | m_animationInputer = main.animationInputer;
59 | m_paramList = main.paramList;
60 | m_paramScroller = main.paramScroller;
61 | m_paramPanel = main.paramPanel;
62 | _instance = this;
63 | initStates();
64 | m_stateInputer.addEventListener(TextOperationEvent.CHANGE,function(e:TextOperationEvent):void{
65 | m_curState.id = e.target.text;
66 | })
67 | m_animationInputer.addEventListener(TextOperationEvent.CHANGE,function(e:TextOperationEvent):void{
68 | m_curState.animation = e.target.text;
69 | })
70 | }
71 |
72 | private function checkStateIdExist(id:String):Boolean
73 | {
74 | for (var i:int = 0; i < m_stateArray.length; i++)
75 | {
76 | var element:AnimState = m_stateArray[i] as AnimState;
77 | if (id == element.id)
78 | {
79 | Alert.show("State Already Exists!");
80 | return true;
81 | }
82 | }
83 | return false;
84 | }
85 |
86 | private function generateNewStateId(id:String):String
87 | {
88 | if (id.indexOf("Untitled") == -1)
89 | {
90 | return checkStateIdExist(id)?id+"(new)":id;
91 | }
92 | var max:int = -1;
93 | for (var i:int = 0; i < m_stateArray.length; i++)
94 | {
95 | var element:AnimState = m_stateArray[i] as AnimState;
96 | if (element.id.indexOf("Untitled") != -1)
97 | {
98 | var arr:Array = element.id.split("Untitled");
99 | if (arr.length > 1)
100 | {
101 | max = Math.max(max, parseInt(arr[1]));
102 | }
103 | }
104 | }
105 | return "Untitled"+(max+1);
106 | }
107 |
108 | public function addState(id:String = "Untitled", x:Number = 0, y:Number = 0):AnimState
109 | {
110 | var state:AnimState = new AnimState(generateNewStateId(id));
111 | state.x = x;
112 | state.y = y;
113 | m_editLayer.addChild(state);
114 | m_stateArray.push(state);
115 | return state;
116 | }
117 |
118 | public function removeState(state:AnimState):void
119 | {
120 | for (var i:int = 0; i < m_stateArray.length; i++)
121 | {
122 | var oneState:AnimState = m_stateArray[i];
123 | if(oneState == state){
124 | for (var j:int = 0; j < m_transitionArray.length; j++)
125 | {
126 | var oneTransition:AnimTransition = m_transitionArray[j];
127 | if(oneTransition.to == state || oneTransition.from == state){
128 | m_transitionArray.splice(j,1);
129 | oneTransition.destroy();
130 | j--;
131 | }
132 | }
133 | m_stateArray.splice(i,1);
134 | state.destroy();
135 | return;
136 | }
137 | }
138 | }
139 |
140 | public function reset():void
141 | {
142 | m_editLayer.removeChildren();
143 | m_inspector.removeAllElements();
144 | m_paramList.removeAllElements();
145 | m_stateArray = new Array();
146 | m_transitionArray = new Array();
147 | m_arrowContainer = new Sprite();
148 | m_curArrow = null;
149 | m_curState = null;
150 | m_editLayer.addChild(m_arrowContainer);
151 | m_paramArray = new Array();
152 | m_paramArray.push(new Parameter(Parameter.COMPLETE_ID, Parameter.TYPE_COMPLETE));
153 | m_armatureInfo = new Object();
154 | }
155 |
156 | public function initStates(input:Array = null,skeletonName:String = "fsm"):void
157 | {
158 | reset();
159 | m_skeletonName = skeletonName;
160 | if (input && input.length > 0)
161 | {
162 | for (var i:int = 0; i < input.length; i++)
163 | {
164 | var stateName:String = input[i]["state"];
165 | var animation:String = input[i]["animation"];
166 | var isDefault:Boolean = input[i]["default"];
167 | var state:AnimState = addState(stateName, m_editLayer.width / 2 - 200 + 250*Math.cos(i/input.length*Math.PI-Math.PI*0.75), m_editLayer.height / 2 + 250*Math.sin(i/input.length*Math.PI-Math.PI*0.75));
168 | state.animation = animation;
169 | if(isDefault){
170 | setDefaultState(state);
171 | }
172 | }
173 | var anyState:AnimState = addState(AnimState.ANYSTATE_ID, m_editLayer.width / 7 * 3, m_editLayer.height / 2);
174 | }
175 | }
176 |
177 | public function addStates(input:Array):void
178 | {
179 | if (input && input.length > 0)
180 | {
181 | for (var i:int = 0; i < input.length; i++)
182 | {
183 | var stateName:String = input[i]["state"];
184 | var animation:String = input[i]["animation"];
185 | var state:AnimState = addState(stateName, m_editLayer.width / 2 - 200 + 250*Math.cos((i+m_stateArray.length)/input.length*Math.PI-Math.PI*0.75), m_editLayer.height / 2 + 250*Math.sin((i+m_stateArray.length)/input.length*Math.PI-Math.PI*0.75));
186 | state.animation = animation;
187 | }
188 | }
189 | }
190 |
191 | public function set paramArray(value:Array):void
192 | {
193 | m_paramArray = value;
194 | }
195 |
196 | public function get paramArray():Array
197 | {
198 | return m_paramArray;
199 | }
200 |
201 | public function get stateArray():Array
202 | {
203 | return m_stateArray;
204 | }
205 |
206 | public function get skeletonName():String
207 | {
208 | return m_skeletonName;
209 | }
210 |
211 | public function get arrowContainer():Sprite
212 | {
213 | return m_arrowContainer;
214 | }
215 |
216 | public function get curArrow():AnimTransition
217 | {
218 | return m_curArrow;
219 | }
220 |
221 | public function set curArrow(value:AnimTransition):void
222 | {
223 | if (m_curArrow)
224 | {
225 | m_curArrow.isSelected = false;
226 | }
227 | m_curArrow = value;
228 | if (value)
229 | {
230 | value.isSelected = true;
231 | }
232 | updateTransitionInspector(m_curArrow);
233 | }
234 |
235 | public function get curState():AnimState
236 | {
237 | return m_curState;
238 | }
239 |
240 | public function set curState(value:AnimState):void
241 | {
242 | if (m_curState)
243 | {
244 | m_curState.isSelected = false;
245 | }
246 | m_curState = value;
247 | if (value)
248 | {
249 | value.isSelected = true;
250 | }
251 | updateStateInfo(m_curState);
252 | }
253 |
254 | private function checkParamExist(param:Parameter):Boolean
255 | {
256 | for (var i:int = 0; i < m_paramArray.length; i++)
257 | {
258 | var element:Parameter = m_paramArray[i] as Parameter;
259 | if (param.id == element.id)
260 | {
261 | return true;
262 | }
263 | }
264 | return false;
265 | }
266 |
267 | public function addParam(param:Parameter):void
268 | {
269 | if (checkParamExist(param))
270 | {
271 | if(param.id != Parameter.COMPLETE_ID){
272 | Alert.show("Parameter Already Exists!");
273 | }
274 | return;
275 | }
276 | m_paramArray.push(param);
277 | var hGroup:HGroup = new HGroup();
278 | hGroup.verticalAlign = VerticalAlign.MIDDLE;
279 | var input:TextInput = new TextInput();
280 | input.text = param.id;
281 | input.addEventListener(TextOperationEvent.CHANGE,function(e:TextOperationEvent):void{
282 | param.id = e.target.text;
283 | updateTransitionInspector(m_curArrow);
284 | })
285 | input.width = 60;
286 | var type:DropDownList = new DropDownList();
287 | type.dataProvider = new ArrayCollection([
288 | {id:Parameter.TYPE_BOOL,label:'bool'},
289 | {id:Parameter.TYPE_NUMBER,label:'number'},
290 | {id:Parameter.TYPE_TRIGGER,label:'trigger'}
291 | ]);
292 | type.width = 80;
293 | type.selectedIndex = param.type - Parameter.TYPE_BOOL;
294 | type.addEventListener(IndexChangeEvent.CHANGING,function(e:IndexChangeEvent):void{
295 | param.type = type.selectedItem.id;
296 | updateTransitionInspector(m_curArrow);
297 | });
298 | var remove:Image = new Image();
299 | remove.source = "assets/-.png";
300 | remove.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
301 | EditController.getInstance().removeParam(param);
302 | m_paramList.removeElement(hGroup);
303 | updateTransitionInspector(m_curArrow);
304 | });
305 | hGroup.addElement(input);
306 | hGroup.addElement(type);
307 | hGroup.addElement(remove);
308 | m_paramList.addElement(hGroup);
309 | if (m_paramPanel.height < m_paramPanel.maxHeight)
310 | {
311 | m_paramPanel.height += 30;
312 | }
313 | m_paramScroller.validateNow();
314 | m_paramScroller.viewport.verticalScrollPosition=m_paramScroller.viewport.contentHeight;
315 | updateTransitionInspector(m_curArrow);
316 | }
317 |
318 | public function removeParam(param:Parameter):void
319 | {
320 | for (var i:int = 0; i < m_paramArray.length; i++)
321 | {
322 | var oneParam:Parameter = m_paramArray[i];
323 | if(param == oneParam){
324 | m_paramArray.splice(i,1);
325 | return;
326 | }
327 | }
328 | }
329 |
330 | private function updateTransitionInspector(transition:AnimTransition):void
331 | {
332 | m_inspector.removeAllElements();
333 | if (transition)
334 | {
335 | for (var i:int = 0; i < transition.conditionArray.length; i++)
336 | {
337 | var element:Condition = transition.conditionArray[i] as Condition;
338 | m_inspector.addElement(createConditionContent(element,transition));
339 | }
340 | var hGroup:HGroup = new HGroup();
341 | var add:Button = new Button();
342 | add.width = 150;
343 | add.label = "+ Add Condition";
344 | add.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
345 | transition.addCondition();
346 | updateTransitionInspector(transition);
347 | });
348 | hGroup.addElement(add);
349 | m_inspector.addElement(add);
350 | }
351 | }
352 |
353 | private function createConditionContent(condition:Condition,transition:AnimTransition):HGroup
354 | {
355 | var hGroup:HGroup = new HGroup();
356 | hGroup.verticalAlign = VerticalAlign.MIDDLE;
357 | var type:DropDownList = new DropDownList();
358 | var array:Array = new Array();
359 | for (var i:int = 0; i < m_paramArray.length; i++)
360 | {
361 | var param:Parameter = m_paramArray[i] as Parameter;
362 | array.push({label:param.id, parameter:param});
363 | if(condition.id == param.id){
364 | type.selectedIndex = i;
365 | }
366 | }
367 | type.dataProvider = new ArrayCollection(array);
368 | type.width = 90;
369 | type.addEventListener(IndexChangeEvent.CHANGING,function(e:IndexChangeEvent):void{
370 | changeParameter(condition,transition,hGroup,type.selectedItem.parameter);
371 | });
372 | hGroup.addElement(type);
373 | changeParameter(condition,transition,hGroup,condition.parameter);
374 | return hGroup;
375 | }
376 |
377 | private function changeParameter(condition:Condition,transition:AnimTransition,hGroup:HGroup,param:Parameter):void
378 | {
379 | condition.parameter = param;
380 | for (var i:int = 0; i < hGroup.numElements; i++)
381 | {
382 | var element:SkinnableComponent = hGroup.getElementAt(i) as SkinnableComponent;
383 | if (element.id == LOGIC_ID || element.id == VALUE_ID || element.id == REMOVE_ID || element.id == INPUT_ID)
384 | {
385 | hGroup.removeElementAt(i);
386 | i--;
387 | }
388 | }
389 | switch(param.type)
390 | {
391 | case Parameter.TYPE_BOOL:
392 | {
393 | var boolValue:DropDownList = new DropDownList();
394 | boolValue.dataProvider = new ArrayCollection([
395 | {id:0,label:'false'},
396 | {id:1,label:'true'}
397 | ]);
398 | boolValue.width = 65;
399 | boolValue.id = VALUE_ID;
400 | boolValue.addEventListener(IndexChangeEvent.CHANGING,function(e:IndexChangeEvent):void{
401 | condition.value = boolValue.selectedItem.id;
402 | })
403 | hGroup.addElement(boolValue);
404 | condition.logic = Condition.LOGIC_EQUAL;
405 | boolValue.selectedIndex = condition.value;
406 | break;
407 | }
408 | case Parameter.TYPE_NUMBER:
409 | {
410 | var numLogic:DropDownList = new DropDownList();
411 | numLogic.dataProvider = new ArrayCollection([
412 | {id:Condition.LOGIC_EQUAL,label:'='},
413 | {id:Condition.LOGIC_GREATER,label:'>'},
414 | {id:Condition.LOGIC_LESS,label:'<'},
415 | {id:Condition.LOGIC_NOTEQUAL,label:'≠'}
416 | ]);
417 | numLogic.width = 65;
418 | numLogic.addEventListener(IndexChangeEvent.CHANGING,function(e:IndexChangeEvent):void{
419 | condition.logic = numLogic.selectedItem.id;;
420 | });
421 | var numValue:TextInput = new TextInput();
422 | numValue.width = 50;
423 | numValue.id = VALUE_ID;
424 | numValue.text = condition.value.toString();
425 | numValue.addEventListener(TextOperationEvent.CHANGE,function(e:TextOperationEvent):void{
426 | condition.value = parseInt(e.target.text);
427 | })
428 | numLogic.id = LOGIC_ID;
429 | hGroup.addElement(numLogic);
430 | hGroup.addElement(numValue);
431 | numLogic.selectedIndex = condition.logic;
432 | break;
433 | }
434 | case Parameter.TYPE_TRIGGER:
435 | {
436 | break;
437 | }
438 | case Parameter.TYPE_COMPLETE:
439 | {
440 | break;
441 | }
442 | default:
443 | {
444 | break;
445 | }
446 | }
447 | var remove:Image = new Image();
448 | remove.source = "assets/-.png";
449 | remove.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
450 | transition.removeCondition(condition);
451 | updateTransitionInspector(transition);
452 | });
453 | remove.id = REMOVE_ID;
454 | hGroup.addElement(remove);
455 | }
456 |
457 | public function get editLayer():Sprite
458 | {
459 | return m_editLayer;
460 | }
461 |
462 | public function get inspector():VGroup
463 | {
464 | return m_inspector;
465 | }
466 |
467 | public function setDefaultState(state:AnimState):void
468 | {
469 | if(m_defaultState){
470 | m_defaultState.isDefaultState = false;
471 | }
472 | state.isDefaultState = true;
473 | m_defaultState = state;
474 | }
475 |
476 | public function getStateById(id:String):AnimState
477 | {
478 | for each (var state:AnimState in m_stateArray)
479 | {
480 | if (state.id == id)
481 | {
482 | return state;
483 | }
484 | }
485 | return null;
486 | }
487 |
488 | public function getStateByMouse(pt:Point):AnimState
489 | {
490 | for each (var state:AnimState in m_stateArray)
491 | {
492 | var rect:Rectangle = state.getRect(state);
493 | var point:Point = state.globalToLocal(pt);
494 | if (rect.containsPoint(point))
495 | {
496 | return state;
497 | }
498 | }
499 | return null;
500 | }
501 |
502 | public function updateStateInfo(state:AnimState):void
503 | {
504 | m_stateInputer.text = state.id;
505 | m_animationInputer.text = state.animation;
506 | }
507 |
508 | public function makeTransition(state:AnimState,addDefaultCondition:Boolean = true):AnimTransition
509 | {
510 | var transition:AnimTransition = new AnimTransition(state);
511 | m_transitionArray.push(transition);
512 | if (addDefaultCondition)
513 | {
514 | transition.addCondition();
515 | }
516 | return transition;
517 | }
518 |
519 | public function updateArrow(state:AnimState):void
520 | {
521 | for each (var transition:AnimTransition in m_transitionArray)
522 | {
523 | if(transition.from == state || transition.to == state){
524 | transition.draw();
525 | }
526 | }
527 | }
528 |
529 | public function checkTransitionExist(transition:AnimTransition):void
530 | {
531 | for each (var oneTransition:AnimTransition in m_transitionArray)
532 | {
533 | if(oneTransition != transition && oneTransition.from == transition.from && oneTransition.to == transition.to){
534 | removeTransition(transition);
535 | Alert.show("Transition Already Exists!")
536 | return;
537 | }
538 | }
539 | }
540 |
541 | public function removeTransition(transition:AnimTransition):void
542 | {
543 | for (var i:int = 0; i < m_transitionArray.length; i++)
544 | {
545 | var oneTransition:AnimTransition = m_transitionArray[i];
546 | if(oneTransition == transition){
547 | m_transitionArray.splice(i,1);
548 | oneTransition.destroy();
549 | return;
550 | }
551 | }
552 | }
553 |
554 | public function hasDragState():Boolean
555 | {
556 | for each (var state:AnimState in m_stateArray)
557 | {
558 | if (state.isDrag)
559 | {
560 | return true;
561 | }
562 | }
563 | return false;
564 | }
565 |
566 | public function get armatureInfo():Object
567 | {
568 | return m_armatureInfo;
569 | }
570 |
571 | public function set armatureInfo(value:Object):void
572 | {
573 | m_armatureInfo = value;
574 | }
575 |
576 | public function save():void
577 | {
578 | DataParser.saveFsmJson(m_skeletonName, m_stateArray, m_transitionArray, m_paramArray, m_armatureInfo);
579 | }
580 | }
581 | }
--------------------------------------------------------------------------------
/src/com/wonder/Parameter.as:
--------------------------------------------------------------------------------
1 | package com.wonder
2 | {
3 | public class Parameter
4 | {
5 | public static var COMPLETE_ID:String = "complete";
6 | public static var DEFAULT_ID:String = "unused";
7 |
8 | public static var TYPE_COMPLETE:int = 0;
9 | public static var TYPE_BOOL:int = 1;
10 | public static var TYPE_NUMBER:int = 2;
11 | public static var TYPE_TRIGGER:int = 3;
12 |
13 | private var m_id:String = null;
14 | private var m_type:int = 0;
15 |
16 | public function Parameter(id:String="unused",type:int=3)
17 | {
18 | m_id = id;
19 | m_type = type;
20 | }
21 |
22 | public function get id():String
23 | {
24 | return m_id;
25 | }
26 |
27 | public function set id(value:String):void
28 | {
29 | m_id = value;
30 | }
31 |
32 | public function get type():int
33 | {
34 | return m_type;
35 | }
36 |
37 | public function set type(value:int):void
38 | {
39 | m_type = value;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------