Procházet zdrojové kódy

Merge branch 'master' of http://git.izouma.com/zc/airpg-front

panhui před 2 roky
rodič
revize
edf394e3e5

+ 42 - 42
assets/scence/game.scene

@@ -2043,7 +2043,7 @@
     "__prefab": null,
     "_contentSize": {
       "__type__": "cc.Size",
-      "width": 175,
+      "width": 140,
       "height": 88.2
     },
     "_anchorPoint": {
@@ -2073,7 +2073,7 @@
       "b": 255,
       "a": 255
     },
-    "_string": "隐形守护者",
+    "_string": "故事名称",
     "_horizontalAlign": 1,
     "_verticalAlign": 1,
     "_actualFontSize": 35,
@@ -19020,7 +19020,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "a5ZIf7t/NMHqt8BCCCkOor"
+    "_id": "08cehVpAFCYblpkdjSEP34"
   },
   {
     "__type__": "cc.Node",
@@ -19075,7 +19075,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "88+VxUeU5F7ql4pCofwofd"
+    "_id": "51D6igXTNM2I9Thzpyu5NK"
   },
   {
     "__type__": "cc.Node",
@@ -19123,7 +19123,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "5c7vgUzGNHtaVoF5ZDg5+4"
+    "_id": "daa1H8nc1GNb0HnYT9q8A1"
   },
   {
     "__type__": "cc.UITransform",
@@ -19145,7 +19145,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "58qczpwolMY5zX2ZNs58e+"
+    "_id": "7dtQsNZw9L+rBtmBezaiXD"
   },
   {
     "__type__": "cc.ParticleSystem2D",
@@ -19253,7 +19253,7 @@
       "a": 0
     },
     "_positionType": 0,
-    "_id": "ccmgYE5yFMbo3JuJNIsrdL"
+    "_id": "975OvrwhNLvJPtzWT6CPTJ"
   },
   {
     "__type__": "cc.UITransform",
@@ -19275,7 +19275,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "5fmQXt1MpOEIHINE3xt1qG"
+    "_id": "8cVT5Z7hFCwpEkVlnVqrYn"
   },
   {
     "__type__": "cc.Sprite",
@@ -19314,7 +19314,7 @@
     "_isTrimmedMode": true,
     "_useGrayscale": false,
     "_atlas": null,
-    "_id": "ffYui0ORVFRYPFmAFkGD3F"
+    "_id": "32BgHY7PtH/qaxsyBsgzy0"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -19327,7 +19327,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 120,
-    "_id": "c2iv3wN5ND476Yv5tV8BpH"
+    "_id": "d1RvP5dJlFr6aVY+t4vZ3A"
   },
   {
     "__type__": "cc.UITransform",
@@ -19349,7 +19349,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "d03ah8lNxO6IvW0rFBQO7p"
+    "_id": "19teS9a3pCN6yjKQlUac9T"
   },
   {
     "__type__": "cc.Graphics",
@@ -19389,7 +19389,7 @@
       "a": 0
     },
     "_miterLimit": 10,
-    "_id": "71BHQn9AhFkobdYkqgNwdk"
+    "_id": "f8zspr7ktJ8LjtsDFmrS5X"
   },
   {
     "__type__": "8604fJqRXNI5qtxiCUEZHFo",
@@ -19404,7 +19404,7 @@
     "width": 886,
     "height": 76,
     "cornerRadius": 38,
-    "_id": "b8QpjvyzlPWrzenVyJGO1I"
+    "_id": "0cCXQFMNNB0aGmg2GBzbFO"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -19417,7 +19417,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 180,
-    "_id": "0bxZUIaLBGpLfhOg0iUmS1"
+    "_id": "9feQp4m19B86sOjOt7nehc"
   },
   {
     "__type__": "cc.Mask",
@@ -19433,7 +19433,7 @@
     "_inverted": false,
     "_segments": 64,
     "_alphaThreshold": 0.1,
-    "_id": "abcgfii0pNTLER8Ks9JoNA"
+    "_id": "77a7i4WXFB06pQCiMYnKuf"
   },
   {
     "__type__": "cc.Node",
@@ -19738,7 +19738,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "450f5Vv/pLXIqpYuq4VOik"
+    "_id": "3e4jM0HKVO1ICNNdUjSMTf"
   },
   {
     "__type__": "cc.Node",
@@ -19793,7 +19793,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "36PVP9i5JGFbyxvLpYAi24"
+    "_id": "4aN/8ZfuZHL5wsCAo5Zv5W"
   },
   {
     "__type__": "cc.Node",
@@ -19841,7 +19841,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "bbpBifkFNFVIFrL2NGmBFu"
+    "_id": "06bVQavjlETrYRDZYYJv3h"
   },
   {
     "__type__": "cc.UITransform",
@@ -19863,7 +19863,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "51q9mgMIVEUYXrhmLDCxTw"
+    "_id": "14Pp7vSSNOtahjvWaQAV+N"
   },
   {
     "__type__": "cc.ParticleSystem2D",
@@ -19971,7 +19971,7 @@
       "a": 0
     },
     "_positionType": 0,
-    "_id": "20rKcaNgtPRJvlerTKCsGe"
+    "_id": "52WN0IPJRB2InEHcEt54Jn"
   },
   {
     "__type__": "cc.UITransform",
@@ -19993,7 +19993,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "3cVm8t915Ch5gU7/5t/emu"
+    "_id": "88vg0YCLJAwIz0NBNlU617"
   },
   {
     "__type__": "cc.Sprite",
@@ -20032,7 +20032,7 @@
     "_isTrimmedMode": true,
     "_useGrayscale": false,
     "_atlas": null,
-    "_id": "e0ZNF9bQpG8KyYnTiaI8Kc"
+    "_id": "d2J8w0gwlLb4txyW97d0Y0"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -20045,7 +20045,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 120,
-    "_id": "64FIA1Fs1GKKRyd4a48XLn"
+    "_id": "45RuE7GVZOAa7MD3tp5Nsw"
   },
   {
     "__type__": "cc.UITransform",
@@ -20067,7 +20067,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "f2j5FWDBBITLiH/CI9VCbC"
+    "_id": "717fSjoLJE04oj3ULx3Xy1"
   },
   {
     "__type__": "cc.Graphics",
@@ -20107,7 +20107,7 @@
       "a": 0
     },
     "_miterLimit": 10,
