xiexing před 4 roky
revize
190987e4eb
100 změnil soubory, kde provedl 16242 přidání a 0 odebrání
  1. 51 0
      .gitignore
  2. 2 0
      README.md
  3. 13 0
      assets/Scene.meta
  4. 7306 0
      assets/Scene/gameScence.fire
  5. 8 0
      assets/Scene/gameScence.fire.meta
  6. 13 0
      assets/Script.meta
  7. 13 0
      assets/Script/configData.meta
  8. 46 0
      assets/Script/configData/AudioManager.ts
  9. 10 0
      assets/Script/configData/AudioManager.ts.meta
  10. 817 0
      assets/Script/configData/DataObj.ts
  11. 10 0
      assets/Script/configData/DataObj.ts.meta
  12. 22 0
      assets/Script/configData/Enum.ts
  13. 10 0
      assets/Script/configData/Enum.ts.meta
  14. 82 0
      assets/Script/configData/GameConfig.ts
  15. 10 0
      assets/Script/configData/GameConfig.ts.meta
  16. 81 0
      assets/Script/configData/ReadCsv.ts
  17. 10 0
      assets/Script/configData/ReadCsv.ts.meta
  18. 123 0
      assets/Script/configData/gameData.ts
  19. 10 0
      assets/Script/configData/gameData.ts.meta
  20. 91 0
      assets/Script/configData/path.ts
  21. 10 0
      assets/Script/configData/path.ts.meta
  22. 93 0
      assets/Script/configData/path1.ts
  23. 10 0
      assets/Script/configData/path1.ts.meta
  24. 93 0
      assets/Script/configData/path2.ts
  25. 10 0
      assets/Script/configData/path2.ts.meta
  26. 89 0
      assets/Script/configData/path3.ts
  27. 10 0
      assets/Script/configData/path3.ts.meta
  28. 13 0
      assets/Script/game.meta
  29. 13 0
      assets/Script/game/UIFace.meta
  30. 91 0
      assets/Script/game/UIFace/LevelIntro.ts
  31. 10 0
      assets/Script/game/UIFace/LevelIntro.ts.meta
  32. 30 0
      assets/Script/game/UIFace/TapNode.ts
  33. 10 0
      assets/Script/game/UIFace/TapNode.ts.meta
  34. 162 0
      assets/Script/game/UIFace/gameManger.ts
  35. 10 0
      assets/Script/game/UIFace/gameManger.ts.meta
  36. 126 0
      assets/Script/game/UIFace/gameOver.ts
  37. 10 0
      assets/Script/game/UIFace/gameOver.ts.meta
  38. 378 0
      assets/Script/game/UIFace/gameUI.ts
  39. 10 0
      assets/Script/game/UIFace/gameUI.ts.meta
  40. 48 0
      assets/Script/game/UIFace/viewComtent.ts
  41. 10 0
      assets/Script/game/UIFace/viewComtent.ts.meta
  42. 13 0
      assets/Script/game/monster.meta
  43. 520 0
      assets/Script/game/monster/monsterManger.ts
  44. 10 0
      assets/Script/game/monster/monsterManger.ts.meta
  45. 487 0
      assets/Script/game/monster/monsterNode.ts
  46. 10 0
      assets/Script/game/monster/monsterNode.ts.meta
  47. 508 0
      assets/Script/game/monster/soldie.ts
  48. 10 0
      assets/Script/game/monster/soldie.ts.meta
  49. 13 0
      assets/Script/game/tower.meta
  50. 230 0
      assets/Script/game/tower/Archer.ts
  51. 10 0
      assets/Script/game/tower/Archer.ts.meta
  52. 449 0
      assets/Script/game/tower/Magic.ts
  53. 10 0
      assets/Script/game/tower/Magic.ts.meta
  54. 241 0
      assets/Script/game/tower/SkillSolate.ts
  55. 10 0
      assets/Script/game/tower/SkillSolate.ts.meta
  56. 33 0
      assets/Script/game/tower/TowerData.ts
  57. 10 0
      assets/Script/game/tower/TowerData.ts.meta
  58. 674 0
      assets/Script/game/tower/TowerHuan.ts
  59. 10 0
      assets/Script/game/tower/TowerHuan.ts.meta
  60. 318 0
      assets/Script/game/tower/arrow.ts
  61. 10 0
      assets/Script/game/tower/arrow.ts.meta
  62. 503 0
      assets/Script/game/tower/barracks.ts
  63. 10 0
      assets/Script/game/tower/barracks.ts.meta
  64. 59 0
      assets/Script/game/tower/buildload.ts
  65. 10 0
      assets/Script/game/tower/buildload.ts.meta
  66. 177 0
      assets/Script/game/tower/skillManger.ts
  67. 10 0
      assets/Script/game/tower/skillManger.ts.meta
  68. 343 0
      assets/Script/game/tower/taside.ts
  69. 10 0
      assets/Script/game/tower/taside.ts.meta
  70. 368 0
      assets/Script/game/tower/towerManger.ts
  71. 10 0
      assets/Script/game/tower/towerManger.ts.meta
  72. 440 0
      assets/Script/game/tower/turret.ts
  73. 10 0
      assets/Script/game/tower/turret.ts.meta
  74. 13 0
      assets/Script/mainFace.meta
  75. 162 0
      assets/Script/mainFace/mainManager.ts
  76. 10 0
      assets/Script/mainFace/mainManager.ts.meta
  77. 213 0
      assets/Script/mainFace/talantNode.ts
  78. 10 0
      assets/Script/mainFace/talantNode.ts.meta
  79. 13 0
      assets/Texture.meta
  80. 13 0
      assets/adsdk.meta
  81. 194 0
      assets/adsdk/sdk-jsb.js
  82. 10 0
      assets/adsdk/sdk-jsb.js.meta
  83. 13 0
      assets/migration.meta
  84. 17 0
      assets/migration/use_v2.1-2.2.1_cc.Toggle_event.js
  85. 10 0
      assets/migration/use_v2.1-2.2.1_cc.Toggle_event.js.meta
  86. 13 0
      assets/resources.meta
  87. 13 0
      assets/resources/audio.meta
  88. binární
      assets/resources/audio/bgm1.mp3
  89. 8 0
      assets/resources/audio/bgm1.mp3.meta
  90. binární
      assets/resources/audio/bgm2.mp3
  91. 8 0
      assets/resources/audio/bgm2.mp3.meta
  92. binární
      assets/resources/audio/dianji.mp3
  93. 8 0
      assets/resources/audio/dianji.mp3.meta
  94. binární
      assets/resources/audio/fail.mp3
  95. 8 0
      assets/resources/audio/fail.mp3.meta
  96. binární
      assets/resources/audio/win.mp3
  97. 8 0
      assets/resources/audio/win.mp3.meta
  98. binární
      assets/resources/audio/zd1.mp3
  99. 8 0
      assets/resources/audio/zd1.mp3.meta
  100. 0 0
      assets/resources/audio/zd2.mp3

+ 51 - 0
.gitignore

@@ -0,0 +1,51 @@
+#/////////////////////////////////////////////////////////////////////////////
+# Fireball Projects
+#/////////////////////////////////////////////////////////////////////////////
+
+/library/
+/temp/
+/local/
+/build/
+
+#/////////////////////////////////////////////////////////////////////////////
+# npm files
+#/////////////////////////////////////////////////////////////////////////////
+
+npm-debug.log
+node_modules/
+
+#/////////////////////////////////////////////////////////////////////////////
+# Logs and databases
+#/////////////////////////////////////////////////////////////////////////////
+
+*.log
+*.sql
+*.sqlite
+
+#/////////////////////////////////////////////////////////////////////////////
+# files for debugger
+#/////////////////////////////////////////////////////////////////////////////
+
+*.sln
+*.pidb
+*.suo
+
+#/////////////////////////////////////////////////////////////////////////////
+# OS generated files
+#/////////////////////////////////////////////////////////////////////////////
+
+.DS_Store
+ehthumbs.db
+Thumbs.db
+
+#/////////////////////////////////////////////////////////////////////////////
+# WebStorm files
+#/////////////////////////////////////////////////////////////////////////////
+
+.idea/
+
+#//////////////////////////
+# VS Code files
+#//////////////////////////
+
+.vscode/

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+# hello-world
+Hello world new project template.

+ 13 - 0
assets/Scene.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "29f52784-2fca-467b-92e7-8fd9ef8c57b7",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 7306 - 0
assets/Scene/gameScence.fire


+ 8 - 0
assets/Scene/gameScence.fire.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "1.3.2",
+  "uuid": "e290ff9f-11fb-4f32-aa7b-1d0723c5b8e3",
+  "importer": "scene",
+  "asyncLoadAssets": false,
+  "autoReleaseAssets": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Script.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "4734c20c-0db8-4eb2-92ea-e692f4d70934",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/configData.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "21e28fa6-cf44-4d22-93df-7c841da39d1b",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 46 - 0
assets/Script/configData/AudioManager.ts

@@ -0,0 +1,46 @@
+import gameData from "./gameData";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export class AudioManager {
+
+    public static palyAudio(ID: number) {
+        let model = Number(gameData.instance().audio_Config[ID + 2][3]);
+        if (model == 1) {
+            AudioManager.playMusic(ID);
+        }
+
+        if (model == 2) {
+            AudioManager.playSound(ID);
+        }
+    }
+
+    public static playMusic(ID: number) {
+        const path = 'audio/' + gameData.instance().audio_Config[ID + 2][2];
+
+        cc.loader.loadRes(path, cc.AudioClip, (err, clip) => {
+            if (err) {
+                console.warn(err);
+                return;
+            }
+            cc.audioEngine.playMusic(clip, true);
+        });
+
+      
+
+    }
+
+    public static playSound(ID: number) {
+        const path = 'audio/' + gameData.instance().audio_Config[ID + 2][2];
+        cc.loader.loadRes(path, cc.AudioClip, (err, clip) => {
+            if (err) {
+                console.warn(err);
+                return;
+            }
+
+            cc.audioEngine.playEffect(clip,false);
+        });
+    }
+}

+ 10 - 0
assets/Script/configData/AudioManager.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "b2aef612-554e-479f-a59b-d9d75bf76c99",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 817 - 0
assets/Script/configData/DataObj.ts

@@ -0,0 +1,817 @@
+import GameConfig from "./GameConfig";
+import gameData from "./gameData";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class DataObj extends cc.Component {
+
+    onLoad() {
+
+    }
+
+    /** 怪物数据*/
+    public monsterData = {
+        /**预制体名 */
+        name1: '',
+        /**模型缩放比 */
+        model_scaling: 1,
+        /**阵营 1敌方 2我方 3npc*/
+        camp: 1,
+        /**单位类型 1地面单位 2空中单位*/
+        company_type: 1,
+        /**血量总量 */
+        totalHp: 16,
+        /**攻击力 */
+        attack: '',
+        /** 物理减伤*/
+        physics_reduction: 0,
+        /** 魔法减伤*/
+        magic_reduction: 0,
+        /**移动速度 基础35==1 */
+        Movespeed: 35,
+        /**攻击频率  单位秒 */
+        attack_speed: 1.5,
+        /**攻击范围 */
+        attack_range: 0.2,
+        /**预警范围 */
+        warning_range: 1,
+        /**回血速率 0回血量 1频率*/
+        recovery: [],
+        /**攻击类型 1主动 2被动 3不攻击*/
+        active_attack_type: '1',
+        /**技能 */
+        skills: 0,
+        /**对空开关*/
+        air_attack_switch: 'OFF',
+        /**扣血值 */
+        hurt_level_hp: 1,
+        /**掉落金币 */
+        drop_group_1: 1,
+        /** 掉落钻石*/
+        drop_group_2: '',
+        /**掉落砖石百分比几率 */
+        percentage: 10,
+        /**血量难度系数 */
+        hp_diff_coefficient: 1,
+        /**攻击难度系数 */
+        attack_diff_coefficient: 1,
+        /**当前血量 */
+        nowHp: 16,
+    };
+
+    /**初始化怪物数据 */
+    public writeMonster_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().monster_Config.length; i++) {
+            const arr = gameData.instance().monster_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+
+                    break;
+                case 'name':
+
+                    break;
+                case 'name1':
+                    this.monsterData.name1 = oneData[i];
+                    break;
+                case 'monster_icon_path':
+
+                    break;
+                case 'model_scaling':
+                    this.monsterData.model_scaling = Number(oneData[i]);
+                    break;
+                case 'skills':
+                    this.monsterData.skills = Number(oneData[i]);
+                    break;
+                case 'physics_reduction':
+                    this.monsterData.physics_reduction = Number(oneData[i]);
+                    break;
+                case 'magic_reduction':
+                    this.monsterData.magic_reduction = Number(oneData[i]);
+                    break;
+                case 'camp':
+                    this.monsterData.camp = Number(oneData[i]);
+                    break;
+                case 'company_type':
+                    this.monsterData.company_type = Number(oneData[i]);
+                    break;
+                case 'hp':
+                    {
+                        this.monsterData.totalHp = Number(oneData[i]);
+                        this.monsterData.nowHp = this.monsterData.totalHp;
+                    }
+                    break;
+                case 'attack':
+                    this.monsterData.attack = oneData[i];
+                    break;
+                case 'move_speed':
+                    this.monsterData.Movespeed = Number(oneData[i]);
+                    break;
+                case 'attack_speed':
+                    this.monsterData.attack_speed = Number(oneData[i]);
+                    break;
+                case 'attack_range':
+                    this.monsterData.attack_range = Number(oneData[i]);
+                    break;
+                case 'warning_range':
+                    this.monsterData.warning_range = Number(oneData[i]);
+                    break;
+                case 'recovery':
+                    this.monsterData.recovery = this.getArr(oneData[i]);
+                    break;
+                case 'active_attack_type':
+                    this.monsterData.active_attack_type = oneData[i];
+                    break;
+                case 'air_attack_switch':
+                    this.monsterData.air_attack_switch = oneData[i];
+                    break;
+                case 'hurt_level_hp':
+                    this.monsterData.hurt_level_hp = Number(oneData[i]);
+                    break;
+                case 'drop_group_1':
+                    this.monsterData.drop_group_1 = Number(oneData[i]);
+                    break;
+                case 'drop_group_2':
+                    {
+                        this.monsterData.drop_group_2 = oneData[i];
+                        let attackarr = oneData[i].split("*");
+                        this.monsterData.percentage = Number(attackarr[0]);
+                    }
+                    break;
+                case 'hp_diff_coefficient':
+                    {
+                        this.monsterData.hp_diff_coefficient = this.getDiff(oneData[i]);
+                        if (this.monsterData.hp_diff_coefficient > 0) {
+                            this.monsterData.totalHp *= this.monsterData.hp_diff_coefficient;
+                            this.monsterData.nowHp = this.monsterData.totalHp;
+                        }
+                    }
+
+
+                    break;
+                case 'attack_diff_coefficient':
+                    {
+                        this.monsterData.attack_diff_coefficient = this.getDiff(oneData[i]);
+                    }
+                    break;
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+    /**塔数据 */
+    public TowerData = {
+        /** ID*/
+        id: 1,
+        /** 塔名*/
+        name: 1,
+        /** 塔等级*/
+        tower_level: 1,
+        /**塔类 */
+        tower_type: 1,
+        /**对空开关 */
+        air_attack_switch: '',
+        /**初始建造金币 */
+        first_gold: 1,
+        /**升级金币 */
+        up_gold: [],
+        /**变卖金币 */
+        value_gold: 1,
+        /**攻击频率 单位秒*/
+        attack_cd: 1,
+        /** 攻击范围 基础单位135*/
+        attack_range: 1,
+        /**子弹ID */
+        bullet_id: 1,
+        /**士兵ID,数量 */
+        monster_id: [],
+        /** 下一级塔ID*/
+        next_tower_id: [],
+        /**塔技能 */
+        next_skill: [],
+        /** 预制体塔路径*/
+        name1: '',
+        /** 预制体小兵路径*/
+        name2: '',
+        /**塔图标路径 */
+        tower_icon_path: '',
+        /**模型缩放比 */
+        model_scaling: 1,
+    };
+
+    /**初始塔数据 */
+    public writeTower_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().tower_Config.length; i++) {
+            const arr = gameData.instance().tower_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+                    this.TowerData.id = Number(oneData[i]);
+                    break;
+                case 'tower_level':
+                    this.TowerData.tower_level = Number(oneData[i]);
+                    break;
+                case 'tower_type':
+                    this.TowerData.tower_type = Number(oneData[i]);
+                    break;
+                case 'air_attack_switch':
+                    this.TowerData.air_attack_switch = oneData[i];
+                    break;
+                case 'first_gold':
+                    this.TowerData.first_gold = Number(oneData[i]);
+                    break;
+                case 'up_gold':
+                    this.TowerData.up_gold = this.getArr(oneData[i]);
+                    break;
+                case 'value_gold':
+                    this.TowerData.value_gold = Number(oneData[i]);
+                    break;
+                case 'attack_cd':
+                    this.TowerData.attack_cd = Number(oneData[i]);
+                    break;
+                case 'attack_range':
+                    this.TowerData.attack_range = Number(oneData[i]);
+                    break;
+                case 'bullet_id':
+                    this.TowerData.bullet_id = Number(oneData[i]);
+                    break;
+                case 'monster_id':
+                    this.TowerData.monster_id = this.getArr(oneData[i]);
+                    break;
+                case 'next_tower_id':
+                    this.TowerData.next_tower_id = this.getArr(oneData[i]);
+                    break;
+                case 'next_skill':
+                    this.TowerData.next_skill = this.getArr(oneData[i]);
+                    break;
+                case 'name1':
+                    this.TowerData.name1 = oneData[i];
+                    break;
+                case 'name2':
+                    this.TowerData.name2 = oneData[i];
+                    break;
+                case 'tower_icon_path':
+
+                    break;
+                case 'model_scaling':
+                    this.TowerData.model_scaling = Number(oneData[i]);
+                    break;
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+    /**子弹数据 */
+    public BulletData = {
+        /**ID */
+        id: 0,
+        /**子弹名 */
+        name: '',
+        /**子弹类型 */
+        bullet_type: 0,
+        /** 伤害类型*/
+        injury_type: 0,
+        /** 攻击力*/
+        attack: '',
+        /** 飞行速度*/
+        speed: 0,
+        /** 抛物线系数*/
+        parabola: [],
+        /**爆炸范围 */
+        boom_range: 0,
+        /**爆炸伤害 */
+        boom_hurt: '',
+        /** 子弹模型路径*/
+        bullet_model_path: '',
+        /**爆炸特效路径 */
+        effect_bullet_path: '',
+        /**模型缩放比 */
+        model_scaling: 1,
+
+    }
+
+    /**初始子弹数据 */
+    public writeBullet_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().bullet_Config.length; i++) {
+            const arr = gameData.instance().bullet_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+                    this.BulletData.id = Number(oneData[i]);
+                    break;
+                case 'name':
+
+                    break;
+                case 'bullet_type':
+                    this.BulletData.bullet_type = Number(oneData[i]);
+                    break;
+                case 'injury_type':
+                    this.BulletData.injury_type = Number(oneData[i]);
+                    break;
+                case 'attack':
+                    this.BulletData.attack = oneData[i];
+                    break;
+                case 'speed':
+                    this.BulletData.speed = Number(oneData[i]);
+                    break;
+                case 'parabola':
+                    this.BulletData.parabola = this.getArr(oneData[i]);
+                    break;
+                case 'boom_range':
+                    this.BulletData.boom_range = Number(oneData[i]);
+                    break;
+                case 'boom_hurt':
+                    this.BulletData.boom_hurt = oneData[i];
+                    break;
+                case 'bullet_model_path':
+
+                    break;
+                case 'effect_bullet_path':
+
+                    break;
+                case 'model_scaling':
+                    this.BulletData.model_scaling = Number(oneData[i]);
+                    break;
+
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+    /**关卡数据 */
+    public LevelData = {
+        /**ID */
+        id: 0,
+        /** 关卡名*/
+        name: '',
+        /**关卡场景路径 */
+        scene_path: 1,
+        /**地图类型 */
+        map_type: 1,
+        /**关卡节数 */
+        level_num: '',
+        /** 关卡怪物一览*/
+        level_monster: [],
+        /**难度 */
+        diff: 0,
+        /** 初始金币*/
+        start_gold: 0,
+        /** 关卡血量*/
+        level_hp: 0,
+        /**基础通关奖励 */
+        reward: 0,
+        /** 下一章节*/
+        next_level: 0,
+        /** 1星条件血量*/
+        stars_1_hp: 0,
+        /** 2星条件血量*/
+        stars_2_hp: 0,
+        /** 3星条件血量*/
+        stars_3_hp: 0,
+        /** 挑战模式*/
+        events: 0,
+        /**空地X坐标 */
+        coordinate_x: [],
+        /**空地Y坐标 */
+        coordinate_y: [],
+        /** 关卡文本介绍*/
+        story: '',
+        /** 塔升级上限*/
+        tower_limit: [],
+    }
+
+    /**初始关卡数据 */
+    public writeLevel_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().level_Config.length; i++) {
+            const arr = gameData.instance().level_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+                    this.LevelData.id = Number(oneData[i]);
+                    break;
+                case 'name':
+                    this.LevelData.name = oneData[i];
+                    break;
+                case 'level_num':
+                    this.LevelData.level_num = oneData[i];
+                    break;
+                case 'scene_path':
+                    this.LevelData.scene_path = Number(oneData[i]);
+                    break;
+                case 'map_type':
+                    this.LevelData.map_type = Number(oneData[i]);
+                    break;
+                case 'level_monster':
+                    this.LevelData.level_monster = this.getArr(oneData[i]);
+                    break;
+                case 'diff':
+                    this.LevelData.diff = Number(oneData[i]);
+                    break;
+                case 'start_gold':
+                    this.LevelData.start_gold = Number(oneData[i]);
+                    break;
+                case 'level_hp':
+                    this.LevelData.level_hp = Number(oneData[i]);
+                    break;
+                case 'reward':
+                    this.LevelData.reward = Number(oneData[i]);
+                    break;
+                case 'next_level':
+                    this.LevelData.next_level = Number(oneData[i]);
+                    break;
+                case 'stars_1_hp':
+                    this.LevelData.stars_1_hp = Number(oneData[i]);
+                    break;
+                case 'stars_2_hp':
+                    this.LevelData.stars_2_hp = Number(oneData[i]);
+                    break;
+                case 'stars_3_hp':
+                    this.LevelData.stars_3_hp = Number(oneData[i]);
+                    break;
+                case 'events':
+                    this.LevelData.events = Number(oneData[i]);
+                    break;
+                case 'story':
+                    this.LevelData.story = oneData[i];
+                    break;
+                case 'tower_limit':
+                    this.LevelData.tower_limit = this.getArr(oneData[i]);
+                    break;
+                case 'coordinate_x':
+                    this.LevelData.coordinate_x = this.getArr(oneData[i]);
+                    break;
+                case 'coordinate_y':
+                    this.LevelData.coordinate_y = this.getArr(oneData[i]);
+                    break;
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+
+    /**技能数据 */
+    public SkillData = {
+        /**ID */
+        id: 1,
+        /**技能名 */
+        name: '',
+        /**技能类型 */
+        skill_type: 1,
+        /**参数1 */
+        parameter_1: 1,
+        /**参数2 */
+        parameter_2: '',
+        /**参数3 */
+        parameter_3: '',
+        /** 参数4*/
+        parameter_4: 1,
+        /** 参数5*/
+        parameter_5: 1,
+        /**子弹ID */
+        bullet_id: 1,
+        /** 下级技能ID*/
+        next_skill: 1,
+        /**升级金币 */
+        up_gold: 1,
+        /** 技能特效路径*/
+        skill_effect_path: '',
+        /**技能图标 */
+        skill_icon: '',
+        /** 技能文本介绍*/
+        skill_text: '',
+
+    }
+
+    /**初始技能数据 */
+    public writeSkill_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().skill_Config.length; i++) {
+            const arr = gameData.instance().skill_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+                    this.SkillData.id = Number(oneData[i]);
+                    break;
+                case 'name':
+                    this.SkillData.name = oneData[i];
+                    break;
+                case 'skill_type':
+                    this.SkillData.skill_type = Number(oneData[i]);
+                    break;
+                case 'parameter_1':
+                    this.SkillData.parameter_1 = Number(oneData[i]);
+                    break;
+                case 'parameter_2':
+                    this.SkillData.parameter_2 = oneData[i];
+                    break;
+                case 'parameter_3':
+                    this.SkillData.parameter_3 = oneData[i];
+                    break;
+                case 'parameter_4':
+                    this.SkillData.parameter_4 = Number(oneData[i]);
+                    break;
+                case 'parameter_5':
+                    this.SkillData.parameter_5 = Number(oneData[i]);
+                    break;
+                case 'bullet_id':
+                    this.SkillData.bullet_id = Number(oneData[i]);
+                    break;
+                case 'next_skill':
+                    this.SkillData.next_skill = Number(oneData[i]);
+                    break;
+                case 'up_gold':
+                    this.SkillData.up_gold = Number(oneData[i]);
+                    break;
+                case 'skill_effect_path':
+                    this.SkillData.skill_effect_path = oneData[i];
+                    break;
+                case 'skill_icon':
+                    this.SkillData.skill_icon = oneData[i];
+                    break;
+                case 'skill_text':
+                    this.SkillData.skill_text = oneData[i];
+                    break;
+
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+    /**天赋数据 */
+    public talentData = {
+        /**ID */
+        id: 1,
+        /**天赋名 */
+        name: '',
+        /** 消耗星数*/
+        star_required: 1,
+        /**天赋类型 */
+        talent_type: 1,
+        /**参数1 */
+        parameter_1: 1,
+        /**参数2 */
+        parameter_2: 1,
+        /**参数3 */
+        parameter_3: 1,
+        /** 参数4*/
+        parameter_4: 1,
+        /**参数5 */
+        parameter_5: 1,
+        /**图片名 */
+        talent_icon: '',
+        /**技能文本介绍 */
+        talent_text: '',
+
+    }
+
+    /**初始天赋数据 */
+    public writeTalent_Config(ID: number) {
+        let nameData = [];
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().uiSkill_Config.length; i++) {
+            const arr = gameData.instance().uiSkill_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    nameData.push(element);
+                }
+            }
+
+            if (Number(arr[0]) == ID) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    oneData.push(element);
+                }
+                break;
+            }
+        }
+
+        for (let i = 0; i < nameData.length; i++) {
+            const element = nameData[i];
+            switch (element) {
+                case 'id':
+                    this.talentData.id = Number(oneData[i]);
+                    break;
+                case 'name':
+                    this.talentData.name = oneData[i];
+                    break;
+                case 'star_required':
+                    this.talentData.star_required = Number(oneData[i]);
+                    break;
+                case 'talent_type':
+                    this.talentData.talent_type = Number(oneData[i]);
+                    break;
+                case 'parameter_1':
+                    this.talentData.parameter_1 = Number(oneData[i]);
+                    break;
+                case 'parameter_2':
+                    this.talentData.parameter_2 = Number(oneData[i]);
+                    break;
+                case 'parameter_3':
+                    this.talentData.parameter_3 = Number(oneData[i]);
+                    break;
+                case 'parameter_4':
+                    this.talentData.parameter_4 = Number(oneData[i]);
+                    break;
+                case 'parameter_5':
+                    this.talentData.parameter_5 = Number(oneData[i]);
+                    break;
+                case 'talent_icon':
+                    this.talentData.talent_icon = oneData[i];
+                    break;
+                case 'talent_text':
+                    this.talentData.talent_text = '';
+                    for (let k = i; k < oneData.length; k++) {
+                        const element = oneData[k];
+                        if (element == '') {
+                            continue;
+                        }
+                        this.talentData.talent_text += element;
+                    }
+                    break;
+
+
+
+                default:
+                    break;
+            }
+
+        }
+    }
+
+    /**获取数组 */
+    public getArr(str: string): number[] {
+        let numarr: number[] = [];
+        if (str != '') {
+            let arrr = str.split("*");
+            for (let m = 0; m < arrr.length; m++) {
+                const element = arrr[m];
+                numarr.push(Number(element));
+            }
+        }
+        return numarr;
+    }
+
+    /**根据难度获取系数 */
+    private getDiff(strrr): number {
+        if (strrr == '') {
+            return 0;
+        }
+        let attackarr = strrr.split("*");
+        return Number(attackarr[GameConfig.instance().levelDiff]);
+    }
+
+    /**type:1,取整数。2,取小数*/
+    public getRanm(type: number, strrr: string): number {
+        if (strrr == '' || !strrr) {
+            return 0;
+        }
+        let attackarr = strrr.split("*");
+        let leth = attackarr.length;
+        if (leth < 0) {
+            return 0;
+        }
+        let num1 = Number(attackarr[leth - 2]);
+        let num2 = Number(attackarr[leth - 1]);
+        let ranm = 0;
+        if (num1 < num2) {
+            if (type == 1) {
+                ranm = num1 + Math.floor(Math.random() * (num2 - num1 + 1));
+            }
+
+            if (type == 2) {
+                ranm = num1 + Math.random() * (num2 - num1);
+            }
+        }
+        else {
+            if (type == 1) {
+                ranm = num2 + Math.floor(Math.random() * (num1 - num2 + 1));
+            }
+
+            if (type == 2) {
+                ranm = num2 + Math.random() * (num1 - num2);
+            }
+        }
+
+        return ranm;
+    }
+
+}

+ 10 - 0
assets/Script/configData/DataObj.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "066ed95e-33fd-4ff6-9e48-eb80d6211ead",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 22 - 0
assets/Script/configData/Enum.ts

@@ -0,0 +1,22 @@
+/**
+ * 怪物行走路线类型
+ */
+ export enum RoadType {
+    OneRoad = 1,
+    TwoUp,
+    TwoDown,
+    ThreeUp,
+    ThreeDown,
+}
+
+
+
+/**
+ * 塔类型
+ */
+ export enum TowerType {
+    Enum_Turret = 3,
+    Enum_Magic = 2,
+    Enum_Arrow = 1,
+    Enum_Barrack = 4,
+}

+ 10 - 0
assets/Script/configData/Enum.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "45890b1a-d68e-40f9-b325-fc4ebfe09a74",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 82 - 0
assets/Script/configData/GameConfig.ts

@@ -0,0 +1,82 @@
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class GameConfig {
+
+    static _instance: GameConfig = null!;
+    public static instance() 
+    {
+        if (!this._instance) 
+        {
+            this._instance = new GameConfig();
+        }
+        return this._instance;
+    }
+
+    public SreenSize: cc.Vec2 = new cc.Vec2(1920,1080);
+
+    public palyLevel = 1;
+    // /**塔攻击长半径单位 135  0.9*/
+    // public attackA = 1;  
+    // /**塔攻击短半径单位 112.5  0.9*/
+    // public attackB = 5/6;  
+    /**是否暂停 */
+    public isPause = false;
+    /**关卡难度  0,1,2*/
+    public levelDiff = 0;
+
+    /**设置游戏速度 */
+    public speed = 1;
+
+    // public storageData = {
+    //     /**钻石数 */
+    //     Diamond:0,
+    //     /**天赋开启 1开启 0未开启 */
+    //     myTalant:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
+    //     /**剩余星星数 */
+    //     starNum:0,
+    //     /**获得星星总数 */
+    //     TotalStarNum:0,
+    //     /**每一关星星数 */
+    //     levelStar:[],
+    //     /**当前关卡数 */
+    //     level:1,
+    // }
+
+    public storageData = {
+        /**钻石数 */
+        Diamond:0,
+        /**天赋开启 1开启 0未开启 */
+        myTalant:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
+        /**剩余星星数 */
+        starNum:90,
+        /**获得星星总数 */
+        TotalStarNum:90,
+        /**每一关星星数 */
+        levelStar:[3,3,3,3,3,3,3,3,3,3,3,3,3,3,3],
+        /**当前关卡数 */
+        level:15,
+    }
+
+    public  setStorage()
+    {
+        localStorage.setItem("rushuserInfo", JSON.stringify(this.storageData));
+    } 
+
+    public  getStorage() :any
+    {
+        let user = null;
+        let info = localStorage.getItem("rushuserInfo");
+        if (info) {
+            user = JSON.parse(info);
+        }
+        return user;
+    }
+    
+
+
+
+    //塔 兵  怪 安座标更新层数 最高108层
+    //泥土0,建塔环1006  升级环1006 骷髅1008 插旗1007 不能插旗标志1007 陨石1009  激光、冲击光:1008
+}

+ 10 - 0
assets/Script/configData/GameConfig.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "965146dc-76ac-4daa-952c-26ad0a4340c8",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 81 - 0
assets/Script/configData/ReadCsv.ts

@@ -0,0 +1,81 @@
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class ReadCsv extends cc.Component {
+
+    static _instance: ReadCsv = null!;
+    public static instance() 
+    {
+        if (!this._instance) 
+        {
+            this._instance = new ReadCsv();
+        }
+        return this._instance;
+    }
+    
+
+    public CSVToArray(fullPath:string,callback) {
+        cc.resources.load(fullPath, function (err, string) {
+            if (err) {
+                cc.error(err.message || err);
+                return;
+            }
+
+            let array = ReadCsv.instance().CSVStringToArrayJerry(string);
+            if (callback){
+                callback(array);
+            }
+        });
+    }
+
+    public CSVStringToArray( strData: string, strDelimiter:any ):any[] {
+        strDelimiter = (strDelimiter || ",");
+        var objPattern = new RegExp(
+        (
+        "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
+        "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
+        "([^\"\\" + strDelimiter + "\\r\\n]*))"
+        ),
+        "gi"
+        );
+        var arrData = [[]];
+        var arrMatches = null;
+        while (arrMatches = objPattern.exec( strData )){
+            var strMatchedDelimiter = arrMatches[ 1 ];
+            if (strMatchedDelimiter.length && (strMatchedDelimiter != strDelimiter)){
+                arrData.push( [] );
+            }
+            if (arrMatches[ 2 ]){
+                var strMatchedValue = arrMatches[ 2 ].replace(
+                new RegExp( "\"\"", "g" ),
+                "\""
+            );
+            } else {
+                var strMatchedValue = arrMatches[ 3 ];
+            }
+            arrData[ arrData.length - 1 ].push( strMatchedValue );
+        }
+        if(arrData.length>0){
+            arrData.pop();
+        }
+        return arrData;
+    }
+
+    //用这个方法也可以
+    public CSVStringToArrayJerry(strData: cc.Asset):any[]{
+        let str = strData.toString().replace(/\r/g,"");
+        let mapArr = str.split("\n");
+        var array = [];
+        for (let index = 0; index < mapArr.length; index++) {
+            const element = mapArr[index];
+            let arr = element.split(",");
+            array[index] = arr;
+        }
+
+        return array;
+    }
+
+   
+}

