GameController.ts 9.4 KB

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