-    "_id": "f9NnJH8QNMNYmIFZPkaYRB"
+    "_id": "6e8XSl1cpOS4ZXrvcjYCa7"
   },
   {
     "__type__": "8604fJqRXNI5qtxiCUEZHFo",
@@ -20122,7 +20122,7 @@
     "width": 886,
     "height": 76,
     "cornerRadius": 38,
-    "_id": "94UgF7tw1MU7DqeOaMgabz"
+    "_id": "05C8YAk+lHHbQJ8wEJvOht"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -20135,7 +20135,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 180,
-    "_id": "d76+D6ZR1IF4KJttwMeEZc"
+    "_id": "c4exoeiAFAhb15fzdNdTfZ"
   },
   {
     "__type__": "cc.Mask",
@@ -20151,7 +20151,7 @@
     "_inverted": false,
     "_segments": 64,
     "_alphaThreshold": 0.1,
-    "_id": "3cbCKFD4RE0aCkd89HSpT1"
+    "_id": "9epOFsc69N+ao5/JnhAUTE"
   },
   {
     "__type__": "cc.Node",
@@ -20432,7 +20432,7 @@
     "_lpos": {
       "__type__": "cc.Vec3",
       "x": -4,
-      "y": 4.199999999999989,
+      "y": 7.2,
       "z": 0
     },
     "_lrot": {
@@ -20456,7 +20456,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "e6fIFLNb5EariTmqsUkTS9"
+    "_id": "48+Tnu2TJClKKQezs59lgW"
   },
   {
     "__type__": "cc.Node",
@@ -20511,7 +20511,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "6e+YIMY9pL9Z1W5fHG04pv"
+    "_id": "2aRYQL+/RNUbarxVhg8N1k"
   },
   {
     "__type__": "cc.Node",
@@ -20559,7 +20559,7 @@
       "y": 0,
       "z": 0
     },
-    "_id": "64fMgs6iBIO75EpAz0Jb4k"
+    "_id": "c0QPrAXqRB9qL7Jcjb49Wm"
   },
   {
     "__type__": "cc.UITransform",
@@ -20581,7 +20581,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "6fjAfcAEZBVYEDSl+4nSoX"
+    "_id": "72tAPwNcZBbL/HONPp6YeH"
   },
   {
     "__type__": "cc.ParticleSystem2D",
@@ -20689,7 +20689,7 @@
       "a": 0
     },
     "_positionType": 0,
-    "_id": "59cZjhQGVMnqZXHdu6A98w"
+    "_id": "94dVFN7jVO07w/Y5E68a9V"
   },
   {
     "__type__": "cc.UITransform",
@@ -20711,7 +20711,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "fdxacYindIe6zLLI+t/X5+"
+    "_id": "07Tu2x3uFNgaGBK//TxwBu"
   },
   {
     "__type__": "cc.Sprite",
@@ -20750,7 +20750,7 @@
     "_isTrimmedMode": true,
     "_useGrayscale": false,
     "_atlas": null,
-    "_id": "d6g+UdHxNOEqpgV7da8Imk"
+    "_id": "b6nHi/ojNL5YwYNEzQpyWy"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -20763,7 +20763,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 120,
-    "_id": "3bNUCDkC5E/KCLYtO9lR3V"
+    "_id": "f5y9IJsjpOIqBTgn5IGpFL"
   },
   {
     "__type__": "cc.UITransform",
@@ -20785,7 +20785,7 @@
       "x": 0.5,
       "y": 0.5
     },
-    "_id": "e7c91GDnRNIbwre1S3ySmJ"
+    "_id": "2alCfNM+pIa68UloLw+wwh"
   },
   {
     "__type__": "cc.Graphics",
@@ -20825,7 +20825,7 @@
       "a": 0
     },
     "_miterLimit": 10,
-    "_id": "28rw6FA9FP+KKOfxv5oyq6"
+    "_id": "23uszIch9NG4PsGtiaSFQa"
   },
   {
     "__type__": "8604fJqRXNI5qtxiCUEZHFo",
@@ -20840,7 +20840,7 @@
     "width": 886,
     "height": 76,
     "cornerRadius": 38,
-    "_id": "14u2WrQ5JIxoExiJYnLKC+"
+    "_id": "5cu1IeOxlGSqwBiCqaWtfJ"
   },
   {
     "__type__": "cc.UIOpacity",
@@ -20853,7 +20853,7 @@
     "_enabled": true,
     "__prefab": null,
     "_opacity": 180,
-    "_id": "93jFkY8GlO2YjyVD+IAMmK"
+    "_id": "86ru3qYeNDs4bmUxiv0+JK"
   },
   {
     "__type__": "cc.Mask",
@@ -20869,7 +20869,7 @@
     "_inverted": false,
     "_segments": 64,
     "_alphaThreshold": 0.1,
-    "_id": "87RjO3mshBS7uYYTIaG7m/"
+    "_id": "7aiCYjWoZAr5SxfklM59i5"
   },
   {
     "__type__": "cc.Node",

+ 3 - 3
assets/scripts/AudioManager.ts

@@ -25,9 +25,9 @@ export class AudioManager extends Component {
                 return;
             }
 
-            const audioId = clip.play
-            clip.setVolume(volume, audioId);
-            clip.setLoop(loop, audioId);
+            // const audioId = clip.play
+            // clip.setVolume(volume, audioId);
+            // clip.setLoop(loop, audioId);
         });
     }
 }

+ 60 - 63
assets/scripts/OptionsCtr.ts

@@ -1,5 +1,6 @@
 import { _decorator, color, Color, Component, Label, Node, Sprite, tween, UIOpacity, Vec3 } from "cc"
 import { processCtr } from "./socket/processCtr"
+import { GameCtr } from "./gameCtr"
 const { ccclass, property } = _decorator
 
 @ccclass("OptionsCtr")