+ 10 - 0
assets/Script/configData/ReadCsv.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "043f1df7-9089-421c-8491-b2622e3ebbcf",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 123 - 0
assets/Script/configData/gameData.ts

@@ -0,0 +1,123 @@
+import GameConfig from "./GameConfig";
+import ReadCsv from "./ReadCsv";
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class gameData extends cc.Component {
+
+    static _instance: gameData = null!;
+    public static instance() 
+    {
+        if (!this._instance) 
+        {
+            this._instance = new gameData();
+        }
+        return this._instance;
+    }
+
+    /**子弹数据 */
+    public bullet_Config = [];
+    /**综合数据 */
+    public game_Const = [];
+    /**关卡数据 */
+    public level_Config = [];
+    /** 怪物数据*/
+    public monster_Config = [];
+    /**塔数据 */
+    public tower_Config = [];
+    /**每关怪物出场顺序 */
+    public timeLevel_Config  = [];
+    /**技能数据 */
+    public skill_Config  = [];
+    /**ui界面技能升级数据 */
+    public uiSkill_Config  = [];
+    /**音乐音效数据 */
+    public audio_Config  = [];
+
+    private readcount = 0;
+    public readGameData(callback)
+    {
+        this.readcount = 0;
+        let self = this;
+        //子弹数据
+        ReadCsv.instance().CSVToArray("data/bullet_Config",function (data) {
+            self.bullet_Config = data;
+            // console.log("self.bullet_Config:"+data);
+            self.readOver(callback);
+         });
+
+         //综合数据
+        ReadCsv.instance().CSVToArray("data/game_Const",function (data) {
+            self.game_Const = data;
+            // console.log("self.game_Const:"+data);
+            self.readOver(callback);
+        });
+
+        //关卡数据
+        ReadCsv.instance().CSVToArray("data/level_Config",function (data) {
+            self.level_Config = data;
+            // console.log("self.level_Config:"+data);
+            self.readOver(callback);
+        });
+        //怪物数据
+        ReadCsv.instance().CSVToArray("data/monster_Config",function (data) {
+            self.monster_Config = data;
+            // console.log("self.monster_Config:"+data);
+            self.readOver(callback);
+        });
+
+        //塔数据
+        ReadCsv.instance().CSVToArray("data/tower_Config",function (data) {
+            self.tower_Config = data;
+            // console.log("self.tower_Config:"+data);
+            self.readOver(callback);
+        });
+
+        //技能数据
+        ReadCsv.instance().CSVToArray("data/skill_Config",function (data) {
+            self.skill_Config = data;
+            // console.log("self.tower_Config:"+data);
+            self.readOver(callback);
+        });
+
+        //ui界面技能升级数据
+        ReadCsv.instance().CSVToArray("data/talent_Config",function (data) {
+            self.uiSkill_Config = data;
+            // console.log("self.tower_Config:"+data);
+            self.readOver(callback);
+        });
+
+        //音乐数据
+        ReadCsv.instance().CSVToArray("data/audio_Config",function (data) {
+            self.audio_Config = data;
+            // console.log("self.tower_Config:"+data);
+            self.readOver(callback);
+        });
+    }
+
+    private readOver(callback)
+    {
+        this.readcount++;
+        if (this.readcount == 8) {
+            if (callback) {
+                callback();
+            }
+        }
+    }
+
+
+
+    /**读取每关怪物出场数据 */
+    public readLevel(level:number,callback)
+    {
+        let self = this;
+        ReadCsv.instance().CSVToArray("data/level_"+level,function (data) {
+            self.timeLevel_Config = data;
+            if (callback){
+                callback();
+            }
+         });
+    }
+
+}

+ 10 - 0
assets/Script/configData/gameData.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "885dfaaf-1aff-40e2-9c2c-ec2179edc161",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 91 - 0
assets/Script/configData/path.ts

@@ -0,0 +1,91 @@
+import gameUI from "../game/UIFace/gameUI";
+import GameConfig from "./GameConfig";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class path extends cc.Component {
+
+    private anim :cc.Animation = null;
+    private pathdata:cc.Vec3[] = [];
+    public static instance:path = null;
+    onLoad () {
+        path.instance = this;
+        //获取当前节点上的动画组件
+        this.anim = this.node.getComponent(cc.Animation);
+        // this.anim.play("path_1");
+    }
+
+    /**编辑路径 */
+    public changeLevelData(): void
+    {
+        //获取动画片段
+        let clips = this.anim.getClips();
+        //获取当前片段
+        let clip = clips[gameUI.instance.myDataObj.LevelData.scene_path-1];
+        //获取贝塞尔曲线路径
+        this.pathdata = [];
+        if (clip) {
+            //获取贝塞尔曲线路径
+            let frames = clip.curveData.props.position;
+            this.genPathData(frames);
+        }
+    }
+
+
+    private  genPathData(frames): void{
+        let bezier = [];
+        //贝塞尔曲线定义四个点:起点、终点、两个相互分离中间控制点点 [begin, ctrl1, ctrl2, end]
+        let begin = null, ctrl1 = null, ctrl2 = null, end = null;
+        //遍历关键帧获取贝塞尔曲线
+        for(let i=0; i<frames.length; i++){
+            const frame = frames[i];
+            //获取控制起点
+            if(ctrl1 !== null){
+                bezier.push([begin, ctrl1, ctrl1, cc.v3(frame.value[0], frame.value[1])]);
+            }
+            //获取起点坐标
+            begin = cc.v3(frame.value[0], frame.value[1]);
+            //获取关键帧的运动路径
+            const motionPath = frame.motionPath;
+            //遍历关键帧运动路径获取贝塞尔曲线的四个点
+            for(let j=0; j<motionPath.length; j++){
+                const item = motionPath[j];
+                //获取终点
+                end = cc.v3(item[0], item[1]);
+                //获取控制终点
+                ctrl2 = cc.v3(item[2], item[3]);
+                //判断控制起点是否为空
+                if(ctrl1 === null){
+                    ctrl1 = ctrl2;
+                }
+                //添加贝塞尔曲线中各点坐标
+                bezier.push([begin, ctrl1, ctrl2, end]);
+                //获取控制起点
+                ctrl1 = cc.v3(item[4], item[5]);
+                //设置下一个节点的起点为上一个节点的终点
+                begin = end;
+            }
+        }
+        // //将贝塞尔曲线转换为坐标点
+        // const first:cc.Vec3 = bezier[0][0];//获取起始点坐标
+        // let data = [first];
+        let data = [];
+        for(let k=0; k<bezier.length; k++){
+            const item = bezier[k];
+            data.push(item[0]);
+            if (k == bezier.length-1) {
+                data.push(item[3]);
+            }
+        }
+        this.pathdata = data;
+    }
+        
+    /**获取路径 */
+    public getPathData(){
+        return this.pathdata;
+    }
+    
+    
+}

+ 10 - 0
assets/Script/configData/path.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "1aa8f821-373e-4c39-a14b-7082fa57748e",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 93 - 0
assets/Script/configData/path1.ts

@@ -0,0 +1,93 @@
+import gameUI from "../game/UIFace/gameUI";
+import GameConfig from "./GameConfig";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class path1 extends cc.Component {
+
+    private anim :cc.Animation = null;
+    private path1data:cc.Vec3[] = [];
+    public static instance:path1 = null;
+    onLoad () {
+        path1.instance = this;
+        //获取当前节点上的动画组件
+        this.anim = this.node.getComponent(cc.Animation);
+        // this.anim.play("path1_1");
+    }
+
+    /**编辑路径 */
+    public changeLevelData(): void
+    {
+        this.path1data = [];
+        if (this.anim == null) {
+            return;
+        }
+        //获取动画片段
+        let clips = this.anim.getClips();
+        //获取当前片段
+        let clip = clips[gameUI.instance.myDataObj.LevelData.scene_path-1];
+        if (clip) {
+            //获取贝塞尔曲线路径
+            let frames = clip.curveData.props.position;
+            this.genpath1Data(frames);
+        }
+    }
+
+
+    private  genpath1Data(frames): void{
+        let bezier = [];
+        //贝塞尔曲线定义四个点:起点、终点、两个相互分离中间控制点点 [begin, ctrl1, ctrl2, end]
+        let begin = null, ctrl1 = null, ctrl2 = null, end = null;
+        //遍历关键帧获取贝塞尔曲线
+        for(let i=0; i<frames.length; i++){
+            const frame = frames[i];
+            //获取控制起点
+            if(ctrl1 !== null){
+                bezier.push([begin, ctrl1, ctrl1, cc.v3(frame.value[0], frame.value[1])]);
+            }
+            //获取起点坐标
+            begin = cc.v3(frame.value[0], frame.value[1]);
+            //获取关键帧的运动路径
+            const motionPath = frame.motionPath;
+            //遍历关键帧运动路径获取贝塞尔曲线的四个点
+            for(let j=0; j<motionPath.length; j++){
+                const item = motionPath[j];
+                //获取终点
+                end = cc.v3(item[0], item[1]);
+                //获取控制终点
+                ctrl2 = cc.v3(item[2], item[3]);
+                //判断控制起点是否为空
+                if(ctrl1 === null){
+                    ctrl1 = ctrl2;
+                }
+                //添加贝塞尔曲线中各点坐标
+                bezier.push([begin, ctrl1, ctrl2, end]);
+                //获取控制起点
+                ctrl1 = cc.v3(item[4], item[5]);
+                //设置下一个节点的起点为上一个节点的终点
+                begin = end;
+            }
+        }
+        // //将贝塞尔曲线转换为坐标点
+        // const first:cc.Vec3 = bezier[0][0];//获取起始点坐标
+        // let data = [first];
+        let data = [];
+        for(let k=0; k<bezier.length; k++){
+            const item = bezier[k];
+            data.push(item[0]);
+            if (k == bezier.length-1) {
+                data.push(item[3]);
+            }
+        }
+        this.path1data = data;
+    }
+    
+    /**获取路径 */
+    public getpathData(){
+        return this.path1data;
+    }
+    
+    
+}

+ 10 - 0
assets/Script/configData/path1.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "4606b6e8-c95d-4f07-82d2-53cacd54777d",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 93 - 0
assets/Script/configData/path2.ts

@@ -0,0 +1,93 @@
+import gameUI from "../game/UIFace/gameUI";
+import GameConfig from "./GameConfig";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class path2 extends cc.Component {
+
+    private anim: cc.Animation = null;
+    private path2data: cc.Vec3[] = [];
+    public static instance: path2 = null;
+    onLoad() {
+        path2.instance = this;
+        //获取当前节点上的动画组件
+        this.anim = this.node.getComponent(cc.Animation);
+        // this.anim.play("path2_1");
+    }
+
+    /**编辑路径 */
+    public changeLevelData(): void {
+        this.path2data = [];
+        if (this.anim == null) {
+            return;
+        }
+        //获取动画片段
+        let clips = this.anim.getClips();
+        //获取当前片段
+        let clip = clips[gameUI.instance.myDataObj.LevelData.scene_path - 1];
+        if (clip) {
+            //获取贝塞尔曲线路径
+            let frames = clip.curveData.props.position;
+            this.genpath2Data(frames);
+        }
+
+    }
+
+
+    private genpath2Data(frames): void {
+        let bezier = [];
+        //贝塞尔曲线定义四个点:起点、终点、两个相互分离中间控制点点 [begin, ctrl1, ctrl2, end]
+        let begin = null, ctrl1 = null, ctrl2 = null, end = null;
+        //遍历关键帧获取贝塞尔曲线
+        for (let i = 0; i < frames.length; i++) {
+            const frame = frames[i];
+            //获取控制起点
+            if (ctrl1 !== null) {
+                bezier.push([begin, ctrl1, ctrl1, cc.v3(frame.value[0], frame.value[1])]);
+            }
+            //获取起点坐标
+            begin = cc.v3(frame.value[0], frame.value[1]);
+            //获取关键帧的运动路径
+            const motionPath = frame.motionPath;
+            //遍历关键帧运动路径获取贝塞尔曲线的四个点
+            for (let j = 0; j < motionPath.length; j++) {
+                const item = motionPath[j];
+                //获取终点
+                end = cc.v3(item[0], item[1]);
+                //获取控制终点
+                ctrl2 = cc.v3(item[2], item[3]);
+                //判断控制起点是否为空
+                if (ctrl1 === null) {
+                    ctrl1 = ctrl2;
+                }
+                //添加贝塞尔曲线中各点坐标
+                bezier.push([begin, ctrl1, ctrl2, end]);
+                //获取控制起点
+                ctrl1 = cc.v3(item[4], item[5]);
+                //设置下一个节点的起点为上一个节点的终点
+                begin = end;
+            }
+        }
+        // //将贝塞尔曲线转换为坐标点
+        // const first:cc.Vec3 = bezier[0][0];//获取起始点坐标
+        // let data = [first];
+        let data = [];
+        for (let k = 0; k < bezier.length; k++) {
+            const item = bezier[k];
+            data.push(item[0]);
+            if (k == bezier.length - 1) {
+                data.push(item[3]);
+            }
+        }
+        this.path2data = data;
+    }
+
+    /**获取路径 */
+    public getpathData() {
+        return this.path2data;
+    }
+
+
+}

+ 10 - 0
assets/Script/configData/path2.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "d8efa26f-a250-49a0-b151-3451b2de6ff1",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 89 - 0
assets/Script/configData/path3.ts

@@ -0,0 +1,89 @@
+
+import gameUI from "../game/UIFace/gameUI";
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class path3 extends cc.Component {
+
+    private anim: cc.Animation = null;
+    private path3data: cc.Vec3[] = [];
+    public static instance: path3 = null;
+    onLoad() {
+        path3.instance = this;
+        //获取当前节点上的动画组件
+        this.anim = this.node.getComponent(cc.Animation);
+        // this.anim.play("path3_1");
+    }
+
+    /**编辑路径 */
+    public changeLevelData(): void {
+        this.path3data = [];
+        if (this.anim == null) {
+            return;
+        }
+        //获取动画片段
+        let clips = this.anim.getClips();
+        //获取当前片段
+        let clip = clips[gameUI.instance.myDataObj.LevelData.scene_path - 1];
+        if (clip) {
+            //获取贝塞尔曲线路径
+            let frames = clip.curveData.props.position;
+            this.genpath3Data(frames);
+        }
+
+    }
+
+
+    private genpath3Data(frames): void {
+        let bezier = [];
+        //贝塞尔曲线定义四个点:起点、终点、两个相互分离中间控制点点 [begin, ctrl1, ctrl2, end]
+        let begin = null, ctrl1 = null, ctrl2 = null, end = null;
+        //遍历关键帧获取贝塞尔曲线
+        for (let i = 0; i < frames.length; i++) {
+            const frame = frames[i];
+            //获取控制起点
+            if (ctrl1 !== null) {
+                bezier.push([begin, ctrl1, ctrl1, cc.v3(frame.value[0], frame.value[1])]);
+            }
+            //获取起点坐标
+            begin = cc.v3(frame.value[0], frame.value[1]);
+            //获取关键帧的运动路径
+            const motionPath = frame.motionPath;
+            //遍历关键帧运动路径获取贝塞尔曲线的四个点
+            for (let j = 0; j < motionPath.length; j++) {
+                const item = motionPath[j];
+                //获取终点
+                end = cc.v3(item[0], item[1]);
+                //获取控制终点
+                ctrl2 = cc.v3(item[2], item[3]);
+                //判断控制起点是否为空
+                if (ctrl1 === null) {
+                    ctrl1 = ctrl2;
+                }
+                //添加贝塞尔曲线中各点坐标
+                bezier.push([begin, ctrl1, ctrl2, end]);
+                //获取控制起点
+                ctrl1 = cc.v3(item[4], item[5]);
+                //设置下一个节点的起点为上一个节点的终点
+                begin = end;
+            }
+        }
+        // //将贝塞尔曲线转换为坐标点
+        // const first:cc.Vec3 = bezier[0][0];//获取起始点坐标
+        // let data = [first];
+        let data = [];
+        for (let k = 0; k < bezier.length; k++) {
+            const item = bezier[k];
+            data.push(item[0]);
+            if (k == bezier.length - 1) {
+                data.push(item[3]);
+            }
+        }
+        this.path3data = data;
+    }
+
+    /**获取路径 */
+    public getpathData() {
+        return this.path3data;
+    }
+}

+ 10 - 0
assets/Script/configData/path3.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "581b3087-6c04-4200-9a37-32740b0adc1e",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/game.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "ff568a99-8e9b-4215-98ed-5527f6c48826",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/game/UIFace.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "385414c8-5966-43b8-a1db-94abcd2da547",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 91 - 0
assets/Script/game/UIFace/LevelIntro.ts

@@ -0,0 +1,91 @@
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import mainManager from "../../mainFace/mainManager";
+import monsterNode from "../monster/monsterNode";
+import gameManger from "./gameManger";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class LevelIntro extends cc.Component {
+
+    @property(cc.Sprite)
+    private introduce_bg: cc.Sprite = null;
+    @property(cc.Label)
+    private zhangjie: cc.Label = null;
+    @property(cc.Sprite)
+    private zhezhao: cc.Sprite = null;
+
+    public myDataObj: DataObj = null;
+    //-288,-95
+    //-258,100
+    protected onLoad() {
+        this.myDataObj = new DataObj();
+        this.myDataObj.writeLevel_Config(GameConfig.instance().palyLevel);
+        this.introduce_bg.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        this.zhezhao.node.on(cc.Node.EventType.TOUCH_START, this.onclosed, this);
+        this.zhangjie.string = this.myDataObj.LevelData.name;
+        this.loadMonIcon();
+    }
+
+    /**加载怪物图片和星星 */
+    private loadMonIcon() {
+        let self = this;
+        let arrtemp = this.myDataObj.LevelData.level_monster;
+
+
+        cc.resources.load("game/heroheadbg", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+            for (let i = 0; i < arrtemp.length; i++) {
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                mynode.setPosition(cc.v2(-288 + 148 * i, -95));
+                self.introduce_bg.node.addChild(mynode);
+            }
+        });
+
+
+        for (let i = 0; i < arrtemp.length; i++) {
+            this.myDataObj.writeMonster_Config(arrtemp[i]);
+            cc.resources.load("prefabs/" + this.myDataObj.monsterData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+                let guainode = cc.instantiate(prefab);
+                guainode.setPosition(cc.v2(-288 + 148 * i, -95-53));
+                self.introduce_bg.node.addChild(guainode, 2);
+
+                if (guainode.getContentSize().height > 128) {
+                    guainode.setPosition(cc.v2(-288 + 148 * i, -95-90));
+                }
+                let monster = guainode.getComponent(monsterNode);
+                monster.iconShow();
+            });
+        }
+        cc.resources.load("levelIntroduce/introduce_dex", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+            for (let i = 0; i < GameConfig.instance().storageData.levelStar[GameConfig.instance().palyLevel - 1]; i++) {
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                mynode.setPosition(cc.v2(-177 + 182 * i, 99));
+                self.introduce_bg.node.addChild(mynode);
+            }
+        });
+    }
+
+    private onTouchStart(e: cc.Event.EventTouch): void {
+
+
+    }
+
+    /** 关闭介绍*/
+    private onTouchclosed() {
+        mainManager.instance.node.active = false;
+        gameManger.instance.initLevel();
+        this.node.destroy();
+    }
+
+    /** 关闭介绍*/
+    private onclosed() {
+
+        this.node.destroy();
+    }
+}

+ 10 - 0
assets/Script/game/UIFace/LevelIntro.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "a9294d66-5df4-4ae5-897b-07f2fb54942e",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 30 - 0
assets/Script/game/UIFace/TapNode.ts

@@ -0,0 +1,30 @@
+import gameUI from "./gameUI";
+import towerManger from ".././tower/towerManger";
+import viewComtent from "./viewComtent";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class TapNode extends cc.Component {
+
+    public static instance:TapNode = null;
+    protected onLoad () {
+        TapNode.instance = this;
+        this.node.active = false;
+        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+    }
+
+    /**
+     * touchstart 回调
+     * @param e 参数
+     */
+     private onTouchStart(e: cc.Event.EventTouch): void {
+
+        let turnPos = e.getLocation().sub(cc.v2(960,540));
+        towerManger.instance.chaqiGetPos(turnPos.add(cc.v2(0,viewComtent.instance.getOff())));
+
+        gameUI.instance.SkillTap(turnPos.add(cc.v2(0,viewComtent.instance.getOff())));
+    }
+
+}

+ 10 - 0
assets/Script/game/UIFace/TapNode.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "f6074056-238f-4faa-9075-6e6f0446a4f7",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 162 - 0
assets/Script/game/UIFace/gameManger.ts

@@ -0,0 +1,162 @@
+import GameConfig from "../../configData/GameConfig";
+import { TowerType } from "../../configData/Enum";
+import gameData from "../../configData/gameData";
+import path from "../../configData/path";
+import path1 from "../../configData/path1";
+import path2 from "../../configData/path2";
+import gameUI from "./gameUI";
+import monsterManger from ".././monster/monsterManger";
+import towerManger from ".././tower/towerManger";
+import viewComtent from "./viewComtent";
+import path3 from "../../configData/path3";
+import { AudioManager } from "../../configData/AudioManager";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class gameManger extends cc.Component {
+
+ 
+    public static instance:gameManger = null;
+    private _touchId = null;
+    private beijing:cc.Node = null;
+    protected onLoad (): void {
+        gameManger.instance = this;
+        this.beijing = this.node.getChildByName("beijing");
+        let self = this;
+        gameData.instance().readGameData(function(){
+            // self.initLevel();
+            AudioManager.palyAudio(1);
+        });
+
+
+        this.bindTouchEvents();
+    }
+
+    onDestroy(){
+        // gameManger.instance = null;
+    }
+
+    /**加载底图 */
+    private loadGamebg()
+    {
+        let self = this;
+        cc.resources.load("gamebg/game_"+gameUI.instance.myDataObj.LevelData.scene_path, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.beijing.getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+        });
+    }
+ 
+    public initLevel()
+    {
+        // console.log("--------------------ceshi");
+        GameConfig.instance().isPause = false;
+        cc.director.getScheduler().setTimeScale(1);
+        GameConfig.instance().speed = 1;
+        cc.director.resume();
+        GameConfig.instance().levelDiff = 0;
+        gameUI.instance.initData();
+        
+        this.loadGamebg();
+        path.instance.changeLevelData();
+        path1.instance.changeLevelData();
+        path2.instance.changeLevelData();
+        path3.instance.changeLevelData();
+        gameUI.instance.loadGoPos();
+        
+
+
+        
+        monsterManger.instance.initMonster();
+        towerManger.instance.initTowerTaside();
+        towerManger.instance.updateTowerActionSchle();
+    }
+
+    /**游戏结算 */
+    public gameOver(HpNum:number){
+        towerManger.instance.setAniGo(true);
+        viewComtent.instance.gameOver(HpNum);
+    }
+
+    
+    /**
+     * touchstart 回调
+     * @param e 参数
+     */
+     private onTouchStart(e: cc.Event.EventTouch): void {
+        if (this._touchId !== null) {
+            return;
+        }
+        // console.log("坐标:"+e.getLocation());    
+        this._touchId = e.getID();
+       
+        // let turnPos = e.getLocation().sub(cc.v2(960,540));
+      
+
+        towerManger.instance.closedHuan();
+        // towerManger.instance.chaqiGetPos(turnPos.add(cc.v2(0,viewComtent.instance.getOff())));
+  
+    }
+
+
+    /**
+     * touchend 回调
+     */
+     private onTouchMoved(e: cc.Event.EventTouch): void {
+        if (e.getID() !== this._touchId) {
+            return;
+        }
+
+    }
+
+
+     /**
+     * touchend 回调
+     */
+      private onTouchEnd(e: cc.Event.EventTouch): void {
+
+        this.touchEnd(e);
+    }
+
+     /**
+     * touchcancel 回调
+     * @param e 参数
+     */
+      private onTouchCancel(e: cc.Event.EventTouch): void {
+     //   console.log("取消触摸");
+        this.touchEnd(e);
+    }
+
+    private touchEnd(e: cc.Event.EventTouch): void{
+        if (e.getID() !== this._touchId) {
+            return;
+        }
+        this._touchId = null;
+    }
+
+
+    /**
+     * 绑定点击事件
+     */
+     private bindTouchEvents(): void {
+        this.beijing.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        this.beijing.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMoved, this);
+        this.beijing.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
+        this.beijing.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
+     //   console.log("加载触摸");
+    }
+
+    /**
+     * 解绑点击事件
+     */
+    private unbindTouchEvents(): void {
+        this.beijing.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        this.beijing.off(cc.Node.EventType.TOUCH_MOVE, this.onTouchMoved, this);
+        this.beijing.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
+        this.beijing.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
+     //   console.log("关闭触摸");
+    }
+
+
+
+}

+ 10 - 0
assets/Script/game/UIFace/gameManger.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "4e205b2b-5260-4e84-9f70-00c35d7bc408",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 126 - 0
assets/Script/game/UIFace/gameOver.ts

@@ -0,0 +1,126 @@
+import { AudioManager } from "../../configData/AudioManager";
+import GameConfig from "../../configData/GameConfig";
+import mainManager from "../../mainFace/mainManager";
+import gameManger from "./gameManger";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class gameOver extends cc.Component {
+
+    @property(cc.Sprite)
+    private winbg: cc.Sprite = null;
+    @property(cc.Sprite)
+    private Failbg: cc.Sprite = null;
+    @property(cc.Sprite)
+    private zhezhao: cc.Sprite = null;
+
+
+    protected onLoad() {
+        this.winbg.node.opacity = 255;
+        this.Failbg.node.opacity = 255;
+        this.winbg.node.active = false;
+        this.Failbg.node.active = false;
+
+        this.zhezhao.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        cc.director.pause();
+    }
+
+    /**判断结算 iswin:星星数量*/
+    public gameiswin(iswin: number) {
+        this.winbg.node.active = (iswin > 0);
+        this.Failbg.node.active = (iswin == 0);
+        if (iswin > 0) {
+            AudioManager.palyAudio(8);
+            let nowlevel = GameConfig.instance().palyLevel;
+            if (GameConfig.instance().storageData.level <= nowlevel) {
+                GameConfig.instance().storageData.level = nowlevel+1;
+                if (iswin < 10) {
+                    GameConfig.instance().storageData.levelStar.push(1);
+                }
+                if (iswin > 10&&iswin < 16) {
+                    GameConfig.instance().storageData.levelStar.push(2);
+                }
+                if (iswin > 16) {
+                    GameConfig.instance().storageData.levelStar.push(3);
+                }
+                GameConfig.instance().storageData.starNum += GameConfig.instance().storageData.levelStar[nowlevel-1];
+            }
+            else
+            {
+                let starnum = GameConfig.instance().storageData.levelStar[nowlevel-1];
+                
+                if (iswin > 10&&iswin < 16) {
+                    if (starnum < 2) {
+                        GameConfig.instance().storageData.levelStar[nowlevel-1] = 2;
+
+                        GameConfig.instance().storageData.starNum -= GameConfig.instance().storageData.levelStar[nowlevel-1];
+                        GameConfig.instance().storageData.starNum += 2;
+                    }
+                }
+                if (iswin > 16) {
+                    if (starnum < 3) {
+                        GameConfig.instance().storageData.levelStar[nowlevel-1] = 3;
+
+                        GameConfig.instance().storageData.starNum -= GameConfig.instance().storageData.levelStar[nowlevel-1];
+                        GameConfig.instance().storageData.starNum += 3;
+                    }
+                }
+            }
+
+            let totalnum = 0;
+            for (let i = 0; i < GameConfig.instance().storageData.levelStar.length; i++) {
+                const element = GameConfig.instance().storageData.levelStar[i];
+                totalnum += element;
+            }
+            GameConfig.instance().storageData.TotalStarNum = totalnum;
+            GameConfig.instance().setStorage();
+        }
+        else
+        {
+            AudioManager.palyAudio(7);
+        }
+    }
+
+    /**再试一次 */
+    private retry() {
+        AudioManager.palyAudio(6);
+        gameManger.instance.initLevel();
+        this.node.destroy();
+    }
+    
+    /**继续 */
+    private nextGame() {
+        AudioManager.palyAudio(6);
+        GameConfig.instance().palyLevel++;
+        gameManger.instance.initLevel();
+        this.node.destroy();
+
+    }
+
+    /**看广告的奖励 */
+    private seeAdGetGold() {
+        AudioManager.palyAudio(6);
+
+    }
+
+    /**返回 */
+    private failBack() {
+        AudioManager.palyAudio(6);
+        mainManager.instance.node.active = true;
+        mainManager.instance.backInit();
+        this.node.destroy();
+    }
+
+    private onTouchStart(e: cc.Event.EventTouch): void {
+
+
+    }
+
+    onDestroy() {
+        cc.director.resume();
+        
+    }
+
+}

+ 10 - 0
assets/Script/game/UIFace/gameOver.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "e67641e9-9989-4c37-a076-6d73c5a9b0f6",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 378 - 0
assets/Script/game/UIFace/gameUI.ts

