GameController.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Learn TypeScript:
  2. // - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
  3. // Learn Attribute:
  4. // - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
  5. // Learn life-cycle callbacks:
  6. // - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
  7. import ConfigManager from "../../../engines/configs/ConfigManager";
  8. import { GUIManager } from "../../../engines/gui/GUIManager";
  9. import JLoader from "../../../engines/loader/JLoader";
  10. import LoadingView from "../../../engines/loadingView/LoadingView";
  11. import MathUtils from "../../../engines/utils/MathUtils";
  12. import ConfigKeys from "../../models/ConfigKeys";
  13. import GameModel from "../../models/GameModel";
  14. import UIKeys from "../../UIKeys";
  15. import InCirclePolygon from "./InCirclePolygon";
  16. import PlayerController from "./PlayerController";
  17. const {ccclass, property} = cc._decorator;
  18. @ccclass
  19. export default class GameController extends cc.Component {
  20. @property(cc.Node)
  21. camera: cc.Node = null;
  22. @property(cc.Node)
  23. polygon: cc.Node = null;
  24. @property(PlayerController)
  25. player: PlayerController = null;
  26. @property(cc.MeshRenderer)
  27. background:cc.MeshRenderer=null;
  28. /**
  29. * 游戏结束
  30. */
  31. isGameOver:boolean;
  32. private inCirclePolygon:InCirclePolygon;
  33. private isDrop:boolean;
  34. private startDropTime:number;
  35. /**
  36. * 移动向量
  37. */
  38. private moveVec:cc.Vec3=new cc.Vec3();
  39. levelConfig:any;
  40. carConfig:any;
  41. start () {
  42. GameController.__instance=this;
  43. //显示进度条
  44. LoadingView.single.Show();
  45. //关卡配置
  46. let levelConfigs:any[]=ConfigManager.single.GetConfigList(ConfigKeys.Levels);
  47. cc.log(GameModel.single.currentLevel);
  48. let level:number=GameModel.single.currentLevel%levelConfigs.length;
  49. if(level==0){
  50. level=1;
  51. }
  52. this.levelConfig=ConfigManager.single.GetConfigItem(ConfigKeys.Levels,level);
  53. //汽车配置
  54. this.carConfig=ConfigManager.single.GetConfigItem(ConfigKeys.Car,GameModel.single.currentCarId);
  55. this.LoadPolygon();
  56. }
  57. private loader:JLoader;
  58. private LoadPolygon():void{
  59. this.loader=new JLoader();
  60. this.loader.AddEvent(JLoader.EVENT_COMPLETE,this,this.PolygonLoaded);
  61. this.loader.Load(this.levelConfig.packageName,this.levelConfig.polygonPrefab);
  62. }
  63. private PolygonLoaded():void{
  64. let prefab:cc.Prefab=this.loader.GetContent(cc.Prefab) as cc.Prefab;
  65. let node:cc.Node=cc.instantiate(prefab);
  66. this.polygon.addChild(node);
  67. this.loader.RemoveAllEvent();
  68. this.loader.AddEvent(JLoader.EVENT_COMPLETE,this,this.CarLoaded);
  69. this.loader.Load(this.carConfig.packageName,this.carConfig.prefab);
  70. }
  71. private CarLoaded():void{
  72. let prefab:cc.Prefab=this.loader.GetContent(cc.Prefab) as cc.Prefab;
  73. let node:cc.Node=cc.instantiate(prefab);
  74. this.player.node.addChild(node);
  75. //喷气粒子
  76. this.player.particle=cc.find("ParticleRoot",node);
  77. if(this.player.particle!=null){
  78. this.player.particle.active=false;
  79. }
  80. this.loader.RemoveAllEvent();
  81. this.loader.AddEvent(JLoader.EVENT_COMPLETE,this,this.BackgroundLoaded);
  82. this.loader.Load("background",this.levelConfig.background);
  83. }
  84. private BackgroundLoaded():void{
  85. this.loader.RemoveAllEvent();
  86. let texture:cc.Texture2D=this.loader.GetContent(cc.Texture2D) as cc.Texture2D;
  87. let m:cc.Material=this.background.getMaterial(0);
  88. m.setProperty("diffuseTexture",texture);
  89. this.loader=null;
  90. this.InitGame();
  91. LoadingView.single.Hide();
  92. }
  93. private InitGame():void{
  94. this.inCirclePolygon=new InCirclePolygon(this.polygon);
  95. this.StartGame();
  96. }
  97. /**
  98. * 开始游戏
  99. */
  100. StartGame():void{
  101. if(this.player.particle!=null){
  102. this.player.particle.active=false;
  103. }
  104. this.isGameOver=false;
  105. this.isDrop=false;
  106. this.inCirclePolygon.Reset();
  107. this.player.Reset();
  108. }
  109. update (dt:number) {
  110. if(this.inCirclePolygon==null){
  111. return;
  112. }
  113. if(this.isGameOver){
  114. return;
  115. }
  116. cc.Vec3.zero(this.moveVec);
  117. //前进的速度
  118. cc.Vec3.add(this.moveVec,this.moveVec,this.player.speed);
  119. if(this.isDrop){
  120. cc.Vec3.add(this.moveVec,this.moveVec,this.player.dropSpeed);
  121. }else{
  122. if(this.player.isLeft){
  123. cc.Vec3.add(this.moveVec,this.moveVec,this.player.leftSpeed);
  124. }else if(this.player.isRight){
  125. cc.Vec3.add(this.moveVec,this.moveVec,this.player.rightSpeed);
  126. }
  127. //冲刺
  128. if(this.player.isSprint){
  129. cc.Vec3.add(this.moveVec,this.moveVec,this.player.sprintSpeed);
  130. }
  131. }
  132. cc.Vec3.multiplyScalar(this.moveVec,this.moveVec,dt);
  133. //角色移动
  134. let pos:cc.Vec3=this.player.logicPosition;
  135. pos.add(this.moveVec,pos);
  136. //将X轴环形映射
  137. pos.x=MathUtils.CircularMapping(pos.x,this.inCirclePolygon.maxX,this.inCirclePolygon.minX);
  138. this.player.logicPosition=pos;
  139. //背景跟角色使用保持固定的距离
  140. pos=this.background.node.position;
  141. pos.z=0-(this.player.logicPosition.y+1000);
  142. this.background.node.position=pos;
  143. //摄像机跟随
  144. if(!this.isDrop){
  145. pos=this.camera.position;
  146. pos.x=this.player.logicPosition.x;
  147. pos.y=this.inCirclePolygon.center.y;
  148. pos.z=-this.player.logicPosition.z+50;
  149. this.camera.position=pos;
  150. // cc.log("摄像机位置:",pos.x,pos.y,pos.z);
  151. }
  152. //物理计算
  153. if(!this.isDrop&&this.player.isSprint==false){
  154. this.CheckPhysicsPos();
  155. }
  156. this.CheckAngle();
  157. //多边形更新
  158. this.inCirclePolygon.Update(dt);
  159. //检测游戏是否结束
  160. if(this.isGameOver==false){
  161. if(this.isDrop){
  162. let currentTime:number=cc.sys.now();
  163. if(currentTime-this.startDropTime>2000){
  164. cc.log("游戏结束!");
  165. this.GameOver(false);
  166. }
  167. }else{
  168. if(this.player.logicPosition.z>this.levelConfig.endPos){
  169. cc.log("到达终点");
  170. this.GameOver(true);
  171. }
  172. }
  173. }
  174. }
  175. GameOver(isWin:boolean):void{
  176. this.isGameOver=true;
  177. GUIManager.single.Show(UIKeys.WXS04,true);
  178. if(isWin){
  179. GameModel.single.currentLevel++;
  180. GameModel.single.SaveToLoacl();
  181. }
  182. }
  183. private rectsTemp:number[];
  184. private point:cc.Vec3=new cc.Vec3();
  185. private origin:cc.Vec3=new cc.Vec3();
  186. /**
  187. * 计算角度
  188. */
  189. private CheckAngle():void{
  190. if(this.rectsTemp==null){
  191. this.rectsTemp=[];
  192. }
  193. this.inCirclePolygon.PolygonIntersects(this.player.rect,this.rectsTemp);
  194. if(this.rectsTemp.length==0){
  195. return;
  196. }
  197. if(this.rectsTemp.length>2){
  198. cc.error("主角的大小太大了!");
  199. return;
  200. }
  201. let angle:number;
  202. //在单独的一个块中
  203. if(this.rectsTemp.length==1){
  204. angle=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[0]);
  205. let aTile:cc.Rect=this.inCirclePolygon.GetPolygonTile(this.rectsTemp[0]);
  206. this.inCirclePolygon.SetAngle(angle);
  207. this.background.node.angle=angle;
  208. this.inCirclePolygon.SetCenter(aTile.x+aTile.width*0.5,this.inCirclePolygon.centerHeight,0);
  209. }else{//跨块了
  210. let aAngle:number=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[0]);
  211. let bAngle:number=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[1]);
  212. let aTile:cc.Rect=this.inCirclePolygon.GetPolygonTile(this.rectsTemp[0]);
  213. //计算出旋转点
  214. let cx:number=aTile.x+aTile.width;
  215. let helfWidth:number=this.player.width*0.5;
  216. let sx:number=cx-helfWidth;
  217. let ex:number=cx+helfWidth;
  218. let proportion:number=(this.player.logicPosition.x-sx)/(ex-sx);
  219. angle=aAngle+(bAngle-aAngle)*proportion;
  220. this.inCirclePolygon.SetAngle(angle);
  221. this.background.node.angle=angle;
  222. //绕点
  223. this.origin.x=cx;
  224. this.origin.y=0;
  225. this.origin.z=0;
  226. //原始的圆心
  227. this.point.x=aTile.x+(aTile.width*0.5);
  228. this.point.y=this.inCirclePolygon.centerHeight;
  229. this.point.z=0;
  230. angle=0-this.inCirclePolygon.outAngle*proportion;
  231. this.inCirclePolygon.RotationCenter(angle,this.point,this.origin);
  232. }
  233. }
  234. //物理坐标
  235. private physicsPos:cc.Vec2=new cc.Vec2();
  236. private CheckPhysicsPos():void{
  237. let list:cc.Vec3[]=this.player.gridView;
  238. let count:number=0;
  239. let point:cc.Vec3;
  240. let state:number
  241. for (let index = 0; index < list.length; index++) {
  242. point=list[index];
  243. this.inCirclePolygon.GetPhysicsPos(point.x,point.z,this.physicsPos);
  244. state=this.inCirclePolygon.GetPhysicsState(this.physicsPos.x,this.physicsPos.y);
  245. if(state==0){
  246. count++;
  247. }
  248. }
  249. //超过半数悬空则掉落
  250. if(count>=5){
  251. this.isDrop=true;
  252. this.startDropTime=cc.sys.now();
  253. }
  254. }
  255. onDestroy():void{
  256. let list:string[]=[
  257. this.levelConfig.packageName,
  258. this.carConfig.packageName,
  259. "background"
  260. ]
  261. let bundle:cc.AssetManager.Bundle;
  262. list.forEach(bundleName => {
  263. bundle=cc.assetManager.getBundle(bundleName);
  264. bundle.releaseAll();
  265. cc.assetManager.removeBundle(bundle);
  266. });
  267. }
  268. private static __instance:GameController;
  269. public static get single():GameController{
  270. return this.__instance;
  271. }
  272. }