@@ -16,62 +17,59 @@ export class OptionsCtr extends Component {
     @property({ type: Sprite })
     notSelectedSprite: Sprite = null // 设置你想要的选中背景图
 
-    private votesOrgPos_x:number = -894
+    private votesOrgPos_x: number = -894
     private votesWidth = 890
-    start() {
-
-    }
-    resetVotes()
-    {
-        for(let i=0;i<4;i++)
-        {
+    start() {}
+    resetVotes() {
+        for (let i = 0; i < 4; i++) {
             const vote: Node = this.optionNodes[i].getChildByName("votes").getChildByName("toupiaojindu")
+            vote.setPosition(this.votesOrgPos_x, 0, 0)
             vote.active = false
-            vote.getChildByName('votePannel_particle').active = false
-            vote.setPosition(this.votesOrgPos_x,0,0)
+            vote.getChildByName("votePannel_particle").active = false
         }
     }
 
+    showVotes(num: number[],lastVot:number[], processCtr: processCtr) {
+
+        console.log("this!!!!!"+this+" processCtr!!!!!"+processCtr)
 
-    showVotes(num: number[] , processCtr: processCtr) {
         let index = 0
 
         //获取投票范围,修改合适步长
-        let scope:number = 10
+        let scope: number = 10
 
         const maxValue = Math.max(...num)
-            if(maxValue > 10 && maxValue < 100)
-            {
-                scope = 100
-            }
-            else if(maxValue > 99)
-            {
-                scope = 1000
-            }
+        if (maxValue > 10 && maxValue < 100) {
+            scope = 100
+        } else if (maxValue > 99) {
+            scope = 1000
+        }
 
-        for(let i=0;i<4;i++)
-        {
+        for (let i = 0; i < 4; i++) {
             const vote: Node = this.optionNodes[i].getChildByName("votes").getChildByName("toupiaojindu")
-            if(!vote.active || !vote.getChildByName('votePannel_particle').active )
-            {
+            if (!vote.active || !vote.getChildByName("votePannel_particle").active) {
                 vote.active = true
-                vote.getChildByName('votePannel_particle').active = true
+                vote.getChildByName("votePannel_particle").active = true
             }
-            tween(vote).to(1, {
-                position: new Vec3(this.votesOrgPos_x + (this.votesWidth / scope) * num[i], 0, 0)
-            })
-            .call(()=>{
-                if(index ===3)
-                {
-                    processCtr.doneProcessing()
-                }
-                index++
-            })
-            .start()
+            console.log(index+"   "+processCtr)
+
+            tween(vote)
+                .to(0.5, {
+                    position: new Vec3(this.votesOrgPos_x + (this.votesWidth / scope) * num[i], 0, 0)
+                })
+                .call(() => {
+                    console.log(index+"   "+processCtr)
+                    if (index === 3) {
+                        console.log("展示投票处理完成,处理下一个")
+                        processCtr.doneProcessing()
+                    }
+                    index++
+                })
+                .start()
         }
     }
 
-    setOptions(options: string[]) {
+    setOptions(options: string[],gameCtr: GameCtr) {
         if (options.length !== 4) {
             console.warn("Expected 4 options!")
             return
@@ -81,14 +79,23 @@ export class OptionsCtr extends Component {
         for (let i = 0; i < 4; i++) {
             const nodeLabel = this.optionNodes[i].getChildByName("text_option").getComponent(Label)
             nodeLabel.string = ""
+            this.optionNodes[i].getComponent(UIOpacity).opacity = 255
         }
 
         tween(this.node.getComponent(UIOpacity))
             .to(1, { opacity: 255 })
             .call(() => {
+                
                 for (let i = 0; i < 4; i++) {
                     this.setOptionText(this.optionNodes[i], options[i])
+                    if( i===3)
+                    {
+                        console.log("展示选项处理完成,处理下一个")
+                        gameCtr.storyActionStatus = 1
+                        gameCtr.processCtr.doneProcessing()
+                    }
                 }
+
             })
             .start()
     }
@@ -105,7 +112,7 @@ export class OptionsCtr extends Component {
             .start()
     }
 
-    selectOption(index: number) {
+    selectOption(index: number,gameCtr:GameCtr) {
         if (index < 1 || index > 4) {
             console.warn("Invalid option index!")
             return
@@ -126,33 +133,23 @@ export class OptionsCtr extends Component {
                     spriteComponent.spriteFrame = this.selectedSprite.spriteFrame
                 }
 
-               
-                this.selectedAction(optionNode)
-            } else {
-                // 这是未被选中的选项
-                labelComponent.color = Color.WHITE // 假设默认颜色为白色,你可以根据需要更改
-
-                // 移除选中背景图
-                const spriteComponent = optionNode.getComponent(Sprite)
-                if (spriteComponent) {
-                    spriteComponent.spriteFrame = this.notSelectedSprite.spriteFrame
-                }
-            }
+                tween(optionNode)
+                .to(0.1, { scale: new Vec3(1.1, 1.1, 1.1) }) // 放大到原始大小的110%
+                .by(0.1, { position: new Vec3(5, 0, 0) }) // 向右移动5个单位
+                .by(0.1, { position: new Vec3(-10, 0, 0) }) // 向左移动10个单位
+                .by(0.1, { position: new Vec3(10, 0, 0) }) // 向右移动10个单位
+                .by(0.1, { position: new Vec3(-10, 0, 0) }) // 向左移动10个单位
+                .by(0.1, { position: new Vec3(5, 0, 0) }) // 向右移动5个单位回到原位置
+                .to(0.1, { scale: new Vec3(1, 1, 1) }) // 缩小回原始大小
+                .call(()=>{
+                    console.log("选中选项处理完成,处理下一个")
+                    gameCtr.storyActionStatus = 2
+                    gameCtr.processCtr.doneProcessing()
+                })
+                .start()
+            } 
         }
     }
-
-    selectedAction(optionNode: Node) {
-        tween(optionNode)
-            .to(0.1, { scale: new Vec3(1.1, 1.1, 1.1) }) // 放大到原始大小的110%
-            .by(0.1, { position: new Vec3(5, 0, 0) }) // 向右移动5个单位
-            .by(0.1, { position: new Vec3(-10, 0, 0) }) // 向左移动10个单位
-            .by(0.1, { position: new Vec3(10, 0, 0) }) // 向右移动10个单位
-            .by(0.1, { position: new Vec3(-10, 0, 0) }) // 向左移动10个单位
-            .by(0.1, { position: new Vec3(5, 0, 0) }) // 向右移动5个单位回到原位置
-            .to(0.1, { scale: new Vec3(1, 1, 1) }) // 缩小回原始大小
-            .start()
-    }
-
     private scaleUp(node: Node) {
         return tween(node).to(0.1, { scale: new Vec3(1.1, 1.1, 1.1) }) // 放大到原始大小的110%
     }

+ 22 - 21
assets/scripts/RoleCtr.ts

@@ -34,22 +34,21 @@ export class RoleCtr extends Component {
     public deathNodes: any[] = []
 
     @property(AudioClip)
-    public attackClip: AudioClip = null!;   
+    public attackClip: AudioClip = null!
 
     @property(AudioClip)
-    public scanClip: AudioClip = null!;   
+    public scanClip: AudioClip = null!
 
     @property(AudioClip)
-    public treatClip: AudioClip = null!;   
+    public treatClip: AudioClip = null!
     @property(AudioClip)
-    public welcomeClip: AudioClip = null!;  
+    public welcomeClip: AudioClip = null!
 
-    public audioSource: AudioSource = null!;
+    public audioSource: AudioSource = null!
 
     start() {
         this.preloadAllFrames()
         this.audioSource = this.node.getComponent(AudioSource)
-        
     }
     preloadAllFrames() {
         for (let i = 1; i <= 62; i++) {
@@ -71,21 +70,19 @@ export class RoleCtr extends Component {
 
     update(deltaTime: number) {}
 
-    playAttackOneShot () {
-        this.audioSource.playOneShot(this.attackClip, 0.2);
+    playAttackOneShot() {
+        this.audioSource.playOneShot(this.attackClip, 0.2)
     }
 
-    playScanOneShot () {
-        this.audioSource.playOneShot(this.scanClip, 0.2);
+    playScanOneShot() {
+        this.audioSource.playOneShot(this.scanClip, 0.2)
     }
 
-    playhealOneShot () {
-        this.audioSource.playOneShot(this.treatClip, 0.2);
-        
+    playhealOneShot() {
+        this.audioSource.playOneShot(this.treatClip, 0.2)
     }
-    playWelcomOneShot()
-    {
-        this.audioSource.playOneShot(this.welcomeClip, 0.2);
+    playWelcomOneShot() {
+        this.audioSource.playOneShot(this.welcomeClip, 0.2)
     }
 
     attack(node: Node) {
@@ -144,6 +141,7 @@ export class RoleCtr extends Component {
 
     //单独处理死亡
     dealDeath(roleNodes: any) {
+        let index = 0
         for (let i = 0; i < this.deathNodes.length; i++) {
             const node = roleNodes[this.deathNodes[i].name]
             if (node) {
@@ -154,6 +152,10 @@ export class RoleCtr extends Component {
                 imgNode.getComponent(UIOpacity).opacity = 100
                 default_icon.active = false
             }
+
+            if (index == this.deathNodes.length - 1) {
+                this.deathNodes = []
+            }
         }
     }
 
@@ -181,7 +183,7 @@ export class RoleCtr extends Component {
         uiopa.opacity = 240
         tween(uiopa).to(2, { opacity: 0 }).start()
 
-        this.playhealOneShot();
+        this.playhealOneShot()
     }
 
     newPlayer(node: Node, person: any) {
@@ -192,7 +194,6 @@ export class RoleCtr extends Component {
         const effect: Node = node.getChildByName("effect_pannel")
         const default_icon: Node = node.getChildByName("img_icon")
 
-
         //新角色席位刷新头像
         if (nameNode.active) {
             //已存在则只更新hp
@@ -243,9 +244,9 @@ export class RoleCtr extends Component {
                     .start()
 
                 this.playScanOneShot()
-                this.scheduleOnce(() => { this.playWelcomOneShot() }, 3)
-
-                
+                this.scheduleOnce(() => {
+                    this.playWelcomOneShot()
+                }, 3)
             })
         }
     }

+ 30 - 17
assets/scripts/StoryPannelCtr.ts

@@ -4,7 +4,6 @@ const { ccclass, property } = _decorator
 
 @ccclass("StoryPannelCtr")
 export class StoryPannelCtr extends Component {
-
     @property({ type: processCtr })
     public processCtr: processCtr | null = null
 
@@ -15,10 +14,9 @@ export class StoryPannelCtr extends Component {
     maxLines: number = 18 // 最大行数
 
     @property(AudioClip)
-    public typingClip: AudioClip = null!;  
-
-    public audioSource: AudioSource = null!;
+    public typingClip: AudioClip = null!
 
+    public audioSource: AudioSource = null!
 
     private fullText: string = ""
 
@@ -28,19 +26,38 @@ export class StoryPannelCtr extends Component {
     private currentLine: string = ""
     private processedCharsCount: number = 0
 
-    public isOnProcess:boolean = false
+    public isOnProcess: boolean = false
+
+    public finishInit: boolean = false
 
     public storyContent: string =
         "《隐形守护者》巧妙的结合了影视剧专业的演技造诣和电子游戏独有的交互体验,用电子游戏独有的表现手法,让玩家对当时那段充满色彩的历史有了新的认识。剧本没有模仿传统谍战剧,整个故事设定都非常符合当时那个年代,游戏中的每个人物都信手拈来展现出难以想象的独创性。游戏提供了传统游戏所不具备的沉浸式的互动体验、真正意义上的多样选择所导致的不同结局。更强调简化的互动性和操作性,以完全影视剧的镜头和剧本来叙事。游戏采用高成本但效果好的真人实拍的方式。对剧本细节的打磨和对当时人物环境的考究。通过演员精湛的演技给玩家营造出真实的体验。这款游戏用一种特殊的方式,为玩家讲述了一个精彩的抗战背景下的谍战故事。《隐形守护者》是一部国内首款创新性互动影像作品。全程采用真人拍摄,以定格图像辅之以影视化剪辑的手法。游戏还利用真人互动影像的优势为用户进行了一场行之有效的爱国主义教育。人实景拍摄,所有场景均为实拍影像,包括为了增加历史真实感而添加的影像史料。加上精良的影音演绎的方式大大的增加了代入感,选角上,演员颜值、演技双在线,除了主角肖途展现出贯穿全剧的人性弧光外,女性角色都演绎得各有特点。而极为考究的场景、道具和服装,也都彰显出制作组的用心和细致。而全程语音加持,以及根据剧情推进或激燃或紧张的配乐,让人有亲临谍战大片的错觉。看似是一个拥有四大结局,多达12个小时的故事情节,但从整个故事来看,它的主旋律其实很简单。"
 
+    initStory(str: string) {
+        console.log("初始化故事!!!!!!!!!!!!!")
+        this.label.string = str
+
+    }
+
     updateStory(str: string) {
+        console.log("开始更新故事!!!!!!!!!!!!!")
+
         //this.fullText = str.replace(/[\r\n]+/g, ' ').trim();
-        this.fullText = str.replace(/[\r\n]+/g, ' ').replace(/\s+/g, ' ').trim();
+        this.fullText = str
+            .replace(/[\r\n]+/g, " ")
+            .replace(/\s+/g, " ")
+            .trim()
         if (!this.node) {
             console.warn("RichText component is not assigned!")
             return
         }
 
+        //初始化中间值
+        this.processedCharsCount = 0
+        this.currentLine = ""
+        this.allLines = []
+        this.audioSource.pause()
+
         this.currentText = ""
         this.label.string = this.currentText
 
@@ -73,25 +90,21 @@ export class StoryPannelCtr extends Component {
             this.scheduleOnce(() => {
                 this.typeWrite()
             }, this.typeSpeed)
-        }
-        else{
+        } else {
             //初始化中间值
-            this.processedCharsCount = 0;
-            this.currentLine = "";
-            this.allLines = [];
+            this.processedCharsCount = 0
+            this.currentLine = ""
+            this.allLines = []
             this.audioSource.pause()
-            if(this.isOnProcess)
-            {
+            if (this.isOnProcess) {
+                console.log("展示剧情处理完成,处理下一个")
                 this.processCtr.doneProcessing()
-                this.isOnProcess = false;
             }
-
         }
-
     }
 
     start() {
-        this.label = this.getComponent(Label);
+        this.label = this.getComponent(Label)
         this.audioSource = this.node.getComponent(AudioSource)
     }
 

+ 122 - 49
assets/scripts/gameCtr.ts

@@ -77,7 +77,7 @@ export class GameCtr extends Component {
     private initOptionsPosition: Vec3 = null
 
     //剧情布局变化状态:0:展示剧情 ,1:出现选项框  2:已选选项下方展示剧情,3:已选移除剧情上移出现选项框
-    private storyActionStatus: number = 0
+    public storyActionStatus: number = 0
 
     //重启动画
     @property({ type: Label })
@@ -127,13 +127,32 @@ export class GameCtr extends Component {
     public bg2AudioSource: AudioSource = null!
     private isPlayBgm1 = true
 
+    public originUrl: string = null
+    public hostName: string = null
 
-    private moveNum:number = 1
+    private globalUrl: string = "https://airpg1.izouma.com"
+    private globalHostname: string = "airpg1.izouma.com"
+
+    private moveNum: number = 1
+
+    private lastVote: number[] = [0, 0, 0, 0]
+
+    private currentDay: number = 0
 
     init() {
         //播放第一个背景音乐
         this.bg1AudioSource.play()
 
+        console.log(location.href)
+
+        if (location.hostname === "localhost") {
+            this.originUrl = this.globalUrl
+            this.hostName = this.globalHostname
+        } else {
+            this.originUrl = location.origin
+            this.hostName = location.hostname
+        }
+
         let roomId = new URLSearchParams(location.search).get("roomId")
         if (roomId != null) {
             this.roomId = Number(roomId)
@@ -142,8 +161,8 @@ export class GameCtr extends Component {
             console.log("use defult roomId")
         }
 
-        const roomUrl = `https://airpg1.izouma.com/api/room/${this.roomId}`
-
+        const roomUrl = `${this.originUrl}/api/room/${this.roomId}`
+        console.log(roomUrl)
         fetch(roomUrl)
             .then((response) => {
                 if (!response.ok) {
@@ -164,7 +183,7 @@ export class GameCtr extends Component {
                     this.socketClient.initSocketConnection()
                 }
 
-                const gameUrl = `https://airpg1.izouma.com/api/game/${this.gameId}`
+                const gameUrl = `${this.originUrl}/api/game/${this.gameId}`
                 fetch(gameUrl)
                     .then((response) => {
                         if (!response.ok) {
@@ -174,7 +193,7 @@ export class GameCtr extends Component {
                     })
                     .then((data) => {
                         console.log(data)
-                        const historyUrl = `https://airpg1.izouma.com/api/game/${this.gameId}/history`
+                        const historyUrl = `${this.originUrl}/api/game/${this.gameId}/history`
                         this.gameInfo = data
                         this.resetNum = data.resetNum
 
@@ -233,17 +252,19 @@ export class GameCtr extends Component {
         //加载音频播放组件
         this.audioSource = this.node.getComponent(AudioSource)
 
-        // this.startResetAnimation()
+        this.startResetAnimation()
         // this.scheduleOnce(() => { this.accessTargetComponent() }, 0.1)
         this.scheduleOnce(() => {
             this.init()
-        }, 5)
+        }, 10)
         this.processCtr.init(this)
         this.schedule(this.chackGameInfo, 5 * 60)
     }
 
     chackGameInfo() {
-        const roomUrl = `https://airpg1.izouma.com/api/room/${this.roomId}`
+        //轮询检查游戏信息
+
+        const roomUrl = `${this.originUrl}/api/room/${this.roomId}`
 
         fetch(roomUrl)
             .then((response) => {
@@ -254,7 +275,7 @@ export class GameCtr extends Component {
             })
             .then((data) => {
                 //获取游戏ID,房间信息
-                console.log(data.currentGameId + "   " + data.active)
+                console.log('轮询检查房间信息:'+data.currentGameId + "   " + data.active)
 
                 if (this.gameId == data.currentGameId) {
                     if (this.noticeStr == data.notice) {
@@ -270,6 +291,38 @@ export class GameCtr extends Component {
             .catch((error) => {
                 console.error("Fetch error:", error)
             })
+
+        //查看历史记录,校验游戏是否还在同步中
+        const historyUrl = `${this.originUrl}/api/game/${this.gameId}/history`
+
+        fetch(historyUrl)
+            .then((response) => {
+                if (!response.ok) {
+                    throw new Error("Network response was not ok")
+                }
+                return response.json()
+            })
+            .then((data) => {
+                const currentHistory: any[] = data
+
+                // 计算日期差(结果单位为毫秒)
+                const lastHistoryDate = new Date(currentHistory[currentHistory.length - 1].date)
+                const firstHistoryDate = new Date(this.historyInfo[0].date)
+
+                const differenceInMilliseconds = lastHistoryDate.getTime() - firstHistoryDate.getTime()
+                // 将毫秒转为天数
+                const differenceInDays = differenceInMilliseconds / (1000 * 60 * 60 * 24) + 1
+
+                console.log("校验游戏进程是否同步:当前天数:" + this.currentDay + "  后台进行天数" + differenceInDays)
+
+                //如果相差超过3天,则重置
+                if (differenceInDays - this.currentDay > 2) {
+                    director.loadScene("game")
+                }
+            })
+            .catch((error) => {
+                console.error("Fetch error:", error)
+            })
     }
 
     update(deltaTime: number) {}
@@ -386,8 +439,35 @@ export class GameCtr extends Component {
 
             if (this.storyActionStatus === 0 || this.storyActionStatus === 3) {
                 this.optionsAppearAction()
+
+                //重置记票
+                this.lastVote = [0, 0, 0, 0]
+            } else {
+                console.log("handleOptions处理失败" + "   storyActionStatus" + this.storyActionStatus)
+                this.processCtr.doneProcessing()
             }
         } else {
+            console.log("handleOptions处理完成处理下一个")
+            this.processCtr.doneProcessing()
+        }
+    }
+
+    //处理投票进度
+    handleVotes(data: any) {
+        let vote: number[] = data.data
+        if (this.realStart && Math.max(...vote) > 0 && JSON.stringify(this.lastVote) !== JSON.stringify(vote)) {
+            // console.log("this22222"+this+" processCtr!!!!!"+this.processCtr)
+            this.optionsCtr.showVotes(vote, this.lastVote, this.processCtr)
+            this.lastVote = vote
+        } else {
+            console.log(
+                "handle votes do nothing:" +
+                    this.realStart +
+                    "    " +
+                    this.storyActionStatus +
+                    "    " +
+                    Math.max(...(data.data as number[]))
+            )
             this.processCtr.doneProcessing()
         }
     }
@@ -404,8 +484,11 @@ export class GameCtr extends Component {
 
             if (this.storyActionStatus === 1) {
                 this.optionsAppearAction()
+            } else {
+                console.log("handleVoteResul处理失败" + "   storyActionStatus" + this.storyActionStatus)
             }
         } else {
+            console.log("handleVoteResul未处理")
             this.processCtr.doneProcessing()
         }
     }
@@ -427,44 +510,43 @@ export class GameCtr extends Component {
 
         this.roleNodes[data.data.name] = role
 
+        console.log("handleNewPlayer处理完成处理下一个")
         this.processCtr.doneProcessing()
     }
 
     //单独处理死亡
     handleDeath(data: any) {
         this.roleCtr.deathNodes = data.data
+
         this.processCtr.doneProcessing()
     }
 
     //处理收到state时间:如果realStart == false ,则更新游戏初始状态
     handleStateResul(data: any) {
         if (!this.realStart) {
+            console.log("处理开始前的status")
             this.historyInfo.push(data.data)
 
             this.updateGame(this.gameInfo, this.historyInfo)
+            console.log("handleStateResul处理完成处理下一个")
+
+            this.processCtr.doneProcessing()
+        } else {
+            console.log("处理开始后的status完成,处理下一个")
+            this.processCtr.doneProcessing()
         }
-        this.processCtr.doneProcessing()
     }
 
     //处理重置
     handleReset(data: any) {
         //director.reset()
-        director.loadScene("game")
-        this.processCtr.doneProcessing()
-    }
+        console.log("处理重置消息")
 
-    //处理投票进度
-    handleVotes(data: any) {
-        if(this.realStart && this.storyActionStatus == 1 && Math.max(...(data.data as number[]))>0)
-        {
-            let votes:number[] = data.data
-            this.optionsCtr.showVotes(votes,this.processCtr)
-        }
-        else
-        {
-            console.log('handle votes do nothing:'+this.realStart+"    "+this.storyActionStatus+"    "+Math.max(...(data.data as number[])))
-            this.processCtr.doneProcessing()
-        }
+        this.roleCtr.dealDeath(this.roleNodes)
+        this.scheduleOnce(() => {
+            director.loadScene("game")
+        }, 5)
+        this.processCtr.doneProcessing()
     }
 
     //处理所有剧情、选项的移动逻辑
@@ -480,27 +562,24 @@ export class GameCtr extends Component {
                 tween(this.storyPannelCtr.node)
                     .by(0.5, { position: new Vec3(0, storyUI.height - this.storyHeight, 0) })
                     .call(() => {
-                        this.optionsCtr.setOptions(this.optionsLabel)
+                        this.optionsCtr.setOptions(this.optionsLabel, this)
 
-                        //此处需要额外处理死亡,因为前一步有演示播放攻击动画,不排除死亡名单中有攻击后自然死亡角色
+                        //此处需要额外处理死亡,因为前一步有演示播放攻击动画,不排除死亡名单中有攻击后自然死亡角色,最后一个死亡的没啥用,暂没处理
                         this.roleCtr.dealDeath(this.roleNodes)
                     })
                     .start()
             } else {
-                this.optionsCtr.setOptions(this.optionsLabel)
+                this.optionsCtr.setOptions(this.optionsLabel, this)
             }
+
             this.playShowOptionsOneShot()
-            this.processCtr.doneProcessing()
-            this.storyActionStatus = 1
         } else if (this.storyActionStatus === 1) {
             //选中备选项
             this.optionsCtr.resetVotes()
 
             console.log("selectedOptionNum:" + this.selectedOptionNum)
-            this.optionsCtr.selectOption(this.selectedOptionNum + 1)
             this.playSelectedOneShot()
-            this.processCtr.doneProcessing()
-            this.storyActionStatus = 2
+            this.optionsCtr.selectOption(this.selectedOptionNum + 1, this)
         } else if (this.storyActionStatus === 2) {
             this.scheduleOnce(() => {
                 // 隐藏未被选中选项
@@ -565,12 +644,10 @@ export class GameCtr extends Component {
 
             //顶部备选项消失
             tween(selectedOption.getComponent(UIOpacity))
-                .to(0.5, { opacity: 0 })
+                .to(0.5, { opacity: 1 })
                 .call(() => {
                     //重置选项位置与透明度
                     this.optionsCtr.node.position = this.initOptionsPosition
-                    // this.optionsCtr.node.getComponent(UIOpacity).opacity = 0
-                    // this.optionsCtr.node.getChildByName()
 
                     // 这是被选中的选项
                     selectedOption.getChildByName("text_option").getComponent(Label).color = Color.WHITE
@@ -580,11 +657,6 @@ export class GameCtr extends Component {
                     if (spriteComponent) {
                         spriteComponent.spriteFrame = this.optionsCtr.notSelectedSprite.spriteFrame
                     }
-                    for (let i = 0; i < 4; i++) {
-                        this.optionsCtr.optionNodes[i].getComponent(UIOpacity).opacity = 255
-                        const vote:Node = this.optionsCtr.optionNodes[i].getChildByName("votes").getChildByName("toupiaojindu")
-                        console.log("vote info!!!!!!!!!!!!!!"+vote.active+"   "+vote.getPosition+"   "+vote.getComponent(UIOpacity).opacity)
-                    }
 
                     //剧情上移开始展示
                     tween(this.storyPannelCtr.node)
@@ -592,7 +664,9 @@ export class GameCtr extends Component {
                         .call(() => {
                             this.storyActionStatus = 0
                             this.optionsAppearAction()
-                            this.processCtr.doneProcessing()
+
+                            // console.log("剧情上移处理完成,处理下一个")
+                            // this.processCtr.doneProcessing()
                         })
                         .start()
                 })
@@ -611,7 +685,7 @@ export class GameCtr extends Component {
             //初始化剧情!!!
             //触发剧情框文字
             if (this.storyPannelCtr) {
-                this.storyPannelCtr.updateStory(lastHistory.plot)
+                this.storyPannelCtr.initStory(lastHistory.plot)
             } else {
                 console.log("plot error")
             }
@@ -645,10 +719,6 @@ export class GameCtr extends Component {
                 this.roleCtr.newPlayer(role, this.player[i])
                 this.roleNodes[this.player[i].name] = role
             }
-
-            this.scheduleOnce(() => {
-                this.processCtr.doneProcessing()
-            }, 3)
         } else {
             throw new Error("gameInfo or historyInfo is null")
         }
@@ -673,6 +743,7 @@ export class GameCtr extends Component {
         // 将毫秒转为天数
         const differenceInDays = differenceInMilliseconds / (1000 * 60 * 60 * 24) + 1
         this.dayLabel.string = "第" + differenceInDays + "天"
+        this.currentDay = differenceInDays
     }
 
     updateDateByWS(data: any) {
@@ -694,6 +765,8 @@ export class GameCtr extends Component {
         // 将毫秒转为天数
         const differenceInDays = differenceInMilliseconds / (1000 * 60 * 60 * 24) + 1
         this.dayLabel.string = "第" + differenceInDays + "天"
+        this.currentDay = differenceInDays
+        console.log("更新日期处理完成,处理下一个")
 
         this.processCtr.doneProcessing()
     }
@@ -731,7 +804,7 @@ export class GameCtr extends Component {
 
                 //已死亡不触发
                 if (orgHp == 0) {
-                    return
+                    continue
                 }
 
                 let newHp = orgHp + this.modifyHp[i].changeValue / 100

+ 1 - 1
assets/scripts/socket/SocketClient.ts

@@ -13,7 +13,7 @@ export class SocketClient extends Component {
 
     public gameId: number = 8
 
-    private SERVER_URL: String = "wss://airpg1.izouma.com"
+    private SERVER_URL: String = `wss://${location.hostname === 'localhost' ? 'airpg1.izouma.com' :location.hostname}`
 
     public socket:any ;
 

+ 0 - 1
assets/scripts/socket/processCtr.ts

@@ -102,7 +102,6 @@ export class processCtr extends Component {
         console.log("Received State message:", data)
         // 在这里处理 "State" 类型的消息.
         this.gameCtr.handleStateResul(data);
-        this.doneProcessing()
     }
 
     private handleTimeMessage(data: any) {

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
build/web-mobile/assets/main/config.json


+ 1 - 0
build/web-mobile/assets/main/import/01/0108112ee.json

@@ -0,0 +1 @@
+[1,["8fSnWMTz9KXYBf+VPWYjgQ","725bqv0VtKVbYy1jJgxrbn@f9941"],["node","_font","root","data","_spriteFrame"],[["cc.Node",["_name","_layer","_components","_prefab","_lpos","_parent","_children"],1,9,4,5,1,2],["cc.Label",["_string","_actualFontSize","_fontSize","_lineHeight","_isSystemFontUsed","node","__prefab","_font","_color"],-2,1,4,6,5],["cc.Prefab",["_name"],2],["cc.UITransform",["node","__prefab","_contentSize"],3,1,4,5],["cc.CompPrefabInfo",["fileId"],2],["cc.Sprite",["node","__prefab","_spriteFrame"],3,1,4,6],["cc.PrefabInfo",["fileId","instance","targetOverrides","nestedPrefabInstanceRoots","root","asset"],-1,1,1],["cc.TTFFont",["_name","_native"],1]],[[4,0,2],[3,0,1,2,1],[6,0,1,2,3,4,5,5],[0,0,1,5,2,3,4,3],[1,0,1,2,3,4,5,6,7,6],[2,0,2],[0,0,6,2,3,4,2],[0,0,1,5,2,3,3],[5,0,1,2,1],[1,0,1,2,3,4,5,6,8,7,6],[7,0,1,3]],[[[[5,"rank_item1"],[6,"rank_item1",[-4,-5,-6],[[1,-2,[0,"faBrcEFttFcrKQSb34b8HQ"],[5,371,57]],[8,-3,[0,"01G8owDU9Pw7EgE0c1rtjE"],3]],[2,"edvVKEs2dJM6QH6dUZQrKf",null,null,null,-1,0],[1,-12,348.922,0]],[3,"text_rank_number",33554432,1,[[1,-7,[0,"a6C27ru1lODKpgmFJH7Way"],[5,13.974609375,88.2]],[9,"1",30,30,70,false,-8,[0,"52O/QWYhlEAJo5jhWkqKHZ"],[4,4286164404],0]],[2,"9fTjCmwhdFl7Nr/nf5l97S",null,null,null,1,0],[1,-138.671,0,0]],[7,"text_player_name",33554432,1,[[1,-9,[0,"19K7W8rnJBeZaw2hjuJoDa"],[5,9.2529296875,88.2]],[4,"-",25,25,70,false,-10,[0,"23HUcYebdCHqx58tcueZRU"],1]],[2,"79L2MJsnFGUaq/BdvWM9hZ",null,null,null,1,0]],[3,"text_value",33554432,1,[[1,-11,[0,"47qYAsz7xPZI29fmlQYUw9"],[5,9.2529296875,88.2]],[4,"-",25,25,70,false,-12,[0,"87gluk09JAI6cY7pLm0oQU"],2]],[2,"81s2Ftd3NEhJ2WrGgH4/Cz",null,null,null,1,0],[1,124.929,0,0]]],0,[0,2,1,0,0,1,0,0,1,0,-1,2,0,-2,3,0,-3,4,0,0,2,0,0,2,0,0,3,0,0,3,0,0,4,0,0,4,0,3,1,12],[0,0,0,0],[1,1,1,4],[0,0,0,1]],[[[10,"dreamhanserifexpcn-w12","dreamhanserifexpcn-w12.ttf"],-1],0,0,[],[],[]]]]

+ 1 - 1
build/web-mobile/assets/main/import/06/067a91548.json → build/web-mobile/assets/main/import/02/02e42bcdb.json

@@ -1 +1 @@
-{"type":"cc.Texture2D","data":[["2,2,2,2,0,0",["9f2QDdIhtPiY8s+6NCQ8g1"]],["2,2,0,0,0,0",["13e0d1faa"]],["2,2,2,2,0,0",["24pwTaKGdEbY0aXpIMdeCd"]],["2,2,2,2,0,0",["37jgHmh2xFaJsKI3o99zJC"]],["2,2,2,2,0,0",["54TknWPwVPqJqeCR+Y/Czo"]],["2,2,2,2,0,0",["20g1ukYUVPvKWKBRznAKo+"]],["2,2,2,2,0,0",["95EkngnxZFbYuFpsqVTaFr"]],["2,2,2,2,0,0",["abNjRqDNZIYqjp4Ghn1Vht"]],["2,2,2,2,0,0",["e2WvMWNDVEwKYtHPMemyZO"]]]}
+{"type":"cc.Texture2D","data":[["2,2,2,2,0,0",["9f2QDdIhtPiY8s+6NCQ8g1"]],["2,2,0,0,0,0",["13e0d1faa"]],["2,2,2,2,0,0",["24pwTaKGdEbY0aXpIMdeCd"]],["2,2,2,2,0,0",["37jgHmh2xFaJsKI3o99zJC"]],["2,2,2,2,0,0",["54TknWPwVPqJqeCR+Y/Czo"]],["2,2,2,2,0,0",["20g1ukYUVPvKWKBRznAKo+"]],["2,2,2,2,0,0",["95EkngnxZFbYuFpsqVTaFr"]],["2,2,2,2,0,0",["abNjRqDNZIYqjp4Ghn1Vht"]],["2,2,2,2,0,0",["afxHkx8GZGsJC+n+YfITQo"]],["2,2,2,2,0,0",["e2WvMWNDVEwKYtHPMemyZO"]],["2,2,2,2,0,0",["ffuIqPr2JI9I8dPLYGRDpD"]]]}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
build/web-mobile/assets/main/import/02/02ffc6d83.json


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 0
build/web-mobile/assets/main/import/04/04577c584.json


+ 1 - 0
build/web-mobile/assets/main/import/af/afc47931-f066-46b0-90be-9fe61f213428.json

@@ -0,0 +1 @@
+[1,0,0,["cc.ImageAsset"],0,[{"fmt":"0","w":0,"h":0},-1],[0],0,[],[],[]]

+ 1 - 0
build/web-mobile/assets/main/import/ff/ffb88a8f-af62-48f4-8f1d-3cb606443a43.json

@@ -0,0 +1 @@
+[1,0,0,["cc.ImageAsset"],0,[{"fmt":"0","w":0,"h":0},-1],[0],0,[],[],[]]

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1 - 1
build/web-mobile/assets/main/index.js


binární
build/web-mobile/assets/main/native/af/afc47931-f066-46b0-90be-9fe61f213428.png


binární
build/web-mobile/assets/main/native/ff/ffb88a8f-af62-48f4-8f1d-3cb606443a43.png


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