@@ -0,0 +1,378 @@
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import path from "../../configData/path";
+import path1 from "../../configData/path1";
+import path2 from "../../configData/path2";
+import gameManger from "./gameManger";
+import monsterManger from ".././monster/monsterManger";
+import TapNode from "./TapNode";
+import towerManger from ".././tower/towerManger";
+import skillManger from "../tower/skillManger";
+import SkillSolate from "../tower/SkillSolate";
+import path3 from "../../configData/path3";
+import mainManager from "../../mainFace/mainManager";
+import { AudioManager } from "../../configData/AudioManager";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class gameUI extends cc.Component {
+
+    @property(cc.Node)
+    private pausedbg: cc.Node = null;
+
+    @property(cc.Label)
+    private HpLabel: cc.Label = null;
+    @property(cc.Label)
+    private GoupLabel: cc.Label = null;
+    @property(cc.Label)
+    private GoldLabel: cc.Label = null;
+
+    /**陨石技能 */
+    @property(cc.Sprite)
+    private yunshi: cc.Sprite = null;
+    /**援兵技能 */
+    @property(cc.Sprite)
+    private yuanBin: cc.Sprite = null;
+    /**加速按钮 */
+    @property(cc.Button)
+    private soonStep: cc.Button = null;
+    @property(cc.SpriteFrame)
+    private soonStep1: cc.SpriteFrame = null;
+    @property(cc.SpriteFrame)
+    private soonStep2: cc.SpriteFrame = null;
+
+    private GoPos: cc.Vec3[] = [];
+
+    private yunshiCoint = 0;
+    private yuanbinCoint = 0;
+    private isCanPlayYunshi = false;
+    private isCanPlayYuanbin = false;
+    private yunshiDelay = 1;
+    private yuanbinDelay = 1;
+
+    private hpnum = 0;
+    private groupNow = 0;
+    private groupTotal = 0;
+    private goldnum = 0;
+
+
+    public myDataObj: DataObj = null;
+    public static instance: gameUI = null;
+
+    protected onLoad(): void {
+        gameUI.instance = this;
+        this.node.opacity = 255;
+        this.pausedbg.active = false;
+        this.pausedbg.opacity = 255;
+        this.yunshi.node.active = false;
+        this.yuanBin.node.active = false;
+
+        this.pausedbg.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        this.myDataObj = new DataObj();
+
+        // this.node.getChildByName("pause").getComponent(cc.Button).enabled = false;
+        // this.node.getChildByName("pause").getComponent(cc.Button).disabledColor = cc.color(0,0,0);
+
+    }
+
+
+
+    /**初始化关卡数据 */
+    public initData() {
+
+        this.myDataObj.writeLevel_Config(GameConfig.instance().palyLevel);
+        this.hpnum = this.myDataObj.LevelData.level_hp;
+        let maptype = this.myDataObj.LevelData.map_type;
+        AudioManager.palyAudio(maptype + 2);
+
+        this.HpLabel.string = this.hpnum.toString();
+        this.goldnum = 0;
+        this.AddGold(this.myDataObj.LevelData.start_gold);
+        // this.soonStep.normalSprite = this.soonStep2;
+        // this.soonStep.pressedSprite = this.soonStep2;
+
+        this.soonStep.node.getChildByName('Background').getComponent(cc.Sprite).spriteFrame = this.soonStep1;
+    }
+
+    /** 游戏加速*/
+    private setSpeedSoon() {
+        let timescale = cc.director.getScheduler().getTimeScale();
+        if (timescale < 4) {
+            timescale += 1;
+            GameConfig.instance().speed = timescale;
+            cc.director.getScheduler().setTimeScale(timescale);
+            if (timescale == 4) {
+                this.soonStep.node.getChildByName('Background').getComponent(cc.Sprite).spriteFrame = this.soonStep2;
+            }
+        }
+        else {
+            timescale = 1;
+            GameConfig.instance().speed = timescale;
+            cc.director.getScheduler().setTimeScale(timescale);
+            this.soonStep.node.getChildByName('Background').getComponent(cc.Sprite).spriteFrame = this.soonStep1;
+        }
+    }
+
+    /**获取所有路径点 */
+    public getGoPos(): cc.Vec3[] {
+        return this.GoPos;
+    }
+
+    /**本关卡最高塔级数 */
+    public getLevelLimit(): number[] {
+        return this.myDataObj.LevelData.tower_limit;
+    }
+
+    /**设置波次 */
+    public setTotalGroup(nownum: number, totalnum: number) {
+        this.groupNow = nownum;
+        this.groupTotal = totalnum;
+        this.GoupLabel.string = this.groupNow.toString() + "/" + this.groupTotal.toString();
+    }
+
+    /**血量减少 */
+    public HpCut(num: number) {
+        this.hpnum -= num;
+        if (this.hpnum < 0) {
+            this.hpnum = 0;
+        }
+        this.HpLabel.string = this.hpnum.toString();
+        if (this.hpnum == 0) {
+            gameManger.instance.gameOver(this.hpnum);
+        }
+    }
+
+    /**获取血量 */
+    public getHp(): number {
+        return this.hpnum;
+    }
+
+    /**获取金币数 */
+    public getGold(): number {
+        return this.goldnum;
+    }
+
+    /**增加金币数 */
+    public AddGold(num: number) {
+        this.goldnum += num;
+        this.goldnum = Math.floor(this.goldnum);
+        this.GoldLabel.string = this.goldnum.toString();
+    }
+
+    /**获取钻石数 */
+    public getDiamind(): number {
+        return GameConfig.instance().storageData.Diamond;
+    }
+
+    /**增加钻石数 */
+    public addDiamind(num: number, pacent: number) {
+        let raaom = Math.random() * 100;
+        if (raaom <= pacent) {
+            GameConfig.instance().storageData.Diamond += num;
+            GameConfig.instance().setStorage();
+        }
+    }
+
+
+    /**暂停、开始游戏 */
+    private pauseGame() {
+        AudioManager.palyAudio(6);
+        GameConfig.instance().isPause = !GameConfig.instance().isPause;
+        this.pausedbg.active = true;
+        this.pauseFun();
+    }
+
+    /**暂停 */
+    public pauseFun() {
+        towerManger.instance.setAniGo(GameConfig.instance().isPause);
+        cc.director.pause();
+    }
+
+    /**释放暂停 */
+    public ClosepauseFun() {
+        cc.director.resume();
+    }
+
+    /**返回主界面 */
+    private backtomain() {
+        AudioManager.palyAudio(6);
+        mainManager.instance.node.active = true;
+        mainManager.instance.backInit();
+        this.pausedbg.active = false;
+    }
+    /**重玩 */
+    private repaly() {
+        AudioManager.palyAudio(6);
+        gameManger.instance.initLevel();
+        this.pausedbg.active = false;
+        //     cc.director.loadScene("gameScence");
+    }
+    /**继续 */
+    private goongame() {
+        AudioManager.palyAudio(6);
+        GameConfig.instance().isPause = !GameConfig.instance().isPause;
+        cc.director.resume();
+        towerManger.instance.setAniGo(GameConfig.instance().isPause);
+        this.pausedbg.active = false;
+    }
+
+
+    /**打开技能按钮 */
+    public openSkillBtn() {
+        this.myDataObj.writeSkill_Config(60);
+        this.yunshiDelay = this.myDataObj.SkillData.parameter_4;
+        if (towerManger.instance.talantData[22].length > 0) {
+            this.yunshiDelay -= towerManger.instance.talantData[22][2];
+        }
+        if (towerManger.instance.talantData[23].length > 0) {
+            this.yunshiDelay -= towerManger.instance.talantData[23][2];
+        }
+        this.myDataObj.writeSkill_Config(61);
+        this.yuanbinDelay = this.myDataObj.SkillData.parameter_4;
+
+        this.yunshi.node.active = true;
+        this.yuanBin.node.active = true;
+        this.yunshiCoint = 0;
+        this.yuanbinCoint = 0;
+        this.yunshiSchle();
+        this.yuanbinSchle();
+    }
+
+    /**陨石技能进度条 */
+    private yunshiSchle() {
+        if (this.yunshiCoint >= 10000) {
+            return;
+        }
+
+        this.yunshiCoint++;
+        let myprogress = this.yunshi.getComponent(cc.ProgressBar);
+        let total: number = this.yunshiDelay;
+        // let total: number = 2;
+        myprogress.progress = 1 - this.yunshiCoint / (total * 10);
+        if (this.yunshiCoint >= total * 10) {
+            this.yunshi.node.on(cc.Node.EventType.TOUCH_START, this.yunshiTouchOn, this);
+            return;
+        }
+
+        this.scheduleOnce(function () {
+            this.yunshiSchle();
+        }, 0.1);
+    }
+    /**援兵技能进度条 */
+    private yuanbinSchle() {
+        if (this.yuanbinCoint >= 10000) {
+            return;
+        }
+
+        this.yuanbinCoint++;
+        let myprogress = this.yuanBin.getComponent(cc.ProgressBar);
+        let total: number = this.yuanbinDelay;
+        // let total = 2;
+        myprogress.progress = 1 - this.yuanbinCoint / (total * 10);
+        if (this.yuanbinCoint >= total * 10) {
+            this.yuanBin.node.on(cc.Node.EventType.TOUCH_START, this.yuanbingTouchOn, this);
+            return;
+        }
+
+        this.scheduleOnce(function () {
+            this.yuanbinSchle();
+        }, 0.1);
+    }
+
+    /**记录路径点 */
+    public loadGoPos() {
+        this.GoPos = path.instance.getPathData().concat();
+        if (path1.instance.getpathData().length > 0) {
+            this.GoPos = this.GoPos.concat(path1.instance.getpathData());
+        }
+        if (path2.instance.getpathData().length > 0) {
+            this.GoPos = this.GoPos.concat(path2.instance.getpathData());
+        }
+        if (path3.instance.getpathData().length > 0) {
+            this.GoPos = this.GoPos.concat(path3.instance.getpathData());
+        }
+    }
+
+    /**点击援兵和陨石位置判断 */
+    private getIsInGopos(location: cc.Vec2): boolean {
+        let leth = 73;
+        let laca = cc.v3(location.x, location.y);
+        for (let i = 0; i < this.GoPos.length; i++) {
+            const element = this.GoPos[i];
+            if (element.sub(laca).mag() < leth) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**发动陨石技能 */
+    private yunshiTouchOn() {
+        AudioManager.palyAudio(6);
+        this.yunshiCoint = 0;
+        this.yunshi.node.off(cc.Node.EventType.TOUCH_START, this.yunshiTouchOn, this);
+        this.isCanPlayYunshi = true;
+        TapNode.instance.node.active = true;
+    }
+
+    /**发动援兵技能 */
+    private yuanbingTouchOn() {
+        AudioManager.palyAudio(6);
+        this.yuanbinCoint = 0;
+        this.yuanBin.node.off(cc.Node.EventType.TOUCH_START, this.yuanbingTouchOn, this);
+        this.isCanPlayYuanbin = true;
+        TapNode.instance.node.active = true;
+    }
+
+    /**陨石、援兵坐标 */
+    public SkillTap(location: cc.Vec2) {
+        if (this.isCanPlayYunshi == true || this.isCanPlayYuanbin == true) {
+            if (this.getIsInGopos(location)) {
+                TapNode.instance.node.active = false;
+
+                if (this.isCanPlayYunshi == true) {
+                    this.isCanPlayYunshi = false;
+                    this.yunshiSchle();
+                    skillManger.instance.yunshiBuild(location);
+                    if (towerManger.instance.talantData[24].length > 0) {
+                        for (let i = 0; i < towerManger.instance.talantData[24][1]; i++) {
+                            let ppos = this.GoPos[Math.floor(this.GoPos.length * Math.random())];
+                            skillManger.instance.yunshiBuild(cc.v2(ppos));
+                        }
+                    }
+                }
+                if (this.isCanPlayYuanbin == true) {
+                    this.isCanPlayYuanbin = false;
+                    this.yuanbinSchle();
+                    cc.resources.load("prefabs/skillSolate", cc.Prefab, function (err, prefab: cc.Prefab) {
+                        var newNode = cc.instantiate(prefab);
+                        newNode.setPosition(location);
+                        towerManger.instance.node.addChild(newNode, 1006);
+                        let calssName = newNode.getComponent(SkillSolate);
+                        calssName.towerType = 4;
+                        calssName.initID();
+                        towerManger.instance.towerArr.push(calssName);
+                    });
+                }
+            }
+            else {
+                monsterManger.instance.updatest(location);
+            }
+        }
+    }
+
+
+
+
+
+    /**
+     * touchstart 回调
+     * @param e 参数
+     */
+    private onTouchStart(e: cc.Event.EventTouch): void {
+
+
+    }
+}

+ 10 - 0
assets/Script/game/UIFace/gameUI.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "566726bf-5b02-4b3b-b1c3-5f8b1b25a6e4",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 48 - 0
assets/Script/game/UIFace/viewComtent.ts

@@ -0,0 +1,48 @@
+import GameConfig from "../../configData/GameConfig";
+import gameOver from "./gameOver";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class viewComtent extends cc.Component {
+
+    private winsize:cc.Vec2 = null;
+    public static instance: viewComtent = null;
+    protected onLoad() {
+        viewComtent.instance = this;
+        let hhh = cc.winSize.height * (1920 / cc.winSize.width);
+        this.node.setContentSize(1920, hhh);
+        this.winsize = cc.v2(1920, hhh);
+      
+        
+    }
+
+    
+
+    /**游戏结算 */
+    public gameOver(Hpnum: number) {
+        let self = this;
+        cc.resources.load("prefabs/over", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            self.node.addChild(newNode, 1);
+            newNode.setPosition(cc.v2(0, 0));
+            let iver = newNode.getComponent(gameOver);
+            iver.gameiswin(Hpnum);
+        });
+    }
+
+    /**获取屏幕真是大小 */
+    public getWinsize():cc.Vec2
+    {
+        return this.winsize;
+    }
+
+    /**获取偏移量 */
+    public getOff(): number {
+        let scroll = this.node.parent.getComponent(cc.ScrollView);
+        // console.log("最大偏移量:"+scroll.getMaxScrollOffset());
+        return scroll.getMaxScrollOffset().y-scroll.getScrollOffset().y;
+    }
+
+}

+ 10 - 0
assets/Script/game/UIFace/viewComtent.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "f35d666c-82cd-4103-90ed-27d96b4c3ae5",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/game/monster.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "57cc023a-34e9-413c-a0a8-d0f387e7600d",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 520 - 0
assets/Script/game/monster/monsterManger.ts

@@ -0,0 +1,520 @@
+import { RoadType } from "../../configData/Enum";
+import monsterNode from "./monsterNode";
+import path from "../../configData/path";
+import ReadCsv from "../../configData/ReadCsv";
+import GameConfig from "../../configData/GameConfig";
+import gameData from "../../configData/gameData";
+import gameUI from "../UIFace/gameUI";
+import DataObj from "../../configData/DataObj";
+import gameManger from "../UIFace/gameManger";
+import path1 from "../../configData/path1";
+import path2 from "../../configData/path2";
+import path3 from "../../configData/path3";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class monsterManger extends cc.Component {
+
+    @property(cc.Sprite)
+    private testspr: cc.Sprite = null;
+    @property(cc.Sprite)
+    private chaqi: cc.Sprite = null;
+
+    private kulou: cc.Node[] = [];
+
+    private monsterArr: monsterNode[] = [];
+    public myDataObj: DataObj = null;
+    private road_group_1 = [];
+    private road_group_2 = [];
+    private road_group_3 = [];
+    private road_group_4 = [];
+    private kulou_pos_1 = [];
+    private kulou_pos_2 = [];
+    private kulou_pos_3 = [];
+    private kulou_pos_4 = [];
+    private birth_rate_1: number[] = [];
+    private birth_rate_2: number[] = [];
+    private birth_rate_3: number[] = [];
+    private birth_rate_4: number[] = [];
+    private next_time: number[] = [];
+
+    private isKuloushow = [[], [], [], []];
+    private step: number[] = [0, 0, 0];
+    private group_dex: number = 0;
+    private roadcount = 0;
+    private kuloucount = 0;
+
+    /**是否可以判断结算 */
+    private isCanOver: boolean = false;
+    public static instance: monsterManger = null;
+    protected onLoad() {
+        monsterManger.instance = this;
+
+        this.myDataObj = new DataObj();
+        this.chaqi.node.zIndex = 1007;
+        this.testspr.node.zIndex = 1007;
+        this.Loadkulou();
+    }
+    /**加载骷髅 */
+    private Loadkulou() {
+        var self = this;
+        cc.resources.load("prefabs/kulou", cc.Prefab, function (err, prefab: cc.Prefab) {
+            for (let i = 0; i < 4; i++) {
+                var newNode = cc.instantiate(prefab);
+                self.node.addChild(newNode, 1008);
+                newNode.active = false;
+                self.kulou.push(newNode);
+                newNode.on(cc.Node.EventType.TOUCH_START, self.tapOrTimeUp, self);
+            }
+        });
+    }
+
+    /**初始化数据 */
+    public resetData() {
+        this.road_group_1 = [];
+        this.road_group_2 = [];
+        this.road_group_3 = [];
+        this.road_group_4 = [];
+        this.kulou_pos_1 = [];
+        this.kulou_pos_2 = [];
+        this.kulou_pos_3 = [];
+        this.kulou_pos_4 = [];
+        this.birth_rate_1 = [];
+        this.birth_rate_2 = [];
+        this.birth_rate_3 = [];
+        this.birth_rate_4 = [];
+        this.next_time = [];
+        this.isKuloushow = [[], [], [], []];
+        this.step = [0, 0, 0, 0];
+        this.group_dex = -1;
+        this.kuloucount = 0;
+
+        this.unscheduleAllCallbacks();
+        this.node.stopAllActions();
+
+        for (let i = 0; i < this.monsterArr.length; i++) {
+            const element = this.monsterArr[i];
+            element.node.destroy();
+        }
+        this.monsterArr = [];
+
+        for (let i = 0; i < 4; i++) {
+            this.kulou[i].active = false;
+            let myprogress = this.kulou[i].getComponent(cc.ProgressBar);
+            myprogress.progress = 1;
+        }
+
+
+    }
+
+
+
+    /**加载怪物出现时机数据 */
+    public initMonster() {
+        this.resetData();
+        let self = this;
+        gameData.instance().readLevel(gameUI.instance.myDataObj.LevelData.scene_path, function () {
+            self.readData();
+        });
+    }
+
+    private readData() {
+        let data = gameData.instance().timeLevel_Config;
+        let nameArr = [];
+        for (let i = 0; i < data.length; i++) {
+            let rowArr = data[i];
+            if (i == 2) {
+                for (let k = 0; k < rowArr.length; k++) {
+                    const element = rowArr[k];
+                    nameArr.push(element);
+                }
+            }
+
+            if (i >= 3) {
+                for (let k = 0; k < rowArr.length; k++) {
+                    const element = rowArr[k];
+                    let name = nameArr[k];
+
+                    if (name == 'group_num') {
+
+                    }
+                    if (name == 'road_1_group') {
+                        let grouparr: number[] = element.split("*");
+                        this.road_group_1.push(grouparr);
+                    }
+                    if (name == 'road_2_group') {
+                        let grouparr: number[] = element.split("*");
+                        this.road_group_2.push(grouparr);
+                    }
+                    if (name == 'road_3_group') {
+                        let grouparr: number[] = element.split("*");
+                        this.road_group_3.push(grouparr);
+                    }
+                    if (name == 'road_4_group') {
+                        let grouparr: number[] = element.split("*");
+                        this.road_group_4.push(grouparr);
+                    }
+                    if (name == 'road_next_time') {
+                        this.next_time.push(element);
+                    }
+                    if (name == 'road_1_birth_rate') {
+                        this.birth_rate_1.push(Number(element));
+                    }
+                    if (name == 'road_2_birth_rate') {
+                        this.birth_rate_2.push(Number(element));
+                    }
+                    if (name == 'road_3_birth_rate') {
+                        this.birth_rate_3.push(Number(element));
+                    }
+                    if (name == 'road_4_birth_rate') {
+                        this.birth_rate_4.push(Number(element));
+                    }
+
+                    if (name == 'road_1_position') {
+                        let grouparr = element.split("*");
+                        this.kulou_pos_1.push(grouparr);
+                        if (grouparr != '') {
+                            this.isKuloushow[0].push(grouparr);
+                        }
+                    }
+                    if (name == 'road_2_position') {
+                        let grouparr = element.split("*");
+                        this.kulou_pos_2.push(grouparr);
+                        if (grouparr != '') {
+                            this.isKuloushow[1].push(grouparr);
+                        }
+                    }
+                    if (name == 'road_3_position') {
+                        let grouparr = element.split("*");
+                        this.kulou_pos_3.push(grouparr);
+                        if (grouparr != '') {
+                            this.isKuloushow[2].push(grouparr);
+                        }
+                    }
+                    if (name == 'road_4_position') {
+                        let grouparr = element.split("*");
+                        this.kulou_pos_4.push(grouparr);
+                        if (grouparr != '') {
+                            this.isKuloushow[3].push(grouparr);
+                        }
+                    }
+                }
+            }
+        }
+
+        this.initKulou();
+        gameUI.instance.setTotalGroup(0, this.road_group_1.length);
+    }
+
+    /**设置骷髅坐标方向 */
+    private initKulou() {
+        for (let i = 0; i < 4; i++) {
+            let jiantou = this.kulou[i].getChildByName('monsterIndir');
+            let pos = cc.v2();
+            let monpos = cc.v2();
+            if (this.isKuloushow[i].length > 0) {
+                pos = cc.v2(Number(this.isKuloushow[i][0][0]), Number(this.isKuloushow[i][0][1]));
+                let isShow = false;
+                if (i == 0) {
+                    monpos = cc.v2(path.instance.getPathData()[0]);
+                    isShow = this.kulou_pos_1[0][0] != '';
+                }
+                if (i == 1) {
+                    monpos = cc.v2(path1.instance.getpathData()[0]);
+                    isShow = this.kulou_pos_2[0][0] != '';
+                }
+                if (i == 2) {
+                    monpos = cc.v2(path2.instance.getpathData()[0]);
+                    isShow = this.kulou_pos_3[0][0] != '';
+                }
+                if (i == 3) {
+                    monpos = cc.v2(path3.instance.getpathData()[0]);
+                    isShow = this.kulou_pos_4[0][0] != '';
+                }
+
+
+                if (isShow) {
+                    this.kulou[i].active = true;
+                    this.kulou[i].runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.4, 1.1), cc.scaleTo(0.4, 1))));
+                }
+                this.kulou[i].setPosition(pos);
+            }
+
+            if (monpos.y > 540) {
+                //上
+                jiantou.setPosition(0, 70);
+                jiantou.angle = 0;
+            }
+
+            if (monpos.y < -540) {
+                //下
+                jiantou.setPosition(0, -70);
+                jiantou.angle = 180;
+            }
+
+            if (monpos.x > 960) {
+                //右
+                jiantou.setPosition(70, 0);
+                jiantou.angle = 270;
+            }
+
+            if (monpos.x < -960) {
+                //左
+                jiantou.setPosition(-70, 0);
+                jiantou.angle = 90;
+            }
+        }
+    }
+
+    /**怪物开始刷新进场 */
+    public startMonsterGo() {
+        this.group_dex++;
+        gameUI.instance.setTotalGroup(this.group_dex + 1, this.road_group_1.length);
+        this.roadcount = 0;
+        this.step = [0, 0, 0, 0];
+
+        this.roadOne();
+        this.roadTwo();
+        this.roadThree();
+        this.roadFour();
+    }
+
+    /**道路一 */
+    private roadOne() {
+        let leth = this.road_group_1[this.group_dex].length;
+        if (leth - 1 >= this.step[0] && this.road_group_1[this.group_dex][this.step[0]] != '') {
+            let montype: number = Number(this.road_group_1[this.group_dex][this.step[0]]);
+            if (montype != 0) {
+                this.seleMinster(1, Math.floor(Math.random() * 6), montype);
+            }
+            this.scheduleOnce(function () {
+                this.roadOne();
+            }, this.birth_rate_1[this.group_dex]);
+            this.step[0]++;
+        }
+        else {
+            this.roadcount++;
+            if (this.roadcount == 4) {
+                this.delayedTime();
+            }
+        }
+
+    }
+    private roadTwo() {
+        let leth = this.road_group_2[this.group_dex].length;
+        if (leth - 1 >= this.step[1] && this.road_group_2[this.group_dex][this.step[1]] != '') {
+            let montype: number = Number(this.road_group_2[this.group_dex][this.step[1]]);
+            if (montype != 0) {
+                this.seleMinster(2, Math.floor(Math.random() * 6), montype);
+            }
+            this.scheduleOnce(function () {
+                this.roadTwo();
+            }, this.birth_rate_2[this.group_dex]);
+            this.step[1]++;
+        }
+        else {
+            this.roadcount++;
+            if (this.roadcount == 4) {
+                this.delayedTime();
+            }
+        }
+    }
+    private roadThree() {
+        let leth = this.road_group_3[this.group_dex].length;
+        if (leth - 1 >= this.step[2] && this.road_group_3[this.group_dex][this.step[2]] != '') {
+            let montype: number = Number(this.road_group_3[this.group_dex][this.step[2]]);
+            if (montype != 0) {
+                this.seleMinster(3, Math.floor(Math.random() * 6), montype);
+            }
+            this.scheduleOnce(function () {
+                this.roadThree();
+            }, this.birth_rate_3[this.group_dex]);
+            this.step[2]++;
+        }
+        else {
+            this.roadcount++;
+            if (this.roadcount == 4) {
+                this.delayedTime();
+            }
+        }
+    }
+
+    private roadFour() {
+        let leth = this.road_group_4[this.group_dex].length;
+        if (leth - 1 >= this.step[3] && this.road_group_4[this.group_dex][this.step[3]] != '') {
+            let montype: number = Number(this.road_group_4[this.group_dex][this.step[3]]);
+            if (montype != 0) {
+                this.seleMinster(4, Math.floor(Math.random() * 6), montype);
+            }
+            this.scheduleOnce(function () {
+                this.roadFour();
+            }, this.birth_rate_4[this.group_dex]);
+            this.step[3]++;
+        }
+        else {
+            this.roadcount++;
+            if (this.roadcount == 4) {
+                this.delayedTime();
+            }
+        }
+    }
+
+    /**延时 */
+    private delayedTime() {
+        if (this.group_dex < this.road_group_1.length - 1) {
+            this.scheduleOnce(function () {
+                //展示骷髅  
+                this.kulou[0].active = false;
+                this.kulou[1].active = false;
+                this.kulou[2].active = false;
+                this.kulou[3].active = false;
+                if (this.kulou_pos_1[this.group_dex + 1][0] != '') {
+                    this.kulou[0].active = true;
+                    this.kulou[0].runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.4, 1.1), cc.scaleTo(0.4, 1))));
+                    let myprogress = this.kulou[0].getComponent(cc.ProgressBar);
+                    myprogress.progress = 1;
+                }
+                if (this.kulou_pos_2[this.group_dex + 1][0] != '') {
+                    this.kulou[1].active = true;
+                    this.kulou[1].runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.4, 1.1), cc.scaleTo(0.4, 1))));
+                    let myprogress = this.kulou[1].getComponent(cc.ProgressBar);
+                    myprogress.progress = 1;
+                }
+                if (this.kulou_pos_3[this.group_dex + 1][0] != '') {
+                    this.kulou[2].active = true;
+                    this.kulou[2].runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.4, 1.1), cc.scaleTo(0.4, 1))));
+                    let myprogress = this.kulou[2].getComponent(cc.ProgressBar);
+                    myprogress.progress = 1;
+                }
+                if (this.kulou_pos_4[this.group_dex + 1][0] != '') {
+                    this.kulou[3].active = true;
+                    this.kulou[3].runAction(cc.repeatForever(cc.sequence(cc.scaleTo(0.4, 1.1), cc.scaleTo(0.4, 1))));
+                    let myprogress = this.kulou[3].getComponent(cc.ProgressBar);
+                    myprogress.progress = 1;
+                }
+
+                this.kuloucount = 0;
+                this.showKulou();
+            }, this.next_time[this.group_dex]);
+        }
+        else {
+            //判断结算
+            this.isCanOver = true;
+        }
+    }
+
+    /**出现骷髅 */
+    public showKulou() {
+        if (this.kuloucount >= 10000) {
+            return;
+        }
+
+        this.kuloucount++;
+        let total: number = Number(gameData.instance().game_Const[4][2]);
+        for (let i = 0; i < this.kulou.length; i++) {
+            if (this.kulou[i].active == true) {
+                let myprogress = this.kulou[i].getComponent(cc.ProgressBar);
+                myprogress.progress = 1 - this.kuloucount / (total * 10);
+            }
+        }
+
+        if (this.kuloucount >= total * 10) {
+            this.TimeUp();
+            return;
+        }
+
+        this.scheduleOnce(function () {
+            this.showKulou();
+        }, 0.1);
+    }
+
+    /**计时完 */
+    public TimeUp() {
+        for (let i = 0; i < this.kulou.length; i++) {
+            this.kulou[i].active = false;
+            this.kulou[i].stopAllActions();
+        }
+
+        this.kuloucount = 10000;
+        this.startMonsterGo();
+    }
+
+    /**点击骷髅或倒计时完 */
+    public tapOrTimeUp() {
+        for (let i = 0; i < this.kulou.length; i++) {
+            this.kulou[i].active = false;
+            this.kulou[i].stopAllActions();
+        }
+        this.kuloucount = 10000;
+        this.startMonsterGo();
+    }
+    private sddd = 0;
+    /**创建怪物 */
+    private seleMinster(way: number, road: RoadType, monsterId: number): void {
+        var self = this;
+        this.myDataObj.writeMonster_Config(monsterId);
+        cc.resources.load("prefabs/" + this.myDataObj.monsterData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+            let guainode = cc.instantiate(prefab);
+            let monster = guainode.getComponent(monsterNode);
+            self.sddd++;
+            monster.name = "name_" + self.sddd;
+            self.node.addChild(guainode, 2);
+            monster.initLevelData(way, road, monsterId);
+            self.monsterArr.push(monster);
+        });
+    }
+
+    /**不能插旗 */
+    public updatest(poss: cc.Vec2) {
+        this.testspr.node.opacity = 255;
+        this.testspr.node.setPosition(poss);
+        this.testspr.node.stopAllActions();
+        cc.tween(this.testspr.node)
+            .to(0.3, { scale: 1.2 })
+            .to(0.3, { scale: 1 })
+            .to(0.3, { scale: 1.2 })
+            .to(0.3, { scale: 1, opacity: 0 })
+            .start();
+    }
+    /**插旗 */
+    public chaqidian(poss: cc.Vec2) {
+        this.chaqi.node.opacity = 255;
+        this.chaqi.node.setPosition(poss);
+        this.chaqi.node.stopAllActions();
+        cc.tween(this.chaqi.node)
+            .delay(2)
+            .to(0.3, { opacity: 0 })
+            .start();
+    }
+
+    /**删除怪物 */
+    public dieDelatemonster(monter: monsterNode) {
+        let index = this.monsterArr.indexOf(monter);
+        if (index >= 0) {
+            this.monsterArr.splice(index, 1);
+        }
+    }
+
+    /**获取所有怪物 */
+    public GetMonsterArr(): monsterNode[] {
+        return this.monsterArr;
+    }
+
+    /**判断游戏结束结算 */
+    public getIsCanOver(): boolean {
+        return this.isCanOver;
+    }
+
+    /**判断游戏结束结算 */
+    public isGameOver() {
+        if (this.isCanOver) {
+            //结算
+            this.isCanOver = false;
+            // this.node.pauseAllActions();
+            // this.unscheduleAllCallbacks();
+            gameManger.instance.gameOver(gameUI.instance.getHp());
+        }
+    }
+
+}

+ 10 - 0
assets/Script/game/monster/monsterManger.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "127085b4-cb88-44e4-ba76-43d7809ed240",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 487 - 0
assets/Script/game/monster/monsterNode.ts

