Tower.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { _decorator, Animation, Component, macro, Node, Sprite, SpriteFrame, Vec2, Vec3 } from 'cc';
  2. import { TowerData } from '../DataItem/ItemData';
  3. import { resMgr } from '../Frames/ResourcesMgr';
  4. import { GameMgr } from './GameFrameWork/GameMgr';
  5. import { MapMgr } from './GameFrameWork/MapMgr';
  6. import { TowerUI } from './GameFrameWork/TowerUI';
  7. import { BulletMgr } from './GameFrameWork/BulletMgr';
  8. import { MonsterMgr } from './GameFrameWork/MonsterMgr';
  9. import { Tools } from './Tools/Tools';
  10. const { ccclass, property } = _decorator;
  11. @ccclass('Tower')
  12. export class Tower extends Component {
  13. private _tilePos: Vec2 = null;
  14. private _atkRadiums: number = 0;
  15. private _lv: number = 1;
  16. private _atkTarget: Node = null;
  17. //炮
  18. protected _gun: Node = null;
  19. //地盘
  20. protected _chassis: Node = null;
  21. //塔的数据
  22. protected _data: TowerData = null;
  23. protected _isFire: boolean = false;
  24. //保存面向攻击对象的旋转角度
  25. protected _targetAngle: number = 0;
  26. //子弹的动画精灵帧的数组
  27. protected _bulletFrames: SpriteFrame[] = [];
  28. //自己的动画的精灵帧
  29. protected _aniFrames: SpriteFrame[] = [];
  30. //动画组件
  31. protected _ani: Animation = null;
  32. protected onLoad(): void {
  33. this._gun = this.node.getChildByName("Gun");
  34. this._chassis = this.node.getChildByName("Chassis");
  35. }
  36. protected setAni(){
  37. for(let i = 1; i <= this._data.fireAniCount; i++){
  38. this._aniFrames.push(resMgr.getSpriteFrame(this._data.fireAniImg + this._lv + i));
  39. }
  40. this._ani = Tools.createAnimation(this._aniFrames, 20, this._gun);
  41. }
  42. init(data: TowerData, pos: Vec3) {
  43. this._data = data;
  44. //子弹动画精灵帧
  45. for(let i = 1; i <= data.bulletAniCount; i++){
  46. this._bulletFrames.push(resMgr.getSpriteFrame(data.bulletAniImg + this._lv + i));
  47. }
  48. this._atkRadiums = data.atkRadiums[this._lv - 1];
  49. const frame = resMgr.getSpriteFrame(data.chassis[0]);
  50. this._chassis.getComponent(Sprite).spriteFrame = frame;
  51. this.node.setPosition(pos);
  52. //炮的图片
  53. this._gun.getComponent(Sprite).spriteFrame
  54. = resMgr.getSpriteFrame(data.fireAniImg + this._lv + "1");
  55. this._tilePos = GameMgr.Instance.getModuler(MapMgr).getTiledByPos(new Vec2(pos.x, pos.y));
  56. }
  57. protected _attack(){
  58. //一定不要写代码 只是为了产生多态 其实是一个接口 实现不同的派生类的方法
  59. }
  60. protected stopAttack(){
  61. }
  62. //开火
  63. protected _fire(){
  64. this._isFire = true;
  65. this._attack();
  66. }
  67. protected _unFire(){
  68. //this.unscheduleAllCallbacks();
  69. this._isFire = false;
  70. this.stopAttack();
  71. }
  72. bTouch(pos: Vec2): boolean {
  73. const tiled = GameMgr.Instance.getModuler(MapMgr).getTiledByPos(new Vec2(pos.x, pos.y));
  74. if (this._tilePos.equals(tiled)) {
  75. this.showUI();
  76. return true;
  77. };
  78. return false;
  79. }
  80. showUI() {
  81. GameMgr.Instance.getModuler(TowerUI).show(this.node.position)
  82. }
  83. protected update(dt: number): void {
  84. if(this._atkTarget){
  85. //旋转角度
  86. const vec: Vec3 = this._getVec(this._atkTarget).normalize();
  87. let angle = Vec3.angle(new Vec3(0, 1), vec);
  88. if(vec.x > 0){
  89. angle *= -1;
  90. }
  91. //this.unscheduleAllCallbacks();
  92. //弧度转角度
  93. this._targetAngle = angle / Math.PI * 180;
  94. if(this._data.rotate){
  95. this._gun.angle = this._targetAngle;
  96. }
  97. }
  98. if(this._isFire){
  99. //已经锁定的目标 是否死亡(销毁) 是否走出攻击范围
  100. const dis = this._getVec(this._atkTarget).length();
  101. if(dis > this._atkRadiums){
  102. this._atkTarget = null;
  103. this._unFire();
  104. }
  105. return;
  106. }
  107. if(this._findMonster()){
  108. this._fire();
  109. }
  110. }
  111. private _findMonster(){
  112. const monsters: Node[] = GameMgr.Instance.getModuler(MonsterMgr).node.children;
  113. for(const node of monsters){
  114. //计算node和自己的距离
  115. const dis: number = this._getVec(node).length();
  116. if(dis <= this._atkRadiums){
  117. this._atkTarget = node;
  118. return true;
  119. //this._fire();
  120. }
  121. }
  122. return false;
  123. }
  124. protected _getVec(node: Node): Vec3{
  125. return node.position.clone().subtract(this.node.position);
  126. }
  127. }