MapData.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. import { Role } from "../../../common/InterfaceAddEnum";
  2. import { BattlesConf } from "../conf/BattlesConf";
  3. import { EnemyConf } from "../conf/EnemyConf";
  4. import { MapConf } from "../conf/MapConf";
  5. import { BattleUtil } from "./BattleUtil";
  6. import { BuffData, BuffDataPool } from "./BuffData";
  7. import { BulletData, BulletDataPool } from "./BulletData";
  8. import { DataBase } from "./DataBase";
  9. import { EnemyData, EnemyDataPool } from "./EnemyData";
  10. import { HeroData, HeroDataPool } from "./HeroData";
  11. //英雄站位
  12. export interface PosData {
  13. hero: HeroData,
  14. posID: number,
  15. pos: BattleUtil.Vector2
  16. }
  17. enum EnemyBornIndex{
  18. //当前批次第一个出生时间
  19. BornTime = 0,
  20. //出生时格子
  21. PosID,
  22. //敌人类型
  23. TypeID,
  24. //行走路线
  25. RoldID,
  26. //出生数量
  27. Count,
  28. //间隔时间
  29. Interval,
  30. //强度
  31. Level,
  32. }
  33. export interface EnemyBornData {
  34. bornTime: number,
  35. positionID: number,
  36. typeID: number,
  37. level: number,
  38. roldID: number
  39. }
  40. //地图格子 单例
  41. export class MapData {
  42. protected static instance:MapData;
  43. //-------------------配置数据----------------------
  44. //所属类型编号 章节id
  45. typeID: number;
  46. //关卡编号
  47. battlesID: number;
  48. //地图格子数量,目前固定是10*10
  49. size:BattleUtil.Vector2;
  50. //每个格子大小
  51. // sizeUnit:BattleUtil.Vector2;
  52. //格子数量
  53. length:number;
  54. //每个格子的坐标 从左下角开始
  55. /**
  56. * 90 91 92 93 94 95 96 97 98 99
  57. * 80 81 82 83 84 85 86 87 88 89
  58. * 70 71 72 73 74 75 76 77 78 79
  59. * 60 61 62 63 64 65 66 67 68 69
  60. * 50 51 52 53 54 55 56 57 58 59
  61. * 40 41 42 43 44 45 46 47 48 49
  62. * 30 31 32 33 34 35 36 37 38 39
  63. * 20 21 22 23 24 25 26 27 28 29
  64. * 10 11 12 13 14 15 16 17 18 19
  65. * 0 1 2 3 4 5 6 7 8 9
  66. */
  67. //pointList:Array<Array<number>>;
  68. //常规路径
  69. normalRold:Array<Array<number>>;
  70. //特殊路径
  71. // //捷径 至少有3个点:起点,终点,中间点,其中起点和终点是常规路径上的点
  72. // shortcut:Array<Array<number>>;
  73. //终点
  74. endPosition:number;
  75. //攻击点
  76. attackPosition:Array<number>;
  77. //敌人出生列表<turn,Array<EnemyBornData>>
  78. enemyBornMap:Map<number,Array<EnemyBornData>> = new Map();
  79. //出生时长
  80. bornNeedTime:number = 0;
  81. //-------------------动态数据----------------------
  82. // 攻击位<posID,PosData>
  83. attackPosDataMap: Map<number,PosData> = new Map();
  84. //所有存活的敌人
  85. enemyDataList:Array<EnemyData> = []
  86. //所有子弹
  87. bulletList:Array<BulletData> = []
  88. //<ID,BuffData>
  89. buffMap: Map<number,BuffData> = new Map();
  90. //地图点对应坐标坐标
  91. mapPosList:Array<BattleUtil.Vector2> = []
  92. //当前帧
  93. curTurn:number = 0;
  94. //游戏是否结束
  95. protected _battleEnd:boolean = false;
  96. protected _bWin:boolean = false;
  97. //操作列表 number表示帧数<turn,Array<BattleUtil.HeroDataChange>>
  98. actionMap:Map<number,Array<BattleUtil.HeroDataChange>> = new Map();
  99. //关卡总血量 从1开始防止除0异常
  100. allEnemyHP:number = 1;
  101. static GetInstance():MapData{
  102. if(!MapData.instance){
  103. MapData.instance = new MapData();
  104. }
  105. return MapData.instance;
  106. }
  107. //析构
  108. static Dispose(){
  109. MapData.instance = null;
  110. }
  111. set bWin(b:boolean){
  112. this._bWin = b;
  113. }
  114. get bWin():boolean{
  115. return this._bWin;
  116. }
  117. set battleEnd(b:boolean){
  118. this._battleEnd = b;
  119. if(b){
  120. this.bWin = this.enemyDataList.length == 0;
  121. let str:string = JSON.stringify(Object.fromEntries(this.actionMap))
  122. console.log(str)
  123. }
  124. }
  125. get battleEnd():boolean{
  126. return this._battleEnd;
  127. }
  128. init(battlesID:number){
  129. this.size = new BattleUtil.Vector2(10,10);
  130. //this.sizeUnit = new BattleUtil.Vector2(70,70);
  131. this.length = this.size.x*this.size.y;
  132. for(let i = 0; i < this.length; i++){
  133. this.mapPosList.push(this.getPosition(i))
  134. }
  135. this.reset(battlesID);
  136. }
  137. reset(battlesID:number){
  138. this.attackPosDataMap.clear();
  139. //所有存活的敌人
  140. this.enemyDataList.splice(0,this.enemyDataList.length);
  141. //所有子弹
  142. this.bulletList.splice(0,this.bulletList.length);
  143. this.buffMap.clear();
  144. this.enemyBornMap.clear();
  145. //操作列表 number表示帧数
  146. this.actionMap.clear();
  147. console.log("clear!")
  148. //读表
  149. this.battlesID = battlesID;
  150. let battlesConf = BattlesConf.data[battlesID.toString()];
  151. if(!battlesConf){
  152. console.error("没有找到关卡配置表,请检查配置表是否正确")
  153. return;
  154. }
  155. let typeID = battlesConf.Chapter;
  156. this.typeID = typeID;
  157. let mapConf = MapConf.data[typeID.toString()];
  158. this.normalRold = mapConf.RoldJsonArr;
  159. this.endPosition = this.normalRold[0][this.normalRold[0].length-1];
  160. this.attackPosition = mapConf.AttackPositionArray;
  161. this.allEnemyHP = 1;
  162. let EnemyJsonArr = mapConf.EnemyJsonArr;
  163. EnemyJsonArr.forEach((enemyObj)=>{
  164. for(let j=0;j<enemyObj[EnemyBornIndex.Count];j++){
  165. let enemyBornData:EnemyBornData = {
  166. bornTime: enemyObj[EnemyBornIndex.BornTime] + enemyObj[EnemyBornIndex.Interval]*j,
  167. positionID: enemyObj[EnemyBornIndex.PosID],
  168. typeID: enemyObj[EnemyBornIndex.TypeID],
  169. level: battlesConf.EnemyLevel,
  170. roldID: enemyObj[EnemyBornIndex.RoldID],
  171. }
  172. this.allEnemyHP += enemyBornData.level*EnemyConf.data[typeID].Life;
  173. if(this.enemyBornMap.has(enemyBornData.bornTime)){
  174. this.enemyBornMap.get(enemyBornData.bornTime).push(enemyBornData);
  175. }else{
  176. if(this.bornNeedTime < enemyBornData.bornTime){
  177. this.bornNeedTime = enemyBornData.bornTime;
  178. }
  179. this.enemyBornMap.set(enemyBornData.bornTime,[enemyBornData]);
  180. }
  181. }
  182. })
  183. //初始化boss
  184. let bossJsonArr = battlesConf.BossJsonArr;
  185. if(bossJsonArr){
  186. bossJsonArr.forEach((enemyObj)=>{
  187. for(let j=0;j<enemyObj[EnemyBornIndex.Count];j++){
  188. let enemyBornData:EnemyBornData = {
  189. bornTime: enemyObj[EnemyBornIndex.BornTime] + enemyObj[EnemyBornIndex.Interval]*j,
  190. positionID: enemyObj[EnemyBornIndex.PosID],
  191. typeID: enemyObj[EnemyBornIndex.TypeID],
  192. level: enemyObj[EnemyBornIndex.Level],
  193. roldID: enemyObj[EnemyBornIndex.RoldID],
  194. }
  195. this.allEnemyHP += enemyBornData.level*EnemyConf.data[typeID].Life;
  196. if(this.enemyBornMap.has(enemyBornData.bornTime)){
  197. this.enemyBornMap.get(enemyBornData.bornTime).push(enemyBornData);
  198. }else{
  199. if(this.bornNeedTime < enemyBornData.bornTime){
  200. this.bornNeedTime = enemyBornData.bornTime;
  201. }
  202. this.enemyBornMap.set(enemyBornData.bornTime,[enemyBornData]);
  203. }
  204. }
  205. })
  206. }
  207. this.attackPosDataMap.clear()
  208. this.attackPosition.forEach((v,k)=>{
  209. //this.pointList[pos.x][pos.y] = 1;
  210. let podID = Number(v)
  211. let posData:PosData = {
  212. hero: null,
  213. posID: podID,
  214. pos: this.getPosition(podID)
  215. }
  216. this.attackPosDataMap.set(v,posData);
  217. })
  218. this.curTurn = 0;
  219. this._battleEnd = false;
  220. this._bWin = false;
  221. }
  222. getNormalRold(id:number):Array<number>{
  223. return this.normalRold[id%this.normalRold.length];
  224. }
  225. //根据id获取坐标 取值范围[0,this.length-1]
  226. getPosition(id:number):BattleUtil.Vector2{
  227. if(id<0 || id>=this.length) return null;
  228. let pos = new BattleUtil.Vector2(0,0);
  229. pos.x = id%this.size.x;
  230. pos.y = Math.floor(id/this.size.x);
  231. return pos;
  232. }
  233. //添加到地图上
  234. addHero(role:Role,level:number,posID:number){
  235. let hero = HeroDataPool.getObject()
  236. hero.init(role,level,posID);
  237. console.log(typeof(posID),posID)
  238. if(this.attackPosDataMap.has(posID)){
  239. let posData = this.attackPosDataMap.get(posID)
  240. let posHero = posData.hero;
  241. if(posHero){
  242. posHero.clear();
  243. HeroDataPool.putObject(posHero);
  244. }
  245. posData.hero = hero
  246. hero.position = posData.pos;
  247. }
  248. return hero;
  249. }
  250. //移除地图上指定位置的英雄
  251. removeHero(posID:number){
  252. if(this.attackPosDataMap.has(posID)){
  253. let posData = this.attackPosDataMap.get(posID);
  254. let posHero = posData.hero;
  255. if(posHero){
  256. posHero.clear();
  257. HeroDataPool.putObject(posHero);
  258. }
  259. posData.hero = null;
  260. }
  261. }
  262. /**
  263. *添加敌人
  264. * @param typeID 敌人类型
  265. * @param level 敌人等级
  266. * @param roldID 敌人行走路径
  267. * @param bronPos 敌人在路径上哪个点走
  268. */
  269. addEnemy(typeID:number,level:number,roldID:number,bronPos:number){
  270. let enemy = EnemyDataPool.getObject()
  271. let rold = this.getNormalRold(roldID);
  272. enemy.init(typeID,level,rold);
  273. this.enemyDataList.push(enemy);
  274. enemy.position = this.getPosition(bronPos);
  275. enemy.speedVector = new BattleUtil.Vector2(0,0);
  276. enemy.speedVector = this.getEnemySpeedVector(enemy);
  277. enemy.posID = bronPos;
  278. return enemy;
  279. }
  280. //移除地图上指定的敌人
  281. removeEnemy(enemy:EnemyData){
  282. let index = this.enemyDataList.indexOf(enemy);
  283. if(index>=0){
  284. this.enemyDataList.splice(index,1);
  285. }
  286. enemy.clear();
  287. EnemyDataPool.putObject(enemy);
  288. }
  289. getEnemySpeedVector(enemy:EnemyData):BattleUtil.Vector2{
  290. let oldPos = this.mapPosList[enemy.posID]
  291. let newPos = this.mapPosList[enemy.nextPosID]
  292. if(newPos){
  293. let direction = BattleUtil.Vector2.Sub(newPos,oldPos)
  294. direction.multiply(enemy.speedCur)
  295. return direction;
  296. }
  297. return new BattleUtil.Vector2(0,0);
  298. }
  299. addBuff(buffID:number,duration:number,valueList:Array<number>,src:DataBase,target:DataBase){
  300. let buff:BuffData = this.buffMap.get(buffID)
  301. if(buff == null){
  302. buff = BuffDataPool.getObject()
  303. buff.init(buffID,duration,valueList,src,target)
  304. this.buffMap.set(buff.ID,buff)
  305. if(target instanceof EnemyData){
  306. target.addBuff(buff)
  307. }
  308. }
  309. return buff;
  310. }
  311. removeBuff(ID:number){
  312. let buff:BuffData = this.buffMap.get(ID)
  313. if(buff != null){
  314. let target = buff.targetDataBase
  315. if(target instanceof EnemyData){
  316. target.removeBuff(buff)
  317. }
  318. buff.clear()
  319. BuffDataPool.putObject(buff)
  320. this.buffMap.delete(ID)
  321. }
  322. }
  323. addBullet(typeID:number,srcHero:HeroData,targetEnemy:EnemyData){
  324. let bullet:BulletData = BulletDataPool.getObject()
  325. bullet.init(typeID,srcHero,targetEnemy)
  326. this.bulletList.push(bullet)
  327. return bullet;
  328. }
  329. removeBullet(bullet:BulletData){
  330. let index = this.bulletList.indexOf(bullet);
  331. if(index>=0){
  332. this.bulletList.splice(index,1);
  333. }
  334. bullet.clear();
  335. BulletDataPool.putObject(bullet);
  336. }
  337. clear(){
  338. this.attackPosDataMap.forEach((posData,posID)=>{
  339. if(posData.hero){
  340. posData.hero.clear();
  341. HeroDataPool.putObject(posData.hero);
  342. }
  343. })
  344. this.attackPosDataMap.clear();
  345. this.enemyDataList.forEach((enemy)=>{
  346. enemy.clear();
  347. EnemyDataPool.putObject(enemy);
  348. })
  349. this.enemyDataList = [];
  350. // this.bulletList.forEach((bullet)=>{
  351. // bullet.clear();
  352. // BulletDataPool.putObject(bullet);
  353. // })
  354. // this.bulletList = [];
  355. this.buffMap.forEach((buff)=>{
  356. buff.clear();
  357. BuffDataPool.putObject(buff);
  358. })
  359. }
  360. }