@@ -0,0 +1,487 @@
+import DataObj from "../../configData/DataObj";
+import {RoadType } from "../../configData/Enum";
+import GameConfig from "../../configData/GameConfig";
+import gameData from "../../configData/gameData";
+import path from "../../configData/path";
+import path1 from "../../configData/path1";
+import path2 from "../../configData/path2";
+import mainManager from "../../mainFace/mainManager";
+import gameUI from "../UIFace/gameUI";
+import towerManger from "../tower/towerManger";
+import monsterManger from "./monsterManger";
+import soldie from "./soldie";
+import path3 from "../../configData/path3";
+const {ccclass, property} = cc._decorator;
+
+enum EventAction {
+    ZhengWalk = 'ZhengWalk',
+    ZhengAttack = 'ZhengAttack',
+    ZhengDie = 'ZhengDie',
+}
+
+@ccclass
+export default class monsterNode extends cc.Component {
+  
+    @property(cc.Sprite)
+    private myHpbg: cc.Sprite = null;
+    @property(cc.Sprite)
+    public myHp: cc.Sprite = null;
+
+    private animal :sp.Skeleton = null;
+  
+    private GoPos:cc.Vec3[] = null;//1路线坐标集合
+    private step:number = 0;//第几步
+    private isStop = false;
+    public AniStatus:EventAction = EventAction.ZhengWalk;
+    private _type:number = null;
+    private mysoldie:soldie[] = [];
+ 
+    public myDataObj:DataObj = null;
+    /**攻击类型 1主动 2被动 3不攻击 */
+    public attackType:number = 2;
+    private speedTemp = 0;
+    private reduceTemp = 0;
+    protected onLoad () {
+        this.myDataObj = new DataObj();
+        this.myHpbg.node.opacity = 0;
+        this.myHp.node.opacity = 0;
+        
+    }
+
+    public initLevelData(way:number,road:RoadType,type:number)
+    {
+        if (way == 1) {
+            this.GoPos = path.instance.getPathData().concat();
+        }
+
+        if (way == 2) 
+        {
+            this.GoPos = path1.instance.getpathData().concat();
+        }
+
+        if (way == 3) 
+        {
+            this.GoPos = path2.instance.getpathData().concat();
+        }
+
+        if (way == 4) 
+        {
+            this.GoPos = path3.instance.getpathData().concat();
+        }
+        
+
+        this._type = type;
+        this.initMonsterReadData();
+        // console.log("this.GoPos:"+this.GoPos);
+        this.changeRoad(road);
+
+        this.node.setPosition(this.GoPos[this.step]);
+        this.animal = this.node.getComponent(sp.Skeleton);
+        
+        this.animalGo();
+    }
+
+    /**当图片展示 */
+    public iconShow()
+    {
+        this.animal = this.node.getComponent(sp.Skeleton);
+        this.animal.paused = true;
+    }
+
+    /**读取csv怪物数据 */
+    private initMonsterReadData()
+    {
+        this.myDataObj.writeMonster_Config(this._type);
+        this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+        this.node.scaleY = this.myDataObj.monsterData.model_scaling;
+        this.speedTemp = this.myDataObj.monsterData.Movespeed;
+        this.reduceTemp = this.myDataObj.monsterData.physics_reduction;
+
+        this.attackType = Number(this.myDataObj.monsterData.active_attack_type);
+    }
+
+    /**倒退步数 */
+    public setMonterBackStep(step:number)
+    {
+        this.step -= step;
+        if (this.step < 0) {
+            this.step = 0;
+        }
+        this.node.setPosition(this.GoPos[this.step]);
+    }
+
+  
+
+    /**怪物中心点坐标 */
+    public getNewPos():cc.Vec2
+    {
+        let v2temp = cc.v2(0,(this.node.getContentSize().height/2)*this.myDataObj.monsterData.model_scaling);
+        switch (this._type) {
+            case 2:
+                v2temp = cc.v2(12,22*this.myDataObj.monsterData.model_scaling);
+                break;
+            default:
+                break;
+        }
+        
+       
+        return this.node.getPosition().add(v2temp);
+    }
+
+    /**添加攻击自己的兵 */
+    public addBarracks(mysold:soldie)
+    {
+        let index = this.mysoldie.indexOf(mysold);
+        if (index < 0) {
+            this.mysoldie.push(mysold);
+        }
+    }
+    /**删除攻击自己的兵 */
+    public DelateBarracks(mysole:soldie)
+    {
+        let index = this.mysoldie.indexOf(mysole);
+        if (index >= 0) {
+            this.mysoldie.splice(index, 1);
+        }
+    }
+
+    /**删除所有攻击自己的兵 */
+    public DelateAllBarracks()
+    {
+        this.mysoldie = [];
+    }
+
+    /**删除攻击自己的兵保留num个 */
+    public DelateBarracksRetain(num:number)
+    {
+        for (let i = num; i < this.mysoldie.length; i++) {
+            if (this.mysoldie[i].SolStatus == 'ZhengDie') {
+                this.mysoldie.splice(i, 1);
+                i--;
+            }
+        }
+
+        let leth = this.mysoldie.length;
+        if (leth > num) 
+        {
+            for (let i = num; i < leth; i++) {
+                this.mysoldie.pop().animalWalk();
+            }
+        }
+    }
+
+   
+
+
+    /**攻击自己的兵数组 */
+    public getBarracks():soldie[]
+    {
+        return this.mysoldie;
+    }
+
+    /**获取tt时间后增加的坐标向量 */
+    public getTimeSetDistance(tt:number):cc.Vec2
+    {
+        let juli = tt*this.myDataObj.monsterData.Movespeed;
+        let nowPos = this.node.getPosition();
+        let xiangliang = this.GoPos[this.step+1].sub(cc.v3(nowPos.x,nowPos.y));
+        let lenth = xiangliang.mag();
+
+        let laterPos = (cc.v2((juli/lenth)*xiangliang.x,(juli/lenth)*xiangliang.y));
+        return laterPos;
+    }
+
+    /**选择路线 */
+    private changeRoad(road:RoadType)
+    {
+        if (road == RoadType.OneRoad) {
+            return;
+        }
+        let lukuang = Number(gameData.instance().game_Const[6][2]);
+        
+        let length1 = this.GoPos[1].sub(this.GoPos[0]).mag();
+        let sinX = Math.abs(this.GoPos[1].y-this.GoPos[0].y)/length1;
+        let cosX = Math.abs(this.GoPos[1].x-this.GoPos[0].x)/length1;
+
+        let pointUp = cc.v3();
+        let pointdw = cc.v3();
+        if (this.GoPos[1].y-this.GoPos[0].y >= 0) {
+            if (road == RoadType.TwoUp||road == RoadType.TwoDown) {
+                lukuang /= 2;
+            }
+            pointUp = cc.v3(this.GoPos[0].x-lukuang*sinX,this.GoPos[0].y+lukuang*cosX);
+            pointdw = cc.v3(this.GoPos[0].x+lukuang*sinX,this.GoPos[0].y-lukuang*cosX);
+        }
+
+        if (this.GoPos[1].y-this.GoPos[0].y < 0) {
+            pointUp = cc.v3(this.GoPos[0].x+lukuang*sinX,this.GoPos[0].y+lukuang*cosX);
+            pointdw = cc.v3(this.GoPos[0].x-lukuang*sinX,this.GoPos[0].y-lukuang*cosX);
+        }
+
+        switch (road) {
+            case RoadType.TwoUp:
+                this.resetRoad(pointUp);
+                break;
+            case RoadType.TwoDown:
+                this.resetRoad(pointdw);
+                break;
+            case RoadType.ThreeUp:
+                this.resetRoad(pointUp);
+                break;
+            case RoadType.ThreeDown:
+                this.resetRoad(pointdw);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**生成新路线 */
+    public resetRoad(startpos:cc.Vec3)
+    {
+        let postemp:cc.Vec3[] = [];
+        for (let i = 0; i < this.GoPos.length; i++) {
+            postemp.push(this.GoPos[i]);
+        }
+
+        postemp[0] = startpos;
+        for (let i = this.step; i < this.GoPos.length-1; i++) {
+            let newpos = postemp[i].add(this.GoPos[i+1].sub(this.GoPos[i]));
+            postemp[i+1] = newpos;
+        }
+
+        for (let i = this.step; i < this.GoPos.length; i++) {
+            this.GoPos[i] = postemp[i];
+        }
+    }
+
+    /**是否停止前行 true:停止 */
+    public stopAni(isStop:boolean)
+    {
+        this.isStop = isStop;
+        if (isStop) {
+            this.node.stopAllActions();
+        }
+        else
+        {
+            this.GoPos[this.step] = cc.v3(this.node.getPosition().x,this.node.getPosition().y);
+            this.animalGo();
+            this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+            this.myHp.getComponent(cc.ProgressBar).reverse = true;
+        }
+        
+    }
+
+    /**设置怪物走路是否一直走 */
+    public SetWalk(isGo:boolean)
+    {
+        // if (this.AniStatus == EventAction.ZhengWalk) {
+            
+        // }
+        this.animal.paused = isGo;
+        // this.animal.setAnimation(0,"walk",false);
+    }
+
+    public pauseLaterGo()
+    {
+        
+    }
+
+    /**设置方向 */
+    private setScaleX(mypos:cc.Vec3,endpos:cc.Vec3)
+    {
+        let pross = this.myHp.getComponent(cc.ProgressBar);
+        if (mypos.x > endpos.x) {
+            this.node.scaleX = this.myDataObj.monsterData.model_scaling;
+            pross.reverse = false;
+        }
+        else {
+            this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+            pross.reverse = true;
+        }
+    }
+    private animalGo()
+    {
+        if (this.AniStatus != EventAction.ZhengWalk||this.isStop) {
+            return;
+        }
+
+        if (this.step+1 >= this.GoPos.length) {
+            gameUI.instance.HpCut(this.myDataObj.monsterData.hurt_level_hp);
+            // cc.Device.vibrate();
+
+            monsterManger.instance.dieDelatemonster(this);
+            this.node.destroy();
+            return;
+        }
+
+        let lenth = this.GoPos[this.step+1].sub(this.GoPos[this.step]).mag();
+        if (lenth > 600) {
+            this.step++;
+            this.node.setPosition(this.GoPos[this.step]);
+            let mytime = this.myDataObj.getRanm(1,gameData.instance().game_Const[11][2]);
+            this.scheduleOnce(function(){
+                this.animalGo();
+            }, mytime);
+            
+            return;
+        }
+
+        this.animalwalk();
+
+        if (Math.abs(this.GoPos[this.step].x-this.GoPos[this.step+1].x) > 10) {
+            this.setScaleX(this.GoPos[this.step],this.GoPos[this.step+1]);
+        }
+
+        let dt = lenth/this.myDataObj.monsterData.Movespeed;
+        this.node.stopAllActions();
+        cc.tween(this.node)
+        .to(dt,{position:this.GoPos[this.step+1]})
+        .call(()=>{
+            this.step++;
+            this.animalGo();
+        })
+        .start();
+    }
+
+    /**被攻击血量减少  true:死*/
+    public hpDown(attackNum:number)
+    {
+        if (this.AniStatus == EventAction.ZhengDie) {
+            return;
+        }
+        this.myHpbg.node.opacity = 255;
+        this.myHp.node.opacity = 255;
+        let myprogress = this.myHp.getComponent(cc.ProgressBar);
+        this.myDataObj.monsterData.nowHp -= attackNum;
+        if (this.myDataObj.monsterData.nowHp <= 0) {
+            this.myDataObj.monsterData.nowHp = 0;
+            this.animalDie();
+        }
+        if (this.myDataObj.monsterData.nowHp > this.myDataObj.monsterData.totalHp) {
+            this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+        }
+        
+        myprogress.progress = this.myDataObj.monsterData.nowHp/this.myDataObj.monsterData.totalHp;
+    }
+
+    public getIsdie():boolean
+    {
+        if (this.AniStatus == EventAction.ZhengDie) {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**被魔法塔攻击后 魔力侵蚀 */
+    public MagicCutPhysicsreduction()
+    {
+        let self = this;
+        if (towerManger.instance.talantData[11].length > 0&&this.myDataObj.monsterData.physics_reduction == self.reduceTemp) {
+            this.myDataObj.monsterData.physics_reduction -= towerManger.instance.talantData[11][0];
+            if (this.myDataObj.monsterData.physics_reduction < 0) {
+                this.myDataObj.monsterData.physics_reduction = 0;
+            }
+
+            this.scheduleOnce(function(){
+                self.myDataObj.monsterData.physics_reduction = self.reduceTemp;
+            }, towerManger.instance.talantData[11][1]);
+        }
+
+        if (towerManger.instance.talantData[14].length > 0&&this.myDataObj.monsterData.Movespeed == this.speedTemp) {
+            this.myDataObj.monsterData.Movespeed *= (1-towerManger.instance.talantData[14][0]);
+            this.GoPos[this.step] = cc.v3(this.node.getPosition().x,this.node.getPosition().y);
+            this.animalGo();
+            this.scheduleOnce(function(){
+                self.myDataObj.monsterData.Movespeed = self.speedTemp;
+            }, towerManger.instance.talantData[14][1]);
+        }
+    }
+
+    public animalDie()
+    {
+        this.AniStatus = EventAction.ZhengDie;    
+        this.node.stopAllActions();
+        this.animal.setAnimation(0,"die",false).timeScale = GameConfig.instance().speed;
+        monsterManger.instance.dieDelatemonster(this);
+        gameUI.instance.AddGold(this.myDataObj.monsterData.drop_group_1);
+        gameUI.instance.addDiamind(this.myDataObj.getRanm(1,this.myDataObj.monsterData.drop_group_2),this.myDataObj.monsterData.percentage);
+        let self = this;
+        this.scheduleOnce(function(){
+            self.node.opacity = 0;
+        }, 0.6);
+
+        this.scheduleOnce(function(){
+            this.node.destroy();
+            // console.log("销毁:"+monsterManger.instance.GetMonsterArr().length);
+        }, 8);
+        
+    }
+
+    public animalwalk()
+    {
+        if (this.animal.animation != "walk") {
+            this.animal.setAnimation(0,"walk",true).timeScale = GameConfig.instance().speed;
+        }
+        this.AniStatus = EventAction.ZhengWalk;
+    }
+
+    /**放弃攻击离开 */
+    public animalreGo()
+    {
+        this.animalwalk();
+        this.stopAni(false);
+        this.mysoldie = [];
+    }
+
+
+    public animalAttack()
+    {
+        if (this.AniStatus == EventAction.ZhengDie) {
+            return;
+        }
+        if (this.mysoldie.length == 0) {
+            return;
+        }
+        
+        
+        this.animal.setAnimation(0,"attack",false).timeScale = GameConfig.instance().speed;
+        this.AniStatus = EventAction.ZhengAttack;
+        this.animal.setCompleteListener((trackEntry, loopCount) => {
+            let name = trackEntry.animation ? trackEntry.animation.name : '';
+            if (name === 'attack') {
+                let attack = this.myDataObj.getRanm(1,this.myDataObj.monsterData.attack);
+                let diff = this.myDataObj.monsterData.attack_diff_coefficient;
+                let reduction = this.mysoldie[0].myDataObj.monsterData.physics_reduction;
+                if (towerManger.instance.talantData[6].length > 0&&!this.mysoldie[0].getIsSkill()) {
+                    reduction += towerManger.instance.talantData[6][0];
+                }
+
+                let shanghai = attack*diff*(1-reduction);
+                this.mysoldie[0].hpDown(shanghai);
+
+                if (towerManger.instance.talantData[9].length > 0) {
+                    this.hpDown(attack*diff*towerManger.instance.talantData[9][0]);
+                }
+
+                if (this.mysoldie[0].SolStatus == 'ZhengDie') {
+                    this.mysoldie.shift();
+                    if (this.mysoldie.length == 0) {
+                        this.animalwalk();
+                        this.stopAni(false);
+                    }
+                }
+            }
+        });
+
+        this.scheduleOnce(function(){
+            this.animalAttack();
+        }, this.myDataObj.monsterData.attack_speed);
+    }
+
+   
+
+}

+ 10 - 0
assets/Script/game/monster/monsterNode.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "bd60cc0b-8b0e-435c-998f-290e8dde68be",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 508 - 0
assets/Script/game/monster/soldie.ts

@@ -0,0 +1,508 @@
+
+import monsterNode from "./monsterNode";
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import towerManger from "../tower/towerManger";
+import barracks from "../tower/barracks";
+import SkillSolate from "../tower/SkillSolate";
+import gameData from "../../configData/gameData";
+const { ccclass, property } = cc._decorator;
+enum SoldeAction {
+    ZhengWalk = 'ZhengWalk',
+    ZhengAttack = 'ZhengAttack',
+    ZhengDie = 'ZhengDie',
+    ZhengRun = 'ZhengRun',
+}
+@ccclass
+export default class soldie extends cc.Component {
+
+    @property(cc.Sprite)
+    private myHpbg: cc.Sprite = null;
+    @property(cc.Sprite)
+    private myHp: cc.Sprite = null;
+    private animal: sp.Skeleton = null;
+
+    /**是不是技能兵 */
+    private isSkillSolde: boolean = false;
+    /**是否能攻击 */
+    private isCanAttck = true;
+    private myMinter: monsterNode = null;
+    public SolStatus: SoldeAction = SoldeAction.ZhengWalk;
+    private startpos: cc.Vec2 = null;
+    private endtpos: cc.Vec2 = null;
+    public myDataObj: DataObj = null;
+    private myTower = null;
+    /**复活时间 */
+    private reliveNum = 0;
+    private isCanRecovery = true;
+    protected onLoad() {
+        this.myHpbg.node.opacity = 0;
+        this.myHp.node.opacity = 0;
+        this.animal = this.node.getComponent(sp.Skeleton);
+        this.myDataObj = new DataObj();
+
+        
+    }
+
+    /**开始刷新 */
+    public setSche()
+    {
+        this.schedule(this.updateMonster, 0.3);
+    }
+
+    /**是不是技能兵 */
+    public setIsSkill(isSkill: boolean) {
+        this.isSkillSolde = isSkill;
+    }
+
+    /**是不是技能兵 */
+    public getIsSkill(): boolean {
+        return this.isSkillSolde;
+    }
+
+
+    /**是否能攻击 */
+    public setisCanAttck(isCanAttck: boolean) {
+        return this.isCanAttck = isCanAttck;
+    }
+
+    /**设置自己攻击的怪物 */
+    public setMymonster(myMint: monsterNode) {
+        this.myMinter = myMint;
+    }
+
+    /**获取自己攻击的怪物 */
+    public getMymonster() {
+        return this.myMinter;
+    }
+
+    public initLevelData(barr, monster_id: number) {
+        this.myTower = barr;
+        if (!this.isSkillSolde) {
+            this.reliveNum = barr.myDataObj.TowerData.attack_cd;
+        }
+
+        this.myDataObj.writeMonster_Config(monster_id);
+        this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+        this.node.scaleY = this.myDataObj.monsterData.model_scaling;
+
+    }
+
+    public initSkillMinter(barr: SkillSolate, monster_id: number) {
+        this.myTower = barr;
+
+        this.myDataObj.writeMonster_Config(monster_id);
+        this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+        this.node.scaleY = this.myDataObj.monsterData.model_scaling;
+
+        if (towerManger.instance.talantData[28].length > 0) {
+            this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[25][0] + towerManger.instance.talantData[26][0] + towerManger.instance.talantData[27][0] + towerManger.instance.talantData[28][0]);
+            this.myDataObj.monsterData.physics_reduction += (towerManger.instance.talantData[26][2] + towerManger.instance.talantData[27][2] + towerManger.instance.talantData[28][2]);
+            this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+        }
+        else {
+            if (towerManger.instance.talantData[27].length > 0) {
+                this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[25][0] + towerManger.instance.talantData[26][0] + towerManger.instance.talantData[27][0]);
+                this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+                this.myDataObj.monsterData.physics_reduction += (towerManger.instance.talantData[26][2] + towerManger.instance.talantData[27][2]);
+            }
+            else {
+                if (towerManger.instance.talantData[26].length > 0) {
+                    this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[25][0] + towerManger.instance.talantData[26][0]);
+                    this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+                    this.myDataObj.monsterData.physics_reduction += (towerManger.instance.talantData[26][2]);
+                }
+                else {
+                    if (towerManger.instance.talantData[25].length > 0) {
+                        this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[25][0]);
+                        this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+                    }
+                }
+            }
+        }
+
+
+
+
+
+        this.isCanRecovery = true;
+        this.stopWalkLater();
+
+
+    }
+
+    public initTalant() {
+        if (towerManger.instance.talantData[7].length > 0) {
+            this.reliveNum *= (1 - towerManger.instance.talantData[7][1]);
+        }
+
+
+        if (towerManger.instance.talantData[8].length > 0) {
+            this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[8][0] + towerManger.instance.talantData[5][0]);
+            this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+        }
+        else {
+            if (towerManger.instance.talantData[5].length > 0) {
+                this.myDataObj.monsterData.totalHp *= (1 + towerManger.instance.talantData[5][0]);
+                this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+            }
+        }
+    }
+
+
+    /**更新附近怪物 */
+    private updateMonster() {
+
+        let posy = this.node.getPosition().y;
+        this.node.zIndex = Math.floor((540 - posy) / 10);
+
+        let TotalmonArr: monsterNode[] = this.myTower.getAttackmonster();
+        if (TotalmonArr.length == 0 || this.animal.node.opacity == 0) {
+            return;
+        }
+        let isTurn = false;
+        let monArr: monsterNode[] = [];
+
+        for (let i = 0; i < TotalmonArr.length; i++) {
+            const element = TotalmonArr[i];
+            if (!element||element.node == null) {
+                continue;
+            }
+            if (this.node.getPosition().sub(element.node.getPosition()).mag() < this.myDataObj.monsterData.warning_range) {
+                monArr.push(element);
+            }
+        }
+        // console.log("TotalmonArr.length:"+TotalmonArr.length,"       monArr.length:"+monArr.length);
+        for (let i = 0; i < monArr.length; i++) {
+            const element = monArr[i];
+            if (element.getBarracks().length == 0) {
+                this.soldeWalkTo(element);
+                isTurn = true;
+            }
+        }
+
+        if (!isTurn && monArr.length > 0) {
+            let dex = Math.floor(Math.random() * monArr.length);
+            this.soldeWalkTo(monArr[dex]);
+        }
+
+
+    }
+
+    /**兵朝目标点前进 */
+    private soldeWalkTo(monster: monsterNode) {
+        if (this.SolStatus != 'ZhengWalk') {
+            return;
+        }
+        this.setMymonster(monster);
+        this.node.opacity = 255;
+        let end = monster.node.getPosition();
+        this.node.stopAllActions();
+        let sopos = this.node.getPosition();
+        let attack_range = monster.myDataObj.monsterData.attack_range;
+        if (end.x > sopos.x) {
+            this.walkToPointAndAttack(end.add(cc.v2(-attack_range, -5 + Math.random() * 10)));
+        }
+        else {
+            this.walkToPointAndAttack(end.add(cc.v2(attack_range, -5 + Math.random() * 10)));
+        }
+    }
+
+
+
+    /**兵中心点坐标 */
+    public getNewPos(): cc.Vec2 {
+        return this.node.getPosition().add(cc.v2(0, 20 * this.myDataObj.monsterData.model_scaling));
+    }
+
+
+    public setinitPos(start: cc.Vec2, end: cc.Vec2) {
+        if (start != null) {
+            this.startpos = start;
+        }
+        this.endtpos = end;
+    }
+
+    /**起始行走到目标地点---------true:起始 */
+    public initWalkToPoint(isInit: boolean) {
+        if (this.SolStatus == SoldeAction.ZhengDie) {
+            return;
+        }
+        if (isInit) {
+            this.node.setPosition(this.startpos);
+        }
+        let mypos = this.node.getPosition();
+        let lenth = this.endtpos.sub(mypos).mag();
+        if (lenth < 3) {
+            return;
+        }
+        let tt = lenth / this.myDataObj.monsterData.Movespeed;
+        this.setScaleX(mypos, this.endtpos);
+
+        this.node.stopAllActions();
+        this.animalWalk();
+        cc.tween(this.node)
+            .to(tt, { position: cc.v3(this.endtpos.x, this.endtpos.y - 10) })
+            .call(() => {
+                this.animal.setAnimation(0, "walk", false).timeScale = GameConfig.instance().speed;
+                this.animal.animation = '';
+                this.isCanRecovery = true;
+                this.stopLaterRecovery();
+                this.stopWalkLater();
+            })
+            .start();
+    }
+
+    /**待机时随机来回转身 */
+    private stopWalkLater() {
+        if (!this.isCanRecovery) {
+            return;
+        }
+
+        let arr = this.myDataObj.getArr(gameData.instance().game_Const[10][2]);
+        let pross = this.myHp.getComponent(cc.ProgressBar);
+        if (Math.random() < arr[1]) {
+            this.node.scaleX = this.myDataObj.monsterData.model_scaling;
+            pross.reverse = false;
+        }
+        else {
+            this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+            pross.reverse = true;
+        }
+
+        this.scheduleOnce(function () {
+            this.stopWalkLater();
+        }, arr[0]);
+    }
+
+    /**回归原位时回血 */
+    private stopLaterRecovery() {
+        if (!this.isCanRecovery) {
+            return;
+        }
+        if (this.myDataObj.monsterData.nowHp < this.myDataObj.monsterData.totalHp) {
+            this.myDataObj.monsterData.nowHp += this.myDataObj.monsterData.recovery[0];
+            if (this.myDataObj.monsterData.nowHp > this.myDataObj.monsterData.totalHp) {
+                this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+                this.myHp.node.opacity = 0;
+                this.myHpbg.node.opacity = 0;
+            }
+            let myprogress = this.myHp.getComponent(cc.ProgressBar);
+            myprogress.progress = this.myDataObj.monsterData.nowHp / this.myDataObj.monsterData.totalHp;
+        }
+
+
+        this.scheduleOnce(function () {
+            this.stopLaterRecovery();
+        }, this.myDataObj.monsterData.recovery[1]);
+    }
+
+    /**设置方向 */
+    private setScaleX(mypos: cc.Vec2, endpos: cc.Vec2) {
+        let pross = this.myHp.getComponent(cc.ProgressBar);
+        if (mypos.x > endpos.x) {
+            this.node.scaleX = this.myDataObj.monsterData.model_scaling;
+            pross.reverse = false;
+        }
+        else {
+            this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+            pross.reverse = true;
+        }
+    }
+
+    /**行走到目标地点攻击敌人 */
+    public walkToPointAndAttack(end: cc.Vec2) {
+        if (this.SolStatus == SoldeAction.ZhengDie) {
+            return;
+        }
+        let mypos = this.node.getPosition();
+        let lenth = end.sub(mypos).mag();
+        let tt = lenth / this.myDataObj.monsterData.Movespeed;
+
+        this.setScaleX(mypos, end);
+
+
+        this.node.stopAllActions();
+        this.animalWalk();
+        let self = this;
+        cc.tween(this.node)
+            .to(tt, { position: cc.v3(end.x, end.y - 10) })
+            .call(() => {
+
+                self.isCanRecovery = false;
+                self.SolStatus = SoldeAction.ZhengAttack;
+                self.animalAttack();
+                self.setSolAndAniScaleX();
+                if (self.myMinter.AniStatus != 'ZhengAttack') {
+                    if (self.myMinter.myDataObj.monsterData.active_attack_type != '3') {
+                        self.myMinter.animalAttack();
+                        self.myMinter.stopAni(true);
+                    }
+                }
+            })
+            .start();
+    }
+
+    private setSolAndAniScaleX() {
+        let mypross = this.myHp.getComponent(cc.ProgressBar);
+        let Minterpross = this.myMinter.myHp.getComponent(cc.ProgressBar);
+        if (this.myMinter.getNewPos().x > this.getNewPos().x) {
+            //怪在兵右边
+            this.node.scaleX = -this.myDataObj.monsterData.model_scaling;
+            this.myMinter.node.scaleX = this.myMinter.myDataObj.monsterData.model_scaling;
+            mypross.reverse = true;
+            Minterpross.reverse = false;
+        }
+        else {
+            //怪在兵左边
+            this.node.scaleX = this.myDataObj.monsterData.model_scaling;
+            this.myMinter.node.scaleX = -this.myMinter.myDataObj.monsterData.model_scaling;
+            mypross.reverse = false;
+            Minterpross.reverse = true;
+        }
+    }
+
+    /** true:死 */
+    public getIsdie(): boolean {
+        if (this.SolStatus == SoldeAction.ZhengDie) {
+            return true;
+        }
+        else {
+            return false;
+        }
+
+    }
+
+    /**被攻击血量减少  true:死*/
+    public hpDown(attackNum: number) {
+        if (this.SolStatus == SoldeAction.ZhengDie) {
+            return;
+        }
+        this.myHpbg.node.opacity = 255;
+        this.myHp.node.opacity = 255;
+        let myprogress = this.myHp.getComponent(cc.ProgressBar);
+        this.myDataObj.monsterData.nowHp -= attackNum;
+        if (this.myDataObj.monsterData.nowHp <= 0) {
+            this.myDataObj.monsterData.nowHp = 0;
+            this.animalDie();
+        }
+
+        if (this.myDataObj.monsterData.nowHp >= this.myDataObj.monsterData.totalHp) {
+            this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+            this.myHpbg.node.opacity = 0;
+            this.myHp.node.opacity = 0;   
+        }
+        myprogress.progress = this.myDataObj.monsterData.nowHp / this.myDataObj.monsterData.totalHp;
+    }
+
+    public ispaused(ispause: boolean) {
+        this.animal.paused = ispause;
+    }
+
+    public animalDie() {
+        this.animal.setAnimation(0, "die", false).timeScale = GameConfig.instance().speed;
+        this.SolStatus = SoldeAction.ZhengDie;
+
+
+
+        this.scheduleOnce(function () {
+            this.animal.node.opacity = 0;
+            this.animal.node.setPosition(0, 0);
+        }, 1);
+
+        if (this.isSkillSolde) {
+            this.myTower.dieCount();
+            return;
+        }
+
+        this.scheduleOnce(function () {
+            this.reLive();
+        }, this.reliveNum);
+
+    }
+
+    private reLive() {
+        this.animal.node.opacity = 255;
+        this.myDataObj.monsterData.nowHp = this.myDataObj.monsterData.totalHp;
+        this.animalWalk();
+        this.initWalkToPoint(true);
+
+        let myprogress = this.myHp.getComponent(cc.ProgressBar);
+        myprogress.progress = 1;
+    }
+
+    public animalWalk() {
+        // this.unscheduleAllCallbacks();
+        this.isCanRecovery = false;
+        if (this.animal.animation != "walk") {
+            this.animal.setAnimation(0, "walk", true).timeScale = GameConfig.instance().speed;
+        }
+        this.SolStatus = SoldeAction.ZhengWalk;
+    }
+
+    public animalAttack() {
+        if (this.SolStatus != SoldeAction.ZhengAttack || this.myMinter == null) {
+            return;
+        }
+
+        let self = this;
+        this.animal.setAnimation(0, "attack", false).timeScale = GameConfig.instance().speed;
+
+        this.animal.setCompleteListener((trackEntry, loopCount) => {
+            let name = trackEntry.animation ? trackEntry.animation.name : '';
+            if (name === 'attack') {
+                let attack = self.myDataObj.getRanm(1, self.myDataObj.monsterData.attack);
+
+                if (self.isSkillSolde) {
+                    if (towerManger.instance.talantData[28].length > 0) {
+                        attack *= (1 + towerManger.instance.talantData[25][1] + towerManger.instance.talantData[26][1] + towerManger.instance.talantData[27][1] + towerManger.instance.talantData[28][1]);
+                    }
+                    else {
+                        if (towerManger.instance.talantData[27].length > 0) {
+                            attack *= (1 + towerManger.instance.talantData[25][1] + towerManger.instance.talantData[26][1] + towerManger.instance.talantData[27][1]);
+                        }
+                        else {
+                            if (towerManger.instance.talantData[26].length > 0) {
+                                attack *= (1 + towerManger.instance.talantData[25][1] + towerManger.instance.talantData[26][1]);
+                            }
+                            else {
+                                if (towerManger.instance.talantData[25].length > 0) {
+                                    attack *= (1 + towerManger.instance.talantData[25][1]);
+                                }
+                            }
+                        }
+                    }
+                }
+
+
+                let diff = self.myDataObj.monsterData.attack_diff_coefficient;
+                if (diff == 0) {
+                    diff = 1;
+                }
+                self.myMinter.hpDown(attack * diff * (1 - self.myMinter.myDataObj.monsterData.physics_reduction));
+                if (!self.isSkillSolde) {
+                    // self.myTower.skill43_45(self);
+                    // self.myTower.skill46_48(self);
+                    // self.myTower.skill49_51(self);
+                }
+            }
+        
+        });
+
+
+
+        this.myMinter.addBarracks(this);
+
+
+if (this.myMinter.AniStatus == 'ZhengDie') {
+    this.initWalkToPoint(false);
+}
+else {
+    this.scheduleOnce(function () {
+        this.animalAttack();
+    }, this.myDataObj.monsterData.attack_speed);
+}
+
+    }
+
+}

+ 10 - 0
assets/Script/game/monster/soldie.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "f92dca88-1d8b-4465-9ed0-ac0aa0156c8b",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/game/tower.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "057ce2ae-266f-44b3-8f8e-64edf911f5e2",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 230 - 0
assets/Script/game/tower/Archer.ts

@@ -0,0 +1,230 @@
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import monsterNode from "../monster/monsterNode";
+import arrow from "./arrow";
+import towerManger from "./towerManger";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class Archer extends cc.Component {
+    @property(cc.Sprite)
+    private jiantou: cc.Sprite = null;
+
+    private animal: sp.Skeleton = null;
+    private minter: monsterNode = null;
+    private interVec: cc.Vec2 = null;
+    private paodanstartPos: cc.Vec2 = null;
+    /**是否开始计时 */
+    private timeUp = false;
+    /**计时数 */
+    private timeCount = 0;
+    private _arraw: arrow = null;
+    protected onLoad() {
+        this.jiantou.node.opacity = 0;
+        this.animal = this.node.getComponent(sp.Skeleton);
+        this.jiantou.node.setPosition(1, 45);
+        this.paodanstartPos = this.jiantou.node.getPosition();
+    }
+
+    public initTower(myarraw: arrow) {
+        this._arraw = myarraw;
+
+        this.jiantou.node.scale = this._arraw.myDataObj.BulletData.model_scaling;
+        if (this._arraw.myDataObj.TowerData.id != 7) {
+            this.archerAngleUpdate();
+        }
+        
+    }
+
+    public attack(aminter: monsterNode) {
+        this.minter = aminter;
+        this.animal.setAnimation(0, "animation", false).timeScale = GameConfig.instance().speed;
+        this.interVec = this.minter.getNewPos().sub(cc.v2(0, -45));
+        let xianglin = this.minter.getTimeSetDistance(this._arraw.myDataObj.BulletData.speed+0.4);
+        this.interVec = this.interVec.add(xianglin);
+
+        this.scheduleOnce(function () {
+            this.initFeiData();
+        }, 0.4);
+
+    }
+
+
+    private initFeiData() {
+
+        
+        this.jiantou.node.setPosition(this.paodanstartPos);
+
+
+        let arrawpos = this._arraw.node.getPosition();
+        let mypos = arrawpos.add(this.node.getPosition());
+        let danpos = mypos.add(this.jiantou.node.getPosition());
+        this.paodanUpAction(this.interVec, danpos);
+        // console.log("this.interVec:"+this.interVec+"        danpos:"+danpos);
+    }
+
+
+    private paodanUpAction(pos: cc.Vec2, danpos: cc.Vec2) {
+
+        // this.jiantou.node.angle = 0;
+
+        let hetght = this._arraw.myDataObj.BulletData.parabola[0];
+        if (pos.y > danpos.y) {
+            hetght = 50+Math.abs(pos.y - danpos.y)*0.5 + this._arraw.myDataObj.BulletData.parabola[0];
+        }
+
+        let endpos = pos.sub(danpos);
+        if (this.interVec.x > this._arraw.taHuanVec.x) {
+            this.animal.node.scaleX = -1;
+            endpos = cc.v2(-endpos.x, endpos.y);
+        }
+        else {
+            this.animal.node.scaleX = 1;
+        }
+
+
+        
+        if (this._arraw.myDataObj.TowerData.id == 7) {
+            cc.tween(this.jiantou.node)
+            .by(this._arraw.myDataObj.BulletData.speed,{position:cc.v3(endpos.sub(cc.v2(0,25)))})
+            .start();
+            this.jiantou.node.opacity = 255;
+        }
+        else {
+            this.ParabolaTo(this._arraw.myDataObj.BulletData.speed, cc.v2(0, 0), endpos, hetght, this._arraw.myDataObj.BulletData.parabola[1]);
+            this.scheduleOnce(function () {
+                this.jiantou.node.opacity = 255;
+            }, 0.03);
+        }
+
+
+
+
+        
+
+        this.scheduleOnce(function () {
+            this.paodanhuanyuan();
+        }, this._arraw.myDataObj.BulletData.speed);
+
+        this.scheduleOnce(function () {
+            this._arraw.oneAccack(this);
+        }, this._arraw.myDataObj.TowerData.attack_cd);
+    }
+
+    /**即时更新箭头角度 */
+    private archerAngleUpdate() {
+        let self = this;
+        let lastP = this.jiantou.node.getPosition();
+        this.schedule(function () {
+            let curP = self.jiantou.node.getPosition();
+            if (curP.x != lastP.x && curP.y != lastP.y) {
+                let dirVec = curP.sub(lastP);//获得从startPos指向endPos的方向向量
+                let comVec = new cc.Vec2(0, 1);//计算夹角的参考方向,这里选择x轴正方向
+                let radian = cc.v2(dirVec).signAngle(comVec);// --向量夹角弧度(相对于y轴正向)
+                let angle = radian * 180 / Math.PI; //-- 弧度值转换为角度 公式:弧度=度*π/180
+                self.jiantou.node.angle = -angle;
+            }
+            lastP = curP;
+        }, 0);
+    }
+
+    /**抛物线运动 */
+    private ParabolaTo(t: number, startPoint: cc.Vec2, endPoint: cc.Vec2, height: number, angle: number) {
+        // 把角度转换为弧度  
+        // let radian = angle ;
+        let radian = angle * 3.14159 / 180.0;
+        // 第一个控制点为抛物线左半弧的中点  
+        let q1x = startPoint.x + (endPoint.x - startPoint.x) / 2.0;
+        let q1 = cc.v2(q1x, height + startPoint.y + Math.cos(radian) * q1x);
+        // 第二个控制点为整个抛物线的中点  
+        let q2x = startPoint.x + (endPoint.x - startPoint.x) / 2.0;
+        let q2 = cc.v2(q2x, height + startPoint.y + Math.cos(radian) * q2x);
+
+        //曲线配置  
+        var bezier = [q1, q2, endPoint];
+        // console.log("endPoint:"+endPoint);
+        //使用CCEaseInOut让曲线运动有一个由慢到快的变化,显得更自然  
+
+        let bezerby = cc.bezierTo(t, bezier);
+        this.jiantou.node.runAction(bezerby);
+        // this.jiantou.node.runAction(bezerby.easing(cc.easeInOut(t)));
+    }
+
+    private paodanhuanyuan() {
+        if (this.minter.AniStatus == 'ZhengDie'&&this._arraw.myDataObj.TowerData.id != 7) {
+            this.scheduleOnce(function () {
+                this.jiantou.node.opacity = 0;
+                this.jiantou.node.setPosition(this.paodanstartPos);
+            }, this._arraw.myDataObj.TowerData.attack_cd - this._arraw.myDataObj.BulletData.speed-0.1);
+        }
+        else {
+            this.jiantou.node.opacity = 0;
+            this.jiantou.node.setPosition(this.paodanstartPos);
+        }
+        let attck = this._arraw.myDataObj.getRanm(1, this._arraw.myDataObj.BulletData.attack);
+        let reduction = this.minter.myDataObj.monsterData.physics_reduction;
+        if (towerManger.instance.talantData[2].length > 0) {
+            reduction -= towerManger.instance.talantData[2][0];
+            if (reduction < 0) {
+                reduction = 0;
+            }
+        }
+        if (towerManger.instance.talantData[4].length > 0) {
+            if (Math.random() < towerManger.instance.talantData[4][0]) {
+                attck *= towerManger.instance.talantData[4][1];
+            }
+        }
+        let realHurt = attck * (1 - reduction);
+
+        //技能7-9 爆头一击
+        // if (this._arraw.SkillIDL >= 7 && this._arraw.SkillIDL <= 9) {
+        //     this._arraw.myDataObj.writeSkill_Config(this._arraw.SkillIDL);
+        //     let jilv = Number(this._arraw.myDataObj.SkillData.parameter_2);
+        //     if (Math.random() < jilv) {
+        //         realHurt *= 2;
+        //     }
+        // }
+        this.minter.hpDown(realHurt);
+
+        // this.skillNorattack(this._arraw.SkillIDL);
+    }
+
+    /**普攻技能 */
+    private skillNorattack(ID: number) {
+        if (ID <= 3 && ID > 0) {
+            if (!this.timeUp) {
+                this.timeUp = true;
+                this.skill1_3();
+            }
+            else {
+                this.timeCount = 0;
+            }
+        }
+    }
+
+    /**id 1-3技能 剧毒箭矢*/
+    private skill1_3() {
+        this.scheduleOnce(() => {
+            this._arraw.myDataObj.writeSkill_Config(this._arraw.SkillIDL);
+            let shanghai = Number(this._arraw.myDataObj.SkillData.parameter_2);
+            let totalcount = Number(this._arraw.myDataObj.SkillData.parameter_3);
+
+            this.minter.hpDown(shanghai);
+            this.timeCount++;
+            if (this.timeCount <= totalcount) {
+                this.skill1_3();
+            }
+            else {
+                this.timeUp = false;
+            }
+        }, 1);
+    }
+
+
+
+
+
+
+}

+ 10 - 0
assets/Script/game/tower/Archer.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "5a6da737-b61a-4e96-8746-c7c0d2589873",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 449 - 0
assets/Script/game/tower/Magic.ts

