PageRenderTime 59ms CodeModel.GetById 12ms RepoModel.GetById 2ms app.codeStats 0ms

/com/lele/Controller/PlayerController.as

https://gitlab.com/Treeky-NULL/LezaiNiubi
ActionScript | 422 lines | 386 code | 14 blank | 22 comment | 79 complexity | 9ab36c9134b576a5d168b5042e797852 MD5 | raw file
  1. package com.lele.Controller
  2. {
  3. import adobe.utils.CustomActions;
  4. import com.lele.Controller.Avatar.ActionSuggest;
  5. import com.lele.Controller.Avatar.Events.Avatar_PlayerController_Event;
  6. import com.lele.Data.GloableData;
  7. import com.lele.Manager.Events.PLC_Player_ManagerEvent;
  8. import com.lele.Manager.GameManager;
  9. import com.lele.Map.BitMapUtil;
  10. import com.lele.Controller.Avatar.Enum.AvatarState;
  11. import com.lele.Controller.Avatar.Interface.IAvatar;
  12. import com.lele.Controller.Interface.IControlMap;
  13. import com.lele.Map.Interface.IClickAble;
  14. import com.lele.Map.Interface.ITrigger;
  15. import com.lele.Map.Interface.ITriggerArray;
  16. import com.lele.Plugin.RoadFind.Interface.IRoadFinder;
  17. import com.lele.Plugin.RoadFind.Interface.IRoadMap;
  18. import com.lele.Manager.Interface.IReport;
  19. import com.lele.Plugin.RoadFind.RoadFinder;
  20. import com.lele.MathTool.LeleMath;
  21. import flash.display.MovieClip;
  22. import flash.display.Sprite;
  23. import flash.events.Event;
  24. import flash.events.MouseEvent;
  25. import flash.events.TimerEvent;
  26. import flash.geom.Point;
  27. import flash.utils.Timer;
  28. /**
  29. * ...
  30. * @author Lele
  31. */
  32. //继承自ControllerBase的类,是基础的控制类,包装好了寻路功能,需要加入一个继承自IAvatar接口的图形显示
  33. public final class PlayerController extends ControllerBase implements IReport
  34. {
  35. private var _freeClock:Timer;//用来触发随机动作的时钟
  36. private var _avatar:IAvatar;
  37. private var _roadFinder:IRoadFinder;
  38. private var _roadMap:IRoadMap;
  39. private var _state:AvatarState;
  40. private var _triggerArray:ITriggerArray;//当碰到并且地点到时会触发的,触发器两种类型,这里使用的是长久站立触发
  41. private var _currentTarget:Point;
  42. private var _currentRoad:Array;
  43. private var _currentChange:Array;
  44. private var _preTarget:Point;
  45. private var _repoter:IReport;
  46. private var _currentMouseMoleDirection:String;
  47. private var _needBrake:Boolean;
  48. private const _brakeDistance:int = 50;
  49. private const _enbleBrakeDistance:int = 200;
  50. private var _rotateAround:Boolean = true;//转来转去
  51. private const _runSpeed:Number = 3.5;
  52. private const _swimSpeed:Number = 2;
  53. private var _speed:Number;
  54. private var _getNetAvatarArray:Function;
  55. public function PlayerController(repoter:IReport)
  56. {
  57. _speed = _runSpeed;
  58. _freeClock = new Timer(((Math.random()*10)+3)*1000);
  59. _freeClock.addEventListener(TimerEvent.TIMER, OnFree);
  60. _freeClock.start();
  61. _state = AvatarState.IDLE;//初始状态为静态站立
  62. _clickEnable = true;
  63. _repoter = repoter;
  64. }
  65. public function get AState():AvatarState
  66. {
  67. return _state;
  68. }
  69. public function Reset()
  70. {
  71. _speed = _runSpeed;
  72. _state = AvatarState.IDLE;
  73. _currentRoad = null;
  74. if (_avatar != null)
  75. {
  76. _preTarget=new Point(_avatar.A_X, _avatar.A_Y);
  77. _currentTarget = null;
  78. DoAction("stand");
  79. }
  80. }
  81. public function AvatarStateCheck()
  82. {
  83. if (_roadFinder == null) { return; }
  84. var tempState:int = _roadFinder.GetState(new Point(_avatar.A_X, _avatar.A_Y));
  85. if (tempState == 2 && _state != AvatarState.SWIM)//该游泳时不游泳
  86. {
  87. if (_state ==AvatarState.WALK)
  88. {
  89. _state = AvatarState.SWIM;
  90. directionHandle();
  91. }
  92. else
  93. {
  94. _state = AvatarState.SWIM;
  95. DoAction("swim", "rd");
  96. }
  97. _speed = _swimSpeed;//改变速度
  98. }
  99. else if (tempState != 2 && _state == AvatarState.SWIM)//不该游泳时游泳
  100. {
  101. _state = AvatarState.IDLE;
  102. _speed = _runSpeed;
  103. DoAction("stand", "dd");
  104. _needBrake = false;
  105. }
  106. }
  107. public function CreatController(roadMap:IRoadMap,avatar:IAvatar,controlMap:IControlMap,triggerArray:ITriggerArray)//现在用的是默认参数因为没有改的需要,以后抽象成config
  108. {
  109. _roadFinder = new RoadFinder();
  110. _avatar = avatar;
  111. _preTarget = new Point(_avatar.A_X, _avatar.A_Y);
  112. _avatar.Repoter = this;
  113. _triggerArray = triggerArray;
  114. _roadMap = roadMap;
  115. _controlMap = controlMap;
  116. var colorObj:Object = { canGo:4289555498, notGo:4294967295, special:4278229503 };
  117. var bitMapUtil:BitMapUtil = new BitMapUtil(roadMap.Type_mc, GloableData.MaxRoadMapSize.x, GloableData.MaxRoadMapSize.y, 2, colorObj);
  118. bitMapUtil.DrawPixelMap();
  119. _roadFinder.CreatRoadDataFromMapData(bitMapUtil);
  120. //要开启
  121. SwitchOn(_controlMap.Size_mc);
  122. }
  123. public function SetMsgDialog(dialog:Sprite)
  124. {
  125. if(_avatar!=null)
  126. _avatar.SetComDialog(dialog);
  127. }
  128. public function ShowMsgDialog(txt:String)//显示消息
  129. {
  130. _avatar.ShowDialog(txt);
  131. }
  132. public function MoveTo(po:Point)
  133. {
  134. var evt:MouseEvent = new MouseEvent(MouseEvent.CLICK);
  135. evt.localX = po.x;
  136. evt.localY = po.y;
  137. OnChildMouseClick(evt);
  138. }
  139. override protected function OnChildMouseClick(evt:MouseEvent)
  140. {
  141. var mbc:PLC_Player_ManagerEvent = new PLC_Player_ManagerEvent(PLC_Player_ManagerEvent.LOCALMAPCLICKED);
  142. mbc.LOCALMAPCLICKED_position = new Point(evt.localX, evt.localY);
  143. _repoter.OnReport(mbc);
  144. //当点击到可交互物件时,获取物件态度,没点到执行,点到看态度执行,这里由抽象父类调用
  145. //判断是否点击在玩家上
  146. _rotateAround = true;
  147. //当点击时自动重启旋转
  148. var source:Point = new Point(_avatar.Avatar.x, _avatar.Avatar.y);
  149. var target:Point = new Point(evt.localX, evt.localY);
  150. if (_preTarget.x==Math.round(evt.localX)&&_preTarget.y==Math.round(evt.localY)) { return; }//如果起点和终点一样驳回请求
  151. _preTarget = new Point(Math.round(evt.localX), Math.round(evt.localY));
  152. _roadFinder.FindRoad(source, CalculateTarget(source,target,4));
  153. _currentRoad = _roadFinder.RoadNode;
  154. _currentChange = _roadFinder.ChangeNode;
  155. _currentTarget = _currentRoad[0];//第一个点就是脚下的点方便判断方向
  156. if(_state!=AvatarState.WALK&&_state!=AvatarState.SWIM)
  157. _state = AvatarState.WALK;
  158. //准备网络事件
  159. var evtM:PLC_Player_ManagerEvent = new PLC_Player_ManagerEvent(PLC_Player_ManagerEvent.LOCALPLAYERMOVE);
  160. evtM.LOCALPLAYERMOVE_target = _currentRoad[_currentRoad.length - 1];
  161. _repoter.OnReport(evtM);
  162. //
  163. if (LeleMath.GetDistance(_currentRoad[_currentRoad.length-1], _currentRoad[_currentRoad.length-2]) > _enbleBrakeDistance) { _needBrake = true; }
  164. }
  165. override protected function EveryFrame(evt:Event)//故意留的bug
  166. {
  167. if (_state==AvatarState.WALK||_state==AvatarState.PLAY||_state==AvatarState.SWIM)//动画都在这
  168. {
  169. if (_currentTarget == null) { return; }
  170. if (Math.abs(_avatar.Avatar.x -_currentTarget.x)<_speed && Math.abs(_avatar.Avatar.y -_currentTarget.y)<_speed) //到节点触发
  171. {
  172. _avatar.Avatar.x = _currentTarget.x;
  173. _avatar.Avatar.y = _currentTarget.y;
  174. if (_currentChange != null&&_currentChange.length>0&& _currentTarget.equals(_currentChange[0]))
  175. {
  176. if (_state == AvatarState.WALK)
  177. {
  178. _state = AvatarState.SWIM;
  179. _speed = _swimSpeed;
  180. }
  181. else if (_state == AvatarState.SWIM)
  182. {
  183. _state = AvatarState.WALK;
  184. _speed = _runSpeed;
  185. }
  186. _currentChange.splice(0, 1);
  187. }
  188. if (_currentTarget.equals(_currentRoad[_currentRoad.length - 1]))//到了
  189. {
  190. if (_state == AvatarState.SWIM)
  191. {
  192. return;
  193. }
  194. _state = AvatarState.IDLE; //设置站立状态
  195. OnFreeActionStop();
  196. _avatar.DoAction("stand", LeleMath.GetDirection(LeleMath.DealRDifference(LeleMath.GetDigree(_currentRoad[_currentRoad.length - 2],_currentTarget))));
  197. TriggerCheckAndDispatchEvt(_currentTarget);//触发触发器
  198. }
  199. _currentTarget = _currentRoad[_currentRoad.indexOf(_currentTarget) + 1];
  200. directionHandle();
  201. return;//这里有一个return??????????????????????????????????????????????????????????//
  202. }
  203. //移动
  204. var tinyStep = LeleMath.GetDistance(new Point(_avatar.Avatar.x, _avatar.Avatar.y), _currentTarget)/_speed;
  205. _avatar.Avatar.x =_avatar.Avatar.x + (_currentTarget.x - _avatar.Avatar.x) / tinyStep;
  206. _avatar.Avatar.y = _avatar.Avatar.y + (_currentTarget.y - _avatar.Avatar.y) / tinyStep;
  207. //模拟刹车
  208. if (_needBrake&&_currentTarget.equals(_currentRoad[_currentRoad.length - 1])&&_state!=AvatarState.SWIM)
  209. {
  210. if ((int)(LeleMath.GetDistance(new Point(_avatar.A_X, _avatar.A_Y), _currentTarget)) <=_brakeDistance)
  211. {
  212. _avatar.DoAction("brake", directionHandle(false));
  213. _needBrake = false;
  214. }
  215. }
  216. //更新玩家坐标
  217. GloableData.AvatarPosition.x = _avatar.Avatar.x;
  218. GloableData.AvatarPosition.y = _avatar.Avatar.y;
  219. //更新地图坐标
  220. GameManager.GetICommand().UpdateMapPosition();
  221. }
  222. if (_state == AvatarState.IDLE)
  223. {//方向不一致才触发
  224. if (_rotateAround&&_currentMouseMoleDirection != LeleMath.GetDirection(LeleMath.DealRDifference(LeleMath.GetDigree(new Point(_avatar.A_X+GloableData.MapOffSetX, _avatar.A_Y+GloableData.MapOffSetY), new Point(mouseX, mouseY)))))
  225. {
  226. _currentMouseMoleDirection = LeleMath.GetDirection(LeleMath.DealRDifference(LeleMath.GetDigree(new Point(_avatar.A_X+GloableData.MapOffSetX, _avatar.A_Y+GloableData.MapOffSetY), new Point(mouseX, mouseY))));
  227. _avatar.DoAction("stand", _currentMouseMoleDirection);
  228. }
  229. }
  230. }
  231. public function set GetNetAvatarArray(func:Function)
  232. {
  233. _getNetAvatarArray = func;
  234. }
  235. override protected function get AdditionClickObj():Array //额外点击事件的接受对象
  236. {
  237. var temp:Array = new Array();
  238. if (_getNetAvatarArray != null)
  239. {
  240. _getNetAvatarArray(temp);
  241. }
  242. temp.push(_avatar);
  243. return temp;
  244. }
  245. public function DoAction(actionName:String,direction:String="dd",callBack:Function=null)
  246. {
  247. //在Avatar内会对actionName进行解释
  248. if (_state == AvatarState.SWIM && actionName != "swim") { return; }
  249. _avatar.DoAction(actionName,direction,callBack);
  250. }
  251. private function OnFree(evt:Event)//当长久站立,由FreeClock触发
  252. {
  253. //判断状态
  254. if (_state != AvatarState.IDLE||_state==AvatarState.SWIM || _avatar == null||_state==AvatarState.PLAY) { return; }
  255. //停止计时器
  256. _freeClock.stop();
  257. //切换状态
  258. _state = AvatarState.FREE;
  259. //随机选择动作
  260. var select:int = Math.round(Math.random() * 100);
  261. var actionSelected:String = "yawn";
  262. if (select <= 20)
  263. {
  264. actionSelected = "yawn";
  265. }
  266. else if (select <= 40)
  267. {
  268. actionSelected = "scratch_buns";
  269. }
  270. else if (select <= 60)
  271. {
  272. actionSelected = "scratch_nose";
  273. }
  274. else if (select <= 80)
  275. {
  276. actionSelected = "look";
  277. }
  278. else if (select <= 100)
  279. {
  280. actionSelected = "scratch_head";
  281. }
  282. DoAction(actionSelected, "dd", OnFreeActionStop);
  283. //构建并发送事件
  284. var evvt:PLC_Player_ManagerEvent = new PLC_Player_ManagerEvent(PLC_Player_ManagerEvent.LOCALPLAYERDOACTION);
  285. evvt.LOCALPLAYERDOACTION_dir = "dd";
  286. evvt.LOCALPLAYERDOACTION_name = actionSelected;
  287. _repoter.OnReport(evvt);
  288. }
  289. private function OnFreeActionStop()//回调
  290. {
  291. if (_state == AvatarState.SWIM) { return; }
  292. _freeClock.stop();
  293. _state = AvatarState.IDLE;
  294. var time:Number = Math.round(LeleMath.NextGaussian2(8, 5)) * 1000;
  295. if (time > 20000)
  296. {
  297. time = 20000;
  298. }
  299. _freeClock.delay = time;
  300. _freeClock.start();
  301. }
  302. private function CalculateTarget(source:Point, meansTarget:Point,offset:int):Point//得到一个差一点距离的点
  303. {
  304. if (LeleMath.GetDistance(source, meansTarget) < offset) { return meansTarget; }
  305. if (meansTarget.x > source.x)
  306. {
  307. meansTarget.x -= offset;
  308. }
  309. else
  310. {
  311. meansTarget.x += offset;
  312. }
  313. if (meansTarget.y > source.y)
  314. {
  315. meansTarget.y -= offset;
  316. }
  317. else
  318. {
  319. meansTarget.y += offset;
  320. }
  321. return meansTarget;
  322. }
  323. private function TriggerCheckAndDispatchEvt(checkPoint:Point)
  324. {
  325. var temp:Array = _triggerArray.TriggerArray;
  326. for (var a:int = 0; a <temp.length; a++ )
  327. {
  328. if ((temp[a] as ITrigger).IsMeetTerm(checkPoint))
  329. {
  330. (temp[a] as ITrigger).OnTrigge();
  331. }
  332. }
  333. }
  334. public function get State():AvatarState
  335. {
  336. return _state;
  337. }
  338. public function SetStatePlay()
  339. {
  340. if (_state == AvatarState.SWIM) { return; }
  341. _state = AvatarState.PLAY;
  342. }
  343. public function SetStateIdle()
  344. {
  345. if (_state == AvatarState.SWIM) { return; }
  346. _state = AvatarState.IDLE;
  347. OnFreeActionStop();
  348. }
  349. private function directionHandle(doAction:Boolean = true):String//右下优先原则//这个用于转化Avatar的内容
  350. {
  351. if (_currentTarget == null) { return "dd"; }//默认执行转向命令,false就否
  352. var dir:String;
  353. if (_avatar.Avatar.x - _currentTarget.x > 0)//先判断左右,,在左边
  354. {
  355. if (_avatar.Avatar.y - _currentTarget.y <= 0)//在下边
  356. {
  357. dir = "dl";
  358. }
  359. else//在上边
  360. {
  361. dir = "lu";
  362. }
  363. }
  364. else//在右边
  365. {
  366. if (_avatar.Avatar.y - _currentTarget.y <= 0)//在下边
  367. {
  368. dir = "rd";
  369. }
  370. else//在上边
  371. {
  372. dir = "ur";
  373. }
  374. }
  375. if (doAction)
  376. {
  377. if(_state==AvatarState.WALK)
  378. _avatar.DoAction("run", dir);
  379. if (_state == AvatarState.SWIM)
  380. _avatar.DoAction("swim", dir);
  381. }
  382. return dir;
  383. }
  384. public function OnReport(evt:Event):void
  385. {
  386. var event:Avatar_PlayerController_Event = evt as Avatar_PlayerController_Event;
  387. switch(event.EvtType)
  388. {
  389. case Avatar_PlayerController_Event.CALLOFFROTATEAROUND:
  390. {
  391. _rotateAround = false;
  392. return;
  393. }
  394. case Avatar_PlayerController_Event.CALLONROTATEAROUND:
  395. {
  396. _rotateAround = true;
  397. return;
  398. }
  399. case Avatar_PlayerController_Event.BECLICKED:
  400. {
  401. var evttt:PLC_Player_ManagerEvent = new PLC_Player_ManagerEvent(PLC_Player_ManagerEvent.LOCALPLAYERBECLICK);
  402. _repoter.OnReport(evttt);
  403. //trace("PlayerBeClick");
  404. }
  405. }
  406. }
  407. }
  408. }