GameController.ts 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. this.loader.RemoveAllEvent();
  76. this.loader.AddEvent(JLoader.EVENT_COMPLETE,this,this.BackgroundLoaded);
  77. this.loader.Load("background",this.levelConfig.background);
  78. }
  79. private BackgroundLoaded():void{
  80. this.loader.RemoveAllEvent();
  81. let texture:cc.Texture2D=this.loader.GetContent(cc.Texture2D) as cc.Texture2D;
  82. let m:cc.Material=this.background.getMaterial(0);
  83. m.setProperty("diffuseTexture",texture);
  84. this.loader=null;
  85. this.InitGame();
  86. LoadingView.single.Hide();
  87. }
  88. private InitGame():void{
  89. this.inCirclePolygon=new InCirclePolygon(this.polygon);
  90. this.StartGame();
  91. }
  92. /**
  93. * 开始游戏
  94. */
  95. StartGame():void{
  96. this.isGameOver=false;
  97. this.isDrop=false;
  98. this.inCirclePolygon.Reset();
  99. this.player.Reset();
  100. }
  101. update (dt:number) {
  102. if(this.inCirclePolygon==null){
  103. return;
  104. }
  105. if(this.isGameOver){
  106. return;
  107. }
  108. cc.Vec3.zero(this.moveVec);
  109. //前进的速度
  110. cc.Vec3.add(this.moveVec,this.moveVec,this.player.speed);
  111. if(this.isDrop){
  112. cc.Vec3.add(this.moveVec,this.moveVec,this.player.dropSpeed);
  113. }else{
  114. if(this.player.isLeft){
  115. cc.Vec3.add(this.moveVec,this.moveVec,this.player.leftSpeed);
  116. }else if(this.player.isRight){
  117. cc.Vec3.add(this.moveVec,this.moveVec,this.player.rightSpeed);
  118. }
  119. //冲刺
  120. if(this.player.isSprint){
  121. cc.Vec3.add(this.moveVec,this.moveVec,this.player.sprintSpeed);
  122. }
  123. }
  124. cc.Vec3.multiplyScalar(this.moveVec,this.moveVec,dt);
  125. //角色移动
  126. let pos:cc.Vec3=this.player.logicPosition;
  127. pos.add(this.moveVec,pos);
  128. //将X轴环形映射
  129. pos.x=MathUtils.CircularMapping(pos.x,this.inCirclePolygon.maxX,this.inCirclePolygon.minX);
  130. this.player.logicPosition=pos;
  131. //背景跟角色使用保持固定的距离
  132. pos=this.background.node.position;
  133. pos.z=0-(this.player.logicPosition.y+1000);
  134. this.background.node.position=pos;
  135. //摄像机跟随
  136. if(!this.isDrop){
  137. pos=this.camera.position;
  138. pos.x=this.player.logicPosition.x;
  139. pos.y=this.inCirclePolygon.center.y;
  140. pos.z=-this.player.logicPosition.z+60;
  141. this.camera.position=pos;
  142. // cc.log("摄像机位置:",pos.x,pos.y,pos.z);
  143. }
  144. //物理计算
  145. if(!this.isDrop&&this.player.isSprint==false){
  146. this.CheckPhysicsPos();
  147. }
  148. this.CheckAngle();
  149. //多边形更新
  150. this.inCirclePolygon.Update(dt);
  151. //检测游戏是否结束
  152. if(this.isGameOver==false){
  153. if(this.isDrop){
  154. let currentTime:number=cc.sys.now();
  155. if(currentTime-this.startDropTime>2000){
  156. cc.log("游戏结束!");
  157. this.GameOver(false);
  158. }
  159. }else{
  160. if(this.player.logicPosition.z>this.levelConfig.endPos){
  161. cc.log("到达终点");
  162. this.GameOver(true);
  163. }
  164. }
  165. }
  166. }
  167. GameOver(isWin:boolean):void{
  168. this.isGameOver=true;
  169. GUIManager.single.Show(UIKeys.WXS04,true);
  170. if(isWin){
  171. GameModel.single.currentLevel++;
  172. GameModel.single.SaveToLoacl();
  173. }
  174. }
  175. private rectsTemp:number[];
  176. private point:cc.Vec3=new cc.Vec3();
  177. private origin:cc.Vec3=new cc.Vec3();
  178. /**
  179. * 计算角度
  180. */
  181. private CheckAngle():void{
  182. if(this.rectsTemp==null){
  183. this.rectsTemp=[];
  184. }
  185. this.inCirclePolygon.PolygonIntersects(this.player.rect,this.rectsTemp);
  186. if(this.rectsTemp.length==0){
  187. return;
  188. }
  189. if(this.rectsTemp.length>2){
  190. cc.error("主角的大小太大了!");
  191. return;
  192. }
  193. let angle:number;
  194. //在单独的一个块中
  195. if(this.rectsTemp.length==1){
  196. angle=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[0]);
  197. let aTile:cc.Rect=this.inCirclePolygon.GetPolygonTile(this.rectsTemp[0]);
  198. this.inCirclePolygon.SetAngle(angle);
  199. this.background.node.angle=angle;
  200. this.inCirclePolygon.SetCenter(aTile.x+aTile.width*0.5,this.inCirclePolygon.centerHeight,0);
  201. }else{//跨块了
  202. let aAngle:number=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[0]);
  203. let bAngle:number=this.inCirclePolygon.GetPolygonTileAngle(this.rectsTemp[1]);
  204. let aTile:cc.Rect=this.inCirclePolygon.GetPolygonTile(this.rectsTemp[0]);
  205. //计算出旋转点
  206. let cx:number=aTile.x+aTile.width;
  207. let helfWidth:number=this.player.width*0.5;
  208. let sx:number=cx-helfWidth;
  209. let ex:number=cx+helfWidth;
  210. let proportion:number=(this.player.logicPosition.x-sx)/(ex-sx);
  211. angle=aAngle+(bAngle-aAngle)*proportion;
  212. this.inCirclePolygon.SetAngle(angle);
  213. this.background.node.angle=angle;
  214. //绕点
  215. this.origin.x=cx;
  216. this.origin.y=0;
  217. this.origin.z=0;
  218. //原始的圆心
  219. this.point.x=aTile.x+(aTile.width*0.5);
  220. this.point.y=this.inCirclePolygon.centerHeight;
  221. this.point.z=0;
  222. angle=0-this.inCirclePolygon.outAngle*proportion;
  223. this.inCirclePolygon.RotationCenter(angle,this.point,this.origin);
  224. }
  225. }
  226. //物理坐标
  227. private physicsPos:cc.Vec2=new cc.Vec2();
  228. private CheckPhysicsPos():void{
  229. let list:cc.Vec3[]=this.player.gridView;
  230. let count:number=0;
  231. let point:cc.Vec3;
  232. let state:number
  233. for (let index = 0; index < list.length; index++) {
  234. point=list[index];
  235. this.inCirclePolygon.GetPhysicsPos(point.x,point.z,this.physicsPos);
  236. state=this.inCirclePolygon.GetPhysicsState(this.physicsPos.x,this.physicsPos.y);
  237. if(state==0){
  238. count++;
  239. }
  240. }
  241. //超过半数悬空则掉落
  242. if(count>=5){
  243. this.isDrop=true;
  244. this.startDropTime=cc.sys.now();
  245. }
  246. }
  247. onDestroy():void{
  248. let list:string[]=[
  249. this.levelConfig.packageName,
  250. this.carConfig.packageName,
  251. "background"
  252. ]
  253. let bundle:cc.AssetManager.Bundle;
  254. list.forEach(bundleName => {
  255. bundle=cc.assetManager.getBundle(bundleName);
  256. bundle.releaseAll();
  257. cc.assetManager.removeBundle(bundle);
  258. });
  259. }
  260. private static __instance:GameController;
  261. public static get single():GameController{
  262. return this.__instance;
  263. }
  264. }