@@ -0,0 +1,449 @@
+
+import GameConfig from "../../configData/GameConfig";
+import TowerHuan from "./TowerHuan";
+import monsterNode from "../monster/monsterNode";
+import taside from "./taside";
+import towerManger from "./towerManger";
+import DataObj from "../../configData/DataObj";
+import monsterManger from "../monster/monsterManger";
+import soldie from "../monster/soldie";
+import gameUI from "../UIFace/gameUI";
+import SkillSolate from "./SkillSolate";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class Magic extends cc.Component {
+
+    @property(sp.Skeleton)
+    private magicta: sp.Skeleton = null;
+    @property(cc.Sprite)
+    private guang_a: cc.Sprite = null;
+    @property(cc.Sprite)
+    private guang_b: cc.Sprite = null;
+
+    /**地面激光烧过火光 */
+    private chongji: cc.Sprite = null;
+
+    private clips: cc.Animation = null;
+    private jiaodu = 0;
+
+    private _taHuan: TowerHuan = null;
+    public _taside: taside = null;
+    private taHuanVec: cc.Vec2 = null;
+    private interVec: cc.Vec2 = null;
+    public myDataObj: DataObj = null;
+    private isStartWait = true;
+    public towerType = 0;
+    /**左技能ID */
+    public SkillIDL = 0;
+    /**右技能ID */
+    public SkillIDR = 0;
+    private GoPos: cc.Vec3[] = null;//1路线坐标集合
+    /**石头人 */
+    private skillPeo:SkillSolate = null;
+
+
+    private isdieLine = false;
+    /**攻击范围内的怪物 */
+    private attackmonster: monsterNode[] = [];
+
+    protected onLoad() {
+        this.guang_a.node.opacity = 0;
+        this.guang_b.node.opacity = 0;
+        let poss = this.node.getPosition().add(this.guang_b.node.getPosition());
+        this.guang_b.node.removeFromParent();
+        this.node.parent.addChild(this.guang_b.node, 1008);
+        this.guang_b.node.setPosition(poss);
+        this.loadChongjiGuang();
+        this.myDataObj = new DataObj();
+        this.GoPos = gameUI.instance.getGoPos();
+    }
+
+    /**加载冲击光 */
+    private loadChongjiGuang() {
+        let self = this;
+        cc.resources.load("prefabs/chongji", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            self.node.parent.addChild(newNode, 1008);
+            newNode.opacity = 0;
+            newNode.setPosition(cc.v2(0, 0));
+            self.chongji = newNode.getComponent(cc.Sprite);
+        });
+    }
+
+    /**根据ID读取数据 */
+    public initID(ID: number) {
+        this.myDataObj.writeTower_Config(ID);
+        this.myDataObj.writeBullet_Config(this.myDataObj.TowerData.bullet_id);
+
+        if (towerManger.instance.talantData[10].length > 0) {
+            this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[10][0]);
+        }
+
+        if (towerManger.instance.talantData[12].length > 0) {
+            this.myDataObj.TowerData.up_gold[0] *= (1 - towerManger.instance.talantData[12][1]);
+            this.myDataObj.TowerData.up_gold[0] = Math.floor(this.myDataObj.TowerData.up_gold[0]);
+        }
+
+        if (this.myDataObj.TowerData.tower_level == 1) {
+            this.isStartWait = false;
+        }
+        else {
+            this.scheduleOnce(function () {
+                this.isStartWait = false;
+            }, this.myDataObj.TowerData.attack_cd);
+        }
+
+    }
+
+    /**设置或升级技能ID  技能类型 1左边  2右边*/
+    public setandUpSkillId(skillType: number) {
+        if (skillType == 1) {
+            if (this.SkillIDL == 0) {
+                this.SkillIDL = this.myDataObj.TowerData.next_skill[0];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDL);
+                this.SkillIDL = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+
+        if (skillType == 2) {
+            if (this.SkillIDR == 0) {
+                this.SkillIDR = this.myDataObj.TowerData.next_skill[1];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDR);
+                this.SkillIDR = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+        // this.skillSpeattack();
+    }
+
+    public setTaHuan(taHuan: TowerHuan) {
+        this._taHuan = taHuan;
+        this.taHuanVec = taHuan.node.getPosition();
+        this._taside.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+        this._taHuan.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+        this.guang_b.node.scaleX = this.myDataObj.BulletData.model_scaling;
+    }
+
+    public setNitu(mytaside: taside) {
+        this._taside = mytaside;
+
+    }
+    onDestroy() {
+        this._taHuan.node.destroy();
+        this.guang_b.node.destroy();
+        this.attackmonster = [];
+    }
+    public getIsInSqrt(pos: cc.Vec2) {
+        let xiangl = this.taHuanVec.sub(pos);
+        let a = this.myDataObj.TowerData.attack_range;
+        let b = this.myDataObj.TowerData.attack_range * 5 / 6;
+        if (xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b) < 1) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+    public getAttackmonster(): monsterNode[] {
+        return this.attackmonster;
+    }
+
+    public addAttackmonster(monter: monsterNode) {
+        if (!this.isStartWait) {
+            if (monter.myDataObj.monsterData.company_type == 2) {
+                if (this.myDataObj.TowerData.air_attack_switch == 'ON') {
+                    this.attackmonster.push(monter);
+                }
+            }
+            else
+            {
+                this.attackmonster.push(monter);
+            }
+        }
+    }
+
+    public DelateAllAttackmonster() {
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                console.log("magic!!!!!!!!!!");
+                this.attackmonster.splice(i, 1);
+                i--;
+                continue;
+            }
+            if (!this.getIsInSqrt(element.node.getPosition()) || element.AniStatus == 'ZhengDie') {
+                this.attackmonster.splice(i, 1);
+                i--;
+            }
+        }
+    }
+
+    /**开始攻击 */
+    public attckStart() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.guang_a.node.opacity = 255;
+        this.clips = this.guang_a.node.getComponent(cc.Animation);
+        this.clips.play("laser_A").speed = GameConfig.instance().speed;
+        this.clips.on('finished', this.startGuang, this);
+    }
+
+    private startGuang() {
+        let self = this;
+        this.interVec = this.attackmonster[0].getNewPos();
+        // this.interVec = this.interVec.add(this.attackmonster[0].getTimeSetDistance(0.4));
+        let danpos = this.guang_b.node.getPosition();
+        this.jiaodu = this.GetPointHAngle(this.interVec, danpos);
+        // console.log("角度:"+this.jiaodu);
+        this.guang_b.node.angle = this.jiaodu;
+
+        this.guang_b.node.opacity = 255;
+        this.guang_b.node.scaleY = 1;
+        /**激光到怪的距离 */
+        let juli = this.interVec.sub(danpos).mag();
+        /** 设置激光长度*/
+        let leth = 1300;
+        let xiangliang = this.interVec.sub(this._taside.node.getPosition());
+        let XiangLeth = xiangliang.mag();
+        let beishu = leth / XiangLeth;
+        let endpos = this.interVec.add(cc.v2(xiangliang.x * beishu, xiangliang.y * beishu));
+        // let endAngle = this.GetPointHAngle(endpos,danpos);
+
+        if (!this.isdieLine) {
+            this.chongji.node.setPosition(this.interVec);
+            this.chongji.node.opacity = 255;
+            let clips = this.chongji.node.getComponent(cc.Animation);
+            clips.play("chongji_1").speed = GameConfig.instance().speed;
+            cc.tween(this.chongji.node)
+                .delay(0.02)
+                .to(this.myDataObj.BulletData.speed, { position: cc.v3(endpos) })
+                .to(0.02, { opacity: 0 })
+                .start();
+
+
+            let times = Math.floor(this.myDataObj.BulletData.speed / 0.02);
+            this.schedule(function () {
+                let chongjipos = self.chongji.node.getPosition();
+                let leetth = chongjipos.sub(danpos).mag();
+                self.guang_b.node.scaleY = leetth / 50;
+
+                let sjortAngle = self.GetPointHAngle(chongjipos, danpos);
+                self.guang_b.node.angle = sjortAngle;
+            }, 0.02, times);
+        }
+
+
+
+        let attacknu = this.myDataObj.getRanm(1, this.myDataObj.BulletData.attack);
+        if (towerManger.instance.talantData[13].length > 0) {
+            attacknu *= (1 + towerManger.instance.talantData[13][0]);
+        }
+        let t = cc.tween;
+        t(this.guang_b.node)
+            .to(0.02, { scaleY: juli / 50 })
+            .call(() => {
+                if (this.isdieLine) {
+                    /**伤害数值 */
+                    this.myDataObj.writeSkill_Config(this.SkillIDL);
+                    let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+                    this.attackmonster[0].hpDown(shanghai);
+                    this.isdieLine = false;
+                }
+                else {
+                    towerManger.instance.MagicAttckMonster(this._taside.node.getPosition(), this.interVec, attacknu, this.myDataObj.BulletData.boom_range);
+                }
+            })
+            .delay(this.myDataObj.BulletData.speed)
+            .to(0.3, { opacity: 0 })
+            .call(() => {
+                this.guang_a.node.opacity = 0;
+            })
+            .delay(this.myDataObj.TowerData.attack_cd)
+            .call(() => {
+                this.DelateAllAttackmonster();
+                this.attckStart();
+            })
+            .start();
+    }
+
+    /**特殊技能 */
+    private skillSpeattack() {
+        /**冷却时间 */
+        let delayTime = this.myDataObj.SkillData.parameter_4;
+        if (this.SkillIDL >= 13 && this.SkillIDL <= 15) {
+            this.schedule(this.skill13_15, delayTime);
+        }
+
+        if (this.SkillIDR >= 16 && this.SkillIDR <= 18) {
+            this.schedule(this.skill16_18, delayTime);
+        }
+
+        if (this.SkillIDL >= 19 && this.SkillIDL <= 21) {
+            this.schedule(this.skill19_21, delayTime);
+        }
+
+        if (this.SkillIDR >= 22 && this.SkillIDR <= 24) {
+            this.scheduleOnce(this.skill22_24, delayTime);
+        }
+    }
+
+    /**id 13-15技能 神秘射线 */
+    private skill13_15() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.isdieLine = true;
+    }
+
+    /**id 16-18技能 时空传送*/
+    private skill16_18() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        /**倒退步数 */
+        let step = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**目标数量 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (i < pointNum) {
+                element.setMonterBackStep(step);
+            }
+        }
+    }
+
+    /**id 13-15技能 变羊术 */
+    private skill19_21() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDL);
+        //变羊动画
+        let monter = this.attackmonster[0];
+        this.attackmonster[0].myDataObj.monsterData.active_attack_type == '3';
+        this.attackmonster[0].animalreGo();
+
+        let physics_re = this.attackmonster[0].myDataObj.monsterData.physics_reduction;
+        let magic_reduction = this.attackmonster[0].myDataObj.monsterData.magic_reduction;
+        this.attackmonster[0].myDataObj.monsterData.physics_reduction = 0;
+        this.attackmonster[0].myDataObj.monsterData.magic_reduction = 0;
+
+        /**持续时间 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        this.scheduleOnce(() => {
+            if (monter.node != null) {
+                if (monter.AniStatus != 'ZhengDie') {
+                    this.attackmonster[0].myDataObj.monsterData.physics_reduction = physics_re;
+                    this.attackmonster[0].myDataObj.monsterData.magic_reduction = magic_reduction;
+                    //还原
+                }
+            }
+
+        }, totalcount - 1);
+    }
+
+    /**id 13-15技能 召唤石头人 */
+    private skill22_24() {
+        if (this.SkillIDR < 22 && this.SkillIDR > 24) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        let monid = Number(this.myDataObj.SkillData.parameter_2);
+        this.myDataObj.writeMonster_Config(monid);
+        if (this.skillPeo) {
+            this.skillPeo.getsoldieThree().initLevelData(this,monid);
+            return;
+        }
+
+        let self = this;
+        let minPos = this.getMinPoint();
+        // cc.resources.load("prefabs/" + self.myDataObj.monsterData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+        //     var newNode = cc.instantiate(prefab);
+        //     monsterManger.instance.node.addChild(newNode, 3);
+        //     let startpos = self.taHuanVec.add(cc.v2(0, -57));
+        //     if (minPos.y > self.taHuanVec.y) {
+        //         startpos = self.taHuanVec.add(cc.v2(0, 37));
+        //     }
+        //     let theSolde = newNode.getComponent(soldie);
+        //     theSolde.initLevelData(self,monid);
+        //     theSolde.setIsSkill(true);
+        //     theSolde.setinitPos(startpos, minPos);
+        //     theSolde.initWalkToPoint(true);
+        //     self.skillPeo = theSolde;
+        // });
+
+        cc.resources.load("prefabs/skillSolate", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            newNode.setPosition(self.taHuanVec);
+            towerManger.instance.node.addChild(newNode, 1006);
+            let calssName = newNode.getComponent(SkillSolate);
+            calssName.towerType = 4;
+            calssName.initMagicID(minPos,monid,self.taHuanVec);
+            self.skillPeo = calssName;
+            towerManger.instance.towerArr.push(calssName);
+        });
+
+    }
+
+    /**路线距离兵营最近点坐标 */
+    private getMinPoint(): cc.Vec2 {
+        let mylength = this.taHuanVec.sub(cc.v2(this.GoPos[0].x, this.GoPos[0].y)).mag();
+        let mindex = 0;
+        for (let index = 1; index < this.GoPos.length; index++) {
+            const element = this.GoPos[index];
+
+            let juli = this.taHuanVec.sub(cc.v2(element.x, element.y)).mag();
+            if (juli < mylength) {
+                mindex = index;
+                mylength = juli;
+            }
+        }
+
+        return cc.v2(this.GoPos[mindex].x, this.GoPos[mindex].y);
+    }
+
+    private GetPointHAngle(p: cc.Vec2, ori: cc.Vec2): number//根据坐标x、y值计算其方位角
+    {
+        let hAngle = 0;
+        let dy = p.y - ori.y;
+        let dx = p.x - ori.x;
+        if (dx == 0 && dy > 0) {
+            hAngle = 0;
+        }
+        else if (dx == 0 && dy < 0) {
+            hAngle = 180;
+        }
+        else if (dy == 0 && dx > 0) {
+            hAngle = 90;
+        }
+        else if (dy == 0 && dx < 0) {
+            hAngle = 270;
+        }
+        else if (dx > 0 && dy > 0)//第一象限
+        {
+            hAngle = Math.atan2(dx, dy) * 180 / Math.PI;
+        }
+        else if (dx > 0 && dy < 0)//第二象限
+        {
+            hAngle = 180 - Math.atan2(dx, -dy) * 180 / Math.PI;
+        }
+        else if (dx < 0 && dy < 0)//第三象限
+        {
+            hAngle = 180 + Math.atan2(-dx, -dy) * 180 / Math.PI;
+        }
+        else if (dx < 0 && dy > 0)//第四象限
+        {
+            hAngle = 360 - Math.atan2(-dx, dy) * 180 / Math.PI;
+        }
+        return -hAngle + 360;
+    }
+}

+ 10 - 0
assets/Script/game/tower/Magic.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "79a84c6b-4c15-44e8-99ef-53336221cb87",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 241 - 0
assets/Script/game/tower/SkillSolate.ts

@@ -0,0 +1,241 @@
+import GameConfig from "../../configData/GameConfig";
+import monsterManger from "../monster/monsterManger";
+import monsterNode from "../monster/monsterNode";
+import soldie from "../monster/soldie";
+import towerManger from "./towerManger";
+import DataObj from "../../configData/DataObj";
+import gameUI from "../UIFace/gameUI";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class SkillSolate extends cc.Component {
+    private _myPos: cc.Vec2 = null;
+    private soldieThree: soldie[] = [];
+    public towerType = 0;
+    public myDataObj: DataObj = null;
+    private doecount = 0;
+    /**攻击范围内的怪物 */
+    private attackmonster: monsterNode[] = [];
+
+    onLoad() {
+        this.myDataObj = new DataObj();
+        this.node.opacity = 0;
+        // this.initID();
+
+    }
+
+    /**根据ID读取数据 */
+    public initID() {
+        this._myPos = this.node.getPosition();
+        this.myDataObj.writeSkill_Config(61);
+        this.loadSolde(this.myDataObj.SkillData.parameter_1);
+        this.scheduleOnce(() => {
+            towerManger.instance.delateTower(this);
+            this.node.destroy();
+        }, Number(this.myDataObj.SkillData.parameter_2));
+    }
+
+    /**加载兵 
+     * @param num  3塔兵  2技能兵
+    */
+    private loadSolde(num: number) {
+        let self = this;
+        let arr: cc.Vec2[] = [cc.v2(-20, 0), cc.v2(20, 0), cc.v2(0, -20)];
+        let arrtemp = this.myDataObj.getArr(this.myDataObj.SkillData.parameter_3);
+        for (let i = 0; i < num; i++) {
+            let monid = arrtemp[Math.floor(Math.random() * arrtemp.length)];
+            this.myDataObj.writeMonster_Config(monid);
+            cc.resources.load("prefabs/" + self.myDataObj.monsterData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+                var newNode = cc.instantiate(prefab);
+                newNode.setPosition(self._myPos.add(arr[i]));
+                monsterManger.instance.node.addChild(newNode, 3);
+                let theSolde = newNode.getComponent(soldie);
+                theSolde.setIsSkill(true);
+                theSolde.initSkillMinter(self, monid);
+                theSolde.setinitPos(self._myPos, self._myPos.add(arr[i]));
+                self.soldieThree.push(theSolde);
+                theSolde.setSche();
+            });
+        }
+
+
+    }
+
+
+    /**根据ID读取数据 */
+    public initMagicID(minpos: cc.Vec2, ID: number, Startpos: cc.Vec2) {
+        this._myPos = minpos;
+        this.myDataObj.writeSkill_Config(61);
+        this.loadMagicSolde(ID,Startpos);
+    }
+
+    /**加载兵 
+     * @param num  3塔兵  2技能兵
+    */
+    private loadMagicSolde(Id: number, Startpos: cc.Vec2) {
+        let self = this;
+
+        this.myDataObj.writeMonster_Config(Id);
+        cc.resources.load("prefabs/" + self.myDataObj.monsterData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            let startpos = self.node.getPosition().add(cc.v2(0, -57));
+            if (self._myPos.y > Startpos.y) {
+                startpos = Startpos.add(cc.v2(0, 37));
+            }
+            newNode.setPosition(startpos);
+            monsterManger.instance.node.addChild(newNode, 3);
+            let theSolde = newNode.getComponent(soldie);
+            theSolde.setIsSkill(true);
+            theSolde.initLevelData(self, Id);
+            theSolde.setinitPos(startpos, self._myPos);
+            theSolde.initWalkToPoint(true);
+            self.soldieThree.push(theSolde);
+            theSolde.setSche();
+        });
+    }
+
+    /**魔法塔获取石怪 */
+    public getsoldieThree():soldie
+    {
+        return this.soldieThree[0];
+    }
+
+
+    /**兵死亡次数增加 */
+    public dieCount() {
+        this.doecount++;
+        if (this.doecount == this.soldieThree.length) {
+            towerManger.instance.delateTower(this);
+            this.node.destroy();
+        }
+    }
+
+    /**无怪物时兵归位 */
+    private attackOver() {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.initWalkToPoint(false);
+        }
+    }
+
+    /**暂停动画 */
+    public isPaused(ispause: boolean) {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.ispaused(ispause);
+        }
+    }
+
+
+
+    onDestroy() {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.node.destroy();
+        }
+        this.Disassociate();
+    }
+
+    /**接触怪和兵关联 */
+    private Disassociate() {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            if (element.getMymonster() != null) {
+                if (element.getMymonster().node != null) {
+                    element.getMymonster().DelateAllBarracks();
+                    element.getMymonster().animalwalk();
+                    element.getMymonster().stopAni(false);
+                }
+            }
+        }
+    }
+
+    /**刷新 */
+    public getIsInSqrt(pos: cc.Vec2) {
+        let xiangl = this._myPos.sub(pos);
+        let attack_range = 295;
+        let a = attack_range;
+        let b = attack_range * 5 / 6;
+        let jieguo = xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b);
+        if (jieguo < 1) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public getAttackmonster(): monsterNode[] {
+        return this.attackmonster;
+    }
+
+    public addAttackmonster(monter: monsterNode) {
+        let index = this.attackmonster.indexOf(monter);
+        if (index < 0) {
+            if (monter.myDataObj.monsterData.company_type == 2) {
+                // if (this.myDataObj.TowerData.air_attack_switch == 'ON') {
+                //     this.attackmonster.push(monter);
+                //     this.moreMonsterAttack();
+                // }
+            }
+            else
+            {
+                this.attackmonster.push(monter);
+                this.moreMonsterAttack();
+            }
+        }
+    }
+
+    public DelateAllAttackmonster() {
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                this.attackmonster.splice(i, 1);
+                i--;
+                continue;
+            }
+            let isIn = this.getIsInSqrt(element.node.getPosition());
+            if (!isIn || element.AniStatus == 'ZhengDie') {
+                this.attackmonster.splice(i, 1);
+                i--;
+            }
+        }
+    }
+
+    /**调整兵围攻数量  */
+    private moreMonsterAttack() {
+        if (this.attackmonster.length <= 1) {
+            return;
+        }
+
+        if (this.attackmonster.length == 2) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                element.DelateBarracksRetain(2);
+            }
+        }
+
+        if (this.attackmonster.length >= 3) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                element.DelateBarracksRetain(1);
+            }
+        }
+    }
+
+    /**开始攻击 */
+    public attckStart() {
+        if (this.attackmonster.length == 0) {
+            this.attackOver();
+            return;
+        }
+
+        let self = this;
+
+        this.scheduleOnce(function () {
+            self.DelateAllAttackmonster();
+            self.attckStart();
+        }, 0.3);
+    }
+}

+ 10 - 0
assets/Script/game/tower/SkillSolate.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "91a8bb8c-b3dc-4c44-9a4f-af0944d5c07c",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 33 - 0
assets/Script/game/tower/TowerData.ts

@@ -0,0 +1,33 @@
+import gameUI from "../UIFace/gameUI";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class TowerData {
+    static _instance: TowerData = null!;
+    public static instance() 
+    {
+        if (!this._instance) 
+        {
+            this._instance = new TowerData();
+        }
+        return this._instance;
+    }
+
+    public getTowerPos(level:number):cc.Vec2[]
+    {
+        let levelpos1 = [];
+        let leth = gameUI.instance.myDataObj.LevelData.coordinate_x.length;
+        for (let i = 0; i < leth; i++) {
+            const xxx = gameUI.instance.myDataObj.LevelData.coordinate_x[i];
+            const yyy = gameUI.instance.myDataObj.LevelData.coordinate_y[i];
+            let onepos = cc.v2(xxx,yyy);
+            levelpos1.push(onepos);
+        }
+
+        
+        return levelpos1;
+    }
+   
+}

+ 10 - 0
assets/Script/game/tower/TowerData.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "e585d535-4953-4712-a0e4-17599900ffed",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 674 - 0
assets/Script/game/tower/TowerHuan.ts

