Compare commits
84 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5c611b626d | ||
|
38149279bd | ||
|
a762c563d9 | ||
|
6a0d729dee | ||
|
f10389bf55 | ||
|
6b3d1ed49a | ||
|
d25bb5ff10 | ||
|
d38d4b4ec9 | ||
|
03828db6ff | ||
|
917fca2bcd | ||
|
680e4f1f59 | ||
|
f367609276 | ||
|
70ae4a4c92 | ||
|
6f561bea87 | ||
|
70a86c27b0 | ||
|
b0f37d2237 | ||
|
09376b827d | ||
|
d560392c79 | ||
|
c75f642011 | ||
|
5cfcac6cf6 | ||
|
d37ebd4c33 | ||
|
1d138b17c3 | ||
|
851678e2f3 | ||
|
2fb6fd6bea | ||
|
e3440a2a06 | ||
|
8de2d6e4e7 | ||
|
ba2dd0b22e | ||
|
754610d31b | ||
|
a35de9b83c | ||
|
2b6cb57050 | ||
|
677e76179c | ||
|
c65c122f45 | ||
|
b5530b352b | ||
|
4e638fb2ec | ||
|
7c454130db | ||
|
5863f88435 | ||
|
bbf07fe518 | ||
|
26660d75d2 | ||
|
76cdbc8f1f | ||
|
4097a8da75 | ||
|
e7bf6ec16b | ||
|
7ab983949c | ||
|
2028f8277d | ||
|
60bb74169e | ||
|
8536521136 | ||
|
5df545e168 | ||
|
6bc3feab58 | ||
|
e21e1b840f | ||
|
ef345e0e48 | ||
|
0168e2182e | ||
|
58b06f6a10 | ||
|
58e60a789f | ||
|
b5b43bb596 | ||
|
59767c1ed5 | ||
|
1c6ad5c8f8 | ||
|
34e0893eb8 | ||
|
cc7524becd | ||
|
d06cb18a08 | ||
|
00816fb636 | ||
|
ff24bea055 | ||
|
56d66a128a | ||
|
2f097dfec5 | ||
|
ff48b47ecc | ||
|
7a0127b17d | ||
|
59c8427c70 | ||
|
c357ebad3b | ||
|
b2e1f7c2a6 | ||
|
9a8c32197e | ||
|
a82a238ce9 | ||
|
5b76c5bbfb | ||
|
b81c470135 | ||
|
48074d48af | ||
|
342efc623c | ||
|
b8e757064d | ||
|
71b9e72592 | ||
|
21b48b7c0d | ||
|
fbfca965e6 | ||
|
b27b567c77 | ||
|
e9119530f1 | ||
|
e6a4295773 | ||
|
aa14529bf8 | ||
|
84af0d1572 | ||
|
16fb23c376 | ||
|
d1f8a58154 |
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
.vs
|
||||||
|
**/.vs
|
||||||
battle_srv/test_cases/test_cases
|
battle_srv/test_cases/test_cases
|
||||||
battle_srv/test_cases/tests
|
battle_srv/test_cases/tests
|
||||||
*.pid
|
*.pid
|
||||||
|
@@ -47,3 +47,32 @@ renderFrameId | toApplyInputFrameId
|
|||||||
..., ..., ..., 368 | 90
|
..., ..., ..., 368 | 90
|
||||||
369, 370, 371, 372 | 91
|
369, 370, 371, 372 | 91
|
||||||
373, 374, 375, ... | 92
|
373, 374, 375, ... | 92
|
||||||
|
|
||||||
|
# Would using UDP instead of TCP yield better synchronization performance?
|
||||||
|
Yes, but with non-trivial efforts.
|
||||||
|
|
||||||
|
## Neat advantage using UDP
|
||||||
|
Let's check an actual use case. As soon as an inputFrame becomes all-confirmed, the server should downsync it to all active players -- and upon reception loss of the packet containing this "all-confirmed downsync inputFrame" to a certain player, the server MUST retransmit another packet containing the same inputFrame to that player.
|
||||||
|
|
||||||
|
To apply UDP on this use case, additional `ack & retransmission mechanism` would be required, which is a moderately difficult task -- don't just pick a 3rd party lib using TCP flow-control alike `sliding window mechanism`, e.g. [RUDP](https://www.geeksforgeeks.org/reliable-user-datagram-protocol-rudp/)! Here's why.
|
||||||
|
|
||||||
|
Assume that the server is downsyncing `sequence of packets[#1, #2, #3, #4, #5, #6, #7, #8, #9, #10]`, when using TCP we get the advantage that each active player is guaranteed to receive that same sequence in the same order -- however in a bad, lossy network when `packet#2` got lost several times for a certain player whose reception window size is just 5, it has to wait for the arrival of `packet#2` at `[_, #3, #4, #5, #6]`, thus unable to process `[#7, #8, #9, #10]` which could contain `unpredictable inputFrame` while `#2` being `correct prediction` for that player.
|
||||||
|
|
||||||
|
That's so neat but still an advantage for using UDP! Yet if the TCP flow-control alike `sliding window mechanism` is employed on UDP, such advantage'd be compromised.
|
||||||
|
|
||||||
|
To summarize, if UDP is used we need
|
||||||
|
- an `ack & retransmission mechanism` built on top of it to guarantee reception of critical packets for active players, and
|
||||||
|
- reception order is not necessary to be reserved (mimic [markConfirmationIfApplicable](https://github.com/genxium/DelayNoMore/blob/v0.9.14/battle_srv/models/room.go#L1085) to maintain `lastAllConfirmedInputFrameId`), but
|
||||||
|
- TCP flow-control alike `sliding window mechanism` should be avoided to gain advantage over TCP.
|
||||||
|
|
||||||
|
## Additional hassles to care about using UDP
|
||||||
|
When using UDP, it's also necessary to verify authorization of each incoming packet, e.g. by simple time limited symmetric key, due to being connectionless.
|
||||||
|
|
||||||
|
## Why not hybrid?
|
||||||
|
Instead of replacing all use of TCP by UDP, it's more reasonable to keep using TCP for login and the "all-confirmed downsync inputFrames" from server to players (and possibly "upsync inputFrames" from player to server, but tradeoff on that remains to be discussed), while using a `UDP secondary session` for broadcasting inputFrames of each individual player asap (either using p2p or not) just for **better prediction performance**!
|
||||||
|
|
||||||
|
## How do you actually implement the `UDP secondary session`?
|
||||||
|
It's not a global consensus, but in practice many UDP communications are platform specific due to their paired asynchronous I/O choices, e.g. epoll in Linux and kqueue in BSD-ish. Of course there're many 3rd party higher level encapsulated tools for cross-platform use but that introduces extra debugging when things go wrong.
|
||||||
|
|
||||||
|
Therefore, the following plan doesn't assume use of any specific 3rd party encapsulation of UDP communication.
|
||||||
|

|
69
README.md
@@ -2,18 +2,21 @@
|
|||||||
|
|
||||||
This project is a demo for a websocket-based rollback netcode inspired by [GGPO](https://github.com/pond3r/ggpo/blob/master/doc/README.md).
|
This project is a demo for a websocket-based rollback netcode inspired by [GGPO](https://github.com/pond3r/ggpo/blob/master/doc/README.md).
|
||||||
|
|
||||||
_(the following gifs are sped up to ~1.5x for file size reduction, kindly note that animations are resumed from a partial progress)_
|
[Demo recorded over INTERNET (Phone-Wifi v.s. PC-Wifi UDP holepunched) using an input delay of 6 frames](https://pan.baidu.com/s/1UArwqDShLoPjYppjjqsTqQ?pwd=10wc), and it feels SMOOTH when playing!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|
As lots of feedbacks ask for a discussion on using UDP instead, I tried to summarize my personal opinion about it in [ConcerningEdgeCases](./ConcerningEdgeCases.md) -- **since v0.9.25, the project is actually equipped with UDP capabilities as follows**.
|
||||||
|
- When using the so called `native apps` on `Android` and `Windows` (I'm working casually hard to support `iOS` next), the frontends will try to use UDP hole-punching w/ the help of backend as a registry. If UDP hole-punching is working, the rollback is often less than `turn-around frames to recover` and thus not noticeable, being much better than using websocket alone. This video shows how the UDP holepunched p2p performs for [Phone-Wifi v.s. PC-Wifi (viewed by PC side)](https://pan.baidu.com/s/1K6704bJKlrSBTVqGcXhajA?pwd=l7ok).
|
||||||
|
- If UDP hole-punching is not working, e.g. for Symmetric NAT like in 4G/5G cellular network, the frontends will use backend as a UDP tunnel (or relay, whatever you like to call it). This video shows how the UDP tunnel performs for [Phone-4G v.s. PC-Wifi (viewed by PC side)](https://pan.baidu.com/s/1IZVa5wVgAdeH6D-xsZYFUw?pwd=dgkj).
|
||||||
|
- Browser vs `native app` is possible but in that case only websocket is used.
|
||||||
|
|
||||||
Please also checkout [this demo video](https://pan.baidu.com/s/1_DAEuE66s5Obf2GwtVul4Q?pwd=mfpq) to see how this demo carries out a full 60fps synchronization with the help of _batched input upsync/downsync_ for satisfying network I/O performance.
|
|
||||||
|
|
||||||
The video mainly shows the following features.
|
# Notable Features
|
||||||
- The backend receives inputs from frontend peers and broadcasts back for synchronization.
|
- Backend dynamics toggle via [Room.BackendDynamicsEnabled](https://github.com/genxium/DelayNoMore/blob/v0.9.14/battle_srv/models/room.go#L786)
|
||||||
- The game is recovered for a player upon reconnection.
|
- Recovery upon reconnection (only if backend dynamics is ON)
|
||||||
- Both backend(Golang) and frontend(JavaScript) execute collision detection and handle collision contacts by the same algorithm. The backend dynamics is togglable by [Room.BackendDynamicsEnabled](https://github.com/genxium/DelayNoMore/blob/v0.5.2/battle_srv/models/room.go#L813), but **when turned off the game couldn't support recovery upon reconnection**.
|
- Automatically correction for "slow ticker", especially "active slow ticker" which is well-known to be a headache for input synchronization
|
||||||
|
- Frame data logging toggle for both frontend & backend, useful for debugging out of sync entities when developing new features
|
||||||
|
|
||||||
_(how input delay roughly works)_
|
_(how input delay roughly works)_
|
||||||
|
|
||||||
@@ -21,7 +24,10 @@ _(how input delay roughly works)_
|
|||||||
|
|
||||||
_(how rollback-and-chase in this project roughly works)_
|
_(how rollback-and-chase in this project roughly works)_
|
||||||
|
|
||||||
|

|
||||||

|

|
||||||
|
|
||||||
|
(By use of [GopherJs](https://github.com/gopherjs/gopherjs), the frontend codes for dynamics are now automatically generated)
|
||||||

|

|
||||||
|
|
||||||
# 1. Building & running
|
# 1. Building & running
|
||||||
@@ -63,7 +69,7 @@ user@proj-root/battle_srv/configs> cp -r ./configs.template ./configs
|
|||||||
user@proj-root/frontend/assets/plugin_scripts> cp ./conf.js.template ./conf.js
|
user@proj-root/frontend/assets/plugin_scripts> cp ./conf.js.template ./conf.js
|
||||||
```
|
```
|
||||||
|
|
||||||
## 1.2 Actual building & running
|
## 1.3 Actual building & running
|
||||||
### Backend
|
### Backend
|
||||||
```
|
```
|
||||||
### The following command runs mysql-server in foreground, it's almost NEVER run in such a way, please find a proper way to run it for yourself
|
### The following command runs mysql-server in foreground, it's almost NEVER run in such a way, please find a proper way to run it for yourself
|
||||||
@@ -92,3 +98,48 @@ ErrFatal {"err": "MISCONF Redis is configured to save RDB snapshots, but
|
|||||||
```
|
```
|
||||||
|
|
||||||
Just restart your `redis-server` process.
|
Just restart your `redis-server` process.
|
||||||
|
|
||||||
|
### 2.2 Why not show "PING value" on frontend display?
|
||||||
|
The most important reason for not showing "PING value" is simple: in most games the "PING value" is collected by a dedicated kernel thread which doesn't interfere the UI thread or the primary networking thread. As this demo primarily runs on browser by far, I don't have this capability easily.
|
||||||
|
|
||||||
|
Moreover, in practice I found that to spot sync anomalies, the following tools are much more useful than the "PING VALUE".
|
||||||
|
- Detection of [prediction mismatch on the frontend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/frontend/assets/scripts/Map.js#L842).
|
||||||
|
- Detection of [type#1 forceConfirmation on the backend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/battle_srv/models/room.go#L1246).
|
||||||
|
- Detection of [type#2 forceConfirmation on the backend](https://github.com/genxium/DelayNoMore/blob/v0.9.19/battle_srv/models/room.go#L1259).
|
||||||
|
|
||||||
|
There's also some useful information displayed on the frontend when `true == Map.showNetworkDoctorInfo`.
|
||||||
|

|
||||||
|
|
||||||
|
### 2.3 WIN32 platform tool versioning
|
||||||
|

|
||||||
|
When building for native platforms, it's much more convenient to trigger the CocosCreator project forming frmo CLI, e.g.
|
||||||
|
```
|
||||||
|
shell> cd <proj-root>
|
||||||
|
shell> /path/to/CocosCreator.exe --path ./frontend --build "platform=win32;debug=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 CococCreator native build reloading
|
||||||
|
CocosCreator doesn't have perfect file cache management during native project building, use "Developer Tools > Reload" to reset the IDE status upon mysterious errors.
|
||||||
|

|
||||||
|
|
||||||
|
Another issue is with the package name, see the screenshot below, kindly note that after successfully building with a blank package name, you can then re-fill the desired package name and build again!
|
||||||
|

|
||||||
|
|
||||||
|
### 2.5 Checking UDP port binding result
|
||||||
|
__*nix__
|
||||||
|
```
|
||||||
|
netstat -anp | grep <your_port>
|
||||||
|
```
|
||||||
|
|
||||||
|
__Windows__
|
||||||
|
```
|
||||||
|
netstat -ano | grep <your_port>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.6 Checking native code crash on non-rooted Android phone
|
||||||
|
```
|
||||||
|
DeveloperOs> adb bugreport ./logs.zip
|
||||||
|
# The file "logs.zip" will be automatically pulled to current folder of the DeveloperOS, copy "logs/FS/data/tomestones" out of the zip, then use the binary "$NDK_ROOT/ndk-stack" to analyze whichever tombstone you're interested in, for example, I often use the following
|
||||||
|
DeveloperOs> ${NDK_ROOT}/ndk-stack.cmd -sym \path\to\DelayNoMore\frontend\build\jsb-link\frameworks\runtime-src\proj.android-studio\app\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a -dump \path\to\tombstones\tombstone_03
|
||||||
|
# The param "-sym \path\to\objs" tells "ndk-stack" to decode "tombstone_03" with symbols provided by all the files inside that "\path\to\objs".
|
||||||
|
```
|
||||||
|
@@ -37,6 +37,8 @@ type mysqlConf struct {
|
|||||||
|
|
||||||
type sioConf struct {
|
type sioConf struct {
|
||||||
HostAndPort string `json:"hostAndPort"`
|
HostAndPort string `json:"hostAndPort"`
|
||||||
|
UdpHost string `json:"udpHost"`
|
||||||
|
UdpPort int `json:"udpPort"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type botServerConf struct {
|
type botServerConf struct {
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"hostAndPort": "0.0.0.0:9992"
|
"hostAndPort": "0.0.0.0:9992",
|
||||||
|
"udpHost": "0.0.0.0",
|
||||||
|
"udpPort": 3000
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/robfig/cron"
|
"github.com/robfig/cron"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -34,7 +36,7 @@ func main() {
|
|||||||
env_tools.MergeTestPlayerAccounts()
|
env_tools.MergeTestPlayerAccounts()
|
||||||
}
|
}
|
||||||
models.InitRoomHeapManager()
|
models.InitRoomHeapManager()
|
||||||
startScheduler()
|
// startScheduler()
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
setRouter(router)
|
setRouter(router)
|
||||||
|
|
||||||
@@ -54,6 +56,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
Logger.Info("Listening and serving HTTP on", zap.Any("Conf.Sio.HostAndPort", Conf.Sio.HostAndPort))
|
Logger.Info("Listening and serving HTTP on", zap.Any("Conf.Sio.HostAndPort", Conf.Sio.HostAndPort))
|
||||||
}()
|
}()
|
||||||
|
go startGrandUdpServer()
|
||||||
var gracefulStop = make(chan os.Signal)
|
var gracefulStop = make(chan os.Signal)
|
||||||
signal.Notify(gracefulStop, syscall.SIGTERM)
|
signal.Notify(gracefulStop, syscall.SIGTERM)
|
||||||
signal.Notify(gracefulStop, syscall.SIGINT)
|
signal.Notify(gracefulStop, syscall.SIGINT)
|
||||||
@@ -89,6 +92,7 @@ func setRouter(router *gin.Engine) {
|
|||||||
router.StaticFS("/asset", http.Dir(filepath.Join(Conf.General.AppRoot, "asset")))
|
router.StaticFS("/asset", http.Dir(filepath.Join(Conf.General.AppRoot, "asset")))
|
||||||
router.GET("/ping", f)
|
router.GET("/ping", f)
|
||||||
router.GET("/tsrht", ws.Serve)
|
router.GET("/tsrht", ws.Serve)
|
||||||
|
router.GET("/tsrhtSecondary", ws.HandleSecondaryWsSessionForPlayer)
|
||||||
|
|
||||||
apiRouter := router.Group("/api")
|
apiRouter := router.Group("/api")
|
||||||
{
|
{
|
||||||
@@ -113,3 +117,33 @@ func startScheduler() {
|
|||||||
//c.AddFunc("*/1 * * * * *", FuncName)
|
//c.AddFunc("*/1 * * * * *", FuncName)
|
||||||
c.Start()
|
c.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func startGrandUdpServer() {
|
||||||
|
conn, err := net.ListenUDP("udp", &net.UDPAddr{
|
||||||
|
Port: Conf.Sio.UdpPort,
|
||||||
|
IP: net.ParseIP(Conf.Sio.UdpHost),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
conn.Close()
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
Logger.Error("`GrandUdpServer`, recovery spot#1, recovered from: ", zap.Any("panic", r))
|
||||||
|
}
|
||||||
|
Logger.Info(fmt.Sprintf("The `GrandUdpServer` is stopped"))
|
||||||
|
}()
|
||||||
|
|
||||||
|
Logger.Info(fmt.Sprintf("`GrandUdpServer` started at %s", conn.LocalAddr().String()))
|
||||||
|
|
||||||
|
for {
|
||||||
|
message := make([]byte, 2046)
|
||||||
|
rlen, remote, err := conn.ReadFromUDP(message[:])
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
Logger.Info(fmt.Sprintf("`GrandUdpServer` received: %d bytes from %s\n", rlen, remote))
|
||||||
|
ws.HandleUdpHolePunchingForPlayer(message[0:rlen], remote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -41,11 +41,14 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
|
|||||||
OnWall: last.OnWall,
|
OnWall: last.OnWall,
|
||||||
OnWallNormX: last.OnWallNormX,
|
OnWallNormX: last.OnWallNormX,
|
||||||
OnWallNormY: last.OnWallNormY,
|
OnWallNormY: last.OnWallNormY,
|
||||||
|
CapturedByInertia: last.CapturedByInertia,
|
||||||
JoinIndex: last.JoinIndex,
|
JoinIndex: last.JoinIndex,
|
||||||
BulletTeamId: last.BulletTeamId,
|
BulletTeamId: last.BulletTeamId,
|
||||||
ChCollisionTeamId: last.ChCollisionTeamId,
|
ChCollisionTeamId: last.ChCollisionTeamId,
|
||||||
Hp: last.Hp,
|
Hp: last.Hp,
|
||||||
MaxHp: last.MaxHp,
|
MaxHp: last.MaxHp,
|
||||||
|
RevivalVirtualGridX: last.RevivalVirtualGridX,
|
||||||
|
RevivalVirtualGridY: last.RevivalVirtualGridY,
|
||||||
ColliderRadius: last.ColliderRadius,
|
ColliderRadius: last.ColliderRadius,
|
||||||
Score: last.Score,
|
Score: last.Score,
|
||||||
Removed: last.Removed,
|
Removed: last.Removed,
|
||||||
@@ -80,6 +83,12 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
|
|||||||
HitboxSizeY: last.Bullet.HitboxSizeY,
|
HitboxSizeY: last.Bullet.HitboxSizeY,
|
||||||
|
|
||||||
BlowUp: last.Bullet.BlowUp,
|
BlowUp: last.Bullet.BlowUp,
|
||||||
|
|
||||||
|
SpeciesId: last.Bullet.SpeciesId,
|
||||||
|
ExplosionFrames: last.Bullet.ExplosionFrames,
|
||||||
|
|
||||||
|
BlState: last.BlState,
|
||||||
|
FramesInBlState: last.FramesInBlState,
|
||||||
}
|
}
|
||||||
ret.MeleeBullets[i] = pbBullet
|
ret.MeleeBullets[i] = pbBullet
|
||||||
}
|
}
|
||||||
@@ -112,6 +121,12 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
|
|||||||
|
|
||||||
BlowUp: last.Bullet.BlowUp,
|
BlowUp: last.Bullet.BlowUp,
|
||||||
|
|
||||||
|
SpeciesId: last.Bullet.SpeciesId,
|
||||||
|
ExplosionFrames: last.Bullet.ExplosionFrames,
|
||||||
|
|
||||||
|
BlState: last.BlState,
|
||||||
|
FramesInBlState: last.FramesInBlState,
|
||||||
|
|
||||||
VirtualGridX: last.VirtualGridX,
|
VirtualGridX: last.VirtualGridX,
|
||||||
VirtualGridY: last.VirtualGridY,
|
VirtualGridY: last.VirtualGridY,
|
||||||
DirX: last.DirX,
|
DirX: last.DirX,
|
||||||
@@ -119,7 +134,6 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
|
|||||||
VelX: last.VelX,
|
VelX: last.VelX,
|
||||||
VelY: last.VelY,
|
VelY: last.VelY,
|
||||||
Speed: last.Speed,
|
Speed: last.Speed,
|
||||||
SpeciesId: last.SpeciesId,
|
|
||||||
}
|
}
|
||||||
ret.FireballBullets[i] = pbBullet
|
ret.FireballBullets[i] = pbBullet
|
||||||
}
|
}
|
||||||
@@ -154,9 +168,14 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
|
|||||||
OnWall: last.OnWall,
|
OnWall: last.OnWall,
|
||||||
OnWallNormX: last.OnWallNormX,
|
OnWallNormX: last.OnWallNormX,
|
||||||
OnWallNormY: last.OnWallNormY,
|
OnWallNormY: last.OnWallNormY,
|
||||||
|
CapturedByInertia: last.CapturedByInertia,
|
||||||
JoinIndex: last.JoinIndex,
|
JoinIndex: last.JoinIndex,
|
||||||
BulletTeamId: last.BulletTeamId,
|
BulletTeamId: last.BulletTeamId,
|
||||||
ChCollisionTeamId: last.ChCollisionTeamId,
|
ChCollisionTeamId: last.ChCollisionTeamId,
|
||||||
|
Hp: last.Hp,
|
||||||
|
MaxHp: last.MaxHp,
|
||||||
|
RevivalVirtualGridX: last.RevivalVirtualGridX,
|
||||||
|
RevivalVirtualGridY: last.RevivalVirtualGridY,
|
||||||
ColliderRadius: last.ColliderRadius,
|
ColliderRadius: last.ColliderRadius,
|
||||||
Score: last.Score,
|
Score: last.Score,
|
||||||
Removed: last.Removed,
|
Removed: last.Removed,
|
||||||
@@ -200,11 +219,14 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
|
|||||||
ChCollisionTeamId: last.ChCollisionTeamId,
|
ChCollisionTeamId: last.ChCollisionTeamId,
|
||||||
Hp: last.Hp,
|
Hp: last.Hp,
|
||||||
MaxHp: last.MaxHp,
|
MaxHp: last.MaxHp,
|
||||||
|
RevivalVirtualGridX: last.RevivalVirtualGridX,
|
||||||
|
RevivalVirtualGridY: last.RevivalVirtualGridY,
|
||||||
ColliderRadius: last.ColliderRadius,
|
ColliderRadius: last.ColliderRadius,
|
||||||
InAir: last.InAir,
|
InAir: last.InAir,
|
||||||
OnWall: last.OnWall,
|
OnWall: last.OnWall,
|
||||||
OnWallNormX: last.OnWallNormX,
|
OnWallNormX: last.OnWallNormX,
|
||||||
OnWallNormY: last.OnWallNormY,
|
OnWallNormY: last.OnWallNormY,
|
||||||
|
CapturedByInertia: last.CapturedByInertia,
|
||||||
Score: last.Score,
|
Score: last.Score,
|
||||||
Removed: last.Removed,
|
Removed: last.Removed,
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
sq "github.com/Masterminds/squirrel"
|
sq "github.com/Masterminds/squirrel"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PlayerBattleState struct {
|
type PlayerBattleState struct {
|
||||||
@@ -47,9 +48,14 @@ type Player struct {
|
|||||||
|
|
||||||
// other in-battle info fields
|
// other in-battle info fields
|
||||||
LastReceivedInputFrameId int32
|
LastReceivedInputFrameId int32
|
||||||
|
LastUdpReceivedInputFrameId int32
|
||||||
LastSentInputFrameId int32
|
LastSentInputFrameId int32
|
||||||
AckingFrameId int32
|
AckingFrameId int32
|
||||||
AckingInputFrameId int32
|
AckingInputFrameId int32
|
||||||
|
|
||||||
|
UdpAddr *PeerUdpAddr
|
||||||
|
BattleUdpTunnelAddr *net.UDPAddr // This addr is used by backend only, not visible to frontend
|
||||||
|
BattleUdpTunnelAuthKey int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExistPlayerByName(name string) (bool, error) {
|
func ExistPlayerByName(name string) (bool, error) {
|
||||||
|
@@ -13,6 +13,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"jsexport/battle"
|
"jsexport/battle"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"resolv"
|
"resolv"
|
||||||
@@ -31,6 +32,8 @@ const (
|
|||||||
DOWNSYNC_MSG_ACT_INPUT_BATCH = int32(2)
|
DOWNSYNC_MSG_ACT_INPUT_BATCH = int32(2)
|
||||||
DOWNSYNC_MSG_ACT_BATTLE_STOPPED = int32(3)
|
DOWNSYNC_MSG_ACT_BATTLE_STOPPED = int32(3)
|
||||||
DOWNSYNC_MSG_ACT_FORCED_RESYNC = int32(4)
|
DOWNSYNC_MSG_ACT_FORCED_RESYNC = int32(4)
|
||||||
|
DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH = int32(5)
|
||||||
|
DOWNSYNC_MSG_ACT_PEER_UDP_ADDR = int32(6)
|
||||||
|
|
||||||
DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START = int32(-1)
|
DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START = int32(-1)
|
||||||
DOWNSYNC_MSG_ACT_BATTLE_START = int32(0)
|
DOWNSYNC_MSG_ACT_BATTLE_START = int32(0)
|
||||||
@@ -117,9 +120,14 @@ type Room struct {
|
|||||||
* Moreover, during the invocation of `PlayerSignalToCloseDict`, the `Player` instance is supposed to be deallocated (though not synchronously).
|
* Moreover, during the invocation of `PlayerSignalToCloseDict`, the `Player` instance is supposed to be deallocated (though not synchronously).
|
||||||
*/
|
*/
|
||||||
PlayerDownsyncSessionDict map[int32]*websocket.Conn
|
PlayerDownsyncSessionDict map[int32]*websocket.Conn
|
||||||
PlayerDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
|
|
||||||
PlayerActiveWatchdogDict map[int32](*Watchdog)
|
|
||||||
PlayerSignalToCloseDict map[int32]SignalToCloseConnCbType
|
PlayerSignalToCloseDict map[int32]SignalToCloseConnCbType
|
||||||
|
PlayerDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
|
||||||
|
|
||||||
|
PlayerSecondaryDownsyncSessionDict map[int32]*websocket.Conn
|
||||||
|
PlayerSecondarySignalToCloseDict map[int32]SignalToCloseConnCbType
|
||||||
|
PlayerSecondaryDownsyncChanDict map[int32](chan pb.InputsBufferSnapshot)
|
||||||
|
|
||||||
|
PlayerActiveWatchdogDict map[int32](*Watchdog)
|
||||||
Score float32
|
Score float32
|
||||||
State int32
|
State int32
|
||||||
Index int
|
Index int
|
||||||
@@ -128,7 +136,7 @@ type Room struct {
|
|||||||
EffectivePlayerCount int32
|
EffectivePlayerCount int32
|
||||||
DismissalWaitGroup sync.WaitGroup
|
DismissalWaitGroup sync.WaitGroup
|
||||||
InputsBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
|
InputsBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
|
||||||
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputList, player.LastReceivedInputFrameId]
|
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputList, player.LastReceivedInputFrameId, player.LastUdpReceivedInputFrameId]
|
||||||
RenderFrameBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
|
RenderFrameBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
|
||||||
LatestPlayerUpsyncedInputFrameId int32
|
LatestPlayerUpsyncedInputFrameId int32
|
||||||
LastAllConfirmedInputFrameId int32
|
LastAllConfirmedInputFrameId int32
|
||||||
@@ -150,6 +158,10 @@ type Room struct {
|
|||||||
|
|
||||||
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
|
||||||
LastIndividuallyConfirmedInputList []uint64
|
LastIndividuallyConfirmedInputList []uint64
|
||||||
|
|
||||||
|
BattleUdpTunnelLock sync.Mutex
|
||||||
|
BattleUdpTunnelAddr *pb.PeerUdpAddr
|
||||||
|
BattleUdpTunnel *net.UDPConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) updateScore() {
|
func (pR *Room) updateScore() {
|
||||||
@@ -170,10 +182,14 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
|
|||||||
|
|
||||||
defer pR.onPlayerAdded(playerId)
|
defer pR.onPlayerAdded(playerId)
|
||||||
|
|
||||||
|
pPlayerFromDbInit.UdpAddr = nil
|
||||||
|
pPlayerFromDbInit.BattleUdpTunnelAddr = nil
|
||||||
|
pPlayerFromDbInit.BattleUdpTunnelAuthKey = rand.Int31()
|
||||||
pPlayerFromDbInit.AckingFrameId = -1
|
pPlayerFromDbInit.AckingFrameId = -1
|
||||||
pPlayerFromDbInit.AckingInputFrameId = -1
|
pPlayerFromDbInit.AckingInputFrameId = -1
|
||||||
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
pPlayerFromDbInit.LastReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
pPlayerFromDbInit.LastReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
|
pPlayerFromDbInit.LastUdpReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
|
||||||
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
|
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
|
||||||
|
|
||||||
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||||
@@ -184,7 +200,7 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
|
|||||||
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
||||||
newWatchdog := NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
|
newWatchdog := NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
|
||||||
Logger.Warn("Conn inactive watchdog triggered#1:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
|
Logger.Warn("Conn inactive watchdog triggered#1:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
|
||||||
signalToCloseConnOfThisPlayer(Constants.RetCode.ActiveWatchdog, "")
|
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.ActiveWatchdog)
|
||||||
})
|
})
|
||||||
newWatchdog.Stop()
|
newWatchdog.Stop()
|
||||||
pR.PlayerActiveWatchdogDict[playerId] = newWatchdog
|
pR.PlayerActiveWatchdogDict[playerId] = newWatchdog
|
||||||
@@ -209,9 +225,13 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
|
|||||||
*/
|
*/
|
||||||
defer pR.onPlayerReAdded(playerId)
|
defer pR.onPlayerReAdded(playerId)
|
||||||
pEffectiveInRoomPlayerInstance := pR.Players[playerId]
|
pEffectiveInRoomPlayerInstance := pR.Players[playerId]
|
||||||
|
pEffectiveInRoomPlayerInstance.UdpAddr = nil
|
||||||
|
pEffectiveInRoomPlayerInstance.BattleUdpTunnelAddr = nil
|
||||||
|
pEffectiveInRoomPlayerInstance.BattleUdpTunnelAuthKey = rand.Int31()
|
||||||
pEffectiveInRoomPlayerInstance.AckingFrameId = -1
|
pEffectiveInRoomPlayerInstance.AckingFrameId = -1
|
||||||
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
|
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
|
||||||
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
|
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
|
||||||
|
// [WARNING] DON'T reset "player.LastReceivedInputFrameId" & "player.LastUdpReceivedInputFrameId" upon reconnection!
|
||||||
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
|
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
|
||||||
|
|
||||||
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
|
||||||
@@ -221,7 +241,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
|
|||||||
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
pR.PlayerSignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
||||||
pR.PlayerActiveWatchdogDict[playerId] = NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
|
pR.PlayerActiveWatchdogDict[playerId] = NewWatchdog(ConstVals.Ws.WillKickIfInactiveFor, func() {
|
||||||
Logger.Warn("Conn inactive watchdog triggered#2:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
|
Logger.Warn("Conn inactive watchdog triggered#2:", zap.Any("playerId", playerId), zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount))
|
||||||
signalToCloseConnOfThisPlayer(Constants.RetCode.ActiveWatchdog, "")
|
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.ActiveWatchdog)
|
||||||
}) // For ReAdded player the new watchdog starts immediately
|
}) // For ReAdded player the new watchdog starts immediately
|
||||||
|
|
||||||
Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("joinIndex", pEffectiveInRoomPlayerInstance.JoinIndex), zap.Any("playerBattleState", pEffectiveInRoomPlayerInstance.BattleState), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId), zap.Any("LastSentInputFrameId", pEffectiveInRoomPlayerInstance.LastSentInputFrameId))
|
Logger.Warn("ReAddPlayerIfPossible finished.", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("joinIndex", pEffectiveInRoomPlayerInstance.JoinIndex), zap.Any("playerBattleState", pEffectiveInRoomPlayerInstance.BattleState), zap.Any("roomState", pR.State), zap.Any("roomEffectivePlayerCount", pR.EffectivePlayerCount), zap.Any("AckingFrameId", pEffectiveInRoomPlayerInstance.AckingFrameId), zap.Any("AckingInputFrameId", pEffectiveInRoomPlayerInstance.AckingInputFrameId), zap.Any("LastSentInputFrameId", pEffectiveInRoomPlayerInstance.LastSentInputFrameId))
|
||||||
@@ -309,8 +329,8 @@ func (pR *Room) InputsBufferString(allDetails bool) string {
|
|||||||
// Appending of the array of strings can be very SLOW due to on-demand heap allocation! Use this printing with caution.
|
// Appending of the array of strings can be very SLOW due to on-demand heap allocation! Use this printing with caution.
|
||||||
s := make([]string, 0)
|
s := make([]string, 0)
|
||||||
s = append(s, fmt.Sprintf("{renderFrameId: %v, stInputFrameId: %v, edInputFrameId: %v, lastAllConfirmedInputFrameIdWithChange: %v, lastAllConfirmedInputFrameId: %v}", pR.RenderFrameId, pR.InputsBuffer.StFrameId, pR.InputsBuffer.EdFrameId, pR.LastAllConfirmedInputFrameIdWithChange, pR.LastAllConfirmedInputFrameId))
|
s = append(s, fmt.Sprintf("{renderFrameId: %v, stInputFrameId: %v, edInputFrameId: %v, lastAllConfirmedInputFrameIdWithChange: %v, lastAllConfirmedInputFrameId: %v}", pR.RenderFrameId, pR.InputsBuffer.StFrameId, pR.InputsBuffer.EdFrameId, pR.LastAllConfirmedInputFrameIdWithChange, pR.LastAllConfirmedInputFrameId))
|
||||||
for playerId, player := range pR.PlayersArr {
|
for _, player := range pR.PlayersArr {
|
||||||
s = append(s, fmt.Sprintf("{playerId: %v, ackingFrameId: %v, ackingInputFrameId: %v, lastSentInputFrameId: %v}", playerId, player.AckingFrameId, player.AckingInputFrameId, player.LastSentInputFrameId))
|
s = append(s, fmt.Sprintf("{playerId: %v, ackingFrameId: %v, ackingInputFrameId: %v, lastSentInputFrameId: %v}", player.Id, player.AckingFrameId, player.AckingInputFrameId, player.LastSentInputFrameId))
|
||||||
}
|
}
|
||||||
for i := pR.InputsBuffer.StFrameId; i < pR.InputsBuffer.EdFrameId; i++ {
|
for i := pR.InputsBuffer.StFrameId; i < pR.InputsBuffer.EdFrameId; i++ {
|
||||||
tmp := pR.InputsBuffer.GetByFrameId(i)
|
tmp := pR.InputsBuffer.GetByFrameId(i)
|
||||||
@@ -482,7 +502,7 @@ func (pR *Room) StartBattle() {
|
|||||||
kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame)
|
kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame)
|
||||||
pbKickOffRenderFrame := toPbRoomDownsyncFrame(kickoffFrameJs)
|
pbKickOffRenderFrame := toPbRoomDownsyncFrame(kickoffFrameJs)
|
||||||
pbKickOffRenderFrame.SpeciesIdList = pR.SpeciesIdList
|
pbKickOffRenderFrame.SpeciesIdList = pR.SpeciesIdList
|
||||||
pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
|
pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
}
|
}
|
||||||
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
|
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
|
||||||
}
|
}
|
||||||
@@ -509,7 +529,7 @@ func (pR *Room) StartBattle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
downsyncLoop := func(playerId int32, player *Player, playerDownsyncChan chan pb.InputsBufferSnapshot) {
|
downsyncLoop := func(playerId int32, player *Player, playerDownsyncChan chan pb.InputsBufferSnapshot, playerSecondaryDownsyncChan chan pb.InputsBufferSnapshot) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
Logger.Error("downsyncLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
|
Logger.Error("downsyncLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
|
||||||
@@ -517,19 +537,23 @@ func (pR *Room) StartBattle() {
|
|||||||
Logger.Info(fmt.Sprintf("The `downsyncLoop` for (roomId=%v, playerId=%v) is stopped@renderFrameId=%v", pR.Id, playerId, pR.RenderFrameId))
|
Logger.Info(fmt.Sprintf("The `downsyncLoop` for (roomId=%v, playerId=%v) is stopped@renderFrameId=%v", pR.Id, playerId, pR.RenderFrameId))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
Logger.Debug(fmt.Sprintf("Started downsyncLoop for (roomId: %d, playerId:%d, playerDownsyncChan:%p)", pR.Id, playerId, playerDownsyncChan))
|
//Logger.Info(fmt.Sprintf("Started downsyncLoop for (roomId: %d, playerId:%d, playerDownsyncChan:%p)", pR.Id, playerId, playerDownsyncChan))
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
|
||||||
case inputsBufferSnapshot := <-playerDownsyncChan:
|
|
||||||
nowBattleState := atomic.LoadInt32(&pR.State)
|
nowBattleState := atomic.LoadInt32(&pR.State)
|
||||||
switch nowBattleState {
|
switch nowBattleState {
|
||||||
case RoomBattleStateIns.IDLE, RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT, RoomBattleStateIns.IN_SETTLEMENT, RoomBattleStateIns.IN_DISMISSAL:
|
case RoomBattleStateIns.IDLE, RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT, RoomBattleStateIns.IN_SETTLEMENT, RoomBattleStateIns.IN_DISMISSAL:
|
||||||
Logger.Warn(fmt.Sprintf("Battle is not waiting/preparing/active for playerDownsyncChan for (roomId: %d, playerId:%d)", pR.Id, playerId))
|
Logger.Warn(fmt.Sprintf("Battle is not waiting/preparing/active for playerDownsyncChan for (roomId: %d, playerId:%d)", pR.Id, playerId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case inputsBufferSnapshot := <-playerDownsyncChan:
|
||||||
pR.downsyncToSinglePlayer(playerId, player, inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, inputsBufferSnapshot.ToSendInputFrameDownsyncs, inputsBufferSnapshot.ShouldForceResync)
|
pR.downsyncToSinglePlayer(playerId, player, inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, inputsBufferSnapshot.ToSendInputFrameDownsyncs, inputsBufferSnapshot.ShouldForceResync)
|
||||||
//Logger.Info(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d)#2", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId))
|
//Logger.Info(fmt.Sprintf("Sent inputsBufferSnapshot(refRenderFrameId:%d, unconfirmedMask:%v) to for (roomId: %d, playerId:%d)#2", inputsBufferSnapshot.RefRenderFrameId, inputsBufferSnapshot.UnconfirmedMask, pR.Id, playerId))
|
||||||
|
case inputsBufferSnapshot2 := <-playerSecondaryDownsyncChan:
|
||||||
|
pR.downsyncPeerInputFrameUpsyncToSinglePlayer(playerId, player, inputsBufferSnapshot2.ToSendInputFrameDownsyncs, inputsBufferSnapshot2.PeerJoinIndex)
|
||||||
|
//Logger.Info(fmt.Sprintf("Sent secondary inputsBufferSnapshot to for (roomId: %d, playerId:%d)#2", pR.Id, playerId))
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,7 +566,8 @@ func (pR *Room) StartBattle() {
|
|||||||
Each "playerDownsyncChan" stays alive through out the lifecycle of room instead of each "playerDownsyncSession", i.e. not closed or dereferenced upon disconnection.
|
Each "playerDownsyncChan" stays alive through out the lifecycle of room instead of each "playerDownsyncSession", i.e. not closed or dereferenced upon disconnection.
|
||||||
*/
|
*/
|
||||||
pR.PlayerDownsyncChanDict[playerId] = make(chan pb.InputsBufferSnapshot, pR.InputsBuffer.N)
|
pR.PlayerDownsyncChanDict[playerId] = make(chan pb.InputsBufferSnapshot, pR.InputsBuffer.N)
|
||||||
go downsyncLoop(playerId, player, pR.PlayerDownsyncChanDict[playerId])
|
pR.PlayerSecondaryDownsyncChanDict[playerId] = make(chan pb.InputsBufferSnapshot, pR.InputsBuffer.N)
|
||||||
|
go downsyncLoop(playerId, player, pR.PlayerDownsyncChanDict[playerId], pR.PlayerSecondaryDownsyncChanDict[playerId])
|
||||||
}
|
}
|
||||||
|
|
||||||
pR.onBattlePrepare(func() {
|
pR.onBattlePrepare(func() {
|
||||||
@@ -551,7 +576,7 @@ func (pR *Room) StartBattle() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
|
func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq, fromUDP bool) {
|
||||||
/*
|
/*
|
||||||
[WARNING] This function "OnBattleCmdReceived" could be called by different ws sessions and thus from different threads!
|
[WARNING] This function "OnBattleCmdReceived" could be called by different ws sessions and thus from different threads!
|
||||||
|
|
||||||
@@ -596,10 +621,21 @@ func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
|
|||||||
//Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock unlocked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
//Logger.Debug(fmt.Sprintf("OnBattleCmdReceived-InputsBufferLock unlocked: roomId=%v, fromPlayerId=%v", pR.Id, playerId))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
inputsBufferSnapshot := pR.markConfirmationIfApplicable(inputFrameUpsyncBatch, playerId, player)
|
inputsBufferSnapshot := pR.markConfirmationIfApplicable(inputFrameUpsyncBatch, playerId, player, fromUDP)
|
||||||
if nil != inputsBufferSnapshot {
|
if nil != inputsBufferSnapshot {
|
||||||
pR.downsyncToAllPlayers(inputsBufferSnapshot)
|
pR.downsyncToAllPlayers(inputsBufferSnapshot)
|
||||||
|
} /*else {
|
||||||
|
// FIXME: Enable this block after we can proactively detect whether there's any "secondary ws session player" in the battle to avoid waste of resource in creating the snapshot
|
||||||
|
// no new all-confirmed
|
||||||
|
toSendInputFrameDownsyncs := pR.cloneInputsBuffer(inputFrameUpsyncBatch[0].InputFrameId, inputFrameUpsyncBatch[len(inputFrameUpsyncBatch)-1].InputFrameId+1)
|
||||||
|
|
||||||
|
inputsBufferSnapshot = &pb.InputsBufferSnapshot{
|
||||||
|
ToSendInputFrameDownsyncs: toSendInputFrameDownsyncs,
|
||||||
|
PeerJoinIndex: player.JoinIndex,
|
||||||
}
|
}
|
||||||
|
//Logger.Info(fmt.Sprintf("OnBattleCmdReceived no new all-confirmed: roomId=%v, fromPlayerId=%v, forming peer broadcasting snapshot=%v", pR.Id, playerId, inputsBufferSnapshot))
|
||||||
|
pR.broadcastPeerUpsyncForBetterPrediction(inputsBufferSnapshot)
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) onInputFrameDownsyncAllConfirmed(inputFrameDownsync *battle.InputFrameDownsync, playerId int32) {
|
func (pR *Room) onInputFrameDownsyncAllConfirmed(inputFrameDownsync *battle.InputFrameDownsync, playerId int32) {
|
||||||
@@ -641,6 +677,10 @@ func (pR *Room) StopBattleForSettlement() {
|
|||||||
if RoomBattleStateIns.IN_BATTLE != pR.State {
|
if RoomBattleStateIns.IN_BATTLE != pR.State {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
pR.BattleUdpTunnelLock.Lock()
|
||||||
|
pR.BattleUdpTunnel.Close()
|
||||||
|
pR.BattleUdpTunnelLock.Unlock()
|
||||||
|
|
||||||
pR.State = RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT
|
pR.State = RoomBattleStateIns.STOPPING_BATTLE_FOR_SETTLEMENT
|
||||||
Logger.Info("Stopping the `battleMainLoop` for:", zap.Any("roomId", pR.Id))
|
Logger.Info("Stopping the `battleMainLoop` for:", zap.Any("roomId", pR.Id))
|
||||||
pR.RenderFrameId++
|
pR.RenderFrameId++
|
||||||
@@ -650,7 +690,7 @@ func (pR *Room) StopBattleForSettlement() {
|
|||||||
PlayersArr: toPbPlayers(pR.Players, false),
|
PlayersArr: toPbPlayers(pR.Players, false),
|
||||||
CountdownNanos: -1, // TODO: Replace this magic constant!
|
CountdownNanos: -1, // TODO: Replace this magic constant!
|
||||||
}
|
}
|
||||||
pR.sendSafely(&assembledFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_STOPPED, playerId, true)
|
pR.sendSafely(&assembledFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_STOPPED, playerId, true, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
}
|
}
|
||||||
// Note that `pR.onBattleStoppedForSettlement` will be called by `battleMainLoop`.
|
// Note that `pR.onBattleStoppedForSettlement` will be called by `battleMainLoop`.
|
||||||
}
|
}
|
||||||
@@ -679,7 +719,7 @@ func (pR *Room) onBattlePrepare(cb BattleStartCbType) {
|
|||||||
|
|
||||||
Logger.Info("Sending out frame for RoomBattleState.PREPARE:", zap.Any("battleReadyToStartFrame", battleReadyToStartFrame))
|
Logger.Info("Sending out frame for RoomBattleState.PREPARE:", zap.Any("battleReadyToStartFrame", battleReadyToStartFrame))
|
||||||
for _, player := range pR.Players {
|
for _, player := range pR.Players {
|
||||||
pR.sendSafely(battleReadyToStartFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START, player.Id, true)
|
pR.sendSafely(battleReadyToStartFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_READY_TO_START, player.Id, true, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
battlePreparationNanos := int64(6000000000)
|
battlePreparationNanos := int64(6000000000)
|
||||||
@@ -748,6 +788,7 @@ func (pR *Room) OnDismissed() {
|
|||||||
pR.CharacterConfigsArr = make([]*battle.CharacterConfig, pR.Capacity)
|
pR.CharacterConfigsArr = make([]*battle.CharacterConfig, pR.Capacity)
|
||||||
pR.CollisionSysMap = make(map[int32]*resolv.Object)
|
pR.CollisionSysMap = make(map[int32]*resolv.Object)
|
||||||
pR.PlayerDownsyncSessionDict = make(map[int32]*websocket.Conn)
|
pR.PlayerDownsyncSessionDict = make(map[int32]*websocket.Conn)
|
||||||
|
pR.PlayerSecondaryDownsyncSessionDict = make(map[int32]*websocket.Conn)
|
||||||
for _, oldWatchdog := range pR.PlayerActiveWatchdogDict {
|
for _, oldWatchdog := range pR.PlayerActiveWatchdogDict {
|
||||||
oldWatchdog.Stop()
|
oldWatchdog.Stop()
|
||||||
}
|
}
|
||||||
@@ -756,7 +797,12 @@ func (pR *Room) OnDismissed() {
|
|||||||
close(oldChan)
|
close(oldChan)
|
||||||
}
|
}
|
||||||
pR.PlayerDownsyncChanDict = make(map[int32](chan pb.InputsBufferSnapshot))
|
pR.PlayerDownsyncChanDict = make(map[int32](chan pb.InputsBufferSnapshot))
|
||||||
|
for _, oldChan := range pR.PlayerSecondaryDownsyncChanDict {
|
||||||
|
close(oldChan)
|
||||||
|
}
|
||||||
|
pR.PlayerSecondaryDownsyncChanDict = make(map[int32](chan pb.InputsBufferSnapshot))
|
||||||
pR.PlayerSignalToCloseDict = make(map[int32]SignalToCloseConnCbType)
|
pR.PlayerSignalToCloseDict = make(map[int32]SignalToCloseConnCbType)
|
||||||
|
pR.PlayerSecondarySignalToCloseDict = make(map[int32]SignalToCloseConnCbType)
|
||||||
pR.JoinIndexBooleanArr = make([]bool, pR.Capacity)
|
pR.JoinIndexBooleanArr = make([]bool, pR.Capacity)
|
||||||
pR.RenderCacheSize = 1024
|
pR.RenderCacheSize = 1024
|
||||||
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
|
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
|
||||||
@@ -771,7 +817,7 @@ func (pR *Room) OnDismissed() {
|
|||||||
|
|
||||||
pR.RenderFrameId = 0
|
pR.RenderFrameId = 0
|
||||||
pR.CurDynamicsRenderFrameId = 0
|
pR.CurDynamicsRenderFrameId = 0
|
||||||
pR.NstDelayFrames = 16
|
pR.NstDelayFrames = 24
|
||||||
|
|
||||||
serverFps := 60
|
serverFps := 60
|
||||||
pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
|
pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
|
||||||
@@ -779,39 +825,50 @@ func (pR *Room) OnDismissed() {
|
|||||||
dilutedServerFps := float64(58.0) // Don't set this value too small, otherwise we might miss force confirmation needs for slow tickers!
|
dilutedServerFps := float64(58.0) // Don't set this value too small, otherwise we might miss force confirmation needs for slow tickers!
|
||||||
pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(serverFps) / dilutedServerFps)
|
pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(serverFps) / dilutedServerFps)
|
||||||
pR.BattleDurationFrames = int32(60 * serverFps)
|
pR.BattleDurationFrames = int32(60 * serverFps)
|
||||||
|
//pR.BattleDurationFrames = int32(20 * serverFps)
|
||||||
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
|
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
|
||||||
pR.InputFrameUpsyncDelayTolerance = battle.ConvertToNoDelayInputFrameId(pR.NstDelayFrames) - 1 // this value should be strictly smaller than (NstDelayFrames >> InputScaleFrames), otherwise "type#1 forceConfirmation" might become a lag avalanche
|
pR.InputFrameUpsyncDelayTolerance = battle.ConvertToNoDelayInputFrameId(pR.NstDelayFrames) - 1 // this value should be strictly smaller than (NstDelayFrames >> InputScaleFrames), otherwise "type#1 forceConfirmation" might become a lag avalanche
|
||||||
pR.MaxChasingRenderFramesPerUpdate = 12 // Don't set this value too high to avoid exhausting frontend CPU within a single frame
|
pR.MaxChasingRenderFramesPerUpdate = 9 // Don't set this value too high to avoid exhausting frontend CPU within a single frame, roughly as the "turn-around frames to recover" is empirically OK
|
||||||
|
|
||||||
pR.BackendDynamicsEnabled = true // [WARNING] When "false", recovery upon reconnection wouldn't work!
|
pR.BackendDynamicsEnabled = true // [WARNING] When "false", recovery upon reconnection wouldn't work!
|
||||||
pR.ForceAllResyncOnAnyActiveSlowTicker = true // See tradeoff discussion in "downsyncToAllPlayers"
|
pR.ForceAllResyncOnAnyActiveSlowTicker = true // See tradeoff discussion in "downsyncToAllPlayers"
|
||||||
|
|
||||||
pR.FrameDataLoggingEnabled = false // [WARNING] DON'T ENABLE ON LONG BATTLE DURATION! It consumes A LOT OF MEMORY!
|
pR.FrameDataLoggingEnabled = false // [WARNING] DON'T ENABLE ON LONG BATTLE DURATION! It consumes A LOT OF MEMORY!
|
||||||
|
pR.BattleUdpTunnelLock.Lock()
|
||||||
|
pR.BattleUdpTunnel = nil
|
||||||
|
pR.BattleUdpTunnelAddr = nil
|
||||||
|
pR.BattleUdpTunnelLock.Unlock()
|
||||||
|
|
||||||
pR.ChooseStage()
|
pR.ChooseStage()
|
||||||
pR.EffectivePlayerCount = 0
|
pR.EffectivePlayerCount = 0
|
||||||
|
|
||||||
// [WARNING] It's deliberately ordered such that "pR.State = RoomBattleStateIns.IDLE" is put AFTER all the refreshing operations above.
|
// [WARNING] It's deliberately ordered such that "pR.State = RoomBattleStateIns.IDLE" is put AFTER all the refreshing operations above.
|
||||||
pR.State = RoomBattleStateIns.IDLE
|
pR.State = RoomBattleStateIns.IDLE
|
||||||
|
go pR.startBattleUdpTunnel() // Would reassign "pR.BattleUdpTunnel"
|
||||||
pR.updateScore()
|
pR.updateScore()
|
||||||
|
|
||||||
Logger.Info("The room is completely dismissed(all playerDownsyncChan closed):", zap.Any("roomId", pR.Id))
|
Logger.Info("The room is completely dismissed(all playerDownsyncChan closed):", zap.Any("roomId", pR.Id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) expelPlayerDuringGame(playerId int32) {
|
func (pR *Room) expelPlayerDuringGame(playerId int32) {
|
||||||
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
|
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.UnknownError)
|
||||||
signalToCloseConnOfThisPlayer(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
|
|
||||||
}
|
|
||||||
pR.onPlayerExpelledDuringGame(playerId)
|
pR.onPlayerExpelledDuringGame(playerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) expelPlayerForDismissal(playerId int32) {
|
func (pR *Room) expelPlayerForDismissal(playerId int32) {
|
||||||
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
|
pR.signalToCloseAllSessionsOfPlayer(playerId, Constants.RetCode.UnknownError)
|
||||||
signalToCloseConnOfThisPlayer(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
|
|
||||||
}
|
|
||||||
pR.onPlayerExpelledForDismissal(playerId)
|
pR.onPlayerExpelledForDismissal(playerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pR *Room) signalToCloseAllSessionsOfPlayer(playerId int32, retCode int) {
|
||||||
|
if signalToCloseConnOfThisPlayer, existent := pR.PlayerSignalToCloseDict[playerId]; existent {
|
||||||
|
signalToCloseConnOfThisPlayer(retCode, "") // TODO: Specify an error code
|
||||||
|
}
|
||||||
|
if signalToCloseConnOfThisPlayer2, existent2 := pR.PlayerSecondarySignalToCloseDict[playerId]; existent2 {
|
||||||
|
signalToCloseConnOfThisPlayer2(retCode, "") // TODO: Specify an error code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pR *Room) onPlayerExpelledDuringGame(playerId int32) {
|
func (pR *Room) onPlayerExpelledDuringGame(playerId int32) {
|
||||||
pR.onPlayerLost(playerId)
|
pR.onPlayerLost(playerId)
|
||||||
}
|
}
|
||||||
@@ -829,6 +886,10 @@ func (pR *Room) OnPlayerDisconnected(playerId int32) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if signalToCloseConnOfThisPlayer2, existent2 := pR.PlayerSecondarySignalToCloseDict[playerId]; existent2 {
|
||||||
|
signalToCloseConnOfThisPlayer2(Constants.RetCode.UnknownError, "") // TODO: Specify an error code
|
||||||
|
}
|
||||||
|
|
||||||
if player, existent := pR.Players[playerId]; existent {
|
if player, existent := pR.Players[playerId]; existent {
|
||||||
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState))
|
thatPlayerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
switch thatPlayerBattleState {
|
switch thatPlayerBattleState {
|
||||||
@@ -888,6 +949,8 @@ func (pR *Room) clearPlayerNetworkSession(playerId int32) {
|
|||||||
delete(pR.PlayerActiveWatchdogDict, playerId)
|
delete(pR.PlayerActiveWatchdogDict, playerId)
|
||||||
delete(pR.PlayerDownsyncSessionDict, playerId)
|
delete(pR.PlayerDownsyncSessionDict, playerId)
|
||||||
delete(pR.PlayerSignalToCloseDict, playerId)
|
delete(pR.PlayerSignalToCloseDict, playerId)
|
||||||
|
delete(pR.PlayerSecondaryDownsyncSessionDict, playerId)
|
||||||
|
delete(pR.PlayerSecondarySignalToCloseDict, playerId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +980,10 @@ func (pR *Room) onPlayerAdded(playerId int32) {
|
|||||||
if nil == playerPos {
|
if nil == playerPos {
|
||||||
panic(fmt.Sprintf("onPlayerAdded error, nil == playerPos, roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
|
panic(fmt.Sprintf("onPlayerAdded error, nil == playerPos, roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
|
||||||
}
|
}
|
||||||
pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y)
|
pR.Players[playerId].RevivalVirtualGridX, pR.Players[playerId].RevivalVirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y)
|
||||||
|
pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = pR.Players[playerId].RevivalVirtualGridX, pR.Players[playerId].RevivalVirtualGridY
|
||||||
|
pR.Players[playerId].MaxHp = 100 // Hardcoded for now
|
||||||
|
pR.Players[playerId].Hp = pR.Players[playerId].MaxHp
|
||||||
// Hardcoded initial character orientation/facing
|
// Hardcoded initial character orientation/facing
|
||||||
if 0 == (pR.Players[playerId].JoinIndex % 2) {
|
if 0 == (pR.Players[playerId].JoinIndex % 2) {
|
||||||
pR.Players[playerId].DirX = -2
|
pR.Players[playerId].DirX = -2
|
||||||
@@ -977,7 +1043,7 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
|
|||||||
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-middle: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, thatPlayerId=%v, thatPlayerBattleState=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, thatPlayer.Id, thatPlayerBattleState))
|
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-middle: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, thatPlayerId=%v, thatPlayerBattleState=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, thatPlayer.Id, thatPlayerBattleState))
|
||||||
if thatPlayerId == targetPlayer.Id || (PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK == thatPlayerBattleState || PlayerBattleStateIns.ACTIVE == thatPlayerBattleState) {
|
if thatPlayerId == targetPlayer.Id || (PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK == thatPlayerBattleState || PlayerBattleStateIns.ACTIVE == thatPlayerBattleState) {
|
||||||
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-sending DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, pR.Capacity, pR.EffectivePlayerCount))
|
Logger.Debug(fmt.Sprintf("OnPlayerBattleColliderAcked-sending DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED: roomId=%v, roomState=%v, targetPlayerId=%v, targetPlayerBattleState=%v, capacity=%v, EffectivePlayerCount=%v", pR.Id, pR.State, targetPlayer.Id, targetPlayer.BattleState, pR.Capacity, pR.EffectivePlayerCount))
|
||||||
pR.sendSafely(playerAckedFrame, nil, DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED, thatPlayer.Id, true)
|
pR.sendSafely(playerAckedFrame, nil, DOWNSYNC_MSG_ACT_PLAYER_ADDED_AND_ACKED, thatPlayer.Id, true, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic.StoreInt32(&(targetPlayer.BattleState), PlayerBattleStateIns.ACTIVE)
|
atomic.StoreInt32(&(targetPlayer.BattleState), PlayerBattleStateIns.ACTIVE)
|
||||||
@@ -1010,19 +1076,19 @@ func (pR *Room) OnPlayerBattleColliderAcked(playerId int32) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputFrameDownsyncs []*pb.InputFrameDownsync, act int32, playerId int32, needLockExplicitly bool) {
|
func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputFrameDownsyncs []*pb.InputFrameDownsync, act int32, playerId int32, needLockExplicitly bool, peerJoinIndex int32) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
Logger.Error("sendSafely, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
|
Logger.Error("sendSafely, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("playerId", playerId), zap.Any("panic", r))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if playerDownsyncSession, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
|
|
||||||
pResp := &pb.WsResp{
|
pResp := &pb.WsResp{
|
||||||
Ret: int32(Constants.RetCode.Ok),
|
Ret: int32(Constants.RetCode.Ok),
|
||||||
Act: act,
|
Act: act,
|
||||||
Rdf: roomDownsyncFrame,
|
Rdf: roomDownsyncFrame,
|
||||||
InputFrameDownsyncBatch: toSendInputFrameDownsyncs,
|
InputFrameDownsyncBatch: toSendInputFrameDownsyncs,
|
||||||
|
PeerJoinIndex: peerJoinIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
theBytes, marshalErr := proto.Marshal(pResp)
|
theBytes, marshalErr := proto.Marshal(pResp)
|
||||||
@@ -1030,8 +1096,25 @@ func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputF
|
|||||||
panic(fmt.Sprintf("Error marshaling downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
|
panic(fmt.Sprintf("Error marshaling downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldUseSecondaryWsSession := (MAGIC_JOIN_INDEX_DEFAULT != peerJoinIndex && DOWNSYNC_MSG_ACT_INPUT_BATCH == act) // FIXME: Simplify the condition
|
||||||
|
//Logger.Info(fmt.Sprintf("shouldUseSecondaryWsSession=%v: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v", shouldUseSecondaryWsSession, pR.Id, playerId, pR.State, pR.EffectivePlayerCount))
|
||||||
|
if !shouldUseSecondaryWsSession {
|
||||||
|
if playerDownsyncSession, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
|
||||||
if err := playerDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
|
if err := playerDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
|
||||||
panic(fmt.Sprintf("Error sending downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
|
panic(fmt.Sprintf("Error sending primary downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
[FIXME]
|
||||||
|
This branch is preferred to use an additional session of each player for sending, and the session is preferrably UDP instead of any TCP-based protocol, but I'm being lazy here.
|
||||||
|
|
||||||
|
See `<proj-root>/ConcerningEdgeCases.md` for the advantage of using UDP as a supplement.
|
||||||
|
*/
|
||||||
|
if playerSecondaryDownsyncSession, existent := pR.PlayerSecondaryDownsyncSessionDict[playerId]; existent {
|
||||||
|
if err := playerSecondaryDownsyncSession.WriteMessage(websocket.BinaryMessage, theBytes); nil != err {
|
||||||
|
panic(fmt.Sprintf("Error sending secondary downsync message: roomId=%v, playerId=%v, roomState=%v, roomEffectivePlayerCount=%v, err=%v", pR.Id, playerId, pR.State, pR.EffectivePlayerCount, err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1082,7 +1165,7 @@ func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputF
|
|||||||
return currInputFrameDownsync
|
return currInputFrameDownsync
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFrameUpsync, playerId int32, player *Player) *pb.InputsBufferSnapshot {
|
func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFrameUpsync, playerId int32, player *Player, fromUDP bool) *pb.InputsBufferSnapshot {
|
||||||
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
||||||
// Step#1, put the received "inputFrameUpsyncBatch" into "pR.InputsBuffer"
|
// Step#1, put the received "inputFrameUpsyncBatch" into "pR.InputsBuffer"
|
||||||
for _, inputFrameUpsync := range inputFrameUpsyncBatch {
|
for _, inputFrameUpsync := range inputFrameUpsyncBatch {
|
||||||
@@ -1093,6 +1176,7 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if clientInputFrameId < player.LastReceivedInputFrameId {
|
if clientInputFrameId < player.LastReceivedInputFrameId {
|
||||||
|
// [WARNING] It's important for correctness that we use "player.LastReceivedInputFrameId" instead of "player.LastUdpReceivedInputFrameId" here!
|
||||||
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, playerLastReceivedInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, player.LastReceivedInputFrameId, pR.InputsBufferString(false)))
|
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, playerLastReceivedInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, player.LastReceivedInputFrameId, pR.InputsBufferString(false)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -1105,14 +1189,28 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
|
|||||||
targetInputFrameDownsync.InputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
targetInputFrameDownsync.InputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
||||||
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
|
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
|
||||||
|
|
||||||
player.LastReceivedInputFrameId = clientInputFrameId
|
if false == fromUDP {
|
||||||
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
/*
|
||||||
|
[WARNING] We have to distinguish whether or not the incoming batch is from UDP here, otherwise "pR.LatestPlayerUpsyncedInputFrameId - pR.LastAllConfirmedInputFrameId" might become unexpectedly large in case of "UDP packet loss + slow ws session"!
|
||||||
|
|
||||||
|
Moreover, only ws session upsyncs should advance "player.LastReceivedInputFrameId" & "pR.LatestPlayerUpsyncedInputFrameId".
|
||||||
|
|
||||||
|
Kindly note that the updates of "player.LastReceivedInputFrameId" could be discrete before and after reconnection.
|
||||||
|
*/
|
||||||
|
player.LastReceivedInputFrameId = clientInputFrameId
|
||||||
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
|
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
|
||||||
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
|
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if clientInputFrameId > player.LastUdpReceivedInputFrameId {
|
||||||
|
// No need to update "player.LastUdpReceivedInputFrameId" only when "true == fromUDP", we should keep "player.LastUdpReceivedInputFrameId >= player.LastReceivedInputFrameId" at any moment.
|
||||||
|
player.LastUdpReceivedInputFrameId = clientInputFrameId
|
||||||
|
// It's safe (in terms of getting an eventually correct "RenderFrameBuffer") to put the following update of "pR.LastIndividuallyConfirmedInputList" which is ONLY used for prediction in "InputsBuffer" out of "false == fromUDP" block.
|
||||||
|
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Step#2, mark confirmation without forcing
|
// Step#2, mark confirmation without forcing
|
||||||
newAllConfirmedCount := int32(0)
|
newAllConfirmedCount := int32(0)
|
||||||
inputFrameId1 := pR.LastAllConfirmedInputFrameId + 1
|
inputFrameId1 := pR.LastAllConfirmedInputFrameId + 1
|
||||||
@@ -1176,6 +1274,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
|
|||||||
totPlayerCnt := uint32(pR.Capacity)
|
totPlayerCnt := uint32(pR.Capacity)
|
||||||
allConfirmedMask := uint64((1 << totPlayerCnt) - 1)
|
allConfirmedMask := uint64((1 << totPlayerCnt) - 1)
|
||||||
unconfirmedMask := uint64(0)
|
unconfirmedMask := uint64(0)
|
||||||
|
// As "pR.LastAllConfirmedInputFrameId" can be advanced by UDP but "pR.LatestPlayerUpsyncedInputFrameId" could only be advanced by ws session, when the following condition is met we know that the slow ticker is really in trouble!
|
||||||
if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + pR.InputFrameUpsyncDelayTolerance + 1) {
|
if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + pR.InputFrameUpsyncDelayTolerance + 1) {
|
||||||
// Type#1 check whether there's a significantly slow ticker among players
|
// Type#1 check whether there's a significantly slow ticker among players
|
||||||
oldLastAllConfirmedInputFrameId := pR.LastAllConfirmedInputFrameId
|
oldLastAllConfirmedInputFrameId := pR.LastAllConfirmedInputFrameId
|
||||||
@@ -1297,13 +1396,13 @@ func (pR *Room) printBarrier(barrierCollider *resolv.Object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRenderFrameId int32, pDynamicsDuration *int64) {
|
func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRenderFrameId int32, pDynamicsDuration *int64) {
|
||||||
Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock to about lock: roomId=%v", pR.Id))
|
//Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock to about lock: roomId=%v", pR.Id))
|
||||||
pR.InputsBufferLock.Lock()
|
pR.InputsBufferLock.Lock()
|
||||||
Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock locked: roomId=%v", pR.Id))
|
//Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock locked: roomId=%v", pR.Id))
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
pR.InputsBufferLock.Unlock()
|
pR.InputsBufferLock.Unlock()
|
||||||
Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock unlocked: roomId=%v", pR.Id))
|
//Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock unlocked: roomId=%v", pR.Id))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if ok, thatRenderFrameId := battle.ShouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok {
|
if ok, thatRenderFrameId := battle.ShouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok {
|
||||||
@@ -1342,11 +1441,35 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
|
|||||||
snapshotStFrameId = refSnapshotStFrameId
|
snapshotStFrameId = refSnapshotStFrameId
|
||||||
}
|
}
|
||||||
inputsBufferSnapshot := pR.produceInputsBufferSnapshotWithCurDynamicsRenderFrameAsRef(unconfirmedMask, snapshotStFrameId, pR.LastAllConfirmedInputFrameId+1)
|
inputsBufferSnapshot := pR.produceInputsBufferSnapshotWithCurDynamicsRenderFrameAsRef(unconfirmedMask, snapshotStFrameId, pR.LastAllConfirmedInputFrameId+1)
|
||||||
Logger.Debug(fmt.Sprintf("[forceConfirmation] roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, room.LastAllConfirmedInputFrameId=%v, unconfirmedMask=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, unconfirmedMask))
|
//Logger.Warn(fmt.Sprintf("[forceConfirmation] roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, room.LastAllConfirmedInputFrameId=%v, unconfirmedMask=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, unconfirmedMask))
|
||||||
pR.downsyncToAllPlayers(inputsBufferSnapshot)
|
pR.downsyncToAllPlayers(inputsBufferSnapshot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pR *Room) broadcastPeerUpsyncForBetterPrediction(inputsBufferSnapshot *pb.InputsBufferSnapshot) {
|
||||||
|
// See `<proj-root>/ConcerningEdgeCases.md` for why this method exists.
|
||||||
|
for _, player := range pR.PlayersArr {
|
||||||
|
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
|
switch playerBattleState {
|
||||||
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if player.JoinIndex == inputsBufferSnapshot.PeerJoinIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if playerSecondaryDownsyncChan, existent := pR.PlayerSecondaryDownsyncChanDict[player.Id]; existent {
|
||||||
|
/*
|
||||||
|
[FIXME]
|
||||||
|
This function is preferred to use an additional go-channel of each player for sending, see "downsyncLoop" & "Room.sendSafely" for more information!
|
||||||
|
*/
|
||||||
|
playerSecondaryDownsyncChan <- (*inputsBufferSnapshot)
|
||||||
|
} else {
|
||||||
|
Logger.Warn(fmt.Sprintf("playerDownsyncChan for (roomId: %d, playerId:%d) is gone", pR.Id, player.Id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pR *Room) downsyncToAllPlayers(inputsBufferSnapshot *pb.InputsBufferSnapshot) {
|
func (pR *Room) downsyncToAllPlayers(inputsBufferSnapshot *pb.InputsBufferSnapshot) {
|
||||||
/*
|
/*
|
||||||
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is LOCKED to **preserve the order of generation of "inputsBufferSnapshot" for sending** -- see comments in "OnBattleCmdReceived" and [this issue](https://github.com/genxium/DelayNoMore/issues/12).
|
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is LOCKED to **preserve the order of generation of "inputsBufferSnapshot" for sending** -- see comments in "OnBattleCmdReceived" and [this issue](https://github.com/genxium/DelayNoMore/issues/12).
|
||||||
@@ -1423,14 +1546,14 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
|
|||||||
We hereby assume that Golang runtime allocates & frees small amount of RAM quickly enough compared to either network I/O blocking in worst cases or the high frequency "per inputFrameDownsync*player" locking (though "OnBattleCmdReceived" locks at the same frequency but it's inevitable).
|
We hereby assume that Golang runtime allocates & frees small amount of RAM quickly enough compared to either network I/O blocking in worst cases or the high frequency "per inputFrameDownsync*player" locking (though "OnBattleCmdReceived" locks at the same frequency but it's inevitable).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
playerJoinIndex := player.JoinIndex - 1
|
playerJoinIndexInBooleanArr := player.JoinIndex - 1
|
||||||
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
switch playerBattleState {
|
switch playerBattleState {
|
||||||
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isSlowTicker := (0 < (unconfirmedMask & uint64(1<<uint32(playerJoinIndex))))
|
isSlowTicker := (0 < (unconfirmedMask & uint64(1<<uint32(playerJoinIndexInBooleanArr))))
|
||||||
shouldResync1 := (PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED == playerBattleState) // i.e. implies that "MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId"
|
shouldResync1 := (PlayerBattleStateIns.READDED_BATTLE_COLLIDER_ACKED == playerBattleState) // i.e. implies that "MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED == player.LastSentInputFrameId"
|
||||||
shouldResync2 := isSlowTicker // This condition is critical, if we don't send resync upon this condition, the "reconnected or slowly-clocking player" might never get its input synced
|
shouldResync2 := isSlowTicker // This condition is critical, if we don't send resync upon this condition, the "reconnected or slowly-clocking player" might never get its input synced
|
||||||
shouldResync3 := shouldForceResync
|
shouldResync3 := shouldForceResync
|
||||||
@@ -1455,13 +1578,13 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
|
|||||||
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
|
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
|
||||||
pbRefRenderFrame := toPbRoomDownsyncFrame(refRenderFrame)
|
pbRefRenderFrame := toPbRoomDownsyncFrame(refRenderFrame)
|
||||||
pbRefRenderFrame.SpeciesIdList = pR.SpeciesIdList
|
pbRefRenderFrame.SpeciesIdList = pR.SpeciesIdList
|
||||||
pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
|
pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
//Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
|
//Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: InputsBuffer=%v", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, pR.InputsBufferString(false)))
|
||||||
if shouldResync1 {
|
if shouldResync1 || shouldResync3 {
|
||||||
Logger.Warn(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: shouldResync1=%v, shouldResync2=%v, shouldResync3=%v, playerBattleState=%d", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, shouldResync1, shouldResync2, shouldResync3, playerBattleState))
|
Logger.Debug(fmt.Sprintf("Sent refRenderFrameId=%v & inputFrameIds [%d, %d), for roomId=%v, playerId=%d, playerJoinIndex=%d, renderFrameId=%d, curDynamicsRenderFrameId=%d, playerLastSentInputFrameId=%d: shouldResync1=%v, shouldResync2=%v, shouldResync3=%v, playerBattleState=%d", refRenderFrameId, toSendInputFrameIdSt, toSendInputFrameIdEd, pR.Id, playerId, player.JoinIndex, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, player.LastSentInputFrameId, shouldResync1, shouldResync2, shouldResync3, playerBattleState))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false)
|
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false, MAGIC_JOIN_INDEX_DEFAULT)
|
||||||
}
|
}
|
||||||
player.LastSentInputFrameId = toSendInputFrameIdEd - 1
|
player.LastSentInputFrameId = toSendInputFrameIdEd - 1
|
||||||
if shouldResync1 {
|
if shouldResync1 {
|
||||||
@@ -1469,6 +1592,16 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pR *Room) downsyncPeerInputFrameUpsyncToSinglePlayer(playerId int32, player *Player, toSendInputFrameDownsyncsSnapshot []*pb.InputFrameDownsync, peerJoinIndex int32) {
|
||||||
|
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
|
switch playerBattleState {
|
||||||
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL, PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_PEER_INPUT_BATCH, playerId, false, peerJoinIndex)
|
||||||
|
}
|
||||||
|
|
||||||
func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*pb.InputFrameDownsync {
|
func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*pb.InputFrameDownsync {
|
||||||
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
|
||||||
cloned := make([]*pb.InputFrameDownsync, 0, edFrameId-stFrameId)
|
cloned := make([]*pb.InputFrameDownsync, 0, edFrameId-stFrameId)
|
||||||
@@ -1501,3 +1634,163 @@ func (pR *Room) cloneInputsBuffer(stFrameId, edFrameId int32) []*pb.InputFrameDo
|
|||||||
|
|
||||||
return cloned
|
return cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pR *Room) SetSecondarySession(playerId int32, session *websocket.Conn, signalToCloseConnOfThisPlayer SignalToCloseConnCbType) {
|
||||||
|
// TODO: Use a dedicated lock
|
||||||
|
if player, ok := pR.Players[playerId]; ok {
|
||||||
|
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
|
switch playerBattleState {
|
||||||
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||||
|
// Kindly note that "PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK" are allowed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
|
||||||
|
if _, existent2 := pR.PlayerSecondaryDownsyncSessionDict[playerId]; !existent2 {
|
||||||
|
Logger.Info(fmt.Sprintf("SetSecondarySession for roomId=%v, playerId=%d, pR.Players=%v", pR.Id, playerId, pR.Players))
|
||||||
|
pR.PlayerSecondaryDownsyncSessionDict[playerId] = session
|
||||||
|
pR.PlayerSecondarySignalToCloseDict[playerId] = signalToCloseConnOfThisPlayer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pR *Room) UpdatePeerUdpAddrList(playerId int32, peerAddr *net.UDPAddr, pReq *pb.HolePunchUpsync) {
|
||||||
|
// TODO: There's a chance that by now "player.JoinIndex" is not yet determined, use a lock to sync
|
||||||
|
if player, ok := pR.Players[playerId]; ok && MAGIC_JOIN_INDEX_DEFAULT != player.JoinIndex {
|
||||||
|
playerBattleState := atomic.LoadInt32(&(player.BattleState))
|
||||||
|
switch playerBattleState {
|
||||||
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||||
|
// Kindly note that "PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK, PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK" are allowed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
|
||||||
|
player.UdpAddr = &pb.PeerUdpAddr{
|
||||||
|
Ip: peerAddr.IP.String(),
|
||||||
|
Port: int32(peerAddr.Port),
|
||||||
|
AuthKey: pReq.AuthKey,
|
||||||
|
}
|
||||||
|
Logger.Info(fmt.Sprintf("UpdatePeerUdpAddrList done for roomId=%v, playerId=%d, peerAddr=%s", pR.Id, playerId, peerAddr))
|
||||||
|
|
||||||
|
peerJoinIndex := player.JoinIndex
|
||||||
|
peerUdpAddrList := make([]*pb.PeerUdpAddr, pR.Capacity, pR.Capacity)
|
||||||
|
|
||||||
|
for _, otherPlayer := range pR.Players {
|
||||||
|
if MAGIC_JOIN_INDEX_DEFAULT == otherPlayer.JoinIndex {
|
||||||
|
// TODO: Again this shouldn't happen, apply proper locking
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// In case of highly concurrent update that might occur while later marshalling, use the ptr of a copy
|
||||||
|
peerUdpAddrList[otherPlayer.JoinIndex-1] = &pb.PeerUdpAddr{
|
||||||
|
Ip: otherPlayer.UdpAddr.Ip,
|
||||||
|
Port: otherPlayer.UdpAddr.Port,
|
||||||
|
AuthKey: otherPlayer.UdpAddr.AuthKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast this new UDP addr to all the existing players
|
||||||
|
for otherPlayerId, otherPlayer := range pR.Players {
|
||||||
|
otherPlayerBattleState := atomic.LoadInt32(&(otherPlayer.BattleState))
|
||||||
|
switch otherPlayerBattleState {
|
||||||
|
case PlayerBattleStateIns.DISCONNECTED, PlayerBattleStateIns.LOST, PlayerBattleStateIns.EXPELLED_DURING_GAME, PlayerBattleStateIns.EXPELLED_IN_DISMISSAL:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info(fmt.Sprintf("Downsyncing peerUdpAddrList for roomId=%v, playerId=%d", pR.Id, otherPlayerId))
|
||||||
|
pR.sendSafely(&pb.RoomDownsyncFrame{
|
||||||
|
PeerUdpAddrList: peerUdpAddrList,
|
||||||
|
}, nil, DOWNSYNC_MSG_ACT_PEER_UDP_ADDR, otherPlayerId, false, peerJoinIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pR *Room) startBattleUdpTunnel() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
Logger.Error("`BattleUdpTunnel` recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
|
||||||
|
}
|
||||||
|
Logger.Info(fmt.Sprintf("`BattleUdpTunnel` stopped for (roomId=%d)@renderFrameId=%v", pR.Id, pR.RenderFrameId))
|
||||||
|
}()
|
||||||
|
|
||||||
|
pR.BattleUdpTunnelLock.Lock()
|
||||||
|
conn, err := net.ListenUDP("udp", &net.UDPAddr{
|
||||||
|
Port: 0,
|
||||||
|
IP: net.ParseIP(Conf.Sio.UdpHost),
|
||||||
|
})
|
||||||
|
if nil != err {
|
||||||
|
// No need to close the "conn" upon error here
|
||||||
|
pR.BattleUdpTunnelLock.Unlock()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
pR.BattleUdpTunnel = conn
|
||||||
|
switch v := conn.LocalAddr().(type) {
|
||||||
|
case (*net.UDPAddr):
|
||||||
|
pR.BattleUdpTunnelAddr = &pb.PeerUdpAddr{
|
||||||
|
Ip: Conf.Sio.UdpHost,
|
||||||
|
Port: int32(v.Port),
|
||||||
|
AuthKey: 0, // To be determined for each specific player upon joining and sent to it by BattleColliderInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pR.BattleUdpTunnelLock.Unlock()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
Logger.Warn("`BattleUdpTunnel` recovery spot#2, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
|
||||||
|
}
|
||||||
|
Logger.Info(fmt.Sprintf("`BattleUdpTunnel` closed for (roomId=%d)@renderFrameId=%v", pR.Id, pR.RenderFrameId))
|
||||||
|
}()
|
||||||
|
Logger.Info(fmt.Sprintf("`BattleUdpTunnel` started for roomId=%d at %s", pR.Id, conn.LocalAddr().String()))
|
||||||
|
for {
|
||||||
|
message := make([]byte, 128)
|
||||||
|
rlen, remote, err := conn.ReadFromUDP(message[:]) // Would be unblocked when "conn.Close()" is called from another thread/goroutine, reference https://pkg.go.dev/net@go1.18.6#PacketConn
|
||||||
|
if nil != err {
|
||||||
|
// Should proceed to close the "conn" upon error here, if "conn" is already closed it'd just throw another error to be catched by "spot#2"
|
||||||
|
conn.Close()
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
pReq := new(pb.WsReq)
|
||||||
|
bytes := message[0:rlen]
|
||||||
|
if unmarshalErr := proto.Unmarshal(bytes, pReq); nil != unmarshalErr {
|
||||||
|
Logger.Warn(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d failed to unmarshal %d bytes", pR.Id, rlen), zap.Error(unmarshalErr))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
playerId := pReq.PlayerId
|
||||||
|
//Logger.Info(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d received decoded WsReq:", pR.Id), zap.Any("pReq", pReq))
|
||||||
|
if player, exists1 := pR.Players[playerId]; exists1 {
|
||||||
|
authKey := pReq.AuthKey
|
||||||
|
if authKey != player.BattleUdpTunnelAuthKey {
|
||||||
|
Logger.Warn(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d received %d bytes for playerId=%d from %s, but (incomingAuthKey:%d != playerBattleUdpTunnelAuthKey:%d)\n", pR.Id, rlen, playerId, remote, authKey, player.BattleUdpTunnelAuthKey))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, existent := pR.PlayerDownsyncSessionDict[playerId]; existent {
|
||||||
|
player.BattleUdpTunnelAddr = remote
|
||||||
|
//Logger.Info(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d updated battleUdpAddr for playerId=%d to be %s\n", pR.Id, playerId, remote))
|
||||||
|
|
||||||
|
nowBattleState := atomic.LoadInt32(&pR.State)
|
||||||
|
if RoomBattleStateIns.IN_BATTLE == nowBattleState {
|
||||||
|
batch := pReq.InputFrameUpsyncBatch
|
||||||
|
if nil != batch && 0 < len(batch) {
|
||||||
|
peerJoinIndex := pReq.JoinIndex
|
||||||
|
// Broadcast to every other player in the same room/battle
|
||||||
|
for _, otherPlayer := range pR.PlayersArr {
|
||||||
|
if otherPlayer.JoinIndex == peerJoinIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, wrerr := conn.WriteTo(bytes, otherPlayer.BattleUdpTunnelAddr)
|
||||||
|
if nil != wrerr {
|
||||||
|
Logger.Warn(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d failed to forward upsync from (playerId:%d, joinIndex:%d, addr:%s) to (otherPlayerId:%d, otherPlayerJoinIndex:%d, otherPlayerAddr:%s)\n", pR.Id, playerId, peerJoinIndex, remote, otherPlayer.Id, otherPlayer.JoinIndex, otherPlayer.BattleUdpTunnelAddr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pR.OnBattleCmdReceived(pReq, true) // To help advance "pR.LastAllConfirmedInputFrameId" asap, and even if "pR.LastAllConfirmedInputFrameId" is not advanced due to packet loss, these UDP packets would help prefill the "InputsBuffer" with correct player "future inputs (compared to ws session)" such that when "forceConfirmation" occurs we have as many correct predictions as possible
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.Warn(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d received validated %d bytes for playerId=%d from %s, but primary downsync session for it doesn't exist\n", pR.Id, rlen, playerId, remote))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.Warn(fmt.Sprintf("`BattleUdpTunnel` for roomId=%d received invalid %d bytes for playerId=%d from %s, but it doesn't belong to this room!\n", pR.Id, rlen, playerId, remote))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -46,6 +47,7 @@ func Serve(c *gin.Context) {
|
|||||||
c.AbortWithStatus(http.StatusBadRequest)
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
boundRoomId := 0
|
boundRoomId := 0
|
||||||
expectedRoomId := 0
|
expectedRoomId := 0
|
||||||
var err error
|
var err error
|
||||||
@@ -257,6 +259,13 @@ func Serve(c *gin.Context) {
|
|||||||
|
|
||||||
RenderCacheSize: pRoom.RenderCacheSize,
|
RenderCacheSize: pRoom.RenderCacheSize,
|
||||||
CollisionMinStep: pRoom.CollisionMinStep,
|
CollisionMinStep: pRoom.CollisionMinStep,
|
||||||
|
BoundRoomCapacity: int32(pRoom.Capacity),
|
||||||
|
|
||||||
|
BattleUdpTunnel: &pb.PeerUdpAddr{
|
||||||
|
Ip: pRoom.BattleUdpTunnelAddr.Ip,
|
||||||
|
Port: pRoom.BattleUdpTunnelAddr.Port,
|
||||||
|
AuthKey: pThePlayer.BattleUdpTunnelAuthKey,
|
||||||
|
},
|
||||||
|
|
||||||
FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled,
|
FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled,
|
||||||
}
|
}
|
||||||
@@ -266,6 +275,7 @@ func Serve(c *gin.Context) {
|
|||||||
EchoedMsgId: int32(0),
|
EchoedMsgId: int32(0),
|
||||||
Act: models.DOWNSYNC_MSG_ACT_HB_REQ,
|
Act: models.DOWNSYNC_MSG_ACT_HB_REQ,
|
||||||
BciFrame: bciFrame,
|
BciFrame: bciFrame,
|
||||||
|
PeerJoinIndex: pThePlayer.JoinIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Sending downsync HeartbeatRequirements:", zap.Any("roomId", pRoom.Id), zap.Any("playerId", playerId), zap.Any("resp", resp))
|
Logger.Debug("Sending downsync HeartbeatRequirements:", zap.Any("roomId", pRoom.Id), zap.Any("playerId", playerId), zap.Any("resp", resp))
|
||||||
@@ -378,7 +388,7 @@ func Serve(c *gin.Context) {
|
|||||||
startOrFeedHeartbeatWatchdog(conn)
|
startOrFeedHeartbeatWatchdog(conn)
|
||||||
case models.UPSYNC_MSG_ACT_PLAYER_CMD:
|
case models.UPSYNC_MSG_ACT_PLAYER_CMD:
|
||||||
startOrFeedHeartbeatWatchdog(conn)
|
startOrFeedHeartbeatWatchdog(conn)
|
||||||
pRoom.OnBattleCmdReceived(pReq)
|
pRoom.OnBattleCmdReceived(pReq, false)
|
||||||
case models.UPSYNC_MSG_ACT_PLAYER_COLLIDER_ACK:
|
case models.UPSYNC_MSG_ACT_PLAYER_COLLIDER_ACK:
|
||||||
res := pRoom.OnPlayerBattleColliderAcked(int32(playerId))
|
res := pRoom.OnPlayerBattleColliderAcked(int32(playerId))
|
||||||
if false == res {
|
if false == res {
|
||||||
@@ -395,3 +405,118 @@ func Serve(c *gin.Context) {
|
|||||||
startOrFeedHeartbeatWatchdog(conn)
|
startOrFeedHeartbeatWatchdog(conn)
|
||||||
go receivingLoopAgainstPlayer()
|
go receivingLoopAgainstPlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleSecondaryWsSessionForPlayer(c *gin.Context) {
|
||||||
|
token, ok := c.GetQuery("intAuthToken")
|
||||||
|
if !ok {
|
||||||
|
Logger.Warn("Secondary ws session req must have intAuthToken param!")
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
boundRoomId := 0
|
||||||
|
var err error = nil
|
||||||
|
if boundRoomIdStr, hasBoundRoomId := c.GetQuery("boundRoomId"); hasBoundRoomId {
|
||||||
|
boundRoomId, err = strconv.Atoi(boundRoomIdStr)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Logger.Warn("Secondary ws session req must have boundRoomId param:", zap.Any("intAuthToken", token))
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var pRoom *models.Room = nil
|
||||||
|
// Deliberately querying playerId after querying room, because the former is against persistent storage and could be slow!
|
||||||
|
if tmpPRoom, existent := (*models.RoomMapManagerIns)[int32(boundRoomId)]; !existent {
|
||||||
|
Logger.Warn("Secondary ws session failed to get:\n", zap.Any("intAuthToken", token), zap.Any("forBoundRoomId", boundRoomId))
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
} else {
|
||||||
|
pRoom = tmpPRoom
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Wrap the following 2 stmts by sql transaction!
|
||||||
|
playerId, err := models.GetPlayerIdByToken(token)
|
||||||
|
if err != nil || playerId == 0 {
|
||||||
|
// TODO: Abort with specific message.
|
||||||
|
Logger.Warn("Secondary ws session playerLogin record not found:", zap.Any("intAuthToken", token))
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info("Secondary ws session playerLogin record has been found:", zap.Any("playerId", playerId), zap.Any("intAuthToken", token), zap.Any("boundRoomId", boundRoomId))
|
||||||
|
|
||||||
|
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
|
if err != nil {
|
||||||
|
Logger.Error("Secondary ws session upgrade:", zap.Error(err), zap.Any("playerId", playerId))
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
connHasBeenSignaledToClose := int32(0)
|
||||||
|
pConnHasBeenSignaledToClose := &connHasBeenSignaledToClose
|
||||||
|
|
||||||
|
signalToCloseConnOfThisPlayer := func(customRetCode int, customRetMsg string) {
|
||||||
|
if swapped := atomic.CompareAndSwapInt32(pConnHasBeenSignaledToClose, 0, 1); !swapped {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Logger.Warn("Secondary ws session signalToCloseConnOfThisPlayer:", zap.Any("playerId", playerId), zap.Any("customRetCode", customRetCode), zap.Any("customRetMsg", customRetMsg))
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
Logger.Error("Secondary ws session recovered from: ", zap.Any("panic", r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
closeMessage := websocket.FormatCloseMessage(customRetCode, customRetMsg)
|
||||||
|
err := conn.WriteControl(websocket.CloseMessage, closeMessage, time.Now().Add(time.Millisecond*(ConstVals.Ws.WillKickIfInactiveFor)))
|
||||||
|
if err != nil {
|
||||||
|
Logger.Error("Secondary ws session unable to send the CloseFrame control message to player(client-side):", zap.Any("playerId", playerId), zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
time.AfterFunc(3*time.Second, func() {
|
||||||
|
// To actually terminates the underlying TCP connection which might be in `CLOSE_WAIT` state if inspected by `netstat`.
|
||||||
|
conn.Close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onReceivedCloseMessageFromClient := func(code int, text string) error {
|
||||||
|
Logger.Warn("Secondary ws session triggered `onReceivedCloseMessageFromClient`:", zap.Any("code", code), zap.Any("playerId", playerId), zap.Any("message", text))
|
||||||
|
signalToCloseConnOfThisPlayer(code, text)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.SetCloseHandler(onReceivedCloseMessageFromClient)
|
||||||
|
|
||||||
|
pRoom.SetSecondarySession(int32(playerId), conn, signalToCloseConnOfThisPlayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleUdpHolePunchingForPlayer(message []byte, peerAddr *net.UDPAddr) {
|
||||||
|
pReq := new(pb.HolePunchUpsync)
|
||||||
|
if unmarshalErr := proto.Unmarshal(message, pReq); nil != unmarshalErr {
|
||||||
|
Logger.Error("`GrandUdpServer` failed to unmarshal", zap.Error(unmarshalErr))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
token := pReq.IntAuthToken
|
||||||
|
boundRoomId := pReq.BoundRoomId
|
||||||
|
|
||||||
|
pRoom, existent := (*models.RoomMapManagerIns)[int32(boundRoomId)]
|
||||||
|
// Deliberately querying playerId after querying room, because the former is against persistent storage and could be slow!
|
||||||
|
if !existent {
|
||||||
|
Logger.Warn("`GrandUdpServer` failed to get:\n", zap.Any("intAuthToken", token), zap.Any("forBoundRoomId", boundRoomId))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Wrap the following 2 stmts by sql transaction!
|
||||||
|
playerId, err := models.GetPlayerIdByToken(token)
|
||||||
|
if err != nil || playerId == 0 {
|
||||||
|
// TODO: Abort with specific message.
|
||||||
|
Logger.Warn("`GrandUdpServer` playerLogin record not found for:", zap.Any("intAuthToken", token))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info("`GrandUdpServer` playerLogin record has been found:", zap.Any("playerId", playerId), zap.Any("intAuthToken", token), zap.Any("boundRoomId", boundRoomId), zap.Any("peerAddr", peerAddr))
|
||||||
|
pRoom.UpdatePeerUdpAddrList(int32(playerId), peerAddr, pReq)
|
||||||
|
}
|
||||||
|
BIN
charts/Merged_cut_annotated_spedup.gif
Normal file
After Width: | Height: | Size: 7.4 MiB |
BIN
charts/NativeBuildReload.png
Normal file
After Width: | Height: | Size: 118 KiB |
BIN
charts/PackageNameIssueInCcc.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
charts/ServerClients.jpg
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
charts/UDPEssentials.jpg
Normal file
After Width: | Height: | Size: 472 KiB |
BIN
charts/VisualStudioSetup.png
Normal file
After Width: | Height: | Size: 191 KiB |
Before Width: | Height: | Size: 4.5 MiB |
Before Width: | Height: | Size: 11 MiB |
BIN
charts/networkstats.png
Normal file
After Width: | Height: | Size: 2.2 MiB |
@@ -1,66 +0,0 @@
|
|||||||
function NetworkDoctor(serverFps, clientUpsyncFps) {
|
|
||||||
this.serverFps = serverFps;
|
|
||||||
this.clientUpsyncFps = clientUpsyncFps;
|
|
||||||
this.millisPerServerFrame = parseInt(1000 / this.serverFps);
|
|
||||||
this._tooLongSinceLastFrameDiffReceivedThreshold = (this.millisPerServerFrame << 6);
|
|
||||||
|
|
||||||
this.setupFps = function(fps) {
|
|
||||||
this.serverFps = this.clientUpsyncFps = fps;
|
|
||||||
this.millisPerServerFrame = parseInt(1000 / this.serverFps);
|
|
||||||
this._tooLongSinceLastFrameDiffReceivedThreshold = (this.millisPerServerFrame << 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._lastFrameDiffRecvTime = null;
|
|
||||||
this._tooLongSinceLastFrameDiffReceived = function() {
|
|
||||||
if (undefined === this._lastFrameDiffRecvTime || null === this._lastFrameDiffRecvTime) return false;
|
|
||||||
return (this._tooLongSinceLastFrameDiffReceivedThreshold <= (Date.now() - this._lastFrameDiffRecvTime));
|
|
||||||
};
|
|
||||||
|
|
||||||
this._consecutiveALittleLongFrameDiffReceivedIntervalCount = 0;
|
|
||||||
this._consecutiveALittleLongFrameDiffReceivedIntervalCountThreshold = 120;
|
|
||||||
|
|
||||||
this.onNewFrameDiffReceived = function(frameDiff) {
|
|
||||||
var now = Date.now();
|
|
||||||
if (undefined !== this._lastFrameDiffRecvTime && null !== this._lastFrameDiffRecvTime) {
|
|
||||||
var intervalFromLastFrameDiff = (now - this._lastFrameDiffRecvTime);
|
|
||||||
if ((this.millisPerServerFrame << 5) < intervalFromLastFrameDiff) {
|
|
||||||
++this._consecutiveALittleLongFrameDiffReceivedIntervalCount;
|
|
||||||
console.log('Medium delay, intervalFromLastFrameDiff is', intervalFromLastFrameDiff);
|
|
||||||
} else {
|
|
||||||
this._consecutiveALittleLongFrameDiffReceivedIntervalCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._lastFrameDiffRecvTime = now;
|
|
||||||
};
|
|
||||||
|
|
||||||
this._networkComplaintPrefix = "\nNetwork is not good >_<\n";
|
|
||||||
|
|
||||||
this.generateNetworkComplaint = function(excludeTypeConstantALittleLongFrameDiffReceivedInterval, excludeTypeTooLongSinceLastFrameDiffReceived) {
|
|
||||||
if (this.hasBattleStopped) return null;
|
|
||||||
var shouldComplain = false;
|
|
||||||
var ret = this._networkComplaintPrefix;
|
|
||||||
if (true != excludeTypeConstantALittleLongFrameDiffReceivedInterval && this._consecutiveALittleLongFrameDiffReceivedIntervalCountThreshold <= this._consecutiveALittleLongFrameDiffReceivedIntervalCount) {
|
|
||||||
this._consecutiveALittleLongFrameDiffReceivedIntervalCount = 0;
|
|
||||||
ret += "\nConstantly having a little long recv interval.\n";
|
|
||||||
shouldComplain = true;
|
|
||||||
}
|
|
||||||
if (true != excludeTypeTooLongSinceLastFrameDiffReceived && this._tooLongSinceLastFrameDiffReceived()) {
|
|
||||||
ret += "\nToo long since last received frameDiff.\n";
|
|
||||||
shouldComplain = true;
|
|
||||||
}
|
|
||||||
return (shouldComplain ? ret : null);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.hasBattleStopped = false;
|
|
||||||
this.onBattleStopped = function() {
|
|
||||||
this.hasBattleStopped = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isClientSessionConnected = function() {
|
|
||||||
if (!window.game) return false;
|
|
||||||
if (!window.game.clientSession) return false;
|
|
||||||
return window.game.clientSession.connected;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
window.NetworkDoctor = NetworkDoctor;
|
|
@@ -198,3 +198,6 @@ window.getOrCreateAnimationClipForGid = function(gid, tiledMapInfo, tilesElListU
|
|||||||
animationClip: animClip,
|
animationClip: animClip,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Node.js, this is a workaround to avoid accessing the non-existent "TextDecoder class" from "jsexport.js".
|
||||||
|
window.fs = function() {};
|
||||||
|
7
frontend/assets/resources/animation/Explosion.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.0.1",
|
||||||
|
"uuid": "c7c2ac6e-f1ea-4233-b6a4-aa5b96b61e17",
|
||||||
|
"isSubpackage": false,
|
||||||
|
"subpackageName": "",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Fireball1Explosion",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f4ad4f9f-4890-450b-9334-68fe6b903893"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c6a5994f-251d-4191-a550-dfef979bab59"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "417e58d9-e364-47f7-9364-f31ad3452adc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "8b566f26-b34d-4da6-bdaa-078358a5b685"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.31666666666666665,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "6ec5f75d-307e-4292-b667-cbbb5a52c2f6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.48333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d89977f1-d927-4a08-9591-9feb1daf68c8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "7941215a-2b8c-4798-954b-4f1b16d5f6f5",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Fireball2Explosion",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a1979f05-3ecc-4d70-9ea9-7822e35602c3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "850884ca-2e6a-4d04-94d9-fd929ac33942"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "88b9c254-1fd8-451f-902e-4a43a7ef5d51"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "566342a3-cfde-44c9-afbe-7d9469653ccb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.18333333333333332,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d1620a98-de62-4069-8910-122f361d22a4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.23333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "2e9ed070-e592-4e77-8fa1-c5250deb006b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2833333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a3e8357d-39da-42e8-b26b-f5ae7a68aed7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.3333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "3f3cb45c-732d-4bea-89b4-5495fb0d2c37"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.38333333333333336,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d7aeb01a-4e04-4037-a2c4-ba72f45f69f3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.43333333333333335,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "fe4a97a0-1207-4b81-a541-c2da0bf0a6f3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.48333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "97014ab9-8bdd-4b71-9f61-0639327f9159"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "14b92f5c-af81-416a-a162-e5822d20fe68",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Fireball3Explosion",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0e003318-f8c2-40f7-b144-140b5ca1e46a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "9c2b0cc2-9a52-4052-b796-cd6c6bd940d4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "76fe0c09-d2d6-432d-bacb-20d297eb4966"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0735a7ff-0e50-472a-b0f9-8e2cc97be7e7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2833333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "993199a8-54a9-40d1-8d2f-12bf16af934c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.35,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "5d8d9ffc-b4d6-4518-9946-953929ec055c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.38333333333333336,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "6501ae08-b0ff-43ad-b5c5-cb6dc67f989d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.4166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "616cfa00-1dba-4a71-8141-36774933b6a9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.45,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "4b296e86-2e96-4276-b6de-6a6b22530344"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.48333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f9cc8e37-c9c2-4f20-9d7e-4533c4e859fe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "0dbb90ed-a08a-448c-b06e-4831260e9213",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "MeleeExplosion1",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.16666666666666666,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ab4866e8-ce52-4bc1-be19-b03687acf0d6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "67cc8a51-0ebe-49db-a941-7aabc5655ecf"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "367592d0-3566-4b6a-8707-01d6a8dbe34a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "cc336b1e-b5d8-4a89-96fc-7ada0e232389"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a457cc63-08bd-4cfa-b84a-7287d0343ecf"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "89697d35-cde3-4392-a231-db91d4ede29b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "3815bf7a-0a48-40e0-b791-0a0be9ec0da6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "20e691ee-a0c0-4710-8981-8dee1911e819"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "94e678c5-0780-4f2b-bf3b-86c6c0a75c23"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "af4f9c62-4c7e-43a4-b9b3-dd3effbbbafb"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "954a2924-89df-4df4-93fc-36d2b22e7619",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "MeleeExplosion2",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.26666666666666666,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "89e54317-7835-4d4c-9c04-579da8b33c54"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "2a186e00-a0c5-4c8a-b0ab-c84d56dcee7c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "083168e3-6ccc-4c5b-a800-2554bffc67d4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d4b12ec9-6f04-493c-91e5-22b1a212262a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "13038788-b0f9-4714-960b-c98619a0d0ce"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "94c21ed7-94a2-47a4-9537-fe5d9c51d7b0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d5340298-923c-4bd7-9fd7-7a2e029a2b44"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.21666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c4b145c0-0145-4e09-8559-9ef508d95be8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.23333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "79398d4d-305e-4987-b199-d9d9649cf490"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.25,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c032eb65-fdf3-41e6-b868-d95df34168df"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "5bd304eb-c8ba-426f-a9ab-5698ac62de85",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "MeleeExplosion3",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.26666666666666666,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "20d9ce6b-d9ab-4402-8c59-770ad0adf570"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0654601f-6788-4a2c-aed4-8dfbe1c5fdd0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0913e11a-c796-4b58-94cf-f70b3869deff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d6b58622-2cc3-4ee6-a34f-1a18deb73700"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b83c6261-b86f-4323-ad11-7375cac02a2b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b458c047-b7b5-4476-996e-d4c1ca85ef9c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "3971256a-8120-448e-8adf-de8d67dedfd3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.18333333333333332,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0e548d92-36c8-4795-b3dc-2bc2cfcd7170"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.21666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "25f94245-87b0-4954-abab-c817c80fed37"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.25,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "20d9ce6b-d9ab-4402-8c59-770ad0adf570"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "5054633c-a588-4506-b4ac-eef29b1d8511",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,476 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>frames</key>
|
||||||
|
<dict>
|
||||||
|
<key>Explosion1_1.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,506},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_10.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,577},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_2.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{67,506},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_3.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{67,577},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_4.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{134,506},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_5.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{134,577},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_6.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{355,503},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_7.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{426,503},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_8.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{355,570},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion1_9.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{71,67}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{422,570},{71,67}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_1.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{462,0},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_10.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{462,88},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_2.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{462,176},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_3.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{462,264},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_4.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,304},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_5.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{88,304},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_6.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{176,304},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_7.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{264,304},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_8.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{352,304},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion2_9.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{88,45}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{456,352},{88,45}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_1.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,0},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_10.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{154,0},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_2.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{308,0},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_3.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,152},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_4.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{154,152},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_5.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{308,152},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_6.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{0,352},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_7.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{152,349},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_8.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{201,503},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
<key>Explosion3_9.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>aliases</key>
|
||||||
|
<array/>
|
||||||
|
<key>spriteOffset</key>
|
||||||
|
<string>{0,0}</string>
|
||||||
|
<key>spriteSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>spriteSourceSize</key>
|
||||||
|
<string>{154,152}</string>
|
||||||
|
<key>textureRect</key>
|
||||||
|
<string>{{304,349},{154,152}}</string>
|
||||||
|
<key>textureRotated</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>metadata</key>
|
||||||
|
<dict>
|
||||||
|
<key>format</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>pixelFormat</key>
|
||||||
|
<string>RGBA8888</string>
|
||||||
|
<key>premultiplyAlpha</key>
|
||||||
|
<false/>
|
||||||
|
<key>realTextureFileName</key>
|
||||||
|
<string>MeleeExplosions.png</string>
|
||||||
|
<key>size</key>
|
||||||
|
<string>{507,655}</string>
|
||||||
|
<key>smartupdate</key>
|
||||||
|
<string>$TexturePacker:SmartUpdate:6c1498ee6f30bdad4abeb6a9f6af8367:4c81e1a1720f2ad3535ac93f1b42991f:d9b184ec81b83b14db5cf31d298727df$</string>
|
||||||
|
<key>textureFileName</key>
|
||||||
|
<string>MeleeExplosions.png</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@@ -0,0 +1,672 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.2.4",
|
||||||
|
"uuid": "1c4c1dcb-54af-485b-9119-abd6d6d84526",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"size": {
|
||||||
|
"width": 507,
|
||||||
|
"height": 655
|
||||||
|
},
|
||||||
|
"type": "Texture Packer",
|
||||||
|
"subMetas": {
|
||||||
|
"Explosion1_1.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "ab4866e8-ce52-4bc1-be19-b03687acf0d6",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 506,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_10.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "af4f9c62-4c7e-43a4-b9b3-dd3effbbbafb",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 577,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_2.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "67cc8a51-0ebe-49db-a941-7aabc5655ecf",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 67,
|
||||||
|
"trimY": 506,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_3.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "367592d0-3566-4b6a-8707-01d6a8dbe34a",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 67,
|
||||||
|
"trimY": 577,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_4.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "cc336b1e-b5d8-4a89-96fc-7ada0e232389",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 134,
|
||||||
|
"trimY": 506,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_5.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "a457cc63-08bd-4cfa-b84a-7287d0343ecf",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 134,
|
||||||
|
"trimY": 577,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_6.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "89697d35-cde3-4392-a231-db91d4ede29b",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 355,
|
||||||
|
"trimY": 503,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_7.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "3815bf7a-0a48-40e0-b791-0a0be9ec0da6",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 426,
|
||||||
|
"trimY": 503,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_8.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "20e691ee-a0c0-4710-8981-8dee1911e819",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 355,
|
||||||
|
"trimY": 570,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion1_9.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "94e678c5-0780-4f2b-bf3b-86c6c0a75c23",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 422,
|
||||||
|
"trimY": 570,
|
||||||
|
"width": 71,
|
||||||
|
"height": 67,
|
||||||
|
"rawWidth": 71,
|
||||||
|
"rawHeight": 67,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_1.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "89e54317-7835-4d4c-9c04-579da8b33c54",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 462,
|
||||||
|
"trimY": 0,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_10.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "c032eb65-fdf3-41e6-b868-d95df34168df",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 462,
|
||||||
|
"trimY": 88,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_2.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "2a186e00-a0c5-4c8a-b0ab-c84d56dcee7c",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 462,
|
||||||
|
"trimY": 176,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_3.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "083168e3-6ccc-4c5b-a800-2554bffc67d4",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 462,
|
||||||
|
"trimY": 264,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_4.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "d4b12ec9-6f04-493c-91e5-22b1a212262a",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 304,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_5.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "13038788-b0f9-4714-960b-c98619a0d0ce",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 88,
|
||||||
|
"trimY": 304,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_6.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "94c21ed7-94a2-47a4-9537-fe5d9c51d7b0",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 176,
|
||||||
|
"trimY": 304,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_7.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "d5340298-923c-4bd7-9fd7-7a2e029a2b44",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 264,
|
||||||
|
"trimY": 304,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_8.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "c4b145c0-0145-4e09-8559-9ef508d95be8",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 352,
|
||||||
|
"trimY": 304,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion2_9.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "79398d4d-305e-4987-b199-d9d9649cf490",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 456,
|
||||||
|
"trimY": 352,
|
||||||
|
"width": 88,
|
||||||
|
"height": 45,
|
||||||
|
"rawWidth": 88,
|
||||||
|
"rawHeight": 45,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_1.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "84e28787-c6cb-435b-8f59-20d9afe6bf3a",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 0,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_10.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "20d9ce6b-d9ab-4402-8c59-770ad0adf570",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 154,
|
||||||
|
"trimY": 0,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_2.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "0654601f-6788-4a2c-aed4-8dfbe1c5fdd0",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 308,
|
||||||
|
"trimY": 0,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_3.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "0913e11a-c796-4b58-94cf-f70b3869deff",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 152,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_4.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "d6b58622-2cc3-4ee6-a34f-1a18deb73700",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 154,
|
||||||
|
"trimY": 152,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_5.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "b83c6261-b86f-4323-ad11-7375cac02a2b",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 308,
|
||||||
|
"trimY": 152,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_6.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "b458c047-b7b5-4476-996e-d4c1ca85ef9c",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 0,
|
||||||
|
"trimY": 352,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_7.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "3971256a-8120-448e-8adf-de8d67dedfd3",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 152,
|
||||||
|
"trimY": 349,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_8.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "0e548d92-36c8-4795-b3dc-2bc2cfcd7170",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": false,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 201,
|
||||||
|
"trimY": 503,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
},
|
||||||
|
"Explosion3_9.png": {
|
||||||
|
"ver": "1.0.4",
|
||||||
|
"uuid": "25f94245-87b0-4954-abab-c817c80fed37",
|
||||||
|
"rawTextureUuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"trimType": "auto",
|
||||||
|
"trimThreshold": 1,
|
||||||
|
"rotated": true,
|
||||||
|
"offsetX": 0,
|
||||||
|
"offsetY": 0,
|
||||||
|
"trimX": 304,
|
||||||
|
"trimY": 349,
|
||||||
|
"width": 154,
|
||||||
|
"height": 152,
|
||||||
|
"rawWidth": 154,
|
||||||
|
"rawHeight": 152,
|
||||||
|
"borderTop": 0,
|
||||||
|
"borderBottom": 0,
|
||||||
|
"borderLeft": 0,
|
||||||
|
"borderRight": 0,
|
||||||
|
"spriteType": "normal",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.3.3",
|
||||||
|
"uuid": "b11569aa-2e43-4084-a3e5-42eec243c4eb",
|
||||||
|
"type": "raw",
|
||||||
|
"wrapMode": "clamp",
|
||||||
|
"filterMode": "bilinear",
|
||||||
|
"premultiplyAlpha": false,
|
||||||
|
"genMipmaps": false,
|
||||||
|
"packable": true,
|
||||||
|
"platformSettings": {},
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
97
frontend/assets/resources/animation/Fireball/Fireball2.anim
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Fireball2",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.21666666666666667,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 2,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "db4c7e6f-9bee-4e7a-8628-d41b8bcaff42"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "42796576-72b3-49c2-8c5a-ea946fbe1525"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0aa5a52f-a92a-4a4a-b49b-aee2b5a3eb55"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0a7b5e41-acdc-4af3-beff-0a42aca9f91a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "de0b22b7-65ca-455f-bcd1-2ddd6cc114e2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e9ce1383-9e3d-4d44-9f80-ab5fa2224138"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "5b22df7e-414b-44a3-989f-640c5b9417b9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f459615c-70a4-421b-b649-a28460332364"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c2723b9d-fbd8-4524-a0dd-b110451e4e32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "4286b3d1-fea2-41fd-8829-7635f546def4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "4e0d6419-62df-4382-893e-dd7cc47f7770"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.18333333333333332,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f0cd9259-b323-4fba-ad8b-02d5e56c2cd4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0193b66d-06bb-49f9-b2f5-51fff8b16015"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "d2c65ac4-a5b3-411e-8d2d-18d3980649d7",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
73
frontend/assets/resources/animation/Fireball/Fireball3.anim
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Fireball3",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5666666666666667,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 2,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "6af65d40-470c-47de-8b3d-f53c3923bf90"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ebf64819-79a5-4366-bf70-08f3b1c6114c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e03d879b-5227-4c11-a4b9-0a426967d28a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a1aa0c83-4a34-43ae-9a8f-56189808df68"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.26666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "3cc28dd0-2518-4162-a39d-4e4b19f9d60b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.35,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "1b41f500-c55b-4cbf-a040-287b6cc0e958"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.43333333333333335,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "cfa24c51-0ad4-4e3b-b571-c5500002d6e9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d4a46a6a-401c-4694-a192-0a7b3ce6f603"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.55,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c88c5293-9f21-4a1a-a6b6-649e403dc7a2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "6aef5812-d16c-4da1-96a3-a38ac227c823",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -18,61 +18,43 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.06666666666666667,
|
"frame": 0.05,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "dd9a00aa-ddbc-4b01-a7cb-3c43c3a655b6"
|
"__uuid__": "dd9a00aa-ddbc-4b01-a7cb-3c43c3a655b6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.11666666666666667,
|
"frame": 0.08333333333333333,
|
||||||
"value": {
|
|
||||||
"__uuid__": "f66e83bd-1afc-4957-bb16-488d70566ed1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"frame": 0.16666666666666666,
|
|
||||||
"value": {
|
|
||||||
"__uuid__": "bd682c41-dc62-49ff-a96a-18b33e50a6de"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"frame": 0.23333333333333334,
|
|
||||||
"value": {
|
|
||||||
"__uuid__": "94ccab85-e32f-4e13-b0e5-72c798f78ad1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"frame": 0.3,
|
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "e80d3a01-5048-42b7-a280-cb6aa01602c2"
|
"__uuid__": "e80d3a01-5048-42b7-a280-cb6aa01602c2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.36666666666666664,
|
"frame": 0.11666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "d899088c-be62-47b4-9ebf-0a89a2261565"
|
"__uuid__": "d899088c-be62-47b4-9ebf-0a89a2261565"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.4166666666666667,
|
"frame": 0.15,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "5b1e5aa7-fd82-47ae-a5b2-6d4983d848ed"
|
"__uuid__": "5b1e5aa7-fd82-47ae-a5b2-6d4983d848ed"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.48333333333333334,
|
"frame": 0.18333333333333332,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "c2945988-b4bb-4583-a5ef-2fa02b23a347"
|
"__uuid__": "c2945988-b4bb-4583-a5ef-2fa02b23a347"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.5666666666666667,
|
"frame": 0.23333333333333334,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "070ea1e3-9c07-4735-8b94-515ef70216ad"
|
"__uuid__": "070ea1e3-9c07-4735-8b94-515ef70216ad"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.6666666666666666,
|
"frame": 0.2833333333333333,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "3b8bc5c0-26df-4218-b7dc-134a36080a35"
|
"__uuid__": "3b8bc5c0-26df-4218-b7dc-134a36080a35"
|
||||||
}
|
}
|
||||||
|
73
frontend/assets/resources/animation/KnifeGirl/Atk4.anim
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Atk4",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 1.0166666666666666,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "da597a30-22da-4053-b4ee-1cfa27980a75"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b3604b4c-426f-4843-bb76-f09a9687950d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "24b51487-6c91-42d9-bd12-afbbf70f2e4b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2833333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c318ad71-7a5e-43b0-8098-b7a34a6e6fbe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.38333333333333336,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "85d6d8d7-81cf-4369-a501-6ad72d70f5a2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "42b76eaf-db36-4835-9072-893337c83425"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.6,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "152f23a1-f70f-4db6-bb28-68625aef930f"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.8833333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "9c907eb5-84ab-4fa9-9404-9085f29706cc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "74f0ffc8-cc25-4fcf-a6d8-bf093daba9ca"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "2aef91f9-ef47-4bb4-bf43-5441723aa639",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
103
frontend/assets/resources/animation/KnifeGirl/Dying.anim
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Dying",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5333333333333333,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "700f93f9-ef84-4cb2-b759-f39ceac1c1d1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "5b4ea047-594e-4d0b-8e08-e24117bf1e67"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a822576c-d2eb-4c17-8969-03dd1da5a93e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "85e92afc-4359-4a8d-bdfa-958a6134cd6a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "88d6e560-1b65-4d78-949c-cbc0e67d33cc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "9ac16319-c1af-41d1-910b-99cbfd6230b2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.23333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "2a6b168a-458f-4d19-a985-9b00cc6e37e8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.26666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f8482295-dc0d-4265-be56-0b0a9f6f6b9b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.31666666666666665,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0d4a314c-119a-46b9-8dce-dbaacf2523e5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.36666666666666664,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "18d4ff6c-6b57-461b-8588-03521fafc9d1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.4,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f25280f2-442a-4ad7-914e-0f96cbf108f5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.45,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ccccb669-d44d-4a5c-89a1-9aba9476ce12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.48333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "4a45c23d-7bc8-4c5e-b761-ac1100b12a09"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "1c4359c5-b303-403d-82ad-8d5e6ae6ec99"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "ac90c9b8-3b06-4866-89ce-2c953a9d5a9a",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 175 KiB |
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "TurnAround1",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.15,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "28ee1f29-e538-4d36-bb5c-275f9e3b392b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "211a73bb-31d7-4e6c-901e-f6939d9214e0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "048c41dc-fc00-4bc4-8041-6003e7c2b6e4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "9435195e-4560-495e-b1ae-083c0c87e8a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "e906322d-a08b-4477-a2e9-98acd42fa034",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -3,7 +3,7 @@
|
|||||||
"_name": "Walking",
|
"_name": "Walking",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"_native": "",
|
"_native": "",
|
||||||
"_duration": 1.5166666666666666,
|
"_duration": 0.6333333333333333,
|
||||||
"sample": 60,
|
"sample": 60,
|
||||||
"speed": 1.2,
|
"speed": 1.2,
|
||||||
"wrapMode": 2,
|
"wrapMode": 2,
|
||||||
@@ -13,78 +13,78 @@
|
|||||||
"spriteFrame": [
|
"spriteFrame": [
|
||||||
{
|
{
|
||||||
"frame": 0,
|
"frame": 0,
|
||||||
"value": {
|
|
||||||
"__uuid__": "c3b14ecc-a6d9-4cb3-8637-ca7b407a0f5c"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"frame": 0.08333333333333333,
|
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "9435195e-4560-495e-b1ae-083c0c87e8a0"
|
"__uuid__": "9435195e-4560-495e-b1ae-083c0c87e8a0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.18333333333333332,
|
"frame": 0.06666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "ec048360-7a17-4f22-ba52-eb86ec1acae8"
|
"__uuid__": "ec048360-7a17-4f22-ba52-eb86ec1acae8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.2833333333333333,
|
"frame": 0.11666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "82bb81e3-667c-4280-8710-211f4904ef2f"
|
"__uuid__": "82bb81e3-667c-4280-8710-211f4904ef2f"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.4,
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c3b14ecc-a6d9-4cb3-8637-ca7b407a0f5c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.21666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "f958fb7f-ef5a-4918-81f3-564004572f45"
|
"__uuid__": "f958fb7f-ef5a-4918-81f3-564004572f45"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.5333333333333333,
|
"frame": 0.26666666666666666,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "8a0ecf92-db26-4206-9a80-20e749055def"
|
"__uuid__": "8a0ecf92-db26-4206-9a80-20e749055def"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.65,
|
"frame": 0.31666666666666665,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "942f2e02-a700-4fbf-877e-08c93e4d4010"
|
"__uuid__": "942f2e02-a700-4fbf-877e-08c93e4d4010"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.7666666666666667,
|
"frame": 0.36666666666666664,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "30546064-1a11-499e-8523-a82c83951c73"
|
"__uuid__": "30546064-1a11-499e-8523-a82c83951c73"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 0.9,
|
"frame": 0.4166666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "515bb75f-7a1f-4500-8aa9-c895915ce19f"
|
"__uuid__": "515bb75f-7a1f-4500-8aa9-c895915ce19f"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 1.0333333333333334,
|
"frame": 0.4666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "9100da6b-7582-4afb-9698-3d67d3b2012d"
|
"__uuid__": "9100da6b-7582-4afb-9698-3d67d3b2012d"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 1.2166666666666666,
|
"frame": 0.5166666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "1257f72d-0cb3-4750-ae70-13c2d8eb2269"
|
"__uuid__": "1257f72d-0cb3-4750-ae70-13c2d8eb2269"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 1.3833333333333333,
|
"frame": 0.5666666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "1d34b6db-27ba-4e26-864d-0f00d501765e"
|
"__uuid__": "1d34b6db-27ba-4e26-864d-0f00d501765e"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"frame": 1.5,
|
"frame": 0.6166666666666667,
|
||||||
"value": {
|
"value": {
|
||||||
"__uuid__": "c317a75a-52c0-4c38-9300-a064cbf4efb3"
|
"__uuid__": "c317a75a-52c0-4c38-9300-a064cbf4efb3"
|
||||||
}
|
}
|
||||||
|
61
frontend/assets/resources/animation/Monk/Dashing.anim
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Dashing",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.18333333333333332,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ec69a078-4153-49e1-9450-656942c2a567"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.016666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "bbf23710-9dc6-4bbb-9565-df8848819d07"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "cc7b4103-1d6b-44c1-8e0c-ee1c49052837"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "90409bfe-7b6c-4eab-953b-ea630585fad4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "9614dc2a-9bfe-4b85-9aa6-d7d62feec82b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c326e3c0-140f-457b-a086-fe95c025d576"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "8e2d7c5b-452d-44db-b0b4-8ee03b36e7f2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "337d57ad-118c-40e2-be90-2aa1505c152b",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
115
frontend/assets/resources/animation/Monk/Dying.anim
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Dying",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5333333333333333,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "6d1cd049-7a44-4dcb-9018-4f0fbbf3fdf8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "50245b04-bcb1-4488-951c-49944c1037da"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "7a6721bb-2321-4947-832f-9a317565ea88"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.11666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c3553a29-e04a-42e2-8b46-82aa85706e26"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e221838e-740f-45b1-8fd5-80d4ab8563c3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "37ebbd1d-9a18-4514-8331-1358a59cab83"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.23333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b4a9ee91-4315-4fb9-9900-6d763406c81d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.26666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e5388e53-5268-4f54-9a93-f6506db5b77b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.3,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "078814c3-90e2-4b17-a90b-d2046df9a351"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.3333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c605bf48-9cc5-41f1-8ace-a273298f7b21"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.38333333333333336,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "5b5083ca-8fca-4827-9b76-eaa08685b031"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.4166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b454af6f-9e07-4b34-952b-eca69dc13d5e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.45,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "af921d09-a72e-4b48-8585-ba72377ba410"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.48333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "733d339e-ed74-49ab-8955-641d21528fcc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b7335bea-2985-4331-92c2-08c4c2a5ec86"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0ae606ea-93c0-4815-9e24-62c5fb59decc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
5
frontend/assets/resources/animation/Monk/Dying.anim.meta
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "657d4193-2224-44ea-94f7-0305a9f2b322",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 314 KiB |
43
frontend/assets/resources/animation/Monk/TurnAround1.anim
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "TurnAround1",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.15,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ee5e05fa-b515-470f-bc3c-43544f02cb92"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ffa521b6-118e-46e8-be1c-51cc54381ec8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0b27d2c9-c5a3-4020-adbe-0297c1ba3aeb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a47f518e-62fb-4549-8897-4f2d387bd145"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "edd23b2f-1caa-4836-88a7-e4af1f26743e",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
91
frontend/assets/resources/animation/MonkGirl/Atk4.anim
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Atk4",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.5333333333333333,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a9a10466-1e80-4fb8-9c32-2019ee2c988d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.05,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e0e3907f-520c-4c4c-991a-ec554e24f368"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e4bec6fe-db19-4cf6-a8cc-bfcc3e892d5e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.15,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c36ceda7-2e5d-42f4-ae7b-02064348a1c2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.18333333333333332,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "07004da9-abd4-4a05-baee-447235dcdf2d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.23333333333333334,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "dd047451-9715-4e68-9ae5-4e4556007190"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2833333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "7b2acb5e-3ee8-4c26-b950-f201346cefde"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.31666666666666665,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b378b873-fae7-49dd-8581-15136046e2f1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.36666666666666664,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "845b1de6-648f-422a-8289-98222175b787"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.4166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "df09902a-52d8-4dec-9d05-62d3428c4625"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.4666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "da55a31c-ce4a-4003-a119-8c76fd6d1a80"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.5166666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "bd3f63fb-6d6d-47d2-9d96-2b58292fccfa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "168df303-4b6a-4376-940c-3d36fa9e98d8",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
55
frontend/assets/resources/animation/MonkGirl/Dashing.anim
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Dashing",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.18333333333333332,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "b8c177cf-013e-4936-a031-2d3480cf975b"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "ae2d8041-e7ee-4300-b3d6-3e85b146f33c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f0518811-8fc9-4f9c-9ec4-401abdb3917d"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.1,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "3117e445-fe0f-425f-83af-5b719bf8a009"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f9d00d7d-2143-4893-be61-32cf1490c9f2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.16666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "daff32df-5e22-4d4e-94d2-6e4522a02138"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "d7b6d7c4-d2b5-49c6-bbcb-d8d80f52ae7e",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
61
frontend/assets/resources/animation/MonkGirl/Dying.anim
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "Dying",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.45,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "0b31e6af-6d24-4915-b87b-772c6eb10ca7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.06666666666666667,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c597fb09-4621-4d1f-abf9-6484405a6330"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "8c8be852-b65d-41d8-800f-04cbb3cad094"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.2,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "f9522b47-812e-4020-845a-5d9f6d9aca90"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.26666666666666666,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "1ff63b81-49d8-4d68-9526-5f0dc4c88ef0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.3333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "4e96b6fd-2cd1-412b-98a8-7f22040af589"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.43333333333333335,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "a827896b-00b5-4385-9648-2c40414b29c3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "86706adc-e079-4997-883b-3e269d223065",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 227 KiB |
25
frontend/assets/resources/animation/MonkGirl/OnWall.anim
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "OnWall",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.016666666666666666,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "d5c1e6b4-1048-43e2-96f9-801dc23cf418"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "57358699-1d1b-44db-898c-df0c3ce9aab0",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"__type__": "cc.AnimationClip",
|
||||||
|
"_name": "TurnAround1",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_native": "",
|
||||||
|
"_duration": 0.15,
|
||||||
|
"sample": 60,
|
||||||
|
"speed": 1,
|
||||||
|
"wrapMode": 1,
|
||||||
|
"curveData": {
|
||||||
|
"comps": {
|
||||||
|
"cc.Sprite": {
|
||||||
|
"spriteFrame": [
|
||||||
|
{
|
||||||
|
"frame": 0,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "c1a00209-f74d-41b5-a5da-df5720ac34b4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.03333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "2b52c0f1-2360-4a2b-9233-bf5662de09a5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.08333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "e3f9dfe7-ed91-4dc3-b68b-a3a3c2637074"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"frame": 0.13333333333333333,
|
||||||
|
"value": {
|
||||||
|
"__uuid__": "7515ef50-3a14-4e58-8811-a0c890fc40f3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ver": "2.1.0",
|
||||||
|
"uuid": "6e1139d4-03dd-4bd4-9510-606e94f629fe",
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -1,18 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="64" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="135">
|
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="64" tilewidth="16" tileheight="16" infinite="0" nextlayerid="7" nextobjectid="137">
|
||||||
<tileset firstgid="1" source="tiles0.tsx"/>
|
<tileset firstgid="1" source="tiles0.tsx"/>
|
||||||
<tileset firstgid="65" source="tiles1.tsx"/>
|
<tileset firstgid="65" source="tiles1.tsx"/>
|
||||||
<tileset firstgid="129" source="tiles2.tsx"/>
|
<tileset firstgid="129" source="tiles2.tsx"/>
|
||||||
<layer id="6" name="Ground" width="128" height="64">
|
<layer id="6" name="Ground" width="128" height="64">
|
||||||
<data encoding="base64" compression="zlib">
|
<data encoding="base64" compression="zlib">
|
||||||
eJzt2ztuAjEURmELlIYuiKRHyk4iGjo2wP6XkRDGUmThxwx3fC3+U3wNw8v3eEyabEMIWwAAAAAAAAAAAADo4IQ/3h08+3t/B2/KM1BeOzPQXjsz0F47M6iv/c3oc6zeh/7+/Q+NHr1P6z7YGz2H/svWXur1TP/SvqL/OP1LnSz6t7Qt9a1dp//4/VvOgJJeM3hlLf2tzNljI83glY2+9vcMpRko9E/PgFz3NfbBKDNQ7r+kvdU+GHEGHv2/Gl9zNHrOKOh/t5vQX8dt7d+JeC19PDo2yr1+NHEG3i28+m8m8f6//jpnbAzkfsNr15eqfR/1+z/tfxP/Fvj/mFX/0dD/7pz0fsR69p8rmHv20D9vl5mZ1flb67VkP81pT/8QPialmT1z/5f2QK/7v7Q/6Z/vb6F0DvToXzuf1PvDv4Nn/4s4+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/Nvpro782+mujvzb6a6O/tvg/UN4t6E9/+tO/d3+s1/8HUhSy6A==
|
eJzt201uwjAQhuEIxCY7KugeqTepumHXC/T+xyCqYimy4sQ4E2bE9y6eDf+e1w4bOHZddwQAAAAAAAAAAACAF/jBP+8Onv29P4M35Rkor50ZaK+dGWivnRlor50ZtK39UmnL5/owegz94/X/on8Ykfsv9V27n/72a0/drPqfBucZeeMSjxm8m5b+W1m9Dv3fv//c9eG88f3p397fytr1vNR9j31A/1hq21vtg4gziNz/ZvQY+vubrr0fefdv3QOt+0O9/3cm3ZffntwqlZ4fTZqBdwuv/odROv9/g3vBwUDpjFq8dst7q5//vP/0O2B6m1V/T/Qv979nvedY9/jcwTPXHPov9+lXZldjrb/1fqL/c/2vo6W5bTn/S3tg7/Nfsz/pX+5v+Z1L/3i8f3cdhXcHz/6/4uivjf7a6K+N/tror43+2uivjf7a6K+N/tror43+2uivjf7a6K+N/tror43+2uivjf7a6K+N/trSf6C8W9Cf/vSn/6v7Y7/+Dyz1uAA=
|
||||||
</data>
|
</data>
|
||||||
</layer>
|
</layer>
|
||||||
<objectgroup id="1" name="PlayerStartingPos">
|
<objectgroup id="1" name="PlayerStartingPos">
|
||||||
<object id="135" x="1140" y="488">
|
<object id="135" x="1400" y="580">
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
<object id="137" x="1527" y="488">
|
<object id="137" x="1500" y="580">
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="60" x="1232" y="432" width="208" height="16">
|
<object id="60" x="1232" y="448" width="208" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="90" x="1232" y="496" width="320" height="16">
|
<object id="90" x="1248" y="464" width="320" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -114,37 +114,37 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="100" x="1552" y="576" width="128" height="16">
|
<object id="100" x="1538" y="560" width="144" height="32">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="101" x="1568" y="560" width="112" height="16">
|
<object id="101" x="1568" y="528" width="112" height="32">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="102" x="1584" y="544" width="96" height="16">
|
<object id="102" x="1136" y="368" width="96" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="103" x="1600" y="528" width="80" height="16">
|
<object id="103" x="1600" y="496" width="80" height="32">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="104" x="768" y="382" width="304" height="16">
|
<object id="104" x="816" y="414" width="304" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="105" x="768" y="302" width="16" height="96">
|
<object id="105" x="816" y="366" width="16" height="64">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="106" x="1056" y="302" width="16" height="96">
|
<object id="106" x="1104" y="334" width="16" height="96">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
@@ -164,42 +164,7 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="120" x="736" y="512" width="16" height="16">
|
<object id="136" x="1232" y="432" width="208" height="16">
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="121" x="736" y="336" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="125" x="688" y="448" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="127" x="1088" y="320" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="128" x="1120" y="336" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="129" x="1136" y="368" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="130" x="1168" y="384" width="16" height="16">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
</object>
|
|
||||||
<object id="132" x="1184" y="416" width="16" height="16">
|
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
|
@@ -9,9 +9,9 @@ message PlayerDownsync {
|
|||||||
int32 virtualGridX = 2;
|
int32 virtualGridX = 2;
|
||||||
int32 virtualGridY = 3;
|
int32 virtualGridY = 3;
|
||||||
int32 dirX = 4;
|
int32 dirX = 4;
|
||||||
int32 dirY = 5; // "dirX" and "dirY" determines character facing
|
int32 dirY = 5;
|
||||||
int32 velX = 6;
|
int32 velX = 6;
|
||||||
int32 velY = 7; // "velX" and "velY" is used to record the accumulated effect by accelerations (including gravity)
|
int32 velY = 7; // "velX" and "velY" is used to record the accumulated effect by inertia and accelerations (including gravity)
|
||||||
int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
|
int32 speed = 8; // this is the instantaneous scalar attribute of a character, different from but will be accounted in "velX" and "velY"
|
||||||
int32 battleState = 9;
|
int32 battleState = 9;
|
||||||
int32 joinIndex = 10;
|
int32 joinIndex = 10;
|
||||||
@@ -36,6 +36,10 @@ message PlayerDownsync {
|
|||||||
int32 onWallNormX = 27;
|
int32 onWallNormX = 27;
|
||||||
int32 onWallNormY = 28;
|
int32 onWallNormY = 28;
|
||||||
|
|
||||||
|
bool capturedByInertia = 29; // like "inAir", it’s by design a standalone field only inferred by the calc result of "applyInputFrameDownsyncDynamicsOnSingleRenderFrame" instead of "characterState"
|
||||||
|
int32 revivalVirtualGridX = 30;
|
||||||
|
int32 revivalVirtualGridY = 31;
|
||||||
|
|
||||||
string name = 997;
|
string name = 997;
|
||||||
string displayName = 998;
|
string displayName = 998;
|
||||||
string avatar = 999;
|
string avatar = 999;
|
||||||
@@ -51,6 +55,7 @@ message InputFrameDecoded {
|
|||||||
message InputFrameUpsync {
|
message InputFrameUpsync {
|
||||||
int32 inputFrameId = 1;
|
int32 inputFrameId = 1;
|
||||||
uint64 encoded = 2;
|
uint64 encoded = 2;
|
||||||
|
int32 joinIndex = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message InputFrameDownsync {
|
message InputFrameDownsync {
|
||||||
@@ -70,17 +75,9 @@ message WsReq {
|
|||||||
int32 joinIndex = 4;
|
int32 joinIndex = 4;
|
||||||
int32 ackingFrameId = 5;
|
int32 ackingFrameId = 5;
|
||||||
int32 ackingInputFrameId = 6;
|
int32 ackingInputFrameId = 6;
|
||||||
repeated InputFrameUpsync inputFrameUpsyncBatch = 7;
|
int32 authKey = 7;
|
||||||
HeartbeatUpsync hb = 8;
|
repeated InputFrameUpsync inputFrameUpsyncBatch = 8;
|
||||||
}
|
HeartbeatUpsync hb = 9;
|
||||||
|
|
||||||
message WsResp {
|
|
||||||
int32 ret = 1;
|
|
||||||
int32 echoedMsgId = 2;
|
|
||||||
int32 act = 3;
|
|
||||||
RoomDownsyncFrame rdf = 4;
|
|
||||||
repeated InputFrameDownsync inputFrameDownsyncBatch = 5;
|
|
||||||
BattleColliderInfo bciFrame = 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message InputsBufferSnapshot {
|
message InputsBufferSnapshot {
|
||||||
@@ -88,6 +85,7 @@ message InputsBufferSnapshot {
|
|||||||
uint64 unconfirmedMask = 2;
|
uint64 unconfirmedMask = 2;
|
||||||
repeated InputFrameDownsync toSendInputFrameDownsyncs = 3;
|
repeated InputFrameDownsync toSendInputFrameDownsyncs = 3;
|
||||||
bool shouldForceResync = 4;
|
bool shouldForceResync = 4;
|
||||||
|
int32 peerJoinIndex = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message MeleeBullet {
|
message MeleeBullet {
|
||||||
@@ -121,6 +119,11 @@ message MeleeBullet {
|
|||||||
int32 teamId = 19;
|
int32 teamId = 19;
|
||||||
|
|
||||||
int32 bulletLocalId = 20;
|
int32 bulletLocalId = 20;
|
||||||
|
int32 speciesId = 21;
|
||||||
|
int32 explosionFrames = 22;
|
||||||
|
|
||||||
|
int32 blState = 23;
|
||||||
|
int32 framesInBlState = 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FireballBullet {
|
message FireballBullet {
|
||||||
@@ -151,6 +154,10 @@ message FireballBullet {
|
|||||||
|
|
||||||
int32 bulletLocalId = 20;
|
int32 bulletLocalId = 20;
|
||||||
int32 speciesId = 21;
|
int32 speciesId = 21;
|
||||||
|
int32 explosionFrames = 22;
|
||||||
|
|
||||||
|
int32 blState = 23;
|
||||||
|
int32 framesInBlState = 24;
|
||||||
|
|
||||||
int32 virtualGridX = 999;
|
int32 virtualGridX = 999;
|
||||||
int32 virtualGridY = 1000;
|
int32 virtualGridY = 1000;
|
||||||
@@ -161,6 +168,18 @@ message FireballBullet {
|
|||||||
int32 speed = 1005;
|
int32 speed = 1005;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message HolePunchUpsync {
|
||||||
|
string intAuthToken = 1;
|
||||||
|
int32 boundRoomId = 2;
|
||||||
|
int32 authKey = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PeerUdpAddr {
|
||||||
|
string ip = 1;
|
||||||
|
int32 port = 2;
|
||||||
|
int32 authKey = 3;
|
||||||
|
}
|
||||||
|
|
||||||
message BattleColliderInfo {
|
message BattleColliderInfo {
|
||||||
string stageName = 1;
|
string stageName = 1;
|
||||||
|
|
||||||
@@ -177,6 +196,8 @@ message BattleColliderInfo {
|
|||||||
double spaceOffsetX = 11;
|
double spaceOffsetX = 11;
|
||||||
double spaceOffsetY = 12;
|
double spaceOffsetY = 12;
|
||||||
int32 collisionMinStep = 13;
|
int32 collisionMinStep = 13;
|
||||||
|
int32 boundRoomCapacity = 14;
|
||||||
|
PeerUdpAddr battleUdpTunnel = 15;
|
||||||
|
|
||||||
bool frameDataLoggingEnabled = 1024;
|
bool frameDataLoggingEnabled = 1024;
|
||||||
}
|
}
|
||||||
@@ -193,4 +214,15 @@ message RoomDownsyncFrame {
|
|||||||
repeated int32 speciesIdList = 1026;
|
repeated int32 speciesIdList = 1026;
|
||||||
|
|
||||||
int32 bulletLocalIdCounter = 1027;
|
int32 bulletLocalIdCounter = 1027;
|
||||||
|
repeated PeerUdpAddr peerUdpAddrList = 1028;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WsResp {
|
||||||
|
int32 ret = 1;
|
||||||
|
int32 echoedMsgId = 2;
|
||||||
|
int32 act = 3;
|
||||||
|
RoomDownsyncFrame rdf = 4;
|
||||||
|
repeated InputFrameDownsync inputFrameDownsyncBatch = 5;
|
||||||
|
BattleColliderInfo bciFrame = 6;
|
||||||
|
int32 peerJoinIndex = 7;
|
||||||
}
|
}
|
||||||
|
@@ -25,16 +25,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 8
|
"__id__": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 22
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 22
|
"__id__": 29
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 23
|
"__id__": 30
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -324,8 +327,8 @@
|
|||||||
"_color": {
|
"_color": {
|
||||||
"__type__": "cc.Color",
|
"__type__": "cc.Color",
|
||||||
"r": 255,
|
"r": 255,
|
||||||
"g": 255,
|
"g": 0,
|
||||||
"b": 255,
|
"b": 0,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
@@ -482,6 +485,22 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__uuid__": "e8247e2a-1b5b-4618-86f8-224b25246b55"
|
"__uuid__": "e8247e2a-1b5b-4618-86f8-224b25246b55"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "168df303-4b6a-4376-940c-3d36fa9e98d8"
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
"__uuid__": "d7b6d7c4-d2b5-49c6-bbcb-d8d80f52ae7e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "57358699-1d1b-44db-898c-df0c3ce9aab0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "6e1139d4-03dd-4bd4-9510-606e94f629fe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "86706adc-e079-4997-883b-3e269d223065"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"playOnLoad": false,
|
"playOnLoad": false,
|
||||||
@@ -646,13 +665,21 @@
|
|||||||
{
|
{
|
||||||
"__uuid__": "9b500cb0-8048-4715-81db-cc975c914225"
|
"__uuid__": "9b500cb0-8048-4715-81db-cc975c914225"
|
||||||
},
|
},
|
||||||
null,
|
{
|
||||||
|
"__uuid__": "2aef91f9-ef47-4bb4-bf43-5441723aa639"
|
||||||
|
},
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
"__uuid__": "38b2c892-347b-4009-93f8-65b2ab1614f0"
|
"__uuid__": "38b2c892-347b-4009-93f8-65b2ab1614f0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__uuid__": "411f964a-4dd8-424c-b2e2-d92b10474ce2"
|
"__uuid__": "411f964a-4dd8-424c-b2e2-d92b10474ce2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "e906322d-a08b-4477-a2e9-98acd42fa034"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "ac90c9b8-3b06-4866-89ce-2c953a9d5a9a"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"playOnLoad": false,
|
"playOnLoad": false,
|
||||||
@@ -822,6 +849,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__uuid__": "0abbd156-980e-475e-9994-3c958bd913fc"
|
"__uuid__": "0abbd156-980e-475e-9994-3c958bd913fc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "337d57ad-118c-40e2-be90-2aa1505c152b"
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
"__uuid__": "edd23b2f-1caa-4836-88a7-e4af1f26743e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "657d4193-2224-44ea-94f7-0305a9f2b322"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"playOnLoad": false,
|
"playOnLoad": false,
|
||||||
@@ -877,6 +914,244 @@
|
|||||||
"fileId": "7aN7Gcc/tBw5EGlTJVBj2+",
|
"fileId": "7aN7Gcc/tBw5EGlTJVBj2+",
|
||||||
"sync": false
|
"sync": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "HpBar",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [
|
||||||
|
{
|
||||||
|
"__id__": 23
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 28
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 50,
|
||||||
|
"height": 8
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
0,
|
||||||
|
42.256,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "bar",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 22
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 24
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 25
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 10,
|
||||||
|
"g": 252,
|
||||||
|
"b": 0,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 50,
|
||||||
|
"height": 8
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
-25,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 23
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "67e68bc9-dad5-4ad9-a2d8-7e03d458e32f"
|
||||||
|
},
|
||||||
|
"_type": 1,
|
||||||
|
"_sizeMode": 0,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": null,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
|
||||||
|
},
|
||||||
|
"fileId": "1b5Rz5KABPK5Nv1wogghs6",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 22
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "88e79fd5-96b4-4a77-a1f4-312467171014"
|
||||||
|
},
|
||||||
|
"_type": 1,
|
||||||
|
"_sizeMode": 0,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": null,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.ProgressBar",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 22
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_N$totalLength": 50,
|
||||||
|
"_N$barSprite": {
|
||||||
|
"__id__": 24
|
||||||
|
},
|
||||||
|
"_N$mode": 0,
|
||||||
|
"_N$progress": 1,
|
||||||
|
"_N$reverse": false,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "59bff7a2-23e1-4d69-bce7-afb37eae196a"
|
||||||
|
},
|
||||||
|
"fileId": "1cDdFO9Z5KYIcRR52ZmtqO",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "b74b05YDqZFRo4OkZRFZX8k",
|
"__type__": "b74b05YDqZFRo4OkZRFZX8k",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
@@ -895,6 +1170,9 @@
|
|||||||
"coordLabel": {
|
"coordLabel": {
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
},
|
},
|
||||||
|
"hpBar": {
|
||||||
|
"__id__": 27
|
||||||
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -8,7 +8,8 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"optimizationPolicy": 0,
|
"optimizationPolicy": 0,
|
||||||
"asyncLoadAssets": false
|
"asyncLoadAssets": false,
|
||||||
|
"readonly": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@@ -27,20 +28,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 11
|
"__id__": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 14
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 1,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 14
|
"__id__": 17
|
||||||
},
|
|
||||||
{
|
|
||||||
"__id__": 15
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 16
|
"__id__": 18
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -52,25 +52,14 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 1024,
|
"width": 960,
|
||||||
"height": 1920
|
"height": 640
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@@ -86,18 +75,29 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
"_name": "WhiteStars",
|
"_name": "Background",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"_parent": {
|
"_parent": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
@@ -109,37 +109,26 @@
|
|||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
"__type__": "cc.Color",
|
"__type__": "cc.Color",
|
||||||
"r": 255,
|
"r": 0,
|
||||||
"g": 255,
|
"g": 163,
|
||||||
"b": 255,
|
"b": 255,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 268,
|
"width": 1920,
|
||||||
"height": 112
|
"height": 1280
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
-16,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -150,7 +139,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -160,11 +161,18 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "1a2d934e-9d6d-45bf-83c6-564586cc8400"
|
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
|
||||||
},
|
},
|
||||||
"_type": 0,
|
"_type": 0,
|
||||||
"_sizeMode": 1,
|
"_sizeMode": 0,
|
||||||
"_fillType": 0,
|
"_fillType": 0,
|
||||||
"_fillCenter": {
|
"_fillCenter": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -174,12 +182,9 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": {
|
"_atlas": {
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
},
|
},
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -190,7 +195,7 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
|
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
|
||||||
},
|
},
|
||||||
"fileId": "50Mjaee6xFXLrZ/mSBD3P5",
|
"fileId": "83iQr+5XNNF5E2qjV+WUp0",
|
||||||
"sync": false
|
"sync": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -202,7 +207,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 3,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 6
|
"__id__": 6
|
||||||
@@ -229,17 +233,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@@ -255,7 +248,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -265,6 +270,13 @@
|
|||||||
"__id__": 5
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "75a2c1e3-2c22-480c-9572-eb65f4a554e1"
|
"__uuid__": "75a2c1e3-2c22-480c-9572-eb65f4a554e1"
|
||||||
},
|
},
|
||||||
@@ -279,12 +291,9 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": {
|
"_atlas": {
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
},
|
},
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -307,7 +316,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 9
|
"__id__": 9
|
||||||
@@ -327,24 +335,13 @@
|
|||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 111.23,
|
"width": 111.23,
|
||||||
"height": 200
|
"height": 252
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@@ -360,7 +357,19 @@
|
|||||||
0.66667,
|
0.66667,
|
||||||
0.66667
|
0.66667
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Label",
|
"__type__": "cc.Label",
|
||||||
@@ -370,6 +379,11 @@
|
|||||||
"__id__": 8
|
"__id__": 8
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
"_useOriginalSize": false,
|
"_useOriginalSize": false,
|
||||||
"_string": "3",
|
"_string": "3",
|
||||||
"_N$string": "3",
|
"_N$string": "3",
|
||||||
@@ -407,7 +421,6 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 2,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 12
|
"__id__": 12
|
||||||
@@ -434,17 +447,6 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
@@ -460,7 +462,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
@@ -470,6 +484,13 @@
|
|||||||
"__id__": 11
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": {
|
"_spriteFrame": {
|
||||||
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
|
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
|
||||||
},
|
},
|
||||||
@@ -484,12 +505,9 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": {
|
"_atlas": {
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
},
|
},
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -503,6 +521,115 @@
|
|||||||
"fileId": "21dxpL7zlKIIDhUt+GIMbg",
|
"fileId": "21dxpL7zlKIIDhUt+GIMbg",
|
||||||
"sync": false
|
"sync": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "WhiteStars",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 15
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 16
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 268,
|
||||||
|
"height": 112
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
-16,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "1a2d934e-9d6d-45bf-83c6-564586cc8400"
|
||||||
|
},
|
||||||
|
"_type": 0,
|
||||||
|
"_sizeMode": 1,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": {
|
||||||
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "230eeb1f-e0f9-4a41-ab6c-05b3771cbf3e"
|
||||||
|
},
|
||||||
|
"fileId": "50Mjaee6xFXLrZ/mSBD3P5",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "6a3d6Y6Ki1BiqAVSKIRdwRl",
|
"__type__": "6a3d6Y6Ki1BiqAVSKIRdwRl",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
@@ -516,34 +643,6 @@
|
|||||||
},
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"__type__": "cc.Sprite",
|
|
||||||
"_name": "",
|
|
||||||
"_objFlags": 0,
|
|
||||||
"node": {
|
|
||||||
"__id__": 1
|
|
||||||
},
|
|
||||||
"_enabled": true,
|
|
||||||
"_spriteFrame": {
|
|
||||||
"__uuid__": "334d4f93-b007-49e8-9268-35891d4f4ebb"
|
|
||||||
},
|
|
||||||
"_type": 0,
|
|
||||||
"_sizeMode": 1,
|
|
||||||
"_fillType": 0,
|
|
||||||
"_fillCenter": {
|
|
||||||
"__type__": "cc.Vec2",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0
|
|
||||||
},
|
|
||||||
"_fillStart": 0,
|
|
||||||
"_fillRange": 0,
|
|
||||||
"_isTrimmedMode": true,
|
|
||||||
"_state": 0,
|
|
||||||
"_atlas": null,
|
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_id": ""
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
"root": {
|
"root": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ver": "1.2.5",
|
"ver": "1.2.5",
|
||||||
"uuid": "3ed4c7bc-79d0-4075-a563-d5a58ae798f9",
|
"uuid": "dc804c5c-ff76-445e-ac69-52269055c3c5",
|
||||||
"optimizationPolicy": "AUTO",
|
"optimizationPolicy": "AUTO",
|
||||||
"asyncLoadAssets": false,
|
"asyncLoadAssets": false,
|
||||||
"readonly": false,
|
"readonly": false,
|
||||||
|
@@ -24,11 +24,11 @@
|
|||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 8
|
"__id__": 20
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 9
|
"__id__": 21
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -87,12 +87,21 @@
|
|||||||
"_children": [
|
"_children": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 15
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [],
|
"_components": [],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 7
|
"__id__": 19
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -208,6 +217,28 @@
|
|||||||
"groupIndex": 0,
|
"groupIndex": 0,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Animation",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 3
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_defaultClip": {
|
||||||
|
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
|
||||||
|
},
|
||||||
|
"_clips": [
|
||||||
|
{
|
||||||
|
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "7941215a-2b8c-4798-954b-4f1b16d5f6f5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"playOnLoad": false,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
@@ -216,11 +247,7 @@
|
|||||||
"__id__": 3
|
"__id__": 3
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_materials": [
|
"_materials": [],
|
||||||
{
|
|
||||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"_srcBlendFactor": 770,
|
"_srcBlendFactor": 770,
|
||||||
"_dstBlendFactor": 771,
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": null,
|
"_spriteFrame": null,
|
||||||
@@ -240,25 +267,132 @@
|
|||||||
},
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
|
||||||
|
},
|
||||||
|
"fileId": "5f1s6pDt5F3rknJTu0gQW7",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Fireball2",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": false,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 9
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 10
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Animation",
|
"__type__": "cc.Animation",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 3
|
"__id__": 7
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_defaultClip": {
|
"_defaultClip": null,
|
||||||
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
|
|
||||||
},
|
|
||||||
"_clips": [
|
"_clips": [
|
||||||
{
|
{
|
||||||
"__uuid__": "ba12416b-eec3-4260-8402-7fc25b125624"
|
"__uuid__": "d2c65ac4-a5b3-411e-8d2d-18d3980649d7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "14b92f5c-af81-416a-a162-e5822d20fe68"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"playOnLoad": false,
|
"playOnLoad": false,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 7
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": null,
|
||||||
|
"_type": 0,
|
||||||
|
"_sizeMode": 1,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": {
|
||||||
|
"__uuid__": "725c90f9-56f8-48ea-9159-4d2949cd3ce0"
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
"root": {
|
"root": {
|
||||||
@@ -267,7 +401,262 @@
|
|||||||
"asset": {
|
"asset": {
|
||||||
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
|
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
|
||||||
},
|
},
|
||||||
"fileId": "5f1s6pDt5F3rknJTu0gQW7",
|
"fileId": "b0ZpleOHlFqIjwc8HDI9df",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Fireball3",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": false,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 13
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 14
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Animation",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_defaultClip": null,
|
||||||
|
"_clips": [
|
||||||
|
{
|
||||||
|
"__uuid__": "6aef5812-d16c-4da1-96a3-a38ac227c823"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "0dbb90ed-a08a-448c-b06e-4831260e9213"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"playOnLoad": false,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 11
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": null,
|
||||||
|
"_type": 0,
|
||||||
|
"_sizeMode": 1,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": {
|
||||||
|
"__uuid__": "579bc0c1-f5e2-4a5d-889b-9d567e53b0e6"
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
|
||||||
|
},
|
||||||
|
"fileId": "03W6UmKHVAz4hCpMvTCpP9",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "MeleeExplosion",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": false,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 17
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 18
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
24,
|
||||||
|
8,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Animation",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 15
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_defaultClip": null,
|
||||||
|
"_clips": [
|
||||||
|
{
|
||||||
|
"__uuid__": "954a2924-89df-4df4-93fc-36d2b22e7619"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "5bd304eb-c8ba-426f-a9ab-5698ac62de85"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__uuid__": "5054633c-a588-4506-b4ac-eef29b1d8511"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"playOnLoad": false,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 15
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": null,
|
||||||
|
"_type": 0,
|
||||||
|
"_sizeMode": 1,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": {
|
||||||
|
"__uuid__": "1c4c1dcb-54af-485b-9119-abd6d6d84526"
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "d92d4831-cd65-4eb5-90bd-b77021aec35b"
|
||||||
|
},
|
||||||
|
"fileId": "fd9jQiClRJSI00917fifB8",
|
||||||
"sync": false
|
"sync": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -21,20 +21,20 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 10
|
"__id__": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 13
|
"__id__": 12
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 14
|
"__id__": 13
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 15
|
"__id__": 14
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -46,8 +46,72 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 1024,
|
"width": 960,
|
||||||
"height": 1920
|
"height": 640
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_trs": {
|
||||||
|
"__type__": "TypedArray",
|
||||||
|
"ctor": "Float64Array",
|
||||||
|
"array": [
|
||||||
|
480,
|
||||||
|
320,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "Background",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 4
|
||||||
|
},
|
||||||
|
"_opacity": 255,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1280
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -83,6 +147,51 @@
|
|||||||
"groupIndex": 0,
|
"groupIndex": 0,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"node": {
|
||||||
|
"__id__": 2
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"_materials": [
|
||||||
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_srcBlendFactor": 770,
|
||||||
|
"_dstBlendFactor": 771,
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "637f31c2-c53e-4dec-ae11-d56c0c6177ad"
|
||||||
|
},
|
||||||
|
"_type": 0,
|
||||||
|
"_sizeMode": 0,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_atlas": {
|
||||||
|
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__uuid__": "32b8e752-8362-4783-a4a6-1160af8b7109"
|
||||||
|
},
|
||||||
|
"fileId": "a7oR1cZvVO/pp9QJgLnJyt",
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
"_name": "modeButton",
|
"_name": "modeButton",
|
||||||
@@ -92,20 +201,20 @@
|
|||||||
},
|
},
|
||||||
"_children": [
|
"_children": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 6
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 7
|
"__id__": 9
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 8
|
"__id__": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 9
|
"__id__": 11
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -117,8 +226,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 280,
|
"width": 240,
|
||||||
"height": 130
|
"height": 100
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -130,7 +239,7 @@
|
|||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
-564,
|
-90.495,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -159,20 +268,17 @@
|
|||||||
"_name": "Label",
|
"_name": "Label",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"_parent": {
|
"_parent": {
|
||||||
"__id__": 2
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 4
|
"__id__": 7
|
||||||
},
|
|
||||||
{
|
|
||||||
"__id__": 5
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 6
|
"__id__": 8
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -226,7 +332,7 @@
|
|||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 3
|
"__id__": 6
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_materials": [
|
"_materials": [
|
||||||
@@ -235,8 +341,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_useOriginalSize": false,
|
"_useOriginalSize": false,
|
||||||
"_string": "gameRule.mode",
|
"_string": "1 v 1",
|
||||||
"_N$string": "gameRule.mode",
|
"_N$string": "1 v 1",
|
||||||
"_fontSize": 55,
|
"_fontSize": 55,
|
||||||
"_lineHeight": 50,
|
"_lineHeight": 50,
|
||||||
"_enableWrapText": false,
|
"_enableWrapText": false,
|
||||||
@@ -251,17 +357,6 @@
|
|||||||
"_N$cacheMode": 0,
|
"_N$cacheMode": 0,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"__type__": "744dcs4DCdNprNhG0xwq6FK",
|
|
||||||
"_name": "",
|
|
||||||
"_objFlags": 0,
|
|
||||||
"node": {
|
|
||||||
"__id__": 3
|
|
||||||
},
|
|
||||||
"_enabled": true,
|
|
||||||
"_dataID": "gameRule.mode",
|
|
||||||
"_id": ""
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
"root": {
|
"root": {
|
||||||
@@ -278,7 +373,7 @@
|
|||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 2
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_materials": [
|
"_materials": [
|
||||||
@@ -312,7 +407,7 @@
|
|||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 2
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_normalMaterial": null,
|
"_normalMaterial": null,
|
||||||
@@ -375,7 +470,7 @@
|
|||||||
"hoverSprite": null,
|
"hoverSprite": null,
|
||||||
"_N$disabledSprite": null,
|
"_N$disabledSprite": null,
|
||||||
"_N$target": {
|
"_N$target": {
|
||||||
"__id__": 2
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
@@ -390,115 +485,6 @@
|
|||||||
"fileId": "c54lqSflFD8ogSYAhsAkKh",
|
"fileId": "c54lqSflFD8ogSYAhsAkKh",
|
||||||
"sync": false
|
"sync": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"__type__": "cc.Node",
|
|
||||||
"_name": "decoration",
|
|
||||||
"_objFlags": 0,
|
|
||||||
"_parent": {
|
|
||||||
"__id__": 1
|
|
||||||
},
|
|
||||||
"_children": [],
|
|
||||||
"_active": true,
|
|
||||||
"_components": [
|
|
||||||
{
|
|
||||||
"__id__": 11
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"_prefab": {
|
|
||||||
"__id__": 12
|
|
||||||
},
|
|
||||||
"_opacity": 255,
|
|
||||||
"_color": {
|
|
||||||
"__type__": "cc.Color",
|
|
||||||
"r": 255,
|
|
||||||
"g": 255,
|
|
||||||
"b": 255,
|
|
||||||
"a": 255
|
|
||||||
},
|
|
||||||
"_contentSize": {
|
|
||||||
"__type__": "cc.Size",
|
|
||||||
"width": 543,
|
|
||||||
"height": 117
|
|
||||||
},
|
|
||||||
"_anchorPoint": {
|
|
||||||
"__type__": "cc.Vec2",
|
|
||||||
"x": 0.5,
|
|
||||||
"y": 0.5
|
|
||||||
},
|
|
||||||
"_trs": {
|
|
||||||
"__type__": "TypedArray",
|
|
||||||
"ctor": "Float64Array",
|
|
||||||
"array": [
|
|
||||||
0,
|
|
||||||
-312,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"_eulerAngles": {
|
|
||||||
"__type__": "cc.Vec3",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"_is3DNode": false,
|
|
||||||
"_groupIndex": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__type__": "cc.Sprite",
|
|
||||||
"_name": "",
|
|
||||||
"_objFlags": 0,
|
|
||||||
"node": {
|
|
||||||
"__id__": 10
|
|
||||||
},
|
|
||||||
"_enabled": true,
|
|
||||||
"_materials": [
|
|
||||||
{
|
|
||||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"_srcBlendFactor": 770,
|
|
||||||
"_dstBlendFactor": 771,
|
|
||||||
"_spriteFrame": {
|
|
||||||
"__uuid__": "153d890a-fc37-4d59-8779-93a8fb19fa85"
|
|
||||||
},
|
|
||||||
"_type": 0,
|
|
||||||
"_sizeMode": 1,
|
|
||||||
"_fillType": 0,
|
|
||||||
"_fillCenter": {
|
|
||||||
"__type__": "cc.Vec2",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0
|
|
||||||
},
|
|
||||||
"_fillStart": 0,
|
|
||||||
"_fillRange": 0,
|
|
||||||
"_isTrimmedMode": true,
|
|
||||||
"_atlas": {
|
|
||||||
"__uuid__": "030d9286-e8a2-40cf-98f8-baf713f0b8c4"
|
|
||||||
},
|
|
||||||
"_id": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"__type__": "cc.PrefabInfo",
|
|
||||||
"root": {
|
|
||||||
"__id__": 1
|
|
||||||
},
|
|
||||||
"asset": {
|
|
||||||
"__uuid__": "32b8e752-8362-4783-a4a6-1160af8b7109"
|
|
||||||
},
|
|
||||||
"fileId": "1bbMLAzntHZpEudL8lM/Lx",
|
|
||||||
"sync": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"__type__": "dd92bKVy8FJY7uq3ieoNZCZ",
|
"__type__": "dd92bKVy8FJY7uq3ieoNZCZ",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
@@ -508,41 +494,36 @@
|
|||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"modeButton": {
|
"modeButton": {
|
||||||
"__id__": 8
|
"__id__": 10
|
||||||
},
|
},
|
||||||
"mapNode": null,
|
"mapNode": null,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Widget",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_materials": [
|
"alignMode": 1,
|
||||||
{
|
"_target": null,
|
||||||
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
"_alignFlags": 18,
|
||||||
}
|
"_left": 0,
|
||||||
],
|
"_right": 0,
|
||||||
"_srcBlendFactor": 770,
|
"_top": 0,
|
||||||
"_dstBlendFactor": 771,
|
"_bottom": 0,
|
||||||
"_spriteFrame": {
|
"_verticalCenter": 0,
|
||||||
"__uuid__": "7838f276-ab48-445a-b858-937dd27d9520"
|
"_horizontalCenter": 0,
|
||||||
},
|
"_isAbsLeft": true,
|
||||||
"_type": 0,
|
"_isAbsRight": true,
|
||||||
"_sizeMode": 0,
|
"_isAbsTop": true,
|
||||||
"_fillType": 0,
|
"_isAbsBottom": true,
|
||||||
"_fillCenter": {
|
"_isAbsHorizontalCenter": true,
|
||||||
"__type__": "cc.Vec2",
|
"_isAbsVerticalCenter": true,
|
||||||
"x": 0,
|
"_originalWidth": 0,
|
||||||
"y": 0
|
"_originalHeight": 0,
|
||||||
},
|
|
||||||
"_fillStart": 0,
|
|
||||||
"_fillRange": 0,
|
|
||||||
"_isTrimmedMode": true,
|
|
||||||
"_atlas": null,
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -8,7 +8,8 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"optimizationPolicy": 0,
|
"optimizationPolicy": 0,
|
||||||
"asyncLoadAssets": false
|
"asyncLoadAssets": false,
|
||||||
|
"readonly": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@@ -20,18 +21,17 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 6
|
"__id__": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 1,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 9
|
"__id__": 8
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 10
|
"__id__": 9
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -51,24 +51,12 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"_zIndex": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
512,
|
480,
|
||||||
0,
|
480,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -78,7 +66,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Node",
|
"__type__": "cc.Node",
|
||||||
@@ -89,17 +89,13 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 0,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
},
|
|
||||||
{
|
|
||||||
"__id__": 4
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 5
|
"__id__": 4
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -111,32 +107,20 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 303.5,
|
"width": 805.7,
|
||||||
"height": 30
|
"height": 35.28
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"_zIndex": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
210,
|
-150,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -146,7 +130,19 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Label",
|
"__type__": "cc.Label",
|
||||||
@@ -156,32 +152,26 @@
|
|||||||
"__id__": 2
|
"__id__": 2
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"_srcBlendFactor": 1,
|
"_materials": [
|
||||||
"_dstBlendFactor": 771,
|
{
|
||||||
|
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
|
||||||
|
}
|
||||||
|
],
|
||||||
"_useOriginalSize": false,
|
"_useOriginalSize": false,
|
||||||
"_string": "login.tips.loginSuccess",
|
"_string": "Logged in successfully, loading game resources...",
|
||||||
"_N$string": "login.tips.loginSuccess",
|
"_N$string": "Logged in successfully, loading game resources...",
|
||||||
"_fontSize": 30,
|
"_fontSize": 28,
|
||||||
"_lineHeight": 30,
|
"_lineHeight": 28,
|
||||||
"_enableWrapText": true,
|
"_enableWrapText": true,
|
||||||
"_N$file": null,
|
"_N$file": null,
|
||||||
"_isSystemFontUsed": true,
|
"_isSystemFontUsed": true,
|
||||||
"_spacingX": 0,
|
"_spacingX": 0,
|
||||||
|
"_batchAsBitmap": false,
|
||||||
"_N$horizontalAlign": 1,
|
"_N$horizontalAlign": 1,
|
||||||
"_N$verticalAlign": 1,
|
"_N$verticalAlign": 1,
|
||||||
"_N$fontFamily": "Arial",
|
"_N$fontFamily": "Arial",
|
||||||
"_N$overflow": 0,
|
"_N$overflow": 3,
|
||||||
"_id": ""
|
"_N$cacheMode": 0,
|
||||||
},
|
|
||||||
{
|
|
||||||
"__type__": "744dcs4DCdNprNhG0xwq6FK",
|
|
||||||
"_name": "",
|
|
||||||
"_objFlags": 0,
|
|
||||||
"node": {
|
|
||||||
"__id__": 2
|
|
||||||
},
|
|
||||||
"_enabled": true,
|
|
||||||
"_dataID": "login.tips.loginSuccess",
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -204,14 +194,13 @@
|
|||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_level": 0,
|
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 7
|
"__id__": 6
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 8
|
"__id__": 7
|
||||||
},
|
},
|
||||||
"_opacity": 255,
|
"_opacity": 255,
|
||||||
"_color": {
|
"_color": {
|
||||||
@@ -231,24 +220,12 @@
|
|||||||
"x": 0.5,
|
"x": 0.5,
|
||||||
"y": 0.5
|
"y": 0.5
|
||||||
},
|
},
|
||||||
"_quat": {
|
|
||||||
"__type__": "cc.Quat",
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0,
|
|
||||||
"w": 1
|
|
||||||
},
|
|
||||||
"_skewX": 0,
|
|
||||||
"_skewY": 0,
|
|
||||||
"_zIndex": 0,
|
|
||||||
"groupIndex": 0,
|
|
||||||
"_id": "",
|
|
||||||
"_trs": {
|
"_trs": {
|
||||||
"__type__": "TypedArray",
|
"__type__": "TypedArray",
|
||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
333,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -258,16 +235,29 @@
|
|||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"_eulerAngles": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_skewX": 0,
|
||||||
|
"_skewY": 0,
|
||||||
|
"_is3DNode": false,
|
||||||
|
"_groupIndex": 0,
|
||||||
|
"groupIndex": 0,
|
||||||
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.Sprite",
|
"__type__": "cc.Sprite",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
"_objFlags": 0,
|
"_objFlags": 0,
|
||||||
"node": {
|
"node": {
|
||||||
"__id__": 6
|
"__id__": 5
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
|
"_materials": [],
|
||||||
"_srcBlendFactor": 770,
|
"_srcBlendFactor": 770,
|
||||||
"_dstBlendFactor": 771,
|
"_dstBlendFactor": 771,
|
||||||
"_spriteFrame": null,
|
"_spriteFrame": null,
|
||||||
@@ -282,7 +272,6 @@
|
|||||||
"_fillStart": 0,
|
"_fillStart": 0,
|
||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_state": 0,
|
|
||||||
"_atlas": null,
|
"_atlas": null,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
@@ -307,7 +296,7 @@
|
|||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"alignMode": 0,
|
"alignMode": 0,
|
||||||
"_target": null,
|
"_target": null,
|
||||||
"_alignFlags": 20,
|
"_alignFlags": 18,
|
||||||
"_left": 0,
|
"_left": 0,
|
||||||
"_right": 0,
|
"_right": 0,
|
||||||
"_top": 0,
|
"_top": 0,
|
||||||
|
Before Width: | Height: | Size: 121 KiB |
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "2.3.3",
|
|
||||||
"uuid": "825df908-a4cb-449d-9731-8ef53f3fd44f",
|
|
||||||
"type": "sprite",
|
|
||||||
"wrapMode": "clamp",
|
|
||||||
"filterMode": "bilinear",
|
|
||||||
"premultiplyAlpha": false,
|
|
||||||
"genMipmaps": false,
|
|
||||||
"packable": true,
|
|
||||||
"platformSettings": {},
|
|
||||||
"subMetas": {
|
|
||||||
"MiniGame_Background": {
|
|
||||||
"ver": "1.0.4",
|
|
||||||
"uuid": "7838f276-ab48-445a-b858-937dd27d9520",
|
|
||||||
"rawTextureUuid": "825df908-a4cb-449d-9731-8ef53f3fd44f",
|
|
||||||
"trimType": "auto",
|
|
||||||
"trimThreshold": 1,
|
|
||||||
"rotated": false,
|
|
||||||
"offsetX": 0,
|
|
||||||
"offsetY": 0,
|
|
||||||
"trimX": 0,
|
|
||||||
"trimY": 0,
|
|
||||||
"width": 750,
|
|
||||||
"height": 1624,
|
|
||||||
"rawWidth": 750,
|
|
||||||
"rawHeight": 1624,
|
|
||||||
"borderTop": 0,
|
|
||||||
"borderBottom": 0,
|
|
||||||
"borderLeft": 0,
|
|
||||||
"borderRight": 0,
|
|
||||||
"subMetas": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 95 KiB |
@@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"ver": "2.3.3",
|
|
||||||
"uuid": "94b8bb09-e8ac-4402-a933-b79f01b5a813",
|
|
||||||
"type": "sprite",
|
|
||||||
"wrapMode": "clamp",
|
|
||||||
"filterMode": "bilinear",
|
|
||||||
"premultiplyAlpha": false,
|
|
||||||
"genMipmaps": false,
|
|
||||||
"packable": true,
|
|
||||||
"platformSettings": {},
|
|
||||||
"subMetas": {
|
|
||||||
"MiniGame_Blackboard": {
|
|
||||||
"ver": "1.0.4",
|
|
||||||
"uuid": "334d4f93-b007-49e8-9268-35891d4f4ebb",
|
|
||||||
"rawTextureUuid": "94b8bb09-e8ac-4402-a933-b79f01b5a813",
|
|
||||||
"trimType": "auto",
|
|
||||||
"trimThreshold": 1,
|
|
||||||
"rotated": false,
|
|
||||||
"offsetX": 0,
|
|
||||||
"offsetY": 0,
|
|
||||||
"trimX": 0,
|
|
||||||
"trimY": 0,
|
|
||||||
"width": 1024,
|
|
||||||
"height": 1920,
|
|
||||||
"rawWidth": 1024,
|
|
||||||
"rawHeight": 1920,
|
|
||||||
"borderTop": 0,
|
|
||||||
"borderBottom": 0,
|
|
||||||
"borderLeft": 0,
|
|
||||||
"borderRight": 0,
|
|
||||||
"subMetas": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -18,6 +18,8 @@ window.ATK_CHARACTER_STATE = {
|
|||||||
Atk5: [14, "Atk5"],
|
Atk5: [14, "Atk5"],
|
||||||
Dashing: [15, "Dashing"],
|
Dashing: [15, "Dashing"],
|
||||||
OnWall: [16, "OnWall"],
|
OnWall: [16, "OnWall"],
|
||||||
|
TurnAround1: [17, "TurnAround1"],
|
||||||
|
Dying: [18, "Dying"],
|
||||||
};
|
};
|
||||||
|
|
||||||
window.ATK_CHARACTER_STATE_ARR = [];
|
window.ATK_CHARACTER_STATE_ARR = [];
|
||||||
@@ -74,10 +76,10 @@ cc.Class({
|
|||||||
onLoad() {
|
onLoad() {
|
||||||
BaseCharacter.prototype.onLoad.call(this);
|
BaseCharacter.prototype.onLoad.call(this);
|
||||||
this.effAnimNode = this.animNode.getChildByName(this.speciesName);
|
this.effAnimNode = this.animNode.getChildByName(this.speciesName);
|
||||||
this.animComp = this.effAnimNode.getComponent(dragonBones.ArmatureDisplay);
|
//this.animComp = this.effAnimNode.getComponent(dragonBones.ArmatureDisplay);
|
||||||
if (!this.animComp) {
|
//if (!this.animComp) {
|
||||||
this.animComp = this.effAnimNode.getComponent(cc.Animation);
|
this.animComp = this.effAnimNode.getComponent(cc.Animation);
|
||||||
}
|
//}
|
||||||
this.effAnimNode.active = true;
|
this.effAnimNode.active = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ cc.Class({
|
|||||||
} else if (0 < rdfPlayer.DirX) {
|
} else if (0 < rdfPlayer.DirX) {
|
||||||
this.animNode.scaleX = (+1.0);
|
this.animNode.scaleX = (+1.0);
|
||||||
}
|
}
|
||||||
if (ATK_CHARACTER_STATE.OnWall[0] == newCharacterState) {
|
if (ATK_CHARACTER_STATE.OnWall[0] == newCharacterState || ATK_CHARACTER_STATE.TurnAround1[0] == newCharacterState) {
|
||||||
if (0 < rdfPlayer.OnWallNormX) {
|
if (0 < rdfPlayer.OnWallNormX) {
|
||||||
this.animNode.scaleX = (-1.0);
|
this.animNode.scaleX = (-1.0);
|
||||||
} else {
|
} else {
|
||||||
@@ -106,13 +108,13 @@ cc.Class({
|
|||||||
let playingAnimName = null;
|
let playingAnimName = null;
|
||||||
let underlyingAnimationCtrl = null;
|
let underlyingAnimationCtrl = null;
|
||||||
|
|
||||||
if (this.animComp instanceof dragonBones.ArmatureDisplay) {
|
//if (this.animComp instanceof dragonBones.ArmatureDisplay) {
|
||||||
underlyingAnimationCtrl = this.animComp._armature.animation; // ALWAYS use the dragonBones api instead of ccc's wrapper!
|
// underlyingAnimationCtrl = this.animComp._armature.animation; // ALWAYS use the dragonBones api instead of ccc's wrapper!
|
||||||
playingAnimName = underlyingAnimationCtrl.lastAnimationName;
|
// playingAnimName = underlyingAnimationCtrl.lastAnimationName;
|
||||||
} else {
|
//} else {
|
||||||
underlyingAnimationCtrl = this.animComp.currentClip;
|
underlyingAnimationCtrl = this.animComp.currentClip;
|
||||||
playingAnimName = (!underlyingAnimationCtrl ? null : underlyingAnimationCtrl.name);
|
playingAnimName = (!underlyingAnimationCtrl ? null : underlyingAnimationCtrl.name);
|
||||||
}
|
//}
|
||||||
|
|
||||||
// It turns out that "prevRdfPlayer.CharacterState" is not useful in this function :)
|
// It turns out that "prevRdfPlayer.CharacterState" is not useful in this function :)
|
||||||
if (newAnimName == playingAnimName && window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(newCharacterState)) {
|
if (newAnimName == playingAnimName && window.ATK_CHARACTER_STATE_INTERRUPT_WAIVE_SET.has(newCharacterState)) {
|
||||||
@@ -121,11 +123,11 @@ cc.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.animComp instanceof dragonBones.ArmatureDisplay) {
|
//if (this.animComp instanceof dragonBones.ArmatureDisplay) {
|
||||||
this._interruptPlayingAnimAndPlayNewAnimDragonBones(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, underlyingAnimationCtrl, playingAnimName, chConfig);
|
// this._interruptPlayingAnimAndPlayNewAnimDragonBones(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, underlyingAnimationCtrl, playingAnimName, chConfig);
|
||||||
} else {
|
//} else {
|
||||||
this._interruptPlayingAnimAndPlayNewAnimFrameAnim(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, playingAnimName, chConfig);
|
this._interruptPlayingAnimAndPlayNewAnimFrameAnim(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, playingAnimName, chConfig);
|
||||||
}
|
//}
|
||||||
},
|
},
|
||||||
|
|
||||||
_interruptPlayingAnimAndPlayNewAnimDragonBones(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, underlyingAnimationCtrl, playingAnimName, chConfig) {
|
_interruptPlayingAnimAndPlayNewAnimDragonBones(rdfPlayer, prevRdfPlayer, newCharacterState, newAnimName, underlyingAnimationCtrl, playingAnimName, chConfig) {
|
||||||
|
36
frontend/assets/scripts/Bullet.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
window.BULLET_STATE = {
|
||||||
|
Startup: 0,
|
||||||
|
Active: 1,
|
||||||
|
Exploding: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
cc.Class({
|
||||||
|
extends: cc.Component,
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
animNode: {
|
||||||
|
type: cc.Node,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
updateAnim(newAnimName, frameIdxInAnim, dirX, spontaneousLooping, rdf, newAnimIdx) {
|
||||||
|
this.animComp = this.effAnimNode.getComponent(cc.Animation);
|
||||||
|
// Update directions
|
||||||
|
if (this.animComp && this.animComp.node) {
|
||||||
|
if (0 > dirX) {
|
||||||
|
this.animNode.scaleX = (-1.0);
|
||||||
|
} else if (0 < dirX) {
|
||||||
|
this.animNode.scaleX = (1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentClip = this.animComp.currentClip;
|
||||||
|
if (true == spontaneousLooping && (null != currentClip && currentClip.name == newAnimName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const targetClip = this.animComp.getClips()[newAnimIdx];
|
||||||
|
let fromTime = (frameIdxInAnim / targetClip.sample); // TODO: Anyway to avoid using division here?
|
||||||
|
this.animComp.play(newAnimName, fromTime);
|
||||||
|
},
|
||||||
|
});
|
9
frontend/assets/scripts/Bullet.js.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.0.5",
|
||||||
|
"uuid": "a4b909c4-56a8-4b70-b6ea-b7f928077747",
|
||||||
|
"isPlugin": false,
|
||||||
|
"loadPluginInWeb": true,
|
||||||
|
"loadPluginInNative": true,
|
||||||
|
"loadPluginInEditor": false,
|
||||||
|
"subMetas": {}
|
||||||
|
}
|
@@ -8,7 +8,7 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
speed: {
|
speed: {
|
||||||
type: cc.Float,
|
type: cc.Float,
|
||||||
default: 500
|
default: 100
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -29,6 +29,15 @@ cc.Class({
|
|||||||
if (!selfPlayerRichInfo) return;
|
if (!selfPlayerRichInfo) return;
|
||||||
const selfPlayerNode = selfPlayerRichInfo.node;
|
const selfPlayerNode = selfPlayerRichInfo.node;
|
||||||
if (!selfPlayerNode) return;
|
if (!selfPlayerNode) return;
|
||||||
self.mapNode.setPosition(cc.v2().sub(selfPlayerNode.position));
|
const dst = cc.v2().sub(selfPlayerNode.position);
|
||||||
|
const pDiff = dst.sub(self.mapNode.position);
|
||||||
|
const stepLength = dt * self.speed;
|
||||||
|
if (stepLength > pDiff.mag()) {
|
||||||
|
self.mapNode.setPosition(dst);
|
||||||
|
} else {
|
||||||
|
pDiff.normalizeSelf();
|
||||||
|
const newMapPos = self.mapNode.position.add(pDiff.mul(dt * self.speed));
|
||||||
|
self.mapNode.setPosition(newMapPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -10,7 +10,11 @@ cc.Class({
|
|||||||
coordLabel: {
|
coordLabel: {
|
||||||
type: cc.Label,
|
type: cc.Label,
|
||||||
default: null
|
default: null
|
||||||
}
|
},
|
||||||
|
hpBar: {
|
||||||
|
type: cc.ProgressBar,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
@@ -14,10 +14,6 @@ cc.Class({
|
|||||||
type: cc.Node,
|
type: cc.Node,
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
myAvatarNode: {
|
|
||||||
type: cc.Node,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
exitBtnNode: {
|
exitBtnNode: {
|
||||||
type: cc.Node,
|
type: cc.Node,
|
||||||
default: null
|
default: null
|
||||||
@@ -25,10 +21,10 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// LIFE-CYCLE CALLBACKS:
|
// LIFE-CYCLE CALLBACKS:
|
||||||
onLoad() {
|
onLoad() {},
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
init(mapIns) {
|
||||||
|
this.mapIns = mapIns;
|
||||||
if (null != this.firstPlayerInfoNode) {
|
if (null != this.firstPlayerInfoNode) {
|
||||||
this.firstPlayerInfoNode.active = false;
|
this.firstPlayerInfoNode.active = false;
|
||||||
}
|
}
|
||||||
@@ -58,9 +54,10 @@ cc.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
exitBtnOnClick(evt) {
|
exitBtnOnClick(evt) {
|
||||||
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
|
this.mapIns.hideFindingPlayersGUI();
|
||||||
window.closeWSConnection();
|
cc.log(`FindingPlayers.exitBtnOnClick`);
|
||||||
cc.director.loadScene('login');
|
window.closeWSConnection(constants.RET_CODE.BATTLE_STOPPED, "");
|
||||||
|
window.clearLocalStorageAndBackToLoginScene(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
updatePlayersInfo(playerMetas) {
|
updatePlayersInfo(playerMetas) {
|
||||||
@@ -79,20 +76,11 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//显示自己的头像名称以及他人的头像名称
|
|
||||||
for (let i in playerMetas) {
|
for (let i in playerMetas) {
|
||||||
const playerMeta = playerMetas[i];
|
const playerMeta = playerMetas[i];
|
||||||
console.log("Showing playerMeta:", playerMeta);
|
console.log("Showing playerMeta:", playerMeta);
|
||||||
const playerInfoNode = this.playersInfoNode[playerMeta.joinIndex];
|
const playerInfoNode = this.playersInfoNode[playerMeta.joinIndex];
|
||||||
|
|
||||||
(() => { //远程加载头像
|
|
||||||
let remoteUrl = playerMeta.avatar;
|
|
||||||
if (remoteUrl == null || remoteUrl == '') {
|
|
||||||
cc.log(`No avatar to show for :`);
|
|
||||||
cc.log(playerMeta);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
function isEmptyString(str) {
|
function isEmptyString(str) {
|
||||||
return str == null || str == ''
|
return str == null || str == ''
|
||||||
}
|
}
|
||||||
|