@@ -0,0 +1,674 @@
+import towerManger from "./towerManger";
+import { TowerType } from "../../configData/Enum";
+import gameUI from "../UIFace/gameUI";
+
+import monsterManger from "../monster/monsterManger";
+import gameData from "../../configData/gameData";
+import TapNode from "../UIFace/TapNode";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class TowerHuan extends cc.Component {
+
+    /**环点击区域 */
+    @property(cc.Node)
+    private tapSqrt: cc.Node = null;
+
+    /**预警范围 */
+    @property(cc.Sprite)
+    private lanse: cc.Sprite = null;
+    /**预警范围 */
+    @property(cc.Sprite)
+    private redquan: cc.Sprite = null;
+    /** 圆环底座*/
+    @property(cc.Sprite)
+    private huan: cc.Sprite = null;
+    /**不可升级标志 */
+    @property(cc.Sprite)
+    private nosele: cc.Sprite = null;
+    /**升级金币数量 */
+    @property(cc.Label)
+    private sale: cc.Label = null;
+
+    /**升级底座 */
+    @property(cc.Sprite)
+    private shengji: cc.Sprite = null;
+
+    /**插旗底座 */
+    @property(cc.Sprite)
+    private chaqi: cc.Sprite = null;
+    /**卖掉塔底座 */
+    @property(cc.Sprite)
+    private towerdestory: cc.Sprite = null;
+
+    /**升级标志 */
+    @property(cc.Sprite)
+    private uptip: cc.Sprite = null;
+    /**升级勾 */
+    @property(cc.Sprite)
+    private upgou: cc.Sprite = null;
+    /**卖钱标志 */
+    @property(cc.Sprite)
+    private saletip: cc.Sprite = null;
+    /**卖钱勾 */
+    @property(cc.Sprite)
+    private salegou: cc.Sprite = null;
+    /**圆环是否打开 */
+    public isOpen = false;
+    /**是否可以插旗 */
+    public isCanChaqi = false;
+
+    /**升四级塔选项 */
+    private upfor1: cc.Node = null;
+    private upfor2: cc.Node = null;
+    /**技能升级选项 */
+    private skillupbg1: cc.Node = null;
+    private skillupbg2: cc.Node = null;
+    private skillupbg3: cc.Node = null;
+
+    private skillLv = [0, 0, 0];
+    private GoPos: cc.Vec3[] = [];
+    private norMaterial: cc.Material = cc.Material.getBuiltinMaterial('2d-sprite');
+    private grayMaterial: cc.Material = cc.Material.getBuiltinMaterial('2d-gray-sprite');
+    private tower = null;
+    private towerType: TowerType = 1;
+    onLoad() {
+        this.tapSqrt.on(cc.Node.EventType.TOUCH_START, this.touchNode, this);
+        this.initSpr();
+        this.GoPos = gameUI.instance.getGoPos();
+    }
+
+    private initSpr() {
+        this.redquan.node.active = false;
+        this.huan.node.active = false;
+
+
+        this.chaqi.node.on(cc.Node.EventType.TOUCH_START, this.chaqiclick, this);
+        this.towerdestory.node.on(cc.Node.EventType.TOUCH_START, this.destoryclick, this);
+    }
+
+    public setTowerType(type: TowerType) {
+        this.towerType = type;
+        this.chaqi.node.active = (type == TowerType.Enum_Barrack);
+        if (type == TowerType.Enum_Barrack) {
+            this.redquan.spriteFrame = this.lanse.spriteFrame;
+        }
+    }
+
+    /**设置塔 */
+    public setTower(tower) {
+        this.tower = tower;
+        this.sale.string = tower.myDataObj.TowerData.up_gold[0].toString();
+        // console.log("------");
+        this.initModel();
+    }
+
+    /**设置塔环类型  */
+    private initModel() {
+        let level = this.tower.myDataObj.TowerData.tower_level;
+
+        this.shengji.node.active = false;
+        this.upfor1 = this.huan.node.getChildByName('tower_upFour_1');
+        this.upfor2 = this.huan.node.getChildByName('tower_upFour_2');
+        this.skillupbg1 = this.huan.node.getChildByName('skillupbg1');
+        this.skillupbg2 = this.huan.node.getChildByName('skillupbg2');
+        this.skillupbg3 = this.huan.node.getChildByName('skillupbg3');
+        this.upfor1.active = false;
+        this.upfor2.active = false;
+        this.skillupbg1.active = false;
+        this.skillupbg2.active = false;
+        this.skillupbg3.active = false;
+        if (this.towerType == TowerType.Enum_Barrack) {
+            this.skillupbg1.setPosition(-139, 16);
+            this.skillupbg2.setPosition(-32, 134);
+            this.skillupbg3.setPosition(124, 98);
+        }
+        if (level < 3) {
+            this.shengji.node.active = true;
+            this.shengji.node.on(cc.Node.EventType.TOUCH_START, () => {
+                this.shengjiclick(0);
+            }, this);
+        }
+        if (level == 3) {
+            this.upfor1.active = true;
+            this.upfor2.active = true;
+            this.upfor1.on(cc.Node.EventType.TOUCH_START, this.seleTower1click, this);
+            this.upfor2.on(cc.Node.EventType.TOUCH_START, this.seleTower2click, this);
+            let sale1 = this.upfor1.getChildByName('sale').getComponent(cc.Label);
+            let sale2 = this.upfor2.getChildByName('sale').getComponent(cc.Label);
+            sale1.string = this.tower.myDataObj.TowerData.up_gold[0].toString();
+            sale2.string = this.tower.myDataObj.TowerData.up_gold[0].toString();
+            let self = this;
+            cc.resources.load("game/skill/tower_icon_" + this.towerType+"_0", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.upfor1.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+            cc.resources.load("game/skill/tower_icon_" + this.towerType+"_1", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.upfor2.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+        }
+        if (level >= 4) {
+            this.skillupbg1.active = true;
+            this.skillupbg2.active = true;
+            if (this.towerType == TowerType.Enum_Barrack) {
+                this.skillupbg3.active = true;
+            }
+            this.skillupbg1.on(cc.Node.EventType.TOUCH_START, this.upSkill1click, this);
+            this.skillupbg2.on(cc.Node.EventType.TOUCH_START, this.upSkill2click, this);
+            this.skillupbg3.on(cc.Node.EventType.TOUCH_START, this.upSkill3click, this);
+            this.resetSkillTap();
+        }
+    }
+
+    /**设置技能升级按钮 金币数 和图片 */
+    private resetSkillTap() {
+        let sale1 = this.skillupbg1.getChildByName('sale').getComponent(cc.Label);
+        let sale2 = this.skillupbg2.getChildByName('sale').getComponent(cc.Label);
+        let sale3 = this.skillupbg3.getChildByName('sale').getComponent(cc.Label);
+        let self = this;
+        if (this.skillLv[0] == 0) {
+            sale1.string = this.tower.myDataObj.TowerData.up_gold[0].toString();
+            let idd = this.tower.myDataObj.TowerData.next_skill[0];
+            this.tower.myDataObj.writeSkill_Config(idd);
+            cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+        }
+        else {
+            this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDL);
+            sale1.string = this.tower.myDataObj.SkillData.up_gold.toString();
+
+            for (let i = 1; i <= this.skillLv[0]; i++) {
+                this.skillupbg1.getChildByName('skilllv' + i).opacity = 255;
+            }
+
+            cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+        }
+
+        if (this.skillLv[1] == 0) {
+            sale2.string = this.tower.myDataObj.TowerData.up_gold[1].toString();
+            let idd = this.tower.myDataObj.TowerData.next_skill[1];
+            this.tower.myDataObj.writeSkill_Config(idd);
+            cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+        }
+        else {
+            this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDR);
+            sale2.string = this.tower.myDataObj.SkillData.up_gold.toString();
+            for (let i = 1; i <= this.skillLv[1]; i++) {
+                this.skillupbg2.getChildByName('skilllv' + i).opacity = 255;
+            }
+
+            cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                self.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+            });
+        }
+
+        if (this.towerType == TowerType.Enum_Barrack) {
+            if (this.skillLv[2] == 0) {
+                sale3.string = this.tower.myDataObj.TowerData.up_gold[2].toString();
+                let idd = this.tower.myDataObj.TowerData.next_skill[2];
+                this.tower.myDataObj.writeSkill_Config(idd);
+                cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                    self.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+                });
+            }
+            else {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDT);
+                sale3.string = this.tower.myDataObj.SkillData.up_gold.toString();
+                for (let i = 1; i <= this.skillLv[2]; i++) {
+                    this.skillupbg3.getChildByName('skilllv' + i).opacity = 255;
+                }
+                cc.resources.load("game/skill/" + this.tower.myDataObj.SkillData.skill_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                    self.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).spriteFrame = myspriteFrame;
+                });
+            }
+        }
+
+    }
+
+    /**设置环的大小 */
+    public setRedHuanScale(scale: number) {
+        this.redquan.node.scale = scale / 275;
+    }
+
+    /**选择左技能塔 */
+    private seleTower1click() {
+        this.shengjiclick(0);
+    }
+
+    /**选择右技能塔 */
+    private seleTower2click() {
+        this.shengjiclick(1);
+    }
+
+    /**升级左边技能 */
+    private upSkill1click() {
+        if (this.skillLv[0] < 3) {
+            this.shengjiclick(0);
+        }
+    }
+
+    /**升级右边技能 */
+    private upSkill2click() {
+        if (this.skillLv[1] < 3) {
+            this.shengjiclick(1);
+        }
+    }
+    /**升级3边技能 */
+    private upSkill3click() {
+        if (this.skillLv[2] < 3) {
+            this.shengjiclick(2);
+        }
+    }
+
+    /**升级塔 */
+    private shengjiclick(dex: number) {
+        let level = this.tower.myDataObj.TowerData.tower_level;
+        let upgold = this.tower.myDataObj.TowerData.up_gold[dex];
+        if (level == 3) {
+            upgold = this.tower.myDataObj.TowerData.up_gold[0];
+        }
+        let isgoldMore = upgold <= gameUI.instance.getGold();
+        if (level >= 4 && this.skillLv[dex] > 0) {
+            if (dex == 0) {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDL);
+                isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+            }
+
+            if (dex == 1) {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDR);
+                isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+            }
+
+            if (dex == 2) {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDT);
+                isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+            }
+        }
+        let canUpTower = gameUI.instance.getLevelLimit().indexOf(this.tower.myDataObj.TowerData.next_tower_id[dex]) < 0;
+        let dagou = this.upgou;
+
+        if (level == 3) {
+            if (dex == 0) {
+                dagou = this.upfor1.getChildByName('build_1').getComponent(cc.Sprite);
+            }
+
+            if (dex == 1) {
+                dagou = this.upfor2.getChildByName('build_1').getComponent(cc.Sprite);
+            }
+        }
+        if (level >= 4) {
+            if (dex == 0) {
+                dagou = this.skillupbg1.getChildByName('build_1').getComponent(cc.Sprite);
+            }
+
+            if (dex == 1) {
+                dagou = this.skillupbg2.getChildByName('build_1').getComponent(cc.Sprite);
+            }
+
+            if (dex == 2) {
+                dagou = this.skillupbg3.getChildByName('build_1').getComponent(cc.Sprite);
+            }
+        }
+
+        if (isgoldMore && canUpTower) {
+            if (dagou.node.opacity == 0) {
+                dagou.node.opacity = 255;
+                if (level < 3) {
+                    this.uptip.node.opacity = 0;
+                }
+
+                if (level == 3) {
+                    if (dex == 0) {
+                        this.upfor2.getChildByName('build_1').opacity = 0;
+                    }
+
+                    if (dex == 1) {
+                        this.upfor1.getChildByName('build_1').opacity = 0;
+                    }
+                }
+                if (level >= 4) {
+                    if (dex == 0) {
+                        this.skillupbg2.getChildByName('build_1').opacity = 0;
+                        this.skillupbg3.getChildByName('build_1').opacity = 0;
+                    }
+
+                    if (dex == 1) {
+                        this.skillupbg1.getChildByName('build_1').opacity = 0;
+                        this.skillupbg3.getChildByName('build_1').opacity = 0;
+                    }
+
+                    if (dex == 2) {
+                        this.skillupbg1.getChildByName('build_1').opacity = 0;
+                        this.skillupbg2.getChildByName('build_1').opacity = 0;
+                    }
+                }
+            }
+            else {
+                if (level <= 3) {
+                    towerManger.instance.delateTower(this.tower);
+                    towerManger.instance.UpTower(this.tower, this.tower.myDataObj.TowerData.next_tower_id[dex]);
+                    gameUI.instance.AddGold(-this.tower.myDataObj.TowerData.up_gold[0]);
+                    this.scheduleOnce(function () {
+                        this.tower.node.destroy();
+                    }, 0);
+                }
+                else {
+                    this.tower.setandUpSkillId(dex + 1);
+                    if (this.skillLv[dex] == 0) {
+                        gameUI.instance.AddGold(-this.tower.myDataObj.TowerData.up_gold[0]);
+                    }
+                    else {
+                        gameUI.instance.AddGold(-this.tower.myDataObj.SkillData.up_gold);
+                    }
+                    this.skillLv[dex]++;
+
+                    this.resetSkillTap();
+                    this.turnsmall();
+                }
+
+            }
+        }
+    }
+
+    /**插旗 */
+    private chaqiclick() {
+        this.redquan.node.active = true;
+        this.isCanChaqi = true;
+        TapNode.instance.node.active = true;
+        this.turnsmall();
+    }
+    /**插旗 */
+    public chaqiTap(location: cc.Vec2) {
+        if (this.isCanChaqi) {
+            if (this.getIsInGopos(location) && this.tower.getIsInSqrt(location)) {
+                this.isCanChaqi = false;
+                this.redquan.node.active = false;
+                TapNode.instance.node.active = false;
+                this.tower.chaqiWalk(location);
+                monsterManger.instance.chaqidian(location);
+            }
+            else {
+                monsterManger.instance.updatest(location);
+            }
+        }
+    }
+    /**插旗位置判断 */
+    private getIsInGopos(location: cc.Vec2): boolean {
+        let leth = Number(gameData.instance().game_Const[7][2]);
+        let laca = cc.v3(location.x, location.y);
+        for (let i = 0; i < this.GoPos.length; i++) {
+            const element = this.GoPos[i];
+            if (element.sub(laca).mag() < leth) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    /**销毁塔卖钱*/
+    private destoryclick() {
+        if (this.salegou.node.opacity == 0) {
+            this.salegou.node.opacity = 255;
+            this.saletip.node.opacity = 0;
+        }
+        else {
+            this.tower._taside.openTouchOn();
+            towerManger.instance.delateTower(this.tower);
+            let value_gold = this.tower.myDataObj.TowerData.value_gold;
+            if (this.tower.SkillIDL > 0) {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDL);
+                value_gold += this.tower.myDataObj.SkillData.up_gold;
+                this.tower._taside.addtowerGold(this.tower.myDataObj.SkillData.up_gold);
+            }
+            if (this.tower.SkillIDR > 0) {
+                this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDR);
+                value_gold += this.tower.myDataObj.SkillData.up_gold;
+                this.tower._taside.addtowerGold(this.tower.myDataObj.SkillData.up_gold);
+            }
+            if (this.towerType == TowerType.Enum_Barrack) {
+                if (this.tower.SkillIDT > 0) {
+                    this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDT);
+                    value_gold += this.tower.myDataObj.SkillData.up_gold;
+                    this.tower._taside.addtowerGold(this.tower.myDataObj.SkillData.up_gold);
+                }
+            }
+            if (towerManger.instance.talantData[0].length > 0 && this.towerType == TowerType.Enum_Arrow) {
+                value_gold = this.tower._taside.gettowerGold() * towerManger.instance.talantData[0][0];
+                this.tower._taside.settowerGold(0);
+            }
+            gameUI.instance.AddGold(value_gold);
+            this.tower.node.destroy();
+        }
+    }
+    //iconspr
+    /**显示金币不足时状态 */
+    private showNosele() {
+        let isgoldMore = this.tower.myDataObj.TowerData.up_gold[0] <= gameUI.instance.getGold();
+        let canUpTower = gameUI.instance.getLevelLimit().indexOf(this.tower.myDataObj.TowerData.next_tower_id[0]) < 0;
+        let level = this.tower.myDataObj.TowerData.tower_level;
+        if (level < 3) {
+            this.uptip.node.opacity = 255;
+            if (canUpTower) {
+                this.nosele.node.opacity = 0;
+                this.shengji.node.getChildByName('skillupbg3').opacity = 255;
+                this.shengji.node.getChildByName('iconspr').opacity = 255;
+                this.sale.node.opacity = 255;
+            }
+            else {
+                this.nosele.node.opacity = 255;
+                this.shengji.node.getChildByName('iconspr').opacity = 0;
+                this.sale.node.opacity = 0;
+                this.shengji.node.getChildByName('skillupbg3').opacity = 0;
+            }
+            if (isgoldMore) {
+                this.shengji.node.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                this.sale.node.color = cc.color(235, 255, 6);
+            }
+            else {
+                this.shengji.node.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                this.sale.node.color = cc.color(102, 91, 91);
+            }
+        }
+
+        if (level == 3) {
+            
+            if (canUpTower) {
+                this.upfor1.getChildByName('build_2').opacity = 0;
+                this.upfor1.getChildByName('iconspr').opacity = 255;
+                this.upfor1.getChildByName('sale').opacity = 255;
+                this.upfor1.getChildByName('skillupbg3').opacity = 255;
+            }
+            else {
+                this.upfor1.getChildByName('build_2').opacity = 255;
+                this.upfor1.getChildByName('iconspr').opacity = 0;
+                this.upfor1.getChildByName('sale').opacity = 0;
+                this.upfor1.getChildByName('skillupbg3').opacity = 0;
+            }
+            let canUpTower1 = gameUI.instance.getLevelLimit().indexOf(this.tower.myDataObj.TowerData.next_tower_id[1]) < 0;
+            if (canUpTower1) {
+                this.upfor2.getChildByName('build_2').opacity = 0;
+                this.upfor2.getChildByName('iconspr').opacity = 255;
+                this.upfor2.getChildByName('sale').opacity = 255;
+                this.upfor2.getChildByName('skillupbg3').opacity = 255;
+            }
+            else {
+                this.upfor2.getChildByName('build_2').opacity = 255;
+                this.upfor2.getChildByName('iconspr').opacity = 0;
+                this.upfor2.getChildByName('sale').opacity = 0;
+                this.upfor2.getChildByName('skillupbg3').opacity = 0;
+            }
+            if (isgoldMore) {
+                this.upfor1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                this.upfor2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                this.upfor1.getChildByName('sale').color = cc.color(235, 255, 6);
+                this.upfor2.getChildByName('sale').color = cc.color(235, 255, 6);
+            }
+            else {
+                this.upfor1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                this.upfor2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                this.upfor1.getChildByName('sale').color = cc.color(102, 91, 91);
+                this.upfor2.getChildByName('sale').color = cc.color(102, 91, 91);
+            }
+        }
+
+        if (level >= 4) {
+            if (this.tower.SkillIDL == 0) {
+                let isgoldMore = this.tower.myDataObj.TowerData.up_gold[0] <= gameUI.instance.getGold();
+                if (isgoldMore) {
+                    this.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                    this.skillupbg1.getChildByName('sale').color = cc.color(235, 255, 6);
+                }
+                else {
+                    this.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                    this.skillupbg1.getChildByName('sale').color = cc.color(102, 91, 91);
+                }
+            }
+            else {
+                if (this.skillLv[0] < 3) {
+                    this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDL);
+                    let isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+                    if (isgoldMore) {
+                        this.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                        this.skillupbg1.getChildByName('sale').color = cc.color(235, 255, 6);
+                    }
+                    else {
+                        this.skillupbg1.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                        this.skillupbg1.getChildByName('sale').color = cc.color(102, 91, 91);
+                    }
+                }
+                else {
+                    this.skillupbg1.getChildByName('sale').opacity = 0;
+                    this.skillupbg1.getChildByName('skillupbg3').opacity = 0;
+                }
+
+            }
+
+
+            if (this.tower.SkillIDR == 0) {
+                let isgoldMore = this.tower.myDataObj.TowerData.up_gold[1] <= gameUI.instance.getGold();
+                if (isgoldMore) {
+                    this.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                    this.skillupbg2.getChildByName('sale').color = cc.color(235, 255, 6);
+                }
+                else {
+                    this.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                    this.skillupbg2.getChildByName('sale').color = cc.color(102, 91, 91);
+                }
+            }
+            else {
+                if (this.skillLv[1] < 3) {
+                    this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDR);
+                    let isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+                    if (isgoldMore) {
+                        this.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                        this.skillupbg2.getChildByName('sale').color = cc.color(235, 255, 6);
+                    }
+                    else {
+                        this.skillupbg2.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                        this.skillupbg2.getChildByName('sale').color = cc.color(102, 91, 91);
+                    }
+                }
+                else {
+                    this.skillupbg2.getChildByName('sale').opacity = 0;
+                    this.skillupbg2.getChildByName('skillupbg3').opacity = 0;
+                }
+
+            }
+
+            if (this.towerType == TowerType.Enum_Barrack) {
+                if (this.tower.SkillIDT == 0) {
+                    let isgoldMore = this.tower.myDataObj.TowerData.up_gold[2] <= gameUI.instance.getGold();
+                    if (isgoldMore) {
+                        this.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                        this.skillupbg3.getChildByName('sale').color = cc.color(235, 255, 6);
+                    }
+                    else {
+                        this.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                        this.skillupbg3.getChildByName('sale').color = cc.color(102, 91, 91);
+                    }
+                }
+                else {
+                    if (this.skillLv[2] < 3) {
+                        this.tower.myDataObj.writeSkill_Config(this.tower.SkillIDT);
+                        let isgoldMore = this.tower.myDataObj.SkillData.up_gold <= gameUI.instance.getGold();
+                        if (isgoldMore) {
+                            this.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.norMaterial);
+                            this.skillupbg3.getChildByName('sale').color = cc.color(235, 255, 6);
+                        }
+                        else {
+                            this.skillupbg3.getChildByName('iconspr').getComponent(cc.Sprite).setMaterial(0, this.grayMaterial);
+                            this.skillupbg3.getChildByName('sale').color = cc.color(102, 91, 91);
+                        }
+                    }
+                    else {
+                        this.skillupbg3.getChildByName('sale').opacity = 0;
+                        this.skillupbg3.getChildByName('skillupbg3').opacity = 0;
+                    }
+
+                }
+            }
+
+
+
+        }
+
+    }
+    /**打开圆环 */
+    private turnbig() {
+        this.showNosele();
+        towerManger.instance.closedHuan();
+        this.huan.node.scale = 0.5;
+        this.huan.node.opacity = 0;
+        this.huan.node.active = true;
+        this.redquan.node.active = true;
+        this.huan.node.stopAllActions();
+        this.node.zIndex = 1007;
+        cc.tween(this.huan.node)
+            .to(0.1, { scale: 1, opacity: 255 })
+            .call(() => {
+                this.isOpen = true;
+            })
+            .start();
+    }
+
+    /**关闭圆环 */
+    public turnsmall() {
+        if (this.isOpen) {
+            this.node.zIndex = 1006;
+            this.huan.node.stopAllActions();
+            cc.tween(this.huan.node)
+                .to(0.1, { scale: 0.5, opacity: 0 })
+                .call(() => {
+                    this.huan.node.active = false;
+                    this.isOpen = false;
+                    if (!this.isCanChaqi) {
+                        this.redquan.node.active = false;
+                    }
+                    this.upgou.node.opacity = 0;
+                    this.salegou.node.opacity = 0;
+                    this.saletip.node.opacity = 255;
+
+                    this.upfor1.getChildByName('build_1').opacity = 0;
+                    this.upfor2.getChildByName('build_1').opacity = 0;
+                    this.skillupbg1.getChildByName('build_1').opacity = 0;
+                    this.skillupbg2.getChildByName('build_1').opacity = 0;
+                    this.skillupbg3.getChildByName('build_1').opacity = 0;
+                })
+                .start();
+        }
+
+
+    }
+
+    /**点击泥土 */
+    private touchNode() {
+        this.turnbig();
+    }
+
+}

+ 10 - 0
assets/Script/game/tower/TowerHuan.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "09f8a5c0-9ac0-4e7e-95bf-e856de487c4b",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 318 - 0
assets/Script/game/tower/arrow.ts

@@ -0,0 +1,318 @@
+
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import monsterNode from "../monster/monsterNode";
+import Archer from "./Archer";
+import taside from "./taside";
+import TowerHuan from "./TowerHuan";
+import towerManger from "./towerManger";
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class arrow extends cc.Component {
+    private _taHuan: TowerHuan = null;
+    public _taside: taside = null;
+    public taHuanVec: cc.Vec2 = null;
+
+    public myDataObj: DataObj = null;
+    /**攻击范围内的怪物 */
+    private attackmonster: monsterNode[] = [];
+    private archer: Archer[] = [];
+    public towerType = 0;
+ 
+    /**左技能ID */
+    public SkillIDL = 0;
+    /**右技能ID */
+    public SkillIDR = 0;
+
+    private timeCount = 0;
+    private isStartWait = true;
+    public talantData = {
+
+    };
+
+    protected onLoad() {
+        this.myDataObj = new DataObj();
+
+    }
+
+    /**根据ID读取数据 */
+    public initID(ID: number) {
+        this.myDataObj.writeTower_Config(ID);
+        this.myDataObj.writeBullet_Config(this.myDataObj.TowerData.bullet_id);
+        
+        if (towerManger.instance.talantData[1].length > 0 && towerManger.instance.talantData[3].length > 0) {
+            this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[3][0] + towerManger.instance.talantData[1][0]);
+        }
+        else {
+            if (towerManger.instance.talantData[1].length > 0) {
+                this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[1][0]);
+            }
+
+            if (towerManger.instance.talantData[3].length > 0) {
+                this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[3][0]);
+            }
+        }
+
+        this.loadArcher(this.myDataObj.TowerData.monster_id[1]);
+
+    }
+
+    /**设置或升级技能ID  技能类型 1左边  2右边*/
+    public setandUpSkillId(skillType:number)
+    {
+        if (skillType == 1) {
+            if (this.SkillIDL == 0) {
+                this.SkillIDL = this.myDataObj.TowerData.next_skill[0];
+            }
+            else
+            {
+                this.myDataObj.writeSkill_Config(this.SkillIDL);
+                this.SkillIDL = this.myDataObj.SkillData.next_skill;
+            }
+        }
+        
+
+        if (skillType == 2) {
+            if (this.SkillIDR == 0) {
+                this.SkillIDR = this.myDataObj.TowerData.next_skill[1];
+            }
+            else
+            {
+                this.myDataObj.writeSkill_Config(this.SkillIDR);
+                this.SkillIDR = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+        // this.skillSpeattack();
+    }
+
+
+
+    private loadArcher(num: number) {
+        let self = this;
+        let arr = [];
+        if (num == 1) {
+            arr = [cc.v2(0, 20)];
+        }
+        if (num == 2) {
+            arr = [cc.v2(-21, 20), cc.v2(11, 20)];
+            if (this.myDataObj.TowerData.id == 3) {
+                arr = [cc.v2(-19, 5), cc.v2(13, 5)];
+            }
+
+            if (this.myDataObj.TowerData.id == 4) {
+                arr = [cc.v2(-19, -5), cc.v2(13, -5)];
+            }
+            if (this.myDataObj.TowerData.id == 7) {
+                arr = [cc.v2(-19-10, 8), cc.v2(13+10, 8)];
+            }
+        }
+        if (num == 3) {
+            arr = [cc.v2(-30, 20), cc.v2(0, 20), cc.v2(30, 20)];
+        }
+        cc.resources.load("prefabs/" + this.myDataObj.TowerData.name2, cc.Prefab, function (err, prefab: cc.Prefab) {
+            for (let i = 0; i < num; i++) {
+                var newNode = cc.instantiate(prefab);
+                self.node.addChild(newNode);
+                newNode.setPosition(arr[i]);
+                let theSolde = newNode.getComponent(Archer);
+                theSolde.initTower(self);
+                self.archer.push(theSolde);
+            }
+
+            if (self.myDataObj.TowerData.tower_level == 1) {
+                self.isStartWait = false;
+            }
+            else
+            {
+                self.scheduleOnce(function(){
+                    self.isStartWait = false;
+                },self.myDataObj.TowerData.attack_cd);
+            }
+            
+        });
+    }
+
+    public setTaHuan(taHuan: TowerHuan) {
+        this._taHuan = taHuan;
+        this.taHuanVec = taHuan.node.getPosition();
+        this._taHuan.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+        this._taside.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+
+    }
+
+    public setNitu(mytaside: taside) {
+        this._taside = mytaside;
+    }
+
+    onDestroy() {
+        this._taHuan.node.destroy();
+        this.attackmonster = [];
+    }
+
+
+    public getIsInSqrt(pos: cc.Vec2): boolean {
+
+        let xiangl = this.taHuanVec.sub(pos);
+        let attack_range = this.myDataObj.TowerData.attack_range;
+        let a = attack_range;
+        let b = attack_range * 5 / 6;
+        if (xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b) < 1) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public getAttackmonster(): monsterNode[] {
+        return this.attackmonster;
+    }
+
+    public addAttackmonster(monter: monsterNode) {
+        if (!this.isStartWait) {
+            if (monter.myDataObj.monsterData.company_type == 2) {
+                if (this.myDataObj.TowerData.air_attack_switch == 'ON') {
+                    this.attackmonster.push(monter);
+                }
+            }
+            else
+            {
+                this.attackmonster.push(monter);
+            }
+        }
+    }
+
+    private DelateAllAttackmonster() {
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                console.log("arraw!!!!!!!!!!");
+                this.attackmonster.splice(i, 1);
+                i--;
+                continue;
+            }
+            if (!this.getIsInSqrt(element.node.getPosition()) || element.AniStatus == 'ZhengDie') {
+                this.attackmonster.splice(i, 1);
+                i--;
+            }
+        }
+    }
+
+    /**开始攻击 */
+    public attckStart() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        for (let i = 0; i < this.archer.length; i++) {
+            const element = this.archer[i];
+
+            this.scheduleOnce(function () {
+                element.attack(this.attackmonster[0]);
+            }, i * 0.3);
+        }
+    }
+
+    public oneAccack(myArcher: Archer) {
+        this.DelateAllAttackmonster();
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        myArcher.attack(this.attackmonster[0]);
+    }
+
+    /**特殊技能 */
+    private skillSpeattack() {
+        /**冷却时间 */
+        let delayTime = this.myDataObj.SkillData.parameter_4;
+        if (this.SkillIDR >= 4 && this.SkillIDR <= 6) {
+            this.schedule(this.skill4_6, delayTime);
+        }
+
+        if (this.SkillIDR >= 10 && this.SkillIDR <= 12) {
+            this.schedule(this.skill10_12, delayTime);
+        }
+    }
+
+
+
+    /**id 4-6技能 藤蔓缠绕*/
+    private skill4_6() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        this.timeCount = 0;
+        /**伤害数值 */
+        let shanghai = Number(this.myDataObj.SkillData.parameter_2);
+        /**持续时间 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**目标数量 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (i < pointNum) {
+                element.SetWalk(true);
+            }
+        }
+        this.schedule(() => {
+            this.timeCount++;
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                if (i < pointNum) {
+                    element.hpDown(shanghai);
+                    if (this.timeCount >= totalcount) {
+                        element.SetWalk(false);
+                    }
+                }
+            }
+
+        }, 1, totalcount - 1);
+    }
+
+
+    /**id 10-12技能 弹幕射击*/
+    private skill10_12() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        this.timeCount = 0;
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**射程半径 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**目标数量 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+        let dex = 0;
+        let juli = 10000;
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            let monTotaLeth = this.taHuanVec.sub(element.node.getPosition()).mag();
+            if (monTotaLeth < juli) {
+                juli = monTotaLeth;
+                dex = i;
+            }
+        }
+        let dexPos = this.attackmonster[dex].node.getPosition();
+        let arrTemp: monsterNode[] = [];
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            let monToDexLeth = dexPos.sub(element.node.getPosition()).mag();
+            if (monToDexLeth < totalcount) {
+                arrTemp.push(element);
+            }
+        }
+
+        for (let i = 0; i < arrTemp.length; i++) {
+            const element = arrTemp[i];
+            if (i < pointNum) {
+                element.hpDown(shanghai);
+            }
+        }
+
+    }
+}

+ 10 - 0
assets/Script/game/tower/arrow.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "5f11bafa-bc4b-46de-8e0c-867e134b094b",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 503 - 0
assets/Script/game/tower/barracks.ts

@@ -0,0 +1,503 @@
+
+import GameConfig from "../../configData/GameConfig";
+import monsterManger from "../monster/monsterManger";
+import TowerHuan from "./TowerHuan";
+import taside from "./taside";
+import monsterNode from "../monster/monsterNode";
+import soldie from "../monster/soldie";
+import towerManger from "./towerManger";
+import DataObj from "../../configData/DataObj";
+import gameUI from "../UIFace/gameUI";
+import gameData from "../../configData/gameData";
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class barracks extends cc.Component {
+    private GoPos: cc.Vec3[] = null;//1路线坐标集合
+    private minPos: cc.Vec2 = null;
+    private _taHuan: TowerHuan = null;
+    public _taside: taside = null;
+    private taHuanVec: cc.Vec2 = null;
+
+    private soldieThree: soldie[] = [];
+    public towerType = 0;
+    public myDataObj: DataObj = null;
+    private isStartWait = true;
+    private startPosArr: cc.Vec2[] = [];
+    /**左技能ID */
+    public SkillIDL = 0;
+    /**右技能ID */
+    public SkillIDR = 0;
+    /**3技能ID */
+    public SkillIDT = 0;
+    /**攻击范围内的怪物 */
+    private attackmonster: monsterNode[] = [];
+
+    onLoad() {
+
+        this.GoPos = gameUI.instance.getGoPos();
+        this.myDataObj = new DataObj();
+    }
+
+    /**根据ID读取数据 */
+    public initID(ID: number) {
+        this.myDataObj.writeTower_Config(ID);
+        if (towerManger.instance.talantData[7].length > 0) {
+            this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[7][0]);
+        }
+        this._taside.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+
+    }
+
+    /**设置或升级技能ID  技能类型 1左边  2右边*/
+    public setandUpSkillId(skillType: number) {
+        if (skillType == 1) {
+            if (this.SkillIDL == 0) {
+                this.SkillIDL = this.myDataObj.TowerData.next_skill[0];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDL);
+                this.SkillIDL = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+
+        if (skillType == 2) {
+            if (this.SkillIDR == 0) {
+                this.SkillIDR = this.myDataObj.TowerData.next_skill[1];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDR);
+                this.SkillIDR = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+        if (skillType == 3) {
+            if (this.SkillIDT == 0) {
+                this.SkillIDT = this.myDataObj.TowerData.next_skill[2];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDT);
+                this.SkillIDT = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+        // this.skillSpeattack();
+    }
+
+    /**获取兵当前坐标 */
+    public getSoldePosArr(): cc.Vec2[] {
+        this.startPosArr = [];
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            this.startPosArr.push(element.node.getPosition());
+        }
+        return this.startPosArr.concat();
+    }
+
+    /**设置兵当前坐标 */
+    public setSoldePosArr(arr: cc.Vec2[]) {
+        this.startPosArr = arr;
+    }
+
+
+    /**加载兵 
+     * @param num  3塔兵  2技能兵
+    */
+    private loadSolde(num: number) {
+        let self = this;
+        let arr: cc.Vec2[] = [self.minPos.add(cc.v2(-20, 0)), self.minPos.add(cc.v2(20, 20)), self.minPos.add(cc.v2(20, -20))];
+        cc.resources.load("prefabs/" + this.myDataObj.TowerData.name2, cc.Prefab, function (err, prefab: cc.Prefab) {
+            for (let i = 0; i < num; i++) {
+                var newNode = cc.instantiate(prefab);
+
+                monsterManger.instance.node.addChild(newNode, 3);
+                let startpos = self.taHuanVec.add(cc.v2(0, -57));
+                if (self.minPos.y > self.taHuanVec.y) {
+                    startpos = self.taHuanVec.add(cc.v2(0, 37));
+                }
+
+
+                let theSolde = newNode.getComponent(soldie);
+                theSolde.initLevelData(self,self.myDataObj.TowerData.monster_id[0]);
+                theSolde.initTalant();
+                theSolde.setIsSkill(false);
+                theSolde.setinitPos(startpos, arr[i]);
+                if (self.startPosArr.length > 0) {
+                    newNode.setPosition(self.startPosArr[i]);
+                    if (self.startPosArr[i] == cc.v2(0, 0)) {
+                        theSolde.initWalkToPoint(true);
+                    }
+                }
+                else {
+                    theSolde.initWalkToPoint(true);
+                }
+                self.soldieThree.push(theSolde);
+                theSolde.setSche();
+            }
+            self.scheduleOnce(function () {
+                self.isStartWait = false;
+            }, 0);
+        });
+    }
+
+    /**插旗 */
+    public chaqiWalk(laca: cc.Vec2) {
+        let self = this;
+        this.minPos = laca;
+        let arr: cc.Vec2[] = [self.minPos.add(cc.v2(-20, 0)), self.minPos.add(cc.v2(20, 20)), self.minPos.add(cc.v2(20, -20))];
+        this.Disassociate();
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.setinitPos(null, arr[i]);
+            // element.setisCanAttck(false);
+            element.initWalkToPoint(false);
+        }
+
+
+        // this.scheduleOnce(function(){
+        //     for (let i = 0; i < this.soldieThree.length; i++) {
+        //         const element = this.soldieThree[i];
+        //         element.setisCanAttck(true);
+        //     }
+        // },1);
+
+    }
+
+    /**无怪物时兵归位 */
+    private attackOver() {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.initWalkToPoint(false);
+        }
+    }
+
+    /**暂停动画 */
+    public isPaused(ispause: boolean) {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.ispaused(ispause);
+        }
+    }
+
+    /** 环*/
+    public setTaHuan(taHuan: TowerHuan) {
+        this._taHuan = taHuan;
+        this.taHuanVec = taHuan.node.getPosition();
+        this.minPos = this.getMinPoint();
+        if (this.myDataObj.TowerData.tower_level == 1) {
+            cc.tween(this.node)
+                    .delay(Number(gameData.instance().game_Const[1][2]) - 0.04)
+                    .call(() => {
+                        this.loadSolde(this.myDataObj.TowerData.monster_id[1]);
+                    })
+                    .start();
+        }
+        else
+        {
+            this.loadSolde(this.myDataObj.TowerData.monster_id[1]);
+        }
+        
+        this._taHuan.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+    }
+
+    /**设置泥土 */
+    public setNitu(mytaside: taside) {
+        this._taside = mytaside;
+
+    }
+    onDestroy() {
+        this.attackmonster = [];
+
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.node.destroy();
+        }
+        this.Disassociate();
+        this._taHuan.node.destroy();
+    }
+
+    /**接触怪和兵关联 */
+    private Disassociate() {
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            if (element.getMymonster() != null) {
+                if (element.getMymonster().node != null) {
+                    element.getMymonster().DelateAllBarracks();
+                    element.getMymonster().animalwalk();
+                    element.getMymonster().stopAni(false);
+                }
+            }
+        }
+    }
+
+
+
+    /**刷新 */
+    public getIsInSqrt(pos: cc.Vec2) {
+        let xiangl = this.taHuanVec.sub(pos);
+        let attack_range = this.myDataObj.TowerData.attack_range;
+        let a = attack_range;
+        let b = attack_range * 5 / 6;
+        let jieguo = xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b);
+        if (xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b) < 1) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+
+    public getAttackmonster(): monsterNode[] {
+        return this.attackmonster;
+    }
+
+    public addAttackmonster(monter: monsterNode) {
+        if (!this.isStartWait) {
+            let index = this.attackmonster.indexOf(monter);
+            if (index < 0) {
+                if (monter.myDataObj.monsterData.company_type == 2) {
+                    if (this.myDataObj.TowerData.air_attack_switch == 'ON') {
+                        this.attackmonster.push(monter);
+                        this.moreMonsterAttack();
+                    }
+                }
+                else
+                {
+                    this.attackmonster.push(monter);
+                    this.moreMonsterAttack();
+                }
+            }
+        }
+    }
+
+    public DelateAllAttackmonster() {
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                this.attackmonster.splice(i, 1);
+                i--;
+                continue;
+            }
+            let isIn = this.getIsInSqrt(element.node.getPosition());
+            if (!isIn || element.AniStatus == 'ZhengDie') {
+                this.attackmonster.splice(i, 1);
+                i--;
+            }
+        }
+    }
+
+    /**调整兵围攻数量  */
+    private moreMonsterAttack() {
+        if (this.attackmonster.length <= 1) {
+            return;
+        }
+
+        if (this.attackmonster.length == 2) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                element.DelateBarracksRetain(2);
+            }
+        }
+
+        if (this.attackmonster.length >= 3) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                element.DelateBarracksRetain(1);
+            }
+        }
+    }
+
+    /**开始攻击 */
+    public attckStart() {
+        if (this.attackmonster.length == 0) {
+            this.attackOver();
+            return;
+        }
+
+        let self = this;
+
+        this.scheduleOnce(function () {
+            self.DelateAllAttackmonster();
+            self.attckStart();
+        }, 0.3);
+    }
+
+    /**路线距离兵营最近点坐标 */
+    private getMinPoint(): cc.Vec2 {
+        let mylength = this.taHuanVec.sub(cc.v2(this.GoPos[0].x, this.GoPos[0].y)).mag();
+        let mindex = 0;
+        for (let index = 1; index < this.GoPos.length; index++) {
+            const element = this.GoPos[index];
+
+            let juli = this.taHuanVec.sub(cc.v2(element.x, element.y)).mag();
+            if (juli < mylength) {
+                mindex = index;
+                mylength = juli;
+            }
+        }
+
+        return cc.v2(this.GoPos[mindex].x, this.GoPos[mindex].y);
+    }
+
+
+
+    /**特殊技能 */
+    private skillSpeattack() {
+        /**冷却时间 */
+        let delayTime = this.myDataObj.SkillData.parameter_4;
+        if (this.SkillIDL >= 37 && this.SkillIDL <= 39) {
+            this.schedule(this.skill37_39, delayTime);
+        }
+
+        if (this.SkillIDR >= 40 && this.SkillIDR <= 43) {
+            this.skill40_42();
+        }
+
+        if (this.SkillIDT >= 52 && this.SkillIDT <= 54) {
+            this.schedule(this.skill52_54, delayTime);
+        }
+    }
+
+    /**id 37-39技能 治疗术 */
+    private skill37_39() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDL);
+        /**伤害数值 */
+        let huixue = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.hpDown(-huixue);
+        }
+
+    }
+
+    /**id 40-42技能 神圣护甲 */
+    private skill40_42() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        /**物理免伤 */
+        let reduce = Number(this.myDataObj.SkillData.parameter_3);
+
+        for (let i = 0; i < this.soldieThree.length; i++) {
+            const element = this.soldieThree[i];
+            element.myDataObj.monsterData.physics_reduction += reduce * 100;
+        }
+    }
+
+    /**id 43-45技能 神圣之力 */
+    public skill43_45(attackSoldie: soldie) {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        if (this.SkillIDT < 43 || this.SkillIDT > 45) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDT);
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**几率 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**范围 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+
+        if (Math.random() < totalcount) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                if (attackSoldie.getMymonster() == element) {
+                    continue;
+                }
+                let monToDexLeth = attackSoldie.node.getPosition().sub(element.node.getPosition()).mag();
+
+                if (monToDexLeth < pointNum) {
+                    element.hpDown(shanghai);
+                }
+            }
+        }
+    }
+
+    /**id 46-48技能 双持战斧 */
+    public skill46_48(attackSoldie: soldie) {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        if (this.SkillIDL < 46 || this.SkillIDL > 48) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDL);
+        /** */
+        let monId = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**伤害 */
+        let shanghai = Number(this.myDataObj.SkillData.parameter_3);
+       
+        attackSoldie.getMymonster().hpDown(shanghai);
+       
+    }
+
+    /**id 49-51技能 回旋斩 */
+    public skill49_51(attackSoldie: soldie) {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        if (this.SkillIDR < 49 || this.SkillIDR > 51) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**几率 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**范围 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+
+        if (Math.random() < totalcount) {
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                if (attackSoldie.getMymonster() == element) {
+                    continue;
+                }
+                let monToDexLeth = attackSoldie.node.getPosition().sub(element.node.getPosition()).mag();
+
+                if (monToDexLeth < pointNum) {
+                    element.hpDown(shanghai);
+                }
+            }
+        }
+    }
+
+    /**id 52-54技能 投掷领悟 */
+    public skill52_54() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+
+        if (this.SkillIDT < 52 || this.SkillIDT > 54) {
+            return;
+        }
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**射程 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+       
+        for (let k = 0; k < this.soldieThree.length; k++) {
+            const element1 = this.soldieThree[k];
+            for (let i = 0; i < this.attackmonster.length; i++) {
+                const element = this.attackmonster[i];
+                
+                let monToDexLeth = element1.node.getPosition().sub(element.node.getPosition()).mag();
+                if (monToDexLeth < totalcount) {
+                    element.hpDown(shanghai);
+                    break;
+                }
+            }
+        }
+    }
+
+}

+ 10 - 0
assets/Script/game/tower/barracks.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "ebe174a3-de4d-46c8-a883-7b0f7e23dee8",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 59 - 0
assets/Script/game/tower/buildload.ts

@@ -0,0 +1,59 @@
+import gameData from "../../configData/gameData";
+
+
+const {ccclass, property} = cc._decorator;
+
+@ccclass
+export default class buildload extends cc.Component {
+
+  private loadCount = 0;
+
+    onLoad () {
+        if (Math.random() < 0.5) {
+            this.node.getChildByName('b1').opacity = 0;
+            this.node.getChildByName('b2').opacity = 255;
+        }
+        else {
+            this.node.getChildByName('b1').opacity = 255;
+            this.node.getChildByName('b2').opacity = 0;
+        }
+        this.loadCount = 0;
+        this.showBulidAct();
+    }
+
+
+    private showBulidAct() {
+        if (this.loadCount == 10000) {
+            return;
+        }
+        let times = (Number(gameData.instance().game_Const[1][2]) - 0.3) / 0.05;
+        this.loadCount += 200 / times;
+
+        let myprogress = this.node.getChildByName('hp_3').getComponent(cc.ProgressBar);
+        myprogress.progress = this.loadCount / 200;
+        if (this.loadCount >= 200) {
+            myprogress.node.opacity = 0;
+            this.node.getChildByName('hp_bg').opacity = 0;
+            this.node.getChildByName('b1').opacity = 0;
+            this.node.getChildByName('b2').opacity = 0;
+            this.node.getChildByName('act').opacity = 255;
+            this.node.getChildByName('act').getComponent(cc.Animation).play();
+
+            this.scheduleOnce(() => {
+                this.node.destroy();
+            }, 0.4);
+            return;
+        }
+        this.scheduleOnce(() => {
+            this.showBulidAct();
+        }, 0.05);
+    }
+
+    public stopDelate()
+    {
+        this.loadCount = 10000;
+        this.unscheduleAllCallbacks();
+        this.node.destroy();
+    }
+
+}

+ 10 - 0
assets/Script/game/tower/buildload.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "19f28830-1954-4328-82f5-dd74cc9a3da3",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 177 - 0
assets/Script/game/tower/skillManger.ts

@@ -0,0 +1,177 @@
+import DataObj from "../../configData/DataObj";
+import GameConfig from "../../configData/GameConfig";
+import monsterManger from "../monster/monsterManger";
+import towerManger from "./towerManger";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class skillManger extends cc.Component {
+
+    @property(cc.Sprite)
+    private tapQuan: cc.Sprite = null;
+
+    
+
+    public static instance: skillManger = null;
+    public myDataObj: DataObj = null;
+    private yunshiArr: cc.Node[] = [];
+    private yunshiPosArr: cc.Vec3[] = [];
+    /**燃烧半径 */
+    private lenthR = 0;
+    protected onLoad() {
+        skillManger.instance = this;
+        this.myDataObj = new DataObj();
+
+
+    }
+
+    /** 陨石创建*/
+    public yunshiBuild(loca: cc.Vec2) {
+        this.myDataObj.writeSkill_Config(60);
+
+        let num = this.myDataObj.SkillData.parameter_1;
+        if (towerManger.instance.talantData[20].length > 0) {
+            num += towerManger.instance.talantData[20][0];
+        }
+        this.lenthR = this.myDataObj.getArr(this.myDataObj.SkillData.parameter_2)[1];
+        if (towerManger.instance.talantData[22].length > 0) {
+            this.lenthR *=1+ towerManger.instance.talantData[22][1];
+        }
+        let lethShow = this.lenthR - 20;
+        this.yunshiArr = [];
+        this.yunshiPosArr = [];
+        let self = this;
+        cc.resources.load("skill/yunshi", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+            for (let i = 0; i < num; i++) {
+                let suijix = Math.floor((-lethShow + 2 * lethShow * Math.random()) / 20) * 20;
+                let yyLenth = Math.sqrt(lethShow * lethShow - suijix * suijix);
+                let suijiY = Math.floor((-yyLenth + 2 * yyLenth * Math.random()) / 20) * 20;
+                if (i == 0) {
+                    suijix = 0;
+                }
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                mynode.setPosition(cc.v2(loca.x + suijix, 550));
+                mynode.setAnchorPoint(cc.v2(0.5, 0));
+                self.node.addChild(mynode, 1009);
+
+                if (i == 0) {
+                    self.yunshiPosArr.push(cc.v3(loca));
+                    mynode.scale = 0.8;
+                }
+                else {
+                    mynode.scale = 0.4;
+                    self.yunshiPosArr.push(cc.v3(loca).add(cc.v3(suijix, suijiY)));
+                }
+
+                self.yunshiArr.push(mynode);
+            }
+            self.yunshiAct();
+        });
+    }
+
+    /**陨石掉落动画 */
+    private yunshiAct() {
+        for (let i = 0; i < this.yunshiArr.length; i++) {
+            const element = this.yunshiArr[i];
+            let tt = 0.1 + Math.random() / 2;
+            if (i == 0) {
+                tt = 0;
+            }
+            let leth = 550 - this.yunshiPosArr[i].y;
+            cc.tween(element)
+                .delay(tt)
+                .to(leth / Number(this.myDataObj.SkillData.parameter_5), { position: this.yunshiPosArr[i] })
+                .call(() => {
+                    let hurt = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_3);
+
+                    if (towerManger.instance.talantData[24].length > 0) {
+                        hurt *= 1+ towerManger.instance.talantData[20][1]+towerManger.instance.talantData[22][0] + towerManger.instance.talantData[24][0];
+                    }
+                    else
+                    {
+                        if (towerManger.instance.talantData[22].length > 0) {
+                            hurt *= 1 + towerManger.instance.talantData[20][1]+towerManger.instance.talantData[22][0];
+                        }
+                        else
+                        {
+                            if (towerManger.instance.talantData[20].length > 0) {
+                                hurt *= 1 + towerManger.instance.talantData[20][1];
+                            }
+                        }
+                    }
+
+
+                   
+                    
+                    let lethR = this.myDataObj.getArr(this.myDataObj.SkillData.parameter_2)[0];
+                    if (towerManger.instance.talantData[22].length > 0) {
+                        lethR *= 1+ towerManger.instance.talantData[22][1];
+                    }
+                    this.hurtMonster(this.yunshiPosArr[i], hurt, lethR);
+                    if (i == this.yunshiArr.length - 1) {
+                        if (towerManger.instance.talantData[23].length > 0) {
+                            this.schedule(this.burningHurt24, 1, towerManger.instance.talantData[23][1]-1, 0);
+                            this.burningHurtAction();
+                        }
+                        else
+                        {
+                            if (towerManger.instance.talantData[21].length > 0) {
+                                this.schedule(this.burningHurt22, 1, towerManger.instance.talantData[21][1]-1, 0);
+                                this.burningHurtAction();
+                            }
+                        }
+                        
+                    }
+                })
+                .removeSelf()
+                .start();
+        }
+        this.yunshiQuan(cc.v2(this.yunshiPosArr[0]));
+    }
+
+    /**燃烧陷阱 */
+    private burningHurt22() {
+        this.hurtMonster(this.yunshiPosArr[0], towerManger.instance.talantData[21][0], this.lenthR);
+    }
+    /**燃烧陷阱 */
+    private burningHurt24() {
+        this.hurtMonster(this.yunshiPosArr[0], towerManger.instance.talantData[23][0], this.lenthR);
+    }
+
+    /**燃烧陷阱动画 */
+    private burningHurtAction() {
+
+    }
+
+    /**陨石掉落伤害 */
+    private hurtMonster(pos: cc.Vec3, attack: number, sqrt: number) {
+        let monarr = monsterManger.instance.GetMonsterArr();
+        for (let k = 0; k < monarr.length; k++) {
+            const minster = monarr[k];
+            let monPos = minster.node.getPosition();
+            if (monPos.sub(cc.v2(pos)).mag() < sqrt) {
+                minster.hpDown(attack);
+            }
+        }
+    }
+
+    /**陨石圈 */
+    public yunshiQuan(poss: cc.Vec2) {
+        this.tapQuan.node.opacity = 255;
+        this.tapQuan.node.setPosition(poss);
+        this.tapQuan.node.setContentSize(this.lenthR * 2, this.lenthR * 2);
+        this.tapQuan.node.stopAllActions();
+        cc.tween(this.tapQuan.node)
+            .to(0.3, { opacity: 100 })
+            .to(0.3, { opacity: 255 })
+            .to(0.3, { opacity: 100 })
+            .to(0.6, { opacity: 255 })
+            .to(0.3, { opacity: 0 })
+            .start();
+    }
+
+}

+ 10 - 0
assets/Script/game/tower/skillManger.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "59bad4ee-f8ae-4278-a7c5-68ab500c6ef4",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 343 - 0
assets/Script/game/tower/taside.ts

@@ -0,0 +1,343 @@
+import gameData from "../../configData/gameData";
+import gameUI from "../UIFace/gameUI";
+import towerManger from "./towerManger";
+
+
+const { ccclass, property } = cc._decorator;
+
+/**
+ * 塔类型
+ */
+export enum TasideType {
+    Enum_nor = 1,
+    Enum_show,
+}
+
+
+@ccclass
+export default class taside extends cc.Component {
+    @property(cc.Node)
+    private nitubg: cc.Node = null;
+
+    /**塔攻击范围 */
+    @property(cc.Sprite)
+    private quan: cc.Sprite = null;
+
+    /**选择建塔的环 */
+    private huan: cc.Sprite = null;
+
+    private diban: cc.Node[] = [];
+    private coin: cc.Label[] = [];
+    private sele: cc.Sprite[] = [];
+    private iconSpr: cc.Sprite[] = [];
+
+    private norMaterial:cc.Material = cc.Material.getBuiltinMaterial('2d-sprite');
+    private grayMaterial:cc.Material = cc.Material.getBuiltinMaterial('2d-gray-sprite');
+
+    private isCanSele = [true, true, true, true];
+    private seleScale: number[] = [2, 2, 2, 2];
+    /**4个选项是否打勾 */
+    private isGou: boolean[] = [];
+    /**圆环是否打开 */
+    public isOpen = false;
+    /**建塔、升级花费金币 */
+    private towerGold = 0;
+    /**打勾地板 */
+    private _diban:cc.Node[] = [];
+    private towerID = [28, 10, 19, 1];
+    private towerModel:cc.Node[] = [];
+
+    private first_gold: number[] = [0, 0, 0, 0];
+    onLoad() {
+        this.quan.node.setPosition(this.quan.node.getPosition().add(cc.v2(0,45)));
+        this.huan = this.node.getChildByName("sele_tower_huan").getComponent(cc.Sprite);
+        this.initData();
+        this.initSpr();
+
+        this.openTouchOn();
+        this.loadTowerModel();
+    }
+
+    private loadTowerModel()
+    {
+        let self = this;
+        for (let i = 1; i <= 4; i++) {
+            let bb = i;
+            if (i == 1) {
+                bb = 4;
+            }
+            if (i == 4) {
+                bb = 1;
+            }
+            cc.resources.load('prefabs/tower_model'+bb,cc.Prefab, function (err, prefab: cc.Prefab) {
+                var newNode = cc.instantiate(prefab);
+                self.node.addChild(newNode);
+                newNode.active = false;
+                self.towerModel.push(newNode);
+                newNode.scale = 0.7;
+                switch (bb) {
+                    case 1:
+                        newNode.setPosition(cc.v2(-1, 20));
+                        break;
+                    case 2:
+                        newNode.setPosition(cc.v2(-1, -19));
+                        break;
+                    case 3:
+                        newNode.setPosition(cc.v2(-1, -24));
+                        break;
+                    case 4:
+                        newNode.setPosition(cc.v2(5, 15));
+                        break;
+    
+                    default:
+                        break;
+                }
+            });
+        }
+    }
+
+
+    /**花费金币增加 */
+    public addtowerGold(num: number) {
+        this.towerGold += num;
+    }
+
+    /**获取所花费金币 */
+    public gettowerGold(): number {
+        return this.towerGold;
+    }
+
+    /**设置所花费金币 */
+    public settowerGold(num: number) {
+        this.towerGold = num;
+    }
+
+    /**根据ID获取数据 */
+    private initData() {
+        let nameDex = 0;
+        let resdex = 0;
+        let oneData = [];
+        for (let i = 0; i < gameData.instance().tower_Config.length; i++) {
+            const arr = gameData.instance().tower_Config[i];
+            if (i == 2) {
+                for (let k = 0; k < arr.length; k++) {
+                    const element = arr[k];
+                    if (element == 'first_gold') {
+                        nameDex = k;
+                    }
+                    if (element == 'attack_range') {
+                        resdex = k;
+                    }
+                }
+            }
+
+            if (Number(arr[0]) == this.towerID[0]) {
+                this.first_gold[0] = (Number(arr[nameDex]));
+                this.seleScale[0] = (Number(arr[resdex]));
+                if (towerManger.instance.talantData[7].length > 0) {
+                    this.seleScale[0] *= (1 + towerManger.instance.talantData[7][0]);
+                }
+            }
+            if (Number(arr[0]) == this.towerID[1]) {
+                this.first_gold[1] = (Number(arr[nameDex]));
+                if (towerManger.instance.talantData[12].length > 0) {
+                    this.first_gold[1] *= (1 - towerManger.instance.talantData[12][0]);
+                }
+                this.first_gold[1] = Math.floor(this.first_gold[1]);
+                this.seleScale[1] = (Number(arr[resdex]));
+                if (towerManger.instance.talantData[10].length > 0) {
+                    this.seleScale[1] *= (1 + towerManger.instance.talantData[10][0]);
+                }
+            }
+            if (Number(arr[0]) == this.towerID[2]) {
+                this.first_gold[2] = (Number(arr[nameDex]));
+                if (towerManger.instance.talantData[17].length > 0 && towerManger.instance.talantData[18].length > 0) {
+                    this.first_gold[2] *= (1 - towerManger.instance.talantData[17][0] - towerManger.instance.talantData[18][0]);
+                }
+                else {
+                    if (towerManger.instance.talantData[17].length > 0) {
+                        this.first_gold[2] *= (1 - towerManger.instance.talantData[17][0]);
+                    }
+                    if (towerManger.instance.talantData[18].length > 0) {
+                        this.first_gold[2] *= (1 - towerManger.instance.talantData[18][0]);
+                    }
+                }
+                this.first_gold[2] = Math.floor(this.first_gold[2]);
+                this.seleScale[2] = (Number(arr[resdex]));
+                if (towerManger.instance.talantData[16].length > 0) {
+                    this.seleScale[2] *= (1+towerManger.instance.talantData[16][0]);
+                }
+            }
+            if (Number(arr[0]) == this.towerID[3]) {
+                this.first_gold[3] = (Number(arr[nameDex]));
+                this.seleScale[3] = (Number(arr[resdex]));
+
+                if (towerManger.instance.talantData[1].length > 0 && towerManger.instance.talantData[3].length > 0) {
+                    this.seleScale[3] *= (1 + towerManger.instance.talantData[3][0] + towerManger.instance.talantData[1][0]);
+                }
+                else {
+                    if (towerManger.instance.talantData[1].length > 0) {
+                        this.seleScale[3] *= (1 + towerManger.instance.talantData[1][0]);
+                    }
+
+                    if (towerManger.instance.talantData[3].length > 0) {
+                        this.seleScale[3] *= (1 + towerManger.instance.talantData[3][0]);
+                    }
+                }
+            }
+
+        }
+    }
+    /**开启触摸 */
+    public openTouchOn() {
+        this.nitubg.on(cc.Node.EventType.TOUCH_START, this.touchNode, this);
+    }
+
+    /**关闭触摸 */
+    public ClosedTouch() {
+        this.nitubg.off(cc.Node.EventType.TOUCH_START, this.touchNode, this);
+    }
+
+    private initSpr() {
+        this.quan.node.active = false;
+        this.huan.node.active = false;
+        let self = this;
+        this._diban = [];
+        for (let i = 1; i <= 4; i++) {
+            let diban = this.huan.node.getChildByName("sele_tower_build_bg" + i);
+            this._diban.push(diban);
+            diban.on(cc.Node.EventType.TOUCH_START, function () {
+                self.touchDiban(i);
+            }, this);
+         
+
+            let mycoin: cc.Label = diban.getChildByName("coin1").getComponent(cc.Label);
+            mycoin.string = this.first_gold[i - 1].toString();
+            let mysele: cc.Sprite = diban.getChildByName("build_1").getComponent(cc.Sprite);
+            let myicon: cc.Sprite = diban.getChildByName("iconspr").getComponent(cc.Sprite);
+
+            this.isGou.push(false);
+            this.diban.push(diban);
+            this.coin.push(mycoin);
+            this.sele.push(mysele);
+            this.iconSpr.push(myicon);
+        }
+    }
+
+    /**显示金币不足时状态 */
+    private showNosele() {
+        for (let i = 0; i < 4; i++) {
+            if (gameUI.instance.getGold() >= this.first_gold[i]) {
+                this.isCanSele[i] = true;
+                this.iconSpr[i].node.getComponent(cc.Sprite).setMaterial(0,this.norMaterial);
+                this.coin[i].node.color = cc.color(235,255,6);
+            }
+            else {
+                this.isCanSele[i] = false;
+                this.iconSpr[i].node.getComponent(cc.Sprite).setMaterial(0,this.grayMaterial);
+                this.coin[i].node.color = cc.color(102,91,91);
+            }
+        }
+    }
+
+    /**打开圆环 */
+    private turnbig() {
+        this.showNosele();
+        this.node.zIndex = 1007;
+        towerManger.instance.closedHuan();
+        this.huan.node.scale = 0.5;
+        this.huan.node.opacity = 0;
+        this.huan.node.active = true;
+        this.huan.node.stopAllActions();
+        cc.tween(this.huan.node)
+            .to(0.1, { scale: 1, opacity: 255 })
+            .call(() => {
+                this.isOpen = true;
+            })
+            .start();
+    }
+
+    /**关闭圆环 */
+    public turnsmall() {
+        if (this.isOpen) {
+            this.node.zIndex = 1006;
+            this.huan.node.stopAllActions();
+            cc.tween(this.huan.node)
+                .to(0.1, { scale: 0.5, opacity: 0 })
+                .call(() => {
+                    this.huan.node.active = false;
+                    this.isOpen = false;
+                    this.delateGou();
+                    this.quan.node.active = false;
+                    this.showSeleModel(100);
+                })
+                .start();
+        }
+    }
+
+    /**点击泥土 */
+    private touchNode(e: cc.Event.EventTouch) {
+        this.turnbig();
+    }
+
+    /**取消勾 */
+    private delateGou() {
+        for (let i = 0; i < this.isGou.length; i++) {
+            if (this.isGou[i]) {
+                this.isGou[i] = false;
+                this.sele[i].node.opacity = 0;
+            }
+        }
+    }
+
+    private showSeleModel(num:number)
+    {
+        for (let i = 0; i < this.towerModel.length; i++) {
+            const element = this.towerModel[i];
+            if (i == num) {
+                element.active = true;
+            }
+            else
+            {
+                element.active = false;
+            }
+        }
+    }
+
+    
+
+    private touchDiban(type: number) {
+        if (!this.isCanSele[type - 1]) {
+            return;
+        }
+        if (!this.isGou[type - 1]) {
+            this.delateGou();
+            this.isGou[type - 1] = true;
+            this.sele[type - 1].node.opacity = 255;
+            this.quan.node.active = true;
+            this.setRedHuanScale(this.seleScale[type - 1]);
+            this.showSeleModel(type - 1);
+        }
+        else {
+            this.seleTowerBuild(type, this.node.getPosition());
+            this.nitubg.off(cc.Node.EventType.TOUCH_START, this.touchNode, this);
+            this.turnsmall();
+        }
+    }
+
+    /**设置环的大小 */
+    public setRedHuanScale(scale: number) {
+        this.quan.node.scale = scale / 275;
+    }
+
+    /**修建塔  type 1兵塔 2魔法 3炮 4箭塔*/
+    public seleTowerBuild(type: number, vecpos: cc.Vec2) {
+        let salegold = this.first_gold[type - 1];
+        gameUI.instance.AddGold(-salegold);
+        towerManger.instance.buildTower(this, this.towerID[type - 1],[],true);
+        this.addtowerGold(this.first_gold[type - 1]);
+        
+    }
+
+
+}

+ 10 - 0
assets/Script/game/tower/taside.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "420221ae-7151-42ad-b991-8dffa5b78230",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 368 - 0
assets/Script/game/tower/towerManger.ts

@@ -0,0 +1,368 @@
+
+
+import DataObj from "../../configData/DataObj";
+import { TowerType } from "../../configData/Enum";
+import GameConfig from "../../configData/GameConfig";
+import gameUI from "../UIFace/gameUI";
+import monsterManger from "../monster/monsterManger";
+import monsterNode from "../monster/monsterNode";
+
+import arrow from "./arrow";
+import barracks from "./barracks";
+import Magic from "./Magic";
+import taside from "./taside";
+import TowerData from "./TowerData";
+import TowerHuan from "./TowerHuan";
+import turret from "./turret";
+import gameData from "../../configData/gameData";
+import buildload from "./buildload";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class towerManger extends cc.Component {
+
+    /**塔集合 */
+    public towerArr = [];
+
+    private towerpos: cc.Vec2[] = [];
+
+    private mynitu: cc.Node[] = [];
+    private mytaside: taside[] = [];
+    private towerHuan: TowerHuan[] = [];
+
+    public myDataObj: DataObj = null;
+    public static instance: towerManger = null;
+    /**天赋数值 */
+    public talantData = [];
+    protected onLoad() {
+        towerManger.instance = this;
+        this.myDataObj = new DataObj();
+    }
+
+    start() {
+        // console.log("--------------------towerManger");
+    }
+
+    /**初始化数据 */
+    private resetData() {
+        for (let i = 0; i < this.mynitu.length; i++) {
+            const element = this.mynitu[i];
+            element.destroy();
+        }
+        this.mynitu = [];
+
+        for (let i = 0; i < this.mytaside.length; i++) {
+            const element = this.mytaside[i];
+            element.node.destroy();
+        }
+        this.mytaside = [];
+        for (let i = 0; i < this.towerArr.length; i++) {
+            const element = this.towerArr[i];
+            element.node.destroy();
+        }
+        this.towerArr = [];
+
+        this.inittalantData();
+        gameUI.instance.openSkillBtn();
+    }
+    /**加载泥土 */
+    public initTowerTaside() {
+        this.resetData();
+        this.towerpos = TowerData.instance().getTowerPos(gameUI.instance.myDataObj.LevelData.scene_path);
+        var self = this;
+
+        cc.resources.load("gamebg/taside_" + gameUI.instance.myDataObj.LevelData.map_type, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+            for (let i = 0; i < self.towerpos.length; i++) {
+                const element = self.towerpos[i];
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                mynode.setPosition(element);
+                self.node.addChild(mynode);
+                self.mynitu.push(mynode);
+            }
+        });
+
+        cc.resources.load("prefabs/taside", cc.Prefab, function (err, prefab: cc.Prefab) {
+
+            for (let i = 0; i < self.towerpos.length; i++) {
+                const element = self.towerpos[i];
+                var newNode = cc.instantiate(prefab);
+                self.node.addChild(newNode, 1006);
+                newNode.setPosition(element);
+                self.mytaside.push(newNode.getComponent(taside));
+            }
+        });
+    }
+
+    /**创建塔选项环 */
+    private initTowerHuan(type: TowerType, taTs) {
+        var self = this;
+        cc.resources.load("prefabs/taHuan", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            self.node.addChild(newNode, 1006);
+            newNode.setPosition(taTs._taside.node.getPosition().add(cc.v2(0, 45)));
+            let mytahuan = newNode.getComponent(TowerHuan);
+            mytahuan.setTowerType(type);
+            mytahuan.setTower(taTs);
+            taTs.setTaHuan(mytahuan);
+            self.towerHuan.push(mytahuan);
+
+            if (self.myDataObj.TowerData.tower_level != 1) {
+                self.towerArr.push(taTs);
+            }
+
+        });
+    }
+
+    /**关闭已打开的选择环 */
+    public closedHuan() {
+        for (let i = 0; i < this.mytaside.length; i++) {
+            const element = this.mytaside[i];
+            if (element.isOpen) {
+                element.turnsmall();
+            }
+        }
+
+        for (let i = 0; i < this.towerHuan.length; i++) {
+            const element = this.towerHuan[i];
+            if (element.node == null) {
+                this.towerHuan.splice(i, 1);
+                i--;
+                continue;
+            }
+            if (element.isOpen) {
+                element.turnsmall();
+            }
+        }
+    }
+
+    /**传入插旗点 */
+    public chaqiGetPos(loca: cc.Vec2) {
+        for (let i = 0; i < this.towerHuan.length; i++) {
+            const element = this.towerHuan[i];
+            if (element.node == null) {
+                this.towerHuan.splice(i, 1);
+                i--;
+                continue;
+            }
+            element.chaqiTap(loca);
+        }
+    }
+
+    /**修建塔 */
+    public buildTower(mytaside: taside, ID: number, solarr: cc.Vec2[], isBuild: boolean) {
+        var self = this;
+        this.myDataObj.writeTower_Config(ID);
+        mytaside.ClosedTouch();
+        cc.resources.load("prefabs/" + this.myDataObj.TowerData.name1, cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            let calssName = null;
+            let judgevec: cc.Vec2 = mytaside.node.getPosition();
+            switch (self.myDataObj.TowerData.tower_type) {
+                case 1:
+                    calssName = newNode.getComponent(arrow);
+                    judgevec = judgevec.add(cc.v2(-1, 40));
+                    break;
+                case 2:
+                    calssName = newNode.getComponent(Magic);
+                    judgevec = judgevec.add(cc.v2(-1, -19));
+                    break;
+                case 3:
+                    calssName = newNode.getComponent(turret);
+                    judgevec = judgevec.add(cc.v2(-1, -24));
+                    break;
+                case 4:
+                    {
+                        calssName = newNode.getComponent(barracks);
+                        judgevec = judgevec.add(cc.v2(5, 30));
+                        if (solarr.length > 0) {
+                            calssName.setSoldePosArr(solarr);
+                        }
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+            newNode.setPosition(judgevec);
+            newNode.scale = self.myDataObj.TowerData.model_scaling;
+            self.node.addChild(newNode, Math.floor((540 - judgevec.y) / 10));
+            calssName.setNitu(mytaside);
+            calssName.initID(ID);
+            calssName.towerType = self.myDataObj.TowerData.tower_type;
+            self.initTowerHuan(self.myDataObj.TowerData.tower_type, calssName);
+
+            newNode.active = false;
+            if (isBuild) {
+                newNode.opacity = 0;
+                cc.tween(newNode)
+                    .delay(Number(gameData.instance().game_Const[1][2]) - 0.03)
+                    .to(0.03, { opacity: 255 })
+                    .call(() => {
+                        newNode.active = true;
+                        self.towerArr.push(calssName);
+                    })
+                    .start();
+            }
+            else {
+                newNode.active = true;
+            }
+
+
+        });
+
+        if (isBuild) {
+            this.buildload(mytaside);
+        }
+    }
+    /**升级塔 */
+    public UpTower(tower, nextid: number) {
+        tower._taside.addtowerGold(tower.myDataObj.TowerData.up_gold[0]);
+        let arr = [];
+        if (tower.towerType == 4) {
+            arr = tower.getSoldePosArr();
+        }
+        this.buildTower(tower._taside, nextid, arr, false);
+    }
+
+    /**建塔进度条显示 */
+    private buildload(mytaside: taside) {
+        let self = this;
+        cc.resources.load("prefabs/buildLoad", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            mytaside.node.addChild(newNode, 1005);
+            newNode.setPosition(cc.v2(0, 0));
+        });
+    }
+
+
+    /**
+     * 求C到直线AB得距离
+     * @param C 直线外一点
+     * @param A 直线上一点
+     * @param B 直线上一点
+     */
+    public pointToLineDistance(C: cc.Vec2, A: cc.Vec2, B: cc.Vec2): number {
+        let dx = B.x - A.x;
+        let dy = B.y - A.y;
+        let d = dx * dx + dy * dy;
+        let D: cc.Vec2 = cc.v2();
+        if (d === 0) { // |AB| = 0,说明A与B共点
+            D = A;
+        } else {
+            let q = ((C.x - A.x) * dx + (C.y - A.y) * dy) / d; // 求出q得值
+            D = cc.v2(A.x + q * dx, A.y + q * dy);// 得到D得坐标
+        }
+        dx = D.x - C.x;
+        dy = D.y - C.y;
+        return Math.sqrt(dx * dx + dy * dy);
+    }
+
+    /**箭塔激光击中的怪减血 A开始点   B目标点之一   attnum攻击力   magicLeth激光爆炸范围*/
+    public MagicAttckMonster(A: cc.Vec2, B: cc.Vec2, attnum: number, magicLeth: number) {
+        let monarr = monsterManger.instance.GetMonsterArr();
+        for (let k = 0; k < monarr.length; k++) {
+            const minster = monarr[k];
+            if (minster.getIsdie()) {
+                continue;
+            }
+            let C: cc.Vec2 = minster.getNewPos();
+
+            let juli = this.pointToLineDistance(C, A, B);
+
+            if (juli < magicLeth && C.sub(A).mag() > C.sub(B).mag()) {
+                minster.hpDown(attnum * (1 - minster.myDataObj.monsterData.magic_reduction));
+                minster.MagicCutPhysicsreduction();
+            }
+        }
+    }
+
+    /**删除已销毁的塔 */
+    public delateTower(tower) {
+        for (let i = 0; i < this.towerArr.length; i++) {
+            const myarrow = this.towerArr[i];
+            if (myarrow == tower) {
+                this.towerArr.splice(i, 1);
+                return;
+            }
+        }
+    }
+
+    /**设置怪物走路是否一直走  true:停*/
+    public setAniGo(isGo: boolean) {
+        let monarr = monsterManger.instance.GetMonsterArr();
+        for (let k = 0; k < monarr.length; k++) {
+            const minster = monarr[k];
+            minster.SetWalk(isGo);
+        }
+
+        //兵塔
+        for (let i = 0; i < this.towerArr.length; i++) {
+            const myarrow = this.towerArr[i];
+            if (myarrow.towerType == 4) {
+                myarrow.isPaused(isGo);
+            }
+        }
+    }
+
+    /**刷新坐标查看塔周围动静添加定时器 */
+    public updateTowerActionSchle() {
+        this.schedule(this.updateTowerAction, 0.1);
+    }
+    /**刷新坐标查看塔周围动静 */
+    private updateTowerAction() {
+        let monarr = monsterManger.instance.GetMonsterArr();
+        if (monarr.length == 0 && monsterManger.instance.getIsCanOver()) {
+            monsterManger.instance.isGameOver();
+            this.unschedule(this.updateTowerAction);
+        }
+        // console.log("刷新:"+monarr.length);
+        for (let k = 0; k < monarr.length; k++) {
+            const minster = monarr[k];
+            if (minster.node == null) {
+                monarr.splice(k, 1);
+                k--;
+                continue;
+            }
+
+            let posy = minster.node.getPosition().y;
+            minster.node.zIndex = Math.floor((540 - posy) / 10);
+
+            //塔
+            for (let i = 0; i < this.towerArr.length; i++) {
+                const myarrow = this.towerArr[i];
+                if (myarrow.getIsInSqrt(minster.node.getPosition())) {
+                    let index = myarrow.getAttackmonster().indexOf(minster);
+                    if (index < 0) {
+                        myarrow.addAttackmonster(minster);
+                        if (myarrow.getAttackmonster().length == 1) {
+                            myarrow.attckStart();
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+
+    /**天赋数值读取 */
+    private inittalantData() {
+        this.talantData = [];
+        for (let i = 0; i < 30; i++) {
+            let temparr: number[] = [];
+            if (GameConfig.instance().storageData.myTalant[i] == 1) {
+                this.myDataObj.writeTalent_Config(i + 1);
+                temparr.push(this.myDataObj.talentData.parameter_2);
+                temparr.push(this.myDataObj.talentData.parameter_3);
+                temparr.push(this.myDataObj.talentData.parameter_4);
+                temparr.push(this.myDataObj.talentData.parameter_5);
+            }
+            this.talantData.push(temparr);
+        }
+    }
+
+
+}

+ 10 - 0
assets/Script/game/tower/towerManger.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "ffad66cb-0ba3-4dbf-9291-548a55af7bde",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 440 - 0
assets/Script/game/tower/turret.ts

@@ -0,0 +1,440 @@
+import GameConfig from "../../configData/GameConfig";
+import TowerHuan from "./TowerHuan";
+import taside from "./taside";
+import monsterNode from "../monster/monsterNode";
+import monsterManger from "../monster/monsterManger";
+import towerManger from "./towerManger";
+import DataObj from "../../configData/DataObj";
+import gameData from "../../configData/gameData";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class turret extends cc.Component {
+    @property(sp.Skeleton)
+    private paota: sp.Skeleton = null;
+    @property(cc.Sprite)
+    private paodan: cc.Sprite = null;
+    @property(cc.Sprite)
+    private baoza: cc.Sprite = null;
+
+    @property(cc.Sprite)
+    private yanwu: cc.Sprite = null;
+
+    private paodanstartPos: cc.Vec2 = null;
+
+
+    private yanwuclips: cc.Animation = null;
+    private baozaclips: cc.Animation = null;
+    private _taHuan: TowerHuan = null;
+    public _taside: taside = null;
+    private taHuanVec: cc.Vec2 = null;
+    /**左技能ID */
+    public SkillIDL = 0;
+    /**右技能ID */
+    public SkillIDR = 0;
+    private interVec: cc.Vec2 = null;
+    public myDataObj: DataObj = null;
+    public towerType = 0;
+    private isStartWait = true;
+    /**攻击范围内的怪物 */
+    private attackmonster: monsterNode[] = [];
+
+    protected onLoad() {
+        this.baoza.node.removeFromParent();
+        towerManger.instance.node.addChild(this.baoza.node, 2);
+
+
+
+        this.paodan.node.opacity = 0;
+        this.baoza.node.opacity = 0;
+        this.yanwu.node.opacity = 0;
+        this.paodanstartPos = this.paodan.node.getPosition();
+        this.myDataObj = new DataObj();
+    }
+
+    /**根据ID读取数据 */
+    public initID(ID: number) {
+        this.myDataObj.writeTower_Config(ID);
+        this.myDataObj.writeBullet_Config(this.myDataObj.TowerData.bullet_id);
+
+        if (towerManger.instance.talantData[16].length > 0) {
+            this.myDataObj.TowerData.attack_range *= (1 + towerManger.instance.talantData[16][0]);
+        }
+        if (towerManger.instance.talantData[17].length > 0 && towerManger.instance.talantData[18].length > 0) {
+            this.myDataObj.TowerData.up_gold[0] *= (1 - towerManger.instance.talantData[17][1] - towerManger.instance.talantData[18][1]);
+        }
+        else {
+            if (towerManger.instance.talantData[17].length > 0) {
+                this.myDataObj.TowerData.up_gold[0] *= (1 - towerManger.instance.talantData[17][1]);
+            }
+            if (towerManger.instance.talantData[18].length > 0) {
+                this.myDataObj.TowerData.up_gold[0] *= (1 - towerManger.instance.talantData[18][1]);
+            }
+
+        }
+
+        this.myDataObj.TowerData.up_gold[0] = Math.floor(this.myDataObj.TowerData.up_gold[0]);
+
+        if (this.myDataObj.TowerData.tower_level == 1) {
+            this.isStartWait = false;
+        }
+        else {
+            this.scheduleOnce(function () {
+                this.isStartWait = false;
+            }, this.myDataObj.TowerData.attack_cd);
+        }
+    }
+
+    /**设置或升级技能ID  技能类型 1左边  2右边*/
+    public setandUpSkillId(skillType: number) {
+        if (skillType == 1) {
+            if (this.SkillIDL == 0) {
+                this.SkillIDL = this.myDataObj.TowerData.next_skill[0];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDL);
+                this.SkillIDL = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+
+        if (skillType == 2) {
+            if (this.SkillIDR == 0) {
+                this.SkillIDR = this.myDataObj.TowerData.next_skill[1];
+            }
+            else {
+                this.myDataObj.writeSkill_Config(this.SkillIDR);
+                this.SkillIDR = this.myDataObj.SkillData.next_skill;
+            }
+        }
+
+        // this.skillSpeattack();
+    }
+
+    public setTaHuan(taHuan: TowerHuan) {
+        this._taHuan = taHuan;
+        this.taHuanVec = taHuan.node.getPosition();
+        this._taside.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+        this._taHuan.setRedHuanScale(this.myDataObj.TowerData.attack_range);
+        this.paodan.node.scale = this.myDataObj.BulletData.model_scaling;
+    }
+
+    public setNitu(mytaside: taside) {
+        this._taside = mytaside;
+
+
+    }
+    onDestroy() {
+        this.baoza.node.destroy();
+        this._taHuan.node.destroy();
+        this.attackmonster = [];
+    }
+    public getIsInSqrt(pos: cc.Vec2) {
+        let xiangl = this.taHuanVec.sub(pos);
+        let a = this.myDataObj.TowerData.attack_range;
+        let b = this.myDataObj.TowerData.attack_range * 5 / 6;
+        if (xiangl.x * xiangl.x / (a * a) + xiangl.y * xiangl.y / (b * b) < 1) {
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+    public getAttackmonster(): monsterNode[] {
+        return this.attackmonster;
+    }
+
+    public addAttackmonster(monter: monsterNode) {
+        if (!this.isStartWait) {
+            if (monter.myDataObj.monsterData.company_type == 2) {
+                if (this.myDataObj.TowerData.air_attack_switch == 'ON') {
+                    this.attackmonster.push(monter);
+                }
+            }
+            else
+            {
+                this.attackmonster.push(monter);
+            }
+        }
+    }
+
+    private DelateAllAttackmonster() {
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                console.log("turret!!!!!!!!!!!!!!!!!!!!!");
+                this.attackmonster.splice(i, 1);
+                i--;
+                continue;
+            }
+            if (!this.getIsInSqrt(element.node.getPosition()) || element.AniStatus == 'ZhengDie') {
+                this.attackmonster.splice(i, 1);
+                i--;
+            }
+        }
+    }
+
+    /**开始攻击 */
+    public attckStart() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.paota.setAnimation(0, "animation", false).timeScale = GameConfig.instance().speed;
+        this.paodan.node.setPosition(this.paodanstartPos);
+
+        this.paota.setCompleteListener((trackEntry, loopCount) => {
+            let name = trackEntry.animation ? trackEntry.animation.name : '';
+            if (name === 'animation') {
+                this.paodanUpAction();
+            }
+        });
+
+    }
+
+    private paodanUpAction() {
+        let mypos = this.node.getPosition();
+        let danpos = mypos.add(this.paodan.node.getPosition());
+        this.interVec = this.attackmonster[0].node.getPosition().sub(cc.v2(0, -109));
+        // this.interVec = this.attackmonster[0].node.getPosition();
+        this.paodan.node.opacity = 255;
+        let endpos = this.interVec.sub(danpos);
+        this.interVec = this.interVec.add(this.attackmonster[0].getTimeSetDistance(this.myDataObj.BulletData.speed));
+
+        let hetght = this.myDataObj.BulletData.parabola[0];
+        // if (this.interVec.y > danpos.y) {
+        //     hetght = Math.abs(this.interVec.y - danpos.y) + this.myDataObj.BulletData.parabola[0];
+        // }
+        this.ParabolaTo(this.myDataObj.BulletData.speed, cc.v2(0, 0), endpos, hetght, this.myDataObj.BulletData.parabola[1]);
+
+        this.yanwu.node.opacity = 255;
+
+        this.yanwuclips = this.yanwu.node.getComponent(cc.Animation);
+        this.yanwuclips.play("yanwu_1").speed = GameConfig.instance().speed;
+
+        this.scheduleOnce(function () {
+            this.paodanbaoza(endpos);
+        }, this.myDataObj.BulletData.speed);
+
+    }
+
+    private paodanbaoza(endpos: cc.Vec2) {
+        this.paodan.node.opacity = 0;
+        this.baoza.node.opacity = 255;
+        this.yanwu.node.opacity = 0;
+
+        let changepos = cc.v2(15, 150);
+        if (this.myDataObj.TowerData.tower_level == 3) {
+            changepos = cc.v2(15, 117);
+        }
+        let bazapos = this.node.getPosition().add(endpos.add(changepos));
+        this.baoza.node.setPosition(bazapos);
+        this.baozaclips = this.baoza.node.getComponent(cc.Animation);
+        this.baozaclips.play();
+        // this.baozaclips.play("feidan_1");
+        // this.baoza.node.setPosition(endpos.add(cc.v2(10,95)));
+
+
+        let attack = this.myDataObj.getRanm(1, this.myDataObj.BulletData.boom_hurt);
+        if (towerManger.instance.talantData[15].length > 0) {
+            attack *= (1 + towerManger.instance.talantData[15][0]);
+        }
+
+        let sqrtArr = this.myDataObj.getArr(gameData.instance().game_Const[8][2]);
+        let hurtarr = this.myDataObj.getArr(gameData.instance().game_Const[9][2]);
+
+        if (towerManger.instance.talantData[19].length > 0) {
+            hurtarr = [100, 100, 100];
+        }
+        // console.log("----------------------------------------------------------");
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (element.node == null) {
+                continue;
+            }
+
+            let itherpos = element.node.getPosition();
+            let minpos = this.interVec;
+            if (this.attackmonster[0].node != null) {
+                minpos = this.attackmonster[0].node.getPosition();
+            }
+            let circleLeth = minpos.sub(itherpos).mag();
+
+            // console.log("minpos:"+minpos.x+","+minpos.y+"           itherpos:"+itherpos.x+","+itherpos.y);
+            let downhp = attack * (1 - element.myDataObj.monsterData.physics_reduction);
+
+            if (circleLeth < this.myDataObj.BulletData.boom_range * (sqrtArr[2] / 100)) {
+                downhp = attack * (hurtarr[2] / 100) * (1 - element.myDataObj.monsterData.physics_reduction)
+                element.hpDown(downhp);
+            }
+            else if (circleLeth < this.myDataObj.BulletData.boom_range * (sqrtArr[1] / 100)) {
+                downhp = attack * (hurtarr[1] / 100) * (1 - element.myDataObj.monsterData.physics_reduction)
+                element.hpDown(downhp);
+            }
+            else if (circleLeth < this.myDataObj.BulletData.boom_range * (sqrtArr[0] / 100)) {
+                downhp = attack * (hurtarr[0] / 100) * (1 - element.myDataObj.monsterData.physics_reduction)
+                element.hpDown(downhp);
+            }
+            else {
+
+            }
+        }
+
+        // if (this.SkillIDL >= 31 && this.SkillIDL <= 33) {
+        //     this.skill31_33();
+        // }
+
+        // if (this.SkillIDR >= 34 && this.SkillIDR <= 36) {
+        //     this.skill34_36();
+        // }
+
+        this.scheduleOnce(function () {
+            this.paodanhuanyuan();
+        }, this.myDataObj.TowerData.attack_cd - this.myDataObj.BulletData.speed);
+    }
+
+
+
+
+    private ParabolaTo(t: number, startPoint: cc.Vec2, endPoint: cc.Vec2, height: number, angle: number) {
+        // 把角度转换为弧度  
+        let radian = angle * 3.14159 / 180.0;
+        // 第一个控制点为抛物线左半弧的中点  
+        let q1x = startPoint.x + (endPoint.x - startPoint.x) / 2.0;
+        let q1 = cc.v2(q1x, height + startPoint.y + Math.cos(radian) * q1x);
+        // 第二个控制点为整个抛物线的中点  
+        let q2x = startPoint.x + (endPoint.x - startPoint.x) / 2.0;
+        let q2 = cc.v2(q2x, height + startPoint.y + Math.cos(radian) * q2x);
+
+        //曲线配置  
+        var bezier = [q1, q2, endPoint];
+
+        //使用CCEaseInOut让曲线运动有一个由慢到快的变化,显得更自然  
+
+        let bezerby = cc.bezierTo(t, bezier);
+        this.paodan.node.runAction(bezerby);
+    }
+
+    private paodanhuanyuan() {
+        this.baoza.node.opacity = 0;
+        this.paodan.node.setPosition(this.paodanstartPos);
+        this.DelateAllAttackmonster();
+        this.attckStart();
+    }
+
+
+    /**特殊技能 */
+    private skillSpeattack() {
+        /**冷却时间 */
+        let delayTime = this.myDataObj.SkillData.parameter_4;
+        if (this.SkillIDL >= 25 && this.SkillIDL <= 27) {
+            this.schedule(this.skill25_27, delayTime);
+        }
+
+        if (this.SkillIDR >= 28 && this.SkillIDR <= 30) {
+            this.schedule(this.skill28_30, delayTime);
+        }
+
+
+    }
+
+    /**id 25-27技能 跟踪飞弹 */
+    private skill25_27() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDL);
+
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**射程半径 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**伤害范围 */
+        let pointSqrt = this.myDataObj.SkillData.parameter_5;
+
+
+        let dexPos = this.attackmonster[0].node.getPosition();
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            let monToDexLeth = dexPos.sub(element.node.getPosition()).mag();
+            if (monToDexLeth < pointSqrt) {
+                element.hpDown(shanghai);
+            }
+        }
+
+    }
+
+    /**id 28-30技能 破片弹 */
+    private skill28_30() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**射程半径 */
+        let totalcount = Number(this.myDataObj.SkillData.parameter_3);
+        /**伤害范围 */
+        let pointSqrt = this.myDataObj.SkillData.parameter_5;
+
+
+        let dexPos = this.attackmonster[0].node.getPosition();
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            let monToDexLeth = dexPos.sub(element.node.getPosition()).mag();
+            if (monToDexLeth < pointSqrt) {
+                element.hpDown(shanghai);
+            }
+        }
+
+    }
+
+
+    /**id 31-33技能 电弧连锁 */
+    private skill31_33() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDL);
+        let monpos = this.attackmonster[0].node.getPosition();
+        /**目标数量 */
+        let pointNum = this.myDataObj.SkillData.parameter_5;
+        let attack = this.myDataObj.getRanm(1, this.myDataObj.BulletData.boom_hurt);
+
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            if (i < pointNum) {
+                cc.tween(element.node)
+                .delay(i*0.2)
+                .call(()=>{
+                    attack *= 0.8;
+                    element.hpDown(attack)
+                })
+                .start();
+            }
+        }
+    }
+
+    /**id 34-36技能 电荷超载 */
+    private skill34_36() {
+        if (this.attackmonster.length == 0) {
+            return;
+        }
+        this.myDataObj.writeSkill_Config(this.SkillIDR);
+        /**伤害数值 */
+        let shanghai = this.myDataObj.getRanm(1, this.myDataObj.SkillData.parameter_2);
+        /**伤害范围 */
+        let pointSqrt = this.myDataObj.SkillData.parameter_5;
+
+        let dexPos = this.attackmonster[0].node.getPosition();
+        for (let i = 0; i < this.attackmonster.length; i++) {
+            const element = this.attackmonster[i];
+            let monToDexLeth = dexPos.sub(element.node.getPosition()).mag();
+            if (monToDexLeth < pointSqrt) {
+                element.hpDown(shanghai);
+            }
+        }
+
+
+    }
+}

+ 10 - 0
assets/Script/game/tower/turret.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "636dab70-296b-4f82-8b83-042cc9eb56d6",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Script/mainFace.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "fbdf7a86-a41e-45ec-8ff0-9f72b118c9fa",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 162 - 0
assets/Script/mainFace/mainManager.ts

@@ -0,0 +1,162 @@
+import { AudioManager } from "../configData/AudioManager";
+import GameConfig from "../configData/GameConfig";
+import gameManger from "../game/UIFace/gameManger";
+import viewComtent from "../game/UIFace/viewComtent";
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class mainManager extends cc.Component {
+
+    @property(cc.Node)
+    private view: cc.Node = null;
+    /**当前最新关卡 */
+    @property(cc.Node)
+    private nowLevel: cc.Node = null;
+    /**钻石数量 */
+    @property(cc.Label)
+    private dialabel: cc.Label = null;
+    /**总星星数量 */
+    @property(cc.Label)
+    private starlabel: cc.Label = null;
+    /**剩余星星数量 */
+    @property(cc.Label)
+    private nowstarlabel: cc.Label = null;
+
+    private allTapBtn: cc.Node[] = [];
+    private scroll: cc.ScrollView = null;
+    public static instance: mainManager = null;
+    protected onLoad() {
+        mainManager.instance = this;
+        this.node.opacity = 255;
+        let hhh = cc.winSize.height * (1920 / cc.winSize.width);
+        this.view.setContentSize(1920, hhh);
+        this.scroll = this.node.getComponent(cc.ScrollView);
+        this.scroll.scrollToOffset(cc.v2());
+        localStorage.clear();
+        this.initStorage();
+
+      
+
+        this.initData();
+        this.initStartBtn();
+
+        this.nowLevel.on(cc.Node.EventType.TOUCH_START, function () {
+            this.startgame(GameConfig.instance().storageData.level);
+        }, this);
+        this.preLoadSprite();
+    }
+
+    /**钻石星星数量 */
+    public initData() {
+        this.dialabel.string = GameConfig.instance().storageData.Diamond.toString();
+        this.starlabel.string = GameConfig.instance().storageData.TotalStarNum.toString();
+        this.nowstarlabel.string = GameConfig.instance().storageData.starNum.toString();
+    }
+
+    /**返回主界面刷新 */
+    public backInit() {
+        for (let i = 0; i < this.allTapBtn.length; i++) {
+            const element = this.allTapBtn[i];
+            element.destroy();
+        }
+        this.allTapBtn = [];
+        cc.director.resume();
+        cc.director.getScheduler().setTimeScale(1);
+        this.initData();
+        this.initStartBtn();
+        AudioManager.palyAudio(1);
+    }
+
+    /**初始化存储数据 */
+    private initStorage() {
+        let sore = GameConfig.instance().getStorage();
+        if (sore) {
+            GameConfig.instance().storageData = sore;
+        }
+        else {
+            GameConfig.instance().setStorage();
+        }
+    }
+
+    /**开始按钮加载 */
+    private initStartBtn() {
+
+        let self = this;
+        let storeLevel = GameConfig.instance().storageData.level;
+        let posArr = [cc.v2(801, 454), cc.v2(507, 463), cc.v2(423, 292), cc.v2(255, 451), cc.v2(127, 286), cc.v2(-12, 376), cc.v2(-86, 226),
+        cc.v2(-332, 418), cc.v2(-634, 433), cc.v2(-877, 274), cc.v2(-591, 124), cc.v2(-713, -164), cc.v2(-524, -373),
+        cc.v2(-256, -374), cc.v2(-37, -298), cc.v2(264, -329), cc.v2(580, -357), cc.v2(878, -284)];
+        if (storeLevel > 1) {
+            cc.resources.load("prefabs/level_last", cc.Prefab, function (err, prefab: cc.Prefab) {
+                for (let i = 0; i < storeLevel - 1; i++) {
+                    const element = posArr[i];
+                    var newNode = cc.instantiate(prefab);
+                    self.nowLevel.parent.addChild(newNode, 1);
+                    newNode.setPosition(element);
+                    newNode.on(cc.Node.EventType.TOUCH_START, function () {
+                        self.startgame(i + 1);
+                    }, this);
+
+                    let star = newNode.getChildByName("star_" + GameConfig.instance().storageData.levelStar[i]);
+                    star.opacity = 255;
+
+                    self.allTapBtn.push(newNode);
+                }
+            });
+        }
+
+
+        this.nowLevel.setPosition(posArr[storeLevel - 1]);
+    }
+
+    /**天赋界面 */
+    private openTalant() {
+        AudioManager.palyAudio(6);
+        let self = this;
+        cc.resources.load("prefabs/talantNode", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            self.node.addChild(newNode, 10);
+            newNode.setPosition(0, 0);
+        });
+    }
+
+    /**设置界面 */
+    private openSetFace() {
+        AudioManager.palyAudio(6);
+        let self = this;
+    }
+
+    /**开始游戏 */
+    private startgame(level: number) {
+        AudioManager.palyAudio(6);
+        GameConfig.instance().palyLevel = level;
+        this.loadLevelIntro();
+    }
+
+    /**加载关卡介绍界面 */
+    public loadLevelIntro() {
+        let self = this;
+        cc.resources.load("prefabs/LevelIntro", cc.Prefab, function (err, prefab: cc.Prefab) {
+            var newNode = cc.instantiate(prefab);
+            self.node.addChild(newNode, 1);
+            newNode.setPosition(cc.v2(0, 0));
+        });
+    }
+
+    private preLoadSprite() {
+        cc.resources.load("talant/itembg", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+
+        });
+
+        for (let i = 0; i < 30; i++) {
+            cc.resources.load("talant/talant_skill_" + (i + 1), cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+
+            });
+        }
+    }
+
+
+
+
+}

+ 10 - 0
assets/Script/mainFace/mainManager.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "3b7eca40-aa0a-48b1-be17-b58d890788d6",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 213 - 0
assets/Script/mainFace/talantNode.ts

@@ -0,0 +1,213 @@
+import { AudioManager } from "../configData/AudioManager";
+import DataObj from "../configData/DataObj";
+import GameConfig from "../configData/GameConfig";
+import viewComtent from "../game/UIFace/viewComtent";
+import mainManager from "./mainManager";
+
+
+const { ccclass, property } = cc._decorator;
+
+@ccclass
+export default class talantNode extends cc.Component {
+
+    /**背景 */
+    @property(cc.Prefab)
+    private zhehzao: cc.Prefab = null;
+    /**背景 */
+    @property(cc.Sprite)
+    private mainbg: cc.Sprite = null;
+    /**名字 */
+    @property(cc.Sprite)
+    private title: cc.Sprite = null;
+
+    /**滚轮 */
+    @property(cc.ScrollView)
+    private scroll: cc.ScrollView = null;
+    /**可视图 */
+    @property(cc.Node)
+    private view: cc.Node = null;
+    /**容器 */
+    @property(cc.Node)
+    private content: cc.Node = null;
+
+    /**升级按钮 */
+    @property(cc.Button)
+    private upbtn: cc.Button = null;
+    // /**关闭按钮 */
+    // @property(cc.Button)
+    // private closebtn: cc.Button = null;
+
+    /**天赋名字 */
+    @property(cc.Label)
+    private skillname: cc.Label = null;
+    /**描述 */
+    @property(cc.Label)
+    private skillword: cc.Label = null;
+
+    /**星星总数 */
+    @property(cc.Label)
+    private total: cc.Label = null;
+    /**单个天赋价格 */
+    @property(cc.Label)
+    private saleNum: cc.Label = null;
+
+    /**天赋图标 */
+    @property(cc.Sprite)
+    private talantIcon: cc.Sprite = null;
+    /**天赋icon数组 */
+    private skillIcon: cc.SpriteFrame[] = [];
+    /**选择ID */
+    private seleId = 1;
+    /**icon */
+    private iconSpr:cc.Sprite[] = [];
+
+    private norMaterial:cc.Material = cc.Material.getBuiltinMaterial('2d-sprite');
+    private grayMaterial:cc.Material = cc.Material.getBuiltinMaterial('2d-gray-sprite');
+
+    public myDataObj: DataObj = null;
+    public static instance: talantNode = null;
+    protected onLoad() {
+        talantNode.instance = this;
+        this.node.opacity = 255;
+        this.mainbg.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
+        this.myDataObj = new DataObj();
+        this.initPos();
+
+        this.loadSprite();
+        this.scroll.scrollToOffset(cc.v2());
+
+    }
+
+    /**初始化坐标 */
+    private initPos() {
+        let hetgt = viewComtent.instance.getWinsize().y;
+        // let closepos = this.closebtn.node.getPosition();
+        // this.closebtn.node.setPosition(closepos.x, hetgt/2 - 62);
+
+        this.title.node.setPosition(0, hetgt/2 - 72);
+
+
+        this.total.string = '' + GameConfig.instance().storageData.starNum;
+    }
+
+    /**加载图片 */
+    private loadSprite() {
+        let self = this;
+        self.skillIcon = [];
+        cc.resources.load("talant/itembg", cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+            for (let i = 0; i < 6; i++) {
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                mynode.setPosition(0, self.content.getContentSize().height / 2 - 300 - 207 * i);
+                self.content.addChild(mynode);
+            }
+        });
+
+        let strArr = ["sele_tower_build_4","sele_tower_build_1","sele_tower_build_2","sele_tower_build_3","yunshiicon","yuanbinicon"];
+        for (let i = 0; i < 6; i++) {
+            cc.resources.load("game/"+strArr[i], cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                    let mynode = new cc.Node();
+                    let spr = mynode.addComponent(cc.Sprite);
+                    spr.spriteFrame = myspriteFrame;
+                    mynode.setPosition(-500, self.content.getContentSize().height / 2 - 300 - 207 * i);
+                    self.content.addChild(mynode);
+            });
+        }
+
+        for (let i = 0; i < 30; i++) {
+            self.skillIcon.push(null);
+        }
+        let coint = 0;
+        for (let i = 0; i < 30; i++) {
+            this.myDataObj.writeTalent_Config(i+1);
+            cc.resources.load("talant/" + this.myDataObj.talentData.talent_icon, cc.SpriteFrame, function (err, myspriteFrame: cc.SpriteFrame) {
+                let mynode = new cc.Node();
+                let spr = mynode.addComponent(cc.Sprite);
+                spr.spriteFrame = myspriteFrame;
+                self.skillIcon[i] = myspriteFrame;
+                mynode.setPosition(-322 + (i % 5) * 200, self.content.getContentSize().height / 2 - 300 - 207 * Math.floor((i / 5)));
+                self.content.addChild(mynode);
+                mynode.on(cc.Node.EventType.TOUCH_START, function () {
+                    self.tapSkillId(i + 1);
+                }, self);
+                coint++;
+                if (coint == 30) {
+                    self.tapSkillId(self.seleId);
+                }
+                let isKaiqi = GameConfig.instance().storageData.myTalant[i];
+                if (isKaiqi == 0) {
+                    spr.setMaterial(0, self.grayMaterial);
+                }
+                self.iconSpr.push(spr);
+            });
+        }
+    }
+
+    private loadTowerPic()
+    {
+
+    }
+
+    /**点击各个天赋标志 */
+    private tapSkillId(ID: number) {
+        // console.log('-----------:' + ID);
+        this.seleId = ID;
+        this.myDataObj.writeTalent_Config(ID);
+        this.skillname.string = this.myDataObj.talentData.name;
+        this.skillword.string = this.myDataObj.talentData.talent_text;
+        this.talantIcon.spriteFrame = this.skillIcon[ID - 1];
+        this.saleNum.string = '' + this.myDataObj.talentData.star_required;
+        this.saleNum.node.color = cc.color(142,105,52);
+        this.setIsShowUpBtn(ID);
+    }
+
+    /**判断升级按钮是否能显示 */
+    private setIsShowUpBtn(ID: number) {
+        let isKaiqi = GameConfig.instance().storageData.myTalant[ID - 1];
+        this.upbtn.node.active = false;
+        if (isKaiqi == 0) {
+            if ((ID - 1) % 5 == 0) {
+                this.upbtn.node.active = true;
+            }
+            else {
+                if (GameConfig.instance().storageData.myTalant[ID - 2] == 1) {
+                    this.upbtn.node.active = true;
+                }
+            }
+
+            
+            let starNum = GameConfig.instance().storageData.starNum;
+            if (starNum < this.myDataObj.talentData.star_required) {
+                this.upbtn.node.active = false;
+                this.saleNum.node.color = cc.color(255,0,0);
+            }
+        }
+    }
+
+    private onTouchStart(e: cc.Event.EventTouch): void {
+
+    }
+
+    /**升级天赋 */
+    private upTalant() {
+        AudioManager.palyAudio(6);
+        let starNum = GameConfig.instance().storageData.starNum;
+        if (starNum >= this.myDataObj.talentData.star_required) {
+            GameConfig.instance().storageData.starNum -= this.myDataObj.talentData.star_required;
+            GameConfig.instance().storageData.myTalant[this.seleId - 1] = 1;
+            GameConfig.instance().setStorage();
+            this.total.string = '' + GameConfig.instance().storageData.starNum;
+            this.iconSpr[this.seleId - 1].setMaterial(0, this.norMaterial);
+            this.upbtn.node.active = false;
+        }
+    }
+
+    /**关闭界面 */
+    private closed() {
+        AudioManager.palyAudio(6);
+        mainManager.instance.initData();
+        this.node.destroy();
+    }
+
+}

+ 10 - 0
assets/Script/mainFace/talantNode.ts.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "5f269efa-ea87-429d-8f01-3204e38d366f",
+  "importer": "typescript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/Texture.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "7b81d4e8-ec84-4716-968d-500ac1d78a54",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 13 - 0
assets/adsdk.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "dd825baa-493a-4812-91df-83e113c58656",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 194 - 0
assets/adsdk/sdk-jsb.js

@@ -0,0 +1,194 @@
+'use strict'
+
+cc.loader.downloader.loadSubpackage = function(name, progressCallback, completeCallback) {
+    if (!completeCallback && progressCallback) {
+        completeCallback = progressCallback;
+        progressCallback = null;
+    }
+    if (completeCallback) {
+        completeCallback(null);
+    }
+}
+
+var AdObj = {
+    load: function() {
+        setTimeout(function() {
+            adsdk_request_result("onLoad", this._jid);
+        }.bind(this), 100);
+        return this;
+    },
+
+    then: function(callback) {
+        this._cb_then = callback;
+        return this;
+    },
+
+    catch: function(callback) {
+        this._cb_catch = callback;
+        return this;
+    },
+
+    show: function() {
+        setTimeout(function() {
+            adsdk_request_result("onClose", this._jid, true);
+        }.bind(this), 100);
+        return this;
+    },
+
+    onLoad: function(callback) {
+        this._cb_onLoad = callback;
+        return this;
+    },
+
+    onClose: function(callback) {
+        this._cb_onClose = callback;
+        return this;
+    },
+
+    onError: function(callback) {
+        this._cb_onError = callback;
+        return this;
+    },
+
+    offClose: function(callback) {
+        return this;
+    },
+
+    offError: function(callback) {
+        return this;
+    },
+
+    offLoad: function(callback) {
+        return this;
+    },
+
+    destroy: function() {
+        return this;
+    },
+
+    hide: function() {
+        return this;
+    },
+
+    onResize: function() {
+        return this;
+    },
+    
+    style: function() {
+        return this._style;
+    }
+}
+
+var _style = function(objId, left, top, width, height) {
+    this._objId = objId;
+    this._left = left;
+    this._top = top;
+    this._width = width;
+    this._height = height;
+}
+
+_style.prototype = {
+    set left(val) {
+        this._left = val;
+        this._update(0, val);
+    },
+    get left() {
+        return this._left;
+    },
+    set top(val) {
+        this._top = val;
+        this._update(1, val);
+    },
+    get top() {
+        return this._top;
+    },
+    set width(val) {
+        this._width = val;
+        this._update(2, val);
+    },
+    get width() {
+        return this._width;
+    },
+    set height(val) {
+        this._height = val;
+        this._update(3, val);
+    },
+    get height() {
+        return this._height;
+    },
+    _update(t, v) {
+    }
+}
+
+window.AdSdk = {
+    adObjectCache: new Map(),
+
+    createRewardedVideoAd: function(params) {
+        return createAdObj("reward", params);
+    },
+
+    createInterstitialAd: function(params) {
+        return createAdObj("Interstitial", params);
+    },
+
+    createBannerAd: function(params) {
+        let obj = createAdObj("banner", params);
+        obj.style = new _style(obj._objId, params.style.left, params.style.top, params.style.width, params.style.height);
+        return obj;
+    },
+
+    createFullscreenVideoAd: function(params) {
+        return createAdObj("Fullscreen", params);
+    },
+}
+
+window.createAdObj = function(type, params) {
+    let adUnitId = params.adUnitId;
+
+    for (let [key, value] of AdSdk.adObjectCache) {
+        if (value._adUnitId == adUnitId) {
+            return value;
+        }
+    }
+
+    let adObj = Object.create(AdObj);
+    adObj._type = type;
+    adObj._adUnitId = adUnitId;
+    adObj._jid = adsdk_createAdObj(type, params);
+
+    AdSdk.adObjectCache.set(adObj._jid, adObj);
+    return adObj;
+}
+
+window.adsdk_createAdObj = function(type, params) {
+    if (AdSdk._adObjIndex == undefined) {
+        AdSdk._adObjIndex = 0;
+    } else {
+        AdSdk._adObjIndex++;
+    }
+    return AdSdk._adObjIndex;
+}
+
+window.adsdk_request_result = function(cmd, objId, params) {
+    let adObj = AdSdk.adObjectCache.get(objId);
+    if (!adObj) {
+        return;
+    }
+    if (cmd === "onLoad") {
+        if (adObj._cb_onLoad) {
+            adObj._cb_onLoad();
+        }
+        if (adObj._cb_then) {
+            adObj._cb_then();
+        }
+    } else if (cmd === "onClose") {
+        if (adObj._cb_onClose) {
+            if (params) {
+                adObj._cb_onClose({ isEnded: true });
+            } else {
+                adObj._cb_onClose({ isEnded: false });
+            }
+        }
+    } else if (cmd === "onError") {
+    }
+}

+ 10 - 0
assets/adsdk/sdk-jsb.js.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "c9aa0bad-6a39-4c7d-b879-d176578f6186",
+  "importer": "javascript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/migration.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "4819416c-55b5-450e-a856-9f2d83888984",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 17 - 0
assets/migration/use_v2.1-2.2.1_cc.Toggle_event.js

@@ -0,0 +1,17 @@
+/*
+ * This script is automatically generated by Cocos Creator and is only used for projects compatible with the v2.1.0 ~ 2.2.1 version.
+ * You do not need to manually add this script in any other project.
+ * If you don't use cc.Toggle in your project, you can delete this script directly.
+ * If your project is hosted in VCS such as git, submit this script together.
+ *
+ * 此脚本由 Cocos Creator 自动生成,仅用于兼容 v2.1.0 ~ 2.2.1 版本的工程,
+ * 你无需在任何其它项目中手动添加此脚本。
+ * 如果你的项目中没用到 Toggle,可直接删除该脚本。
+ * 如果你的项目有托管于 git 等版本库,请将此脚本一并上传。
+ */
+
+if (cc.Toggle) {
+    // Whether to trigger 'toggle' and 'checkEvents' events when modifying 'toggle.isChecked' in the code
+    // 在代码中修改 'toggle.isChecked' 时是否触发 'toggle' 与 'checkEvents' 事件
+    cc.Toggle._triggerEventInScript_isChecked = true;
+}

+ 10 - 0
assets/migration/use_v2.1-2.2.1_cc.Toggle_event.js.meta

@@ -0,0 +1,10 @@
+{
+  "ver": "1.1.0",
+  "uuid": "c6942802-c6d5-40ed-9e9d-f8cb857e1b23",
+  "importer": "javascript",
+  "isPlugin": false,
+  "loadPluginInWeb": true,
+  "loadPluginInNative": true,
+  "loadPluginInEditor": false,
+  "subMetas": {}
+}

+ 13 - 0
assets/resources.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "c096fefd-4b60-4c2c-9fc2-644934246bdc",
+  "importer": "folder",
+  "isBundle": true,
+  "bundleName": "resources",
+  "priority": 8,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

+ 13 - 0
assets/resources/audio.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.3",
+  "uuid": "29117085-8d37-4306-b60e-5b45b17e8436",
+  "importer": "folder",
+  "isBundle": false,
+  "bundleName": "",
+  "priority": 1,
+  "compressionType": {},
+  "optimizeHotUpdate": {},
+  "inlineSpriteFrames": {},
+  "isRemoteBundle": {},
+  "subMetas": {}
+}

binární
assets/resources/audio/bgm1.mp3


+ 8 - 0
assets/resources/audio/bgm1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "f4b70eab-35e6-4abe-b9aa-9e56e5c746b4",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 185.129796,
+  "subMetas": {}
+}

binární
assets/resources/audio/bgm2.mp3


+ 8 - 0
assets/resources/audio/bgm2.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "7f73671a-a74e-4f26-ba4f-976b3bd0642a",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 112.927347,
+  "subMetas": {}
+}

binární
assets/resources/audio/dianji.mp3


+ 8 - 0
assets/resources/audio/dianji.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "efc9eaa0-3a4f-496a-8c09-fffe267277ce",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.20898,
+  "subMetas": {}
+}

binární
assets/resources/audio/fail.mp3


+ 8 - 0
assets/resources/audio/fail.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "3336c958-6a64-40eb-bb47-711b6b5d8a7f",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 6.164898,
+  "subMetas": {}
+}

binární
assets/resources/audio/win.mp3


+ 8 - 0
assets/resources/audio/win.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "87d59d0d-930a-46f1-8e35-e0b9e281e28b",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 0.20898,
+  "subMetas": {}
+}

binární
assets/resources/audio/zd1.mp3


+ 8 - 0
assets/resources/audio/zd1.mp3.meta

@@ -0,0 +1,8 @@
+{
+  "ver": "2.0.3",
+  "uuid": "b842f8d6-fd20-48a6-81d9-8659073660df",
+  "importer": "audio-clip",
+  "downloadMode": 0,
+  "duration": 95.921633,
+  "subMetas": {}
+}

+ 0 - 0
assets/resources/audio/zd2.mp3


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů