Compare commits

...

38 Commits

Author SHA1 Message Date
genxium
b8e757064d Further enhanced frontend input processing and fixed frame data logging. 2023-01-17 17:38:18 +08:00
genxium
71b9e72592 Minor fix. 2023-01-17 15:16:31 +08:00
genxium
21b48b7c0d Updated frontend input generation. 2023-01-17 13:07:26 +08:00
genxium
fbfca965e6 Minor update. 2023-01-17 12:49:49 +08:00
genxium
b27b567c77 Fixed frontend action triggers. 2023-01-17 12:48:51 +08:00
genxium
e9119530f1 Updated README for UDP discussion. 2023-01-16 23:25:40 +08:00
genxium
e6a4295773 Updated charts in README. 2023-01-15 17:43:02 +08:00
Wing
aa14529bf8 Merge pull request #19 from genxium/explosion
Drafted bullet explosion data structure.
2023-01-15 17:23:52 +08:00
genxium
84af0d1572 Drafted bullet explosion data structure. 2023-01-15 17:21:34 +08:00
genxium
16fb23c376 Updated charts and refs in README. 2023-01-14 23:06:45 +08:00
genxium
d1f8a58154 Updated README. 2023-01-14 09:35:56 +08:00
genxium
89c31e8944 Updated README. 2023-01-13 15:13:27 +08:00
genxium
45380d170f Fixed fireball rollback sync. 2023-01-13 14:55:56 +08:00
genxium
dd9c03404e Fixed fireball rollback mechanism. 2023-01-13 12:10:06 +08:00
genxium
29e402ea71 Integrated onwall movements to multiplayer battle. 2023-01-12 18:09:02 +08:00
genxium
b1e3d6525c Fixes for wall jumping. 2023-01-12 16:09:20 +08:00
genxium
845282db50 Minor fix. 2023-01-12 12:55:57 +08:00
genxium
71a5a7b727 Drafted anti-air attack for Monk. 2023-01-11 22:24:31 +08:00
genxium
934a495d47 Updates for fireball bullet. 2023-01-11 18:42:57 +08:00
genxium
9725fb9df2 Minor updates. 2023-01-10 12:47:05 +08:00
Wing
7d922aab0b Merge pull request #18 from genxium/npc
Emergency fix for bullet lifecycle handling.
2023-01-10 12:40:35 +08:00
genxium
823624d95d Implemented basic fireball collision. 2023-01-10 12:37:38 +08:00
genxium
ab122a7bc8 Drafted new character as NPC. 2023-01-08 20:34:29 +08:00
genxium
5b9b3a0b55 Updated documentation. 2023-01-07 22:51:06 +08:00
genxium
24e980c17f Simplified backend input prediction. 2023-01-05 14:07:59 +08:00
genxium
ab6a04693d Enhanced backend input prediction alignment with the frontend counterpart. 2023-01-05 12:14:55 +08:00
genxium
bce26f4663 Minor fix. 2023-01-05 10:34:32 +08:00
Wing
938ca7e57d Merge pull request #17 from genxium/multihit
Added cancellable skills.
2023-01-05 10:23:28 +08:00
genxium
e2191f9d13 Misc fixes. 2023-01-05 10:20:01 +08:00
genxium
2d04363d69 Fixed frontend debug drawer. 2023-01-04 23:49:19 +08:00
genxium
80c6e05731 Initial attempt integrating online battle. 2023-01-02 23:35:56 +08:00
genxium
69581009ee Further simplified proto communication. 2023-01-02 20:42:23 +08:00
genxium
bd870e4059 Misc fixes. 2023-01-02 16:38:13 +08:00
genxium
915bbcae3d Fixes for KnifeGirl anim. 2023-01-02 12:23:15 +08:00
genxium
4c64c1984c Enhanced multihit config. 2023-01-02 00:08:54 +08:00
genxium
325dbfb79c A temp broken commit except for OfflineMap - drafted basic cancellable skills. 2023-01-01 20:18:35 +08:00
genxium
8b80117d3d A temp broken commit except for OfflineMap - refactoring character/skill/bullet config hierarchy. 2023-01-01 15:43:25 +08:00
genxium
c7fc377a2b A temp broken commit except for OfflineMap - refactoring jumping. 2022-12-31 23:28:09 +08:00
163 changed files with 26174 additions and 3102 deletions

View File

@@ -47,3 +47,23 @@ renderFrameId | toApplyInputFrameId
..., ..., ..., 368 | 90
369, 370, 371, 372 | 91
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.

7
MULTIHIT_ROADMAP.md Normal file
View File

@@ -0,0 +1,7 @@
Major goals
- Create several skills that can be chained by pressing "btnA" 3 times, while the 2nd skill cancels the last hit of 1st skill before the latters' FramesToRecover is over, same goes with 2nd->3rd transition.
- Note that each skill can contain "multihit".
Minor goals
- Split jumping anim into "once" part and "keep" part, depending on "character.framesElapsedInChState" we should play the corresponding part
- Add new "chState = STUNNED", which is applicable to both on ground and in air, while "inAir && STUNNED", "character.FramesToRecover" is regarded as infinite. If implemented, make the last hit of the aforementioned 3rd skill "pushback opponent to air".

View File

@@ -1,25 +1,31 @@
# Preface
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). 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) -- not necessarily correct but that's indeed a question to face :)
_(the following gif is sped up to ~1.5x for file size reduction, kindly note that animations are resumed from a partial progress)_
The following video is recorded over INTERNET using an input delay of 4 frames and it feels SMOOTH when playing! Please also checkout [this demo video](https://pan.baidu.com/s/1ML6hNupaPHPJRd5rcTvQvw?pwd=8ruc) 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.
![gif_demo](./charts/jump_sync_spedup.gif)
![gif_demo_1](./charts/internet_fireball_explosion_wallmove_spedup.gif)
Please also checkout [this demo video](https://pan.baidu.com/s/1Lmot9cb0pYylfUvC8G4fDg?pwd=ia97) 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.
![gif_demo_2](./charts/jump_sync_spedup.gif)
The video mainly shows the following features.
- The backend receives inputs from frontend peers and broadcasts back for synchronization.
- The game is recovered for a player upon reconnection.
- 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**.
All gifs are sped up to ~1.5x for file size reduction, kindly note that animations are resumed from a partial progress!
# Notable Features
- Backend dynamics toggle via [Room.BackendDynamicsEnabled](https://github.com/genxium/DelayNoMore/blob/v0.9.14/battle_srv/models/room.go#L786)
- Recovery upon reconnection (only if backend dynamics is ON)
- 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)_
![input_delay_intro](./charts/InputDelayIntro.jpg)
_(how rollback-and-chase in this project roughly works)_
_(how rollback-and-chase in this project roughly works, kindly note that by the current implementation, each frontend only maintains a `lastAllConfirmedInputFrameId` for all the other peers, because the backend only downsyncs all-confirmed inputFrames, see [markConfirmationIfApplicable](https://github.com/genxium/DelayNoMore/blob/v0.9.14/battle_srv/models/room.go#L1085) for more information -- if a serverless peer-to-peer communication is seriously needed here, consider porting [markConfirmationIfApplicable](https://github.com/genxium/DelayNoMore/blob/v0.9.14/battle_srv/models/room.go#L1085) into frontend for maintaining `lastAllConfirmedInputFrameId` under chaotic reception order of inputFrames from peers)_
![server_clients](./charts/ServerClients.jpg)
![rollback_and_chase_intro](./charts/RollbackAndChase.jpg)
(By use of [GopherJs](https://github.com/gopherjs/gopherjs), the frontend codes for dynamics are now automatically generated)
![floating_point_accumulation_err](./charts/AvoidingFloatingPointAccumulationErr.jpg)
# 1. Building & running
@@ -27,7 +33,8 @@ _(how rollback-and-chase in this project roughly works)_
## 1.1 Tools to install
### Backend
- [Command Line Tools for Xcode](https://developer.apple.com/download/all/?q=command%20line%20tools) (on OSX) or [TDM-GCC](https://jmeubank.github.io/tdm-gcc/download/) (on Windows) (a `make` executable mandatory)
- [Golang1.18.6](https://golang.org/dl/) (brought down to 1.18 for GopherJs support, mandatory, in China please try a mirror site like [that of ustc](https://mirrors.ustc.edu.cn/golang/))
- [Golang1.18.6](https://golang.org/dl/) (brought down to 1.18 for _GopherJs_ support, mandatory, in China please try a mirror site like [that of ustc](https://mirrors.ustc.edu.cn/golang/))
- [GopherJs1.18.0-beta1](https://github.com/gopherjs/gopherjs/tree/v1.18.0-beta1) (optional, only for developemnt)
- [MySQL 5.7](https://dev.mysql.com/downloads/windows/installer/5.7.html) (mandatory, for OSX not all versions of 5.7 can be found thus 5.7.24 is recommended)
- [Redis 3.0.503 or above](https://redis.io/download/) (mandatory)
- [skeema](https://www.skeema.io/) (optional, only for convenient MySQL schema provisioning)

View File

@@ -10,67 +10,129 @@ func toPbRoomDownsyncFrame(rdf *battle.RoomDownsyncFrame) *pb.RoomDownsyncFrame
return nil
}
ret := &pb.RoomDownsyncFrame{
Id: rdf.Id,
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
CountdownNanos: rdf.CountdownNanos,
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
ShouldForceResync: rdf.ShouldForceResync,
PlayerOpPatternToSkillId: make(map[int32]int32),
Id: rdf.Id,
PlayersArr: make([]*pb.PlayerDownsync, len(rdf.PlayersArr), len(rdf.PlayersArr)),
BulletLocalIdCounter: rdf.BulletLocalIdCounter,
MeleeBullets: make([]*pb.MeleeBullet, len(rdf.MeleeBullets), len(rdf.MeleeBullets)),
FireballBullets: make([]*pb.FireballBullet, len(rdf.FireballBullets), len(rdf.FireballBullets)),
CountdownNanos: rdf.CountdownNanos,
BackendUnconfirmedMask: rdf.BackendUnconfirmedMask,
ShouldForceResync: rdf.ShouldForceResync,
}
for i, last := range rdf.PlayersArr {
pbPlayer := &pb.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
FramesToRecover: last.FramesToRecover,
Hp: last.Hp,
MaxHp: last.MaxHp,
Removed: last.Removed,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
}
ret.PlayersArr[i] = pbPlayer
}
for i, last := range rdf.MeleeBullets {
pbBullet := &pb.MeleeBullet{
BattleLocalId: last.BattleLocalId,
StartupFrames: last.StartupFrames,
ActiveFrames: last.ActiveFrames,
RecoveryFrames: last.RecoveryFrames,
RecoveryFramesOnBlock: last.RecoveryFramesOnBlock,
RecoveryFramesOnHit: last.RecoveryFramesOnHit,
HitboxOffset: last.HitboxOffset,
HitStunFrames: last.HitStunFrames,
BlockStunFrames: last.BlockStunFrames,
Pushback: last.Pushback,
ReleaseTriggerType: last.ReleaseTriggerType,
Damage: last.Damage,
BulletLocalId: last.BattleAttr.BulletLocalId,
OriginatedRenderFrameId: last.BattleAttr.OriginatedRenderFrameId,
OffenderJoinIndex: last.BattleAttr.OffenderJoinIndex,
TeamId: last.BattleAttr.TeamId,
SelfMoveforwardX: last.SelfMoveforwardX,
SelfMoveforwardY: last.SelfMoveforwardY,
HitboxSizeX: last.HitboxSizeX,
HitboxSizeY: last.HitboxSizeY,
StartupFrames: last.Bullet.StartupFrames,
CancellableStFrame: last.Bullet.CancellableStFrame,
CancellableEdFrame: last.Bullet.CancellableEdFrame,
ActiveFrames: last.Bullet.ActiveFrames,
OffenderJoinIndex: last.OffenderJoinIndex,
OffenderPlayerId: last.OffenderPlayerId,
HitStunFrames: last.Bullet.HitStunFrames,
BlockStunFrames: last.Bullet.BlockStunFrames,
PushbackVelX: last.Bullet.PushbackVelX,
PushbackVelY: last.Bullet.PushbackVelY,
Damage: last.Bullet.Damage,
SelfLockVelX: last.Bullet.SelfLockVelX,
SelfLockVelY: last.Bullet.SelfLockVelY,
HitboxOffsetX: last.Bullet.HitboxOffsetX,
HitboxOffsetY: last.Bullet.HitboxOffsetY,
HitboxSizeX: last.Bullet.HitboxSizeX,
HitboxSizeY: last.Bullet.HitboxSizeY,
BlowUp: last.Bullet.BlowUp,
SpeciesId: last.Bullet.SpeciesId,
ExplosionFrames: last.Bullet.ExplosionFrames,
BlState: last.BlState,
FramesInBlState: last.FramesInBlState,
}
ret.MeleeBullets[i] = pbBullet
}
for i, last := range rdf.PlayerOpPatternToSkillId {
ret.PlayerOpPatternToSkillId[int32(i)] = int32(last)
for i, last := range rdf.FireballBullets {
pbBullet := &pb.FireballBullet{
BulletLocalId: last.BattleAttr.BulletLocalId,
OriginatedRenderFrameId: last.BattleAttr.OriginatedRenderFrameId,
OffenderJoinIndex: last.BattleAttr.OffenderJoinIndex,
TeamId: last.BattleAttr.TeamId,
StartupFrames: last.Bullet.StartupFrames,
CancellableStFrame: last.Bullet.CancellableStFrame,
CancellableEdFrame: last.Bullet.CancellableEdFrame,
ActiveFrames: last.Bullet.ActiveFrames,
HitStunFrames: last.Bullet.HitStunFrames,
BlockStunFrames: last.Bullet.BlockStunFrames,
PushbackVelX: last.Bullet.PushbackVelX,
PushbackVelY: last.Bullet.PushbackVelY,
Damage: last.Bullet.Damage,
SelfLockVelX: last.Bullet.SelfLockVelX,
SelfLockVelY: last.Bullet.SelfLockVelY,
HitboxOffsetX: last.Bullet.HitboxOffsetX,
HitboxOffsetY: last.Bullet.HitboxOffsetY,
HitboxSizeX: last.Bullet.HitboxSizeX,
HitboxSizeY: last.Bullet.HitboxSizeY,
BlowUp: last.Bullet.BlowUp,
SpeciesId: last.Bullet.SpeciesId,
ExplosionFrames: last.Bullet.ExplosionFrames,
BlState: last.BlState,
FramesInBlState: last.FramesInBlState,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
Speed: last.Speed,
}
ret.FireballBullets[i] = pbBullet
}
return ret
@@ -84,22 +146,31 @@ func toPbPlayers(modelInstances map[int32]*Player, withMetaInfo bool) []*pb.Play
for _, last := range modelInstances {
pbPlayer := &pb.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
FramesToRecover: last.FramesToRecover,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
}
if withMetaInfo {
pbPlayer.Name = last.Name
@@ -120,21 +191,33 @@ func toJsPlayers(modelInstances map[int32]*Player) []*battle.PlayerDownsync {
for _, last := range modelInstances {
toRet[last.JoinIndex-1] = &battle.PlayerDownsync{
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
InAir: last.InAir,
JoinIndex: last.JoinIndex,
ColliderRadius: last.ColliderRadius,
Score: last.Score,
Removed: last.Removed,
Id: last.Id,
VirtualGridX: last.VirtualGridX,
VirtualGridY: last.VirtualGridY,
DirX: last.DirX,
DirY: last.DirY,
VelX: last.VelX,
VelY: last.VelY,
FramesToRecover: last.FramesToRecover,
FramesInChState: last.FramesInChState,
ActiveSkillId: last.ActiveSkillId,
ActiveSkillHit: last.ActiveSkillHit,
FramesInvinsible: last.FramesInvinsible,
Speed: last.Speed,
BattleState: last.BattleState,
CharacterState: last.CharacterState,
JoinIndex: last.JoinIndex,
BulletTeamId: last.BulletTeamId,
ChCollisionTeamId: last.ChCollisionTeamId,
Hp: last.Hp,
MaxHp: last.MaxHp,
ColliderRadius: last.ColliderRadius,
InAir: last.InAir,
OnWall: last.OnWall,
OnWallNormX: last.OnWallNormX,
OnWallNormY: last.OnWallNormY,
Score: last.Score,
Removed: last.Removed,
}
}

View File

@@ -46,9 +46,10 @@ type Player struct {
TutorialStage int `db:"tutorial_stage"`
// other in-battle info fields
LastSentInputFrameId int32
AckingFrameId int32
AckingInputFrameId int32
LastReceivedInputFrameId int32
LastSentInputFrameId int32
AckingFrameId int32
AckingInputFrameId int32
}
func ExistPlayerByName(name string) (bool, error) {

View File

@@ -49,7 +49,7 @@ const (
)
const (
DEFAULT_PLAYER_RADIUS = float64(12)
DEFAULT_PLAYER_RADIUS = int32(float64(12) * battle.WORLD_TO_VIRTUAL_GRID_RATIO)
)
type RoomBattleState struct {
@@ -88,15 +88,16 @@ func calRoomScore(inRoomPlayerCount int32, roomPlayerCnt int, currentRoomBattleS
}
type Room struct {
Id int32
Capacity int
collisionSpaceOffsetX float64
collisionSpaceOffsetY float64
playerOpPatternToSkillId map[int]int
Players map[int32]*Player
PlayersArr []*Player // ordered by joinIndex
Space *resolv.Space
CollisionSysMap map[int32]*resolv.Object
Id int32
Capacity int
BattleDurationFrames int32
NstDelayFrames int32
Players map[int32]*Player
PlayersArr []*Player // ordered by joinIndex
SpeciesIdList []int32 // ordered by joinIndex
CharacterConfigsArr []*battle.CharacterConfig // ordered by joinIndex
Space *resolv.Space
CollisionSysMap map[int32]*resolv.Object
/**
* The following `PlayerDownsyncSessionDict` is NOT individually put
* under `type Player struct` for a reason.
@@ -127,7 +128,7 @@ type Room struct {
EffectivePlayerCount int32
DismissalWaitGroup sync.WaitGroup
InputsBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange]
InputsBufferLock sync.Mutex // Guards [InputsBuffer, LatestPlayerUpsyncedInputFrameId, LastAllConfirmedInputFrameId, LastAllConfirmedInputList, LastAllConfirmedInputFrameIdWithChange, LastIndividuallyConfirmedInputList, player.LastReceivedInputFrameId]
RenderFrameBuffer *battle.RingBuffer // Indices are STRICTLY consecutive
LatestPlayerUpsyncedInputFrameId int32
LastAllConfirmedInputFrameId int32
@@ -138,7 +139,6 @@ type Room struct {
BackendDynamicsEnabled bool
ForceAllResyncOnAnyActiveSlowTicker bool
LastRenderFrameIdTriggeredAt int64
PlayerDefaultSpeed int32
BulletBattleLocalIdCounter int32
dilutedRollbackEstimatedDtNanos int64
@@ -148,7 +148,8 @@ type Room struct {
TmxPointsMap StrToVec2DListMap
TmxPolygonsMap StrToPolygon2DListMap
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
rdfIdToActuallyUsedInput map[int32]*pb.InputFrameDownsync
LastIndividuallyConfirmedInputList []uint64
}
func (pR *Room) updateScore() {
@@ -168,11 +169,13 @@ func (pR *Room) AddPlayerIfPossible(pPlayerFromDbInit *Player, session *websocke
}
defer pR.onPlayerAdded(playerId)
pPlayerFromDbInit.AckingFrameId = -1
pPlayerFromDbInit.AckingInputFrameId = -1
pPlayerFromDbInit.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.LastReceivedInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_NORMAL_ADDED
pPlayerFromDbInit.BattleState = PlayerBattleStateIns.ADDED_PENDING_BATTLE_COLLIDER_ACK
pPlayerFromDbInit.Speed = pR.PlayerDefaultSpeed // Hardcoded
pPlayerFromDbInit.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
pPlayerFromDbInit.InAir = true // Hardcoded
@@ -210,7 +213,7 @@ func (pR *Room) ReAddPlayerIfPossible(pTmpPlayerInstance *Player, session *webso
pEffectiveInRoomPlayerInstance.AckingInputFrameId = -1
pEffectiveInRoomPlayerInstance.LastSentInputFrameId = MAGIC_LAST_SENT_INPUT_FRAME_ID_READDED
pEffectiveInRoomPlayerInstance.BattleState = PlayerBattleStateIns.READDED_PENDING_BATTLE_COLLIDER_ACK
pEffectiveInRoomPlayerInstance.Speed = pR.PlayerDefaultSpeed // Hardcoded
pEffectiveInRoomPlayerInstance.ColliderRadius = DEFAULT_PLAYER_RADIUS // Hardcoded
pEffectiveInRoomPlayerInstance.InAir = true // Hardcoded
@@ -289,35 +292,14 @@ func (pR *Room) ChooseStage() error {
//Logger.Info("parsed tmx:", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("strToVec2DListMap", strToVec2DListMap), zap.Any("strToPolygon2DListMap", strToPolygon2DListMap))
pR.StageDiscreteW = stageDiscreteW
pR.StageDiscreteH = stageDiscreteH
pR.StageTileW = stageTileW
pR.StageTileH = stageTileH
pR.SpaceOffsetX = float64((stageDiscreteW * stageTileW) >> 1)
pR.SpaceOffsetY = float64((stageDiscreteH * stageTileH) >> 1)
pR.TmxPointsMap = strToVec2DListMap
pR.TmxPolygonsMap = strToPolygon2DListMap
return nil
}
func (pR *Room) ConvertToInputFrameId(renderFrameId int32, inputDelayFrames int32) int32 {
if renderFrameId < inputDelayFrames {
return 0
}
return ((renderFrameId - inputDelayFrames) >> pR.InputScaleFrames)
}
func (pR *Room) ConvertToGeneratingRenderFrameId(inputFrameId int32) int32 {
return (inputFrameId << pR.InputScaleFrames)
}
func (pR *Room) ConvertToFirstUsedRenderFrameId(inputFrameId int32, inputDelayFrames int32) int32 {
return ((inputFrameId << pR.InputScaleFrames) + inputDelayFrames)
}
func (pR *Room) ConvertToLastUsedRenderFrameId(inputFrameId int32, inputDelayFrames int32) int32 {
return ((inputFrameId << pR.InputScaleFrames) + inputDelayFrames + (1 << pR.InputScaleFrames) - 1)
}
func (pR *Room) RenderFrameBufferString() string {
return fmt.Sprintf("{renderFrameId: %d, stRenderFrameId: %d, edRenderFrameId: %d, curDynamicsRenderFrameId: %d}", pR.RenderFrameId, pR.RenderFrameBuffer.StFrameId, pR.RenderFrameBuffer.EdFrameId, pR.CurDynamicsRenderFrameId)
}
@@ -353,7 +335,20 @@ func (pR *Room) playerDownsyncStr(player *battle.PlayerDownsync) string {
if player.InAir {
inAirInt = 1
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover,inAirInt)
onWallInt := 0
if player.OnWall {
onWallInt = 1
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d}", player.JoinIndex, player.VirtualGridX, player.VirtualGridY, player.VelX, player.VelY, player.FramesToRecover, inAirInt, onWallInt)
return s
}
func (pR *Room) fireballDownsyncStr(fireball *battle.FireballBullet) string {
if nil == fireball {
return ""
}
s := fmt.Sprintf("{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d}", fireball.BattleAttr.BulletLocalId, fireball.BattleAttr.OriginatedRenderFrameId, fireball.BattleAttr.OffenderJoinIndex, fireball.VirtualGridX, fireball.VirtualGridY, fireball.VelX, fireball.VelY, fireball.DirX, fireball.DirY, fireball.Bullet.HitboxSizeX, fireball.Bullet.HitboxSizeY)
return s
}
@@ -383,7 +378,11 @@ func (pR *Room) rdfIdToActuallyUsedInputString() string {
for _, player := range rdf.PlayersArr {
playersStrBldr = append(playersStrBldr, pR.playerDownsyncStr(player))
}
s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
fireballsStrBldr := make([]string, 0, len(rdf.FireballBullets))
for _, fireball := range rdf.FireballBullets {
fireballsStrBldr = append(fireballsStrBldr, pR.fireballDownsyncStr(fireball))
}
s = append(s, fmt.Sprintf("rdfId:%d\nplayers:[%v]\nfireballs:[%v]\nactuallyUsedinputList:{%v}", rdfId, strings.Join(playersStrBldr, ","), strings.Join(fireballsStrBldr, ","), pR.inputFrameDownsyncStr(pR.rdfIdToActuallyUsedInput[rdfId])))
}
return strings.Join(s, "\n")
@@ -397,28 +396,28 @@ func (pR *Room) StartBattle() {
pR.RenderFrameId = 0
// [WARNING] Only since battle starts do we have all players bound to certain joinIndexes.
for _, player := range pR.Players {
opJoinIndexPrefix := (int(player.JoinIndex) << uint(8))
pR.playerOpPatternToSkillId[opJoinIndexPrefix+0] = 1 // Hardcoded for now
speciesId := int(player.JoinIndex - 1) // FIXME: Hardcoded the values for now
if player.JoinIndex == 1 {
speciesId = 4096
}
chosenCh := battle.Characters[speciesId]
pR.CharacterConfigsArr[player.JoinIndex-1] = chosenCh
pR.SpeciesIdList[player.JoinIndex-1] = int32(speciesId)
}
Logger.Info("[StartBattle] ", zap.Any("roomId", pR.Id), zap.Any("roomState", pR.State), zap.Any("SpeciesIdList", pR.SpeciesIdList))
// Initialize the "collisionSys" as well as "RenderFrameBuffer"
pR.CurDynamicsRenderFrameId = 0
kickoffFrameJs := &battle.RoomDownsyncFrame{
Id: pR.RenderFrameId,
PlayersArr: toJsPlayers(pR.Players),
PlayerOpPatternToSkillId: pR.playerOpPatternToSkillId,
CountdownNanos: pR.BattleDurationNanos,
Id: pR.RenderFrameId,
PlayersArr: toJsPlayers(pR.Players),
CountdownNanos: pR.BattleDurationNanos,
}
pR.RenderFrameBuffer.Put(kickoffFrameJs)
// Refresh "Colliders"
spaceW := pR.StageDiscreteW * pR.StageTileW
spaceH := pR.StageDiscreteH * pR.StageTileH
pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY = float64(spaceW)*0.5, float64(spaceH)*0.5
pR.refreshColliders(spaceW, spaceH)
pR.refreshColliders()
/*
Will be triggered from a goroutine which executes the critical `Room.AddPlayerIfPossible`, thus the `battleMainLoop` should be detached.
@@ -432,7 +431,7 @@ func (pR *Room) StartBattle() {
Logger.Error("battleMainLoop, recovery spot#1, recovered from: ", zap.Any("roomId", pR.Id), zap.Any("panic", r))
}
pR.StopBattleForSettlement()
Logger.Info(fmt.Sprintf("The `battleMainLoop` for roomId=%v is stopped@renderFrameId=%v, with battleDurationFrames=%v:\n%v", pR.Id, pR.RenderFrameId, pR.BattleDurationFrames, pR.InputsBufferString(false))) // This takes sometime to print
Logger.Info(fmt.Sprintf("The `battleMainLoop` for roomId=%v is stopped@renderFrameId=%v:\n%v", pR.Id, pR.RenderFrameId, pR.InputsBufferString(false))) // This takes sometime to print
if pR.FrameDataLoggingEnabled {
rdfIdToActuallyUsedInputDump := pR.rdfIdToActuallyUsedInputString()
os.WriteFile(fmt.Sprintf("room_%d.txt", pR.Id), []byte(rdfIdToActuallyUsedInputDump), 0644) // DEBUG ONLY
@@ -481,7 +480,9 @@ func (pR *Room) StartBattle() {
continue
}
kickoffFrameJs := pR.RenderFrameBuffer.GetByFrameId(0).(*battle.RoomDownsyncFrame)
pR.sendSafely(toPbRoomDownsyncFrame(kickoffFrameJs), nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
pbKickOffRenderFrame := toPbRoomDownsyncFrame(kickoffFrameJs)
pbKickOffRenderFrame.SpeciesIdList = pR.SpeciesIdList
pR.sendSafely(pbKickOffRenderFrame, nil, DOWNSYNC_MSG_ACT_BATTLE_START, playerId, true)
}
Logger.Info(fmt.Sprintf("In `battleMainLoop` for roomId=%v sent out kickoffFrame", pR.Id))
}
@@ -550,10 +551,6 @@ func (pR *Room) StartBattle() {
})
}
func (pR *Room) toDiscreteInputsBufferIndex(inputFrameId int32, joinIndex int32) int32 {
return (inputFrameId << 2) + joinIndex // allowing joinIndex upto 15
}
func (pR *Room) OnBattleCmdReceived(pReq *pb.WsReq) {
/*
[WARNING] This function "OnBattleCmdReceived" could be called by different ws sessions and thus from different threads!
@@ -744,14 +741,11 @@ func (pR *Room) OnDismissed() {
// Always instantiates new HeapRAM blocks and let the old blocks die out due to not being retained by any root reference.
pR.BulletBattleLocalIdCounter = 0
pR.WorldToVirtualGridRatio = float64(100)
pR.VirtualGridToWorldRatio = float64(1.0) / pR.WorldToVirtualGridRatio // this is a one-off computation, should avoid division in iterations
pR.SpAtkLookupFrames = 5
pR.PlayerDefaultSpeed = int32(float64(1) * pR.WorldToVirtualGridRatio) // in virtual grids per frame
pR.CollisionMinStep = (int32(float64(pR.PlayerDefaultSpeed)*pR.VirtualGridToWorldRatio) << 3) // the approx minimum distance a player can move per frame in world coordinate
pR.playerOpPatternToSkillId = make(map[int]int)
pR.CollisionMinStep = 8 // the approx minimum distance a player can move per frame in world coordinate
pR.Players = make(map[int32]*Player)
pR.PlayersArr = make([]*Player, pR.Capacity)
pR.SpeciesIdList = make([]int32, pR.Capacity)
pR.CharacterConfigsArr = make([]*battle.CharacterConfig, pR.Capacity)
pR.CollisionSysMap = make(map[int32]*resolv.Object)
pR.PlayerDownsyncSessionDict = make(map[int32]*websocket.Conn)
for _, oldWatchdog := range pR.PlayerActiveWatchdogDict {
@@ -768,6 +762,7 @@ func (pR *Room) OnDismissed() {
pR.RenderFrameBuffer = battle.NewRingBuffer(pR.RenderCacheSize)
pR.InputsBuffer = battle.NewRingBuffer((pR.RenderCacheSize >> 1) + 1)
pR.rdfIdToActuallyUsedInput = make(map[int32]*pb.InputFrameDownsync)
pR.LastIndividuallyConfirmedInputList = make([]uint64, pR.Capacity)
pR.LatestPlayerUpsyncedInputFrameId = -1
pR.LastAllConfirmedInputFrameId = -1
@@ -776,26 +771,20 @@ func (pR *Room) OnDismissed() {
pR.RenderFrameId = 0
pR.CurDynamicsRenderFrameId = 0
pR.InputDelayFrames = 8
pR.NstDelayFrames = 16
pR.InputScaleFrames = uint32(2)
pR.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.RollbackEstimatedDtNanos = 16666666 // A little smaller than the actual per frame time, just for logging FAST FRAME
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(pR.ServerFps) / dilutedServerFps)
pR.BattleDurationFrames = 60 * pR.ServerFps
pR.dilutedRollbackEstimatedDtNanos = int64(float64(pR.RollbackEstimatedDtNanos) * float64(serverFps) / dilutedServerFps)
pR.BattleDurationFrames = int32(60 * serverFps)
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
pR.InputFrameUpsyncDelayTolerance = (pR.NstDelayFrames >> pR.InputScaleFrames) - 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.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.BackendDynamicsEnabled = true // [WARNING] When "false", recovery upon reconnection wouldn't work!
pR.ForceAllResyncOnAnyActiveSlowTicker = true // See tradeoff discussion in "downsyncToAllPlayers"
pR.SnapIntoPlatformOverlap = float64(0.1)
pR.SnapIntoPlatformThreshold = float64(0.5)
pR.JumpingInitVelY = int32(float64(7) * pR.WorldToVirtualGridRatio)
pR.GravityX = 0
pR.GravityY = -int32(float64(0.5) * pR.WorldToVirtualGridRatio) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
pR.FrameDataLoggingEnabled = false // [WARNING] DON'T ENABLE ON LONG BATTLE DURATION! It consumes A LOT OF MEMORY!
@@ -914,6 +903,10 @@ func (pR *Room) onPlayerAdded(playerId int32) {
pR.Players[playerId].JoinIndex = int32(index) + 1
pR.JoinIndexBooleanArr[index] = true
speciesId := index // FIXME
chosenCh := battle.Characters[speciesId]
pR.Players[playerId].Speed = chosenCh.Speed
// Lazily assign the initial position of "Player" for "RoomDownsyncFrame".
playerPosList := *pR.TmxPointsMap["PlayerStartingPos"]
if index > len(playerPosList) {
@@ -924,7 +917,7 @@ func (pR *Room) onPlayerAdded(playerId int32) {
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))
}
pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y, pR.WorldToVirtualGridRatio)
pR.Players[playerId].VirtualGridX, pR.Players[playerId].VirtualGridY = battle.WorldToVirtualGridPos(playerPos.X, playerPos.Y)
// Hardcoded initial character orientation/facing
if 0 == (pR.Players[playerId].JoinIndex % 2) {
pR.Players[playerId].DirX = -2
@@ -1043,24 +1036,10 @@ func (pR *Room) sendSafely(roomDownsyncFrame *pb.RoomDownsyncFrame, toSendInputF
}
}
func (pR *Room) shouldPrefabInputFrameDownsync(prevRenderFrameId int32, renderFrameId int32) (bool, int32) {
for i := prevRenderFrameId + 1; i <= renderFrameId; i++ {
if (0 <= i) && (0 == (i & ((1 << pR.InputScaleFrames) - 1))) {
return true, i
}
}
return false, -1
}
func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputFrameDownsync {
/*
[WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked.
Kindly note that on backend the prefab is much simpler than its frontend counterpart, because frontend will upsync its latest command immediately if there's any change w.r.t. its own prev cmd, thus if no upsync received from a frontend,
- EITHER it's due to local lag and bad network,
- OR there's no change w.r.t. to its prev cmd.
*/
var currInputFrameDownsync *battle.InputFrameDownsync = nil
tmp1 := pR.InputsBuffer.GetByFrameId(inputFrameId) // Would be nil if "pR.InputsBuffer.EdFrameId <= inputFrameId", else if "pR.InputsBuffer.EdFrameId > inputFrameId" is already met, then by now we can just return "tmp1.(*InputFrameDownsync)"
if nil == tmp1 {
@@ -1072,18 +1051,26 @@ func (pR *Room) getOrPrefabInputFrameDownsync(inputFrameId int32) *battle.InputF
ConfirmedList: uint64(0),
}
j2 := j - 1
tmp2 := pR.InputsBuffer.GetByFrameId(j2)
if nil != tmp2 {
prevInputFrameDownsync := tmp2.(*battle.InputFrameDownsync)
for i, _ := range currInputFrameDownsync.InputList {
currInputFrameDownsync.InputList[i] = prevInputFrameDownsync.InputList[i]
}
}
/*
[WARNING] Don't reference "pR.InputsBuffer.GetByFrameId(j-1)" to prefab here!
Otherwise if an ActiveSlowTicker got a forced confirmation sequence like
```
inputFrame#42 {dx: -2} upsynced;
inputFrame#43-50 {dx: +2} ignored by [type#1 forceConfirmation];
inputFrame#51 {dx: +2} upsynced;
inputFrame#52-60 {dx: +2} ignored by [type#1 forceConfirmation];
inputFrame#61 {dx: +2} upsynced;
...there would be more [type#1 forceConfirmation]s for this ActiveSlowTicker if it doesn't catch up the upsync pace...
```
, the backend might've been prefabbing TOO QUICKLY and thus still replicating "inputFrame#42" by now for this ActiveSlowTicker, making its graphics inconsistent upon "[type#1 forceConfirmation] at inputFrame#52-60", i.e. as if always dragged to the left while having been controlled to the right for a few frames -- what's worse, the same graphical inconsistence could even impact later "[type#1 forceConfirmation]s" if this ActiveSlowTicker doesn't catch up with the upsync pace!
*/
for i, _ := range currInputFrameDownsync.InputList {
// [WARNING] The use of "InputsBufferLock" guarantees that by now "inputFrameId >= pR.InputsBuffer.EdFrameId >= pR.LatestPlayerUpsyncedInputFrameId", thus it's safe to use "pR.LastIndividuallyConfirmedInputList" for prediction.
// Don't predict "btnA & btnB"!
currInputFrameDownsync.InputList[i] = (currInputFrameDownsync.InputList[i] & uint64(15))
currInputFrameDownsync.InputList[i] = (pR.LastIndividuallyConfirmedInputList[i] & uint64(15))
}
pR.InputsBuffer.Put(currInputFrameDownsync)
@@ -1105,8 +1092,8 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#1: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
continue
}
if clientInputFrameId < pR.LastAllConfirmedInputFrameId {
Logger.Debug(fmt.Sprintf("Omitting obsolete inputFrameUpsync#2: roomId=%v, playerId=%v, clientInputFrameId=%v, InputsBuffer=%v", pR.Id, playerId, clientInputFrameId, pR.InputsBufferString(false)))
if clientInputFrameId < player.LastReceivedInputFrameId {
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
}
if clientInputFrameId > pR.InputsBuffer.EdFrameId {
@@ -1118,6 +1105,9 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
targetInputFrameDownsync.InputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
targetInputFrameDownsync.ConfirmedList |= uint64(1 << uint32(player.JoinIndex-1))
player.LastReceivedInputFrameId = clientInputFrameId
pR.LastIndividuallyConfirmedInputList[player.JoinIndex-1] = inputFrameUpsync.Encoded
if clientInputFrameId > pR.LatestPlayerUpsyncedInputFrameId {
pR.LatestPlayerUpsyncedInputFrameId = clientInputFrameId
}
@@ -1170,7 +1160,7 @@ func (pR *Room) markConfirmationIfApplicable(inputFrameUpsyncBatch []*pb.InputFr
*/
snapshotStFrameId := (pR.LastAllConfirmedInputFrameId - newAllConfirmedCount)
refRenderFrameIdIfNeeded := pR.CurDynamicsRenderFrameId - 1
refSnapshotStFrameId := pR.ConvertToInputFrameId(refRenderFrameIdIfNeeded, pR.InputDelayFrames)
refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(refRenderFrameIdIfNeeded)
if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId
}
@@ -1186,7 +1176,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
totPlayerCnt := uint32(pR.Capacity)
allConfirmedMask := uint64((1 << totPlayerCnt) - 1)
unconfirmedMask := uint64(0)
if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + (pR.NstDelayFrames >> pR.InputScaleFrames)) {
if pR.LatestPlayerUpsyncedInputFrameId > (pR.LastAllConfirmedInputFrameId + pR.InputFrameUpsyncDelayTolerance + 1) {
// Type#1 check whether there's a significantly slow ticker among players
oldLastAllConfirmedInputFrameId := pR.LastAllConfirmedInputFrameId
for j := pR.LastAllConfirmedInputFrameId + 1; j <= pR.LatestPlayerUpsyncedInputFrameId; j++ {
@@ -1200,7 +1190,7 @@ func (pR *Room) forceConfirmationIfApplicable(prevRenderFrameId int32) uint64 {
pR.onInputFrameDownsyncAllConfirmed(inputFrameDownsync, -1)
}
if 0 < unconfirmedMask {
Logger.Info(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, oldLastAllConfirmedInputFrameId:%d, newLastAllConfirmedInputFrameId:%d, (pR.NstDelayFrames >> pR.InputScaleFrames):%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameId, (pR.NstDelayFrames >> pR.InputScaleFrames), pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
Logger.Info(fmt.Sprintf("[type#1 forceConfirmation] For roomId=%d@renderFrameId=%d, curDynamicsRenderFrameId=%d, LatestPlayerUpsyncedInputFrameId:%d, oldLastAllConfirmedInputFrameId:%d, newLastAllConfirmedInputFrameId:%d, InputFrameUpsyncDelayTolerance:%d, unconfirmedMask=%d; there's a slow ticker suspect, forcing all-confirmation", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LatestPlayerUpsyncedInputFrameId, oldLastAllConfirmedInputFrameId, pR.LastAllConfirmedInputFrameId, pR.InputFrameUpsyncDelayTolerance, unconfirmedMask))
}
} else {
// Type#2 helps resolve the edge case when all players are disconnected temporarily
@@ -1237,7 +1227,7 @@ func (pR *Room) produceInputsBufferSnapshotWithCurDynamicsRenderFrameAsRef(uncon
}
}
func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32, spaceOffsetX, spaceOffsetY float64) {
func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRenderFrameId int32) {
// [WARNING] This function MUST BE called while "pR.InputsBufferLock" is locked!
if fromRenderFrameId >= toRenderFrameId {
return
@@ -1251,7 +1241,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
panic(fmt.Sprintf("collisionSysRenderFrameId=%v doesn't exist for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v)! RenderFrameBuffer=%v", collisionSysRenderFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, pR.RenderFrameBufferString()))
}
currRenderFrame := currRenderFrameTmp.(*battle.RoomDownsyncFrame)
delayedInputFrameId := pR.ConvertToInputFrameId(collisionSysRenderFrameId, pR.InputDelayFrames)
delayedInputFrameId := battle.ConvertToDelayedInputFrameId(collisionSysRenderFrameId)
if 0 <= delayedInputFrameId {
if delayedInputFrameId > pR.LastAllConfirmedInputFrameId {
panic(fmt.Sprintf("delayedInputFrameId=%v is not yet all-confirmed for roomId=%v, this is abnormal because it's to be used for applying dynamics to [fromRenderFrameId:%v, toRenderFrameId:%v) @ collisionSysRenderFrameId=%v! InputsBuffer=%v", delayedInputFrameId, pR.Id, fromRenderFrameId, toRenderFrameId, collisionSysRenderFrameId, pR.InputsBufferString(false)))
@@ -1275,29 +1265,16 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
}
}
nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.GravityX, pR.GravityY, pR.JumpingInitVelY, pR.InputDelayFrames, pR.InputScaleFrames, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformThreshold, pR.WorldToVirtualGridRatio, pR.VirtualGridToWorldRatio, pR.playerOpPatternToSkillId)
nextRenderFrame := battle.ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(pR.InputsBuffer, currRenderFrame, pR.Space, pR.CollisionSysMap, pR.SpaceOffsetX, pR.SpaceOffsetY, pR.CharacterConfigsArr)
pR.RenderFrameBuffer.Put(nextRenderFrame)
pR.CurDynamicsRenderFrameId++
}
}
func (pR *Room) refreshColliders(spaceW, spaceH int32) {
func (pR *Room) refreshColliders() {
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
topPadding, bottomPadding, leftPadding, rightPadding := pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap, pR.SnapIntoPlatformOverlap
pR.Space = resolv.NewSpace(int(spaceW), int(spaceH), int(pR.CollisionMinStep), int(pR.CollisionMinStep)) // allocate a new collision space everytime after a battle is settled
jsPlayers := toJsPlayers(pR.Players)
for _, player := range jsPlayers {
wx, wy := battle.VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio)
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
playerCollider := battle.GenerateRectCollider(wx, wy, colliderWidth, colliderHeight, topPadding, bottomPadding, leftPadding, rightPadding, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, player, "Player") // the coords of all barrier boundaries are multiples of tileWidth(i.e. 16), by adding snapping y-padding when "landedOnGravityPushback" all "playerCollider.Y" would be a multiple of 1.0
pR.Space.Add(playerCollider)
// Keep track of the collider in "pR.CollisionSysMap"
joinIndex := player.JoinIndex
collisionPlayerIndex := battle.COLLISION_PLAYER_INDEX_PREFIX + joinIndex
pR.CollisionSysMap[collisionPlayerIndex] = playerCollider
}
pR.Space = resolv.NewSpace(int(pR.SpaceOffsetX*2), int(pR.SpaceOffsetY*2), int(pR.CollisionMinStep), int(pR.CollisionMinStep)) // allocate a new collision space everytime after a battle is settled
for _, player := range pR.Players {
joinIndex := player.JoinIndex
@@ -1310,7 +1287,7 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) {
// For debug-printing only.
Logger.Info("ChooseStage printing polygon2D for barrierPolygon2DList", zap.Any("barrierLocalIdInBattle", barrierLocalIdInBattle), zap.Any("polygon2D.Anchor", polygon2D.Anchor), zap.Any("polygon2D.Points", polygon2D.Points))
*/
barrierCollider := battle.GenerateConvexPolygonCollider(polygon2DUnaligned, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, nil, "Barrier")
barrierCollider := battle.GenerateConvexPolygonCollider(polygon2DUnaligned, pR.SpaceOffsetX, pR.SpaceOffsetY, nil, "Barrier")
pR.Space.Add(barrierCollider)
}
}
@@ -1329,8 +1306,8 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
Logger.Debug(fmt.Sprintf("doBattleMainLoopPerTickBackendDynamicsWithProperLocking-InputsBufferLock unlocked: roomId=%v", pR.Id))
}()
if ok, thatRenderFrameId := pR.shouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok {
noDelayInputFrameId := pR.ConvertToInputFrameId(thatRenderFrameId, 0)
if ok, thatRenderFrameId := battle.ShouldPrefabInputFrameDownsync(prevRenderFrameId, pR.RenderFrameId); ok {
noDelayInputFrameId := battle.ConvertToNoDelayInputFrameId(thatRenderFrameId)
pR.getOrPrefabInputFrameDownsync(noDelayInputFrameId)
}
@@ -1341,9 +1318,9 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
if 0 <= pR.LastAllConfirmedInputFrameId {
dynamicsStartedAt := utils.UnixtimeNano()
// Apply "all-confirmed inputFrames" to move forward "pR.CurDynamicsRenderFrameId"
nextDynamicsRenderFrameId := pR.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames) + 1
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, InputDelayFrames=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, pR.InputDelayFrames, nextDynamicsRenderFrameId))
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY)
nextDynamicsRenderFrameId := battle.ConvertToLastUsedRenderFrameId(pR.LastAllConfirmedInputFrameId) + 1
Logger.Debug(fmt.Sprintf("roomId=%v, room.RenderFrameId=%v, room.CurDynamicsRenderFrameId=%v, LastAllConfirmedInputFrameId=%v, nextDynamicsRenderFrameId=%v", pR.Id, pR.RenderFrameId, pR.CurDynamicsRenderFrameId, pR.LastAllConfirmedInputFrameId, nextDynamicsRenderFrameId))
pR.applyInputFrameDownsyncDynamics(pR.CurDynamicsRenderFrameId, nextDynamicsRenderFrameId)
*pDynamicsDuration = utils.UnixtimeNano() - dynamicsStartedAt
}
@@ -1360,12 +1337,12 @@ func (pR *Room) doBattleMainLoopPerTickBackendDynamicsWithProperLocking(prevRend
if 0 < unconfirmedMask {
// [WARNING] As "pR.CurDynamicsRenderFrameId" was just incremented above, "refSnapshotStFrameId" is most possibly larger than "oldLastAllConfirmedInputFrameId + 1", therefore this initial assignment is critical for `ACTIVE NORMAL TICKER`s to receive consecutive ids of inputFrameDownsync.
snapshotStFrameId := oldLastAllConfirmedInputFrameId + 1
refSnapshotStFrameId := pR.ConvertToInputFrameId(pR.CurDynamicsRenderFrameId-1, pR.InputDelayFrames)
refSnapshotStFrameId := battle.ConvertToDelayedInputFrameId(pR.CurDynamicsRenderFrameId - 1)
if refSnapshotStFrameId < snapshotStFrameId {
snapshotStFrameId = refSnapshotStFrameId
}
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)
}
}
@@ -1472,18 +1449,16 @@ func (pR *Room) downsyncToSinglePlayer(playerId int32, player *Player, refRender
}
refRenderFrame := tmp.(*battle.RoomDownsyncFrame)
refRenderFrame.PlayerOpPatternToSkillId = pR.playerOpPatternToSkillId
for i, player := range pR.PlayersArr {
refRenderFrame.PlayersArr[i].ColliderRadius = player.ColliderRadius // hardcoded for now
}
if shouldResync3 {
refRenderFrame.ShouldForceResync = true
}
refRenderFrame.BackendUnconfirmedMask = unconfirmedMask
pR.sendSafely(toPbRoomDownsyncFrame(refRenderFrame), toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, false)
pbRefRenderFrame := toPbRoomDownsyncFrame(refRenderFrame)
pbRefRenderFrame.SpeciesIdList = pR.SpeciesIdList
pR.sendSafely(pbRefRenderFrame, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_FORCED_RESYNC, playerId, 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 {
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))
if shouldResync1 || shouldResync3 {
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 {
pR.sendSafely(nil, toSendInputFrameDownsyncsSnapshot, DOWNSYNC_MSG_ACT_INPUT_BATCH, playerId, false)

File diff suppressed because it is too large Load Diff

View File

@@ -240,37 +240,23 @@ func Serve(c *gin.Context) {
// Construct "battleColliderInfo" to downsync
bciFrame := &pb.BattleColliderInfo{
BoundRoomId: pRoom.Id,
StageName: pRoom.StageName,
StageDiscreteW: pRoom.StageDiscreteW,
StageDiscreteH: pRoom.StageDiscreteH,
StageTileW: pRoom.StageTileW,
StageTileH: pRoom.StageTileH,
BoundRoomId: pRoom.Id,
StageName: pRoom.StageName,
IntervalToPing: int32(Constants.Ws.IntervalToPing),
WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor),
BattleDurationNanos: pRoom.BattleDurationNanos,
IntervalToPing: int32(Constants.Ws.IntervalToPing),
WillKickIfInactiveFor: int32(Constants.Ws.WillKickIfInactiveFor),
BattleDurationNanos: pRoom.BattleDurationNanos,
ServerFps: pRoom.ServerFps,
InputDelayFrames: pRoom.InputDelayFrames,
InputScaleFrames: pRoom.InputScaleFrames,
NstDelayFrames: pRoom.NstDelayFrames,
InputFrameUpsyncDelayTolerance: pRoom.InputFrameUpsyncDelayTolerance,
MaxChasingRenderFramesPerUpdate: pRoom.MaxChasingRenderFramesPerUpdate,
PlayerBattleState: pThePlayer.BattleState, // For frontend to know whether it's rejoining
RollbackEstimatedDtMillis: pRoom.RollbackEstimatedDtMillis,
RollbackEstimatedDtNanos: pRoom.RollbackEstimatedDtNanos,
WorldToVirtualGridRatio: pRoom.WorldToVirtualGridRatio,
VirtualGridToWorldRatio: pRoom.VirtualGridToWorldRatio,
SpaceOffsetX: pRoom.SpaceOffsetX,
SpaceOffsetY: pRoom.SpaceOffsetY,
SpAtkLookupFrames: pRoom.SpAtkLookupFrames,
RenderCacheSize: pRoom.RenderCacheSize,
SnapIntoPlatformOverlap: pRoom.SnapIntoPlatformOverlap,
SnapIntoPlatformThreshold: pRoom.SnapIntoPlatformThreshold,
JumpingInitVelY: pRoom.JumpingInitVelY,
GravityX: pRoom.GravityX,
GravityY: pRoom.GravityY,
CollisionMinStep: pRoom.CollisionMinStep,
RenderCacheSize: pRoom.RenderCacheSize,
CollisionMinStep: pRoom.CollisionMinStep,
FrameDataLoggingEnabled: pRoom.FrameDataLoggingEnabled,
}

File diff suppressed because one or more lines are too long

View File

@@ -14,3 +14,15 @@ ffmpeg -vsync vfr -i input.gif output%d.png
```
The `-vsync vfr` tells ffmpeg to disrespect the original delays set within the GIF file, otherwise many duplicate frame will be extracted by the default 60FPS.
More complicated transparent padding example (used when alignment in image source is much more preferred than aligning in codes)
```
ffmpeg -vsync vfr -i LayDown1.gif -vf "scale=iw:188:force_original_aspect_ratio=decrease,pad=iw:188:0:(oh-ih):color=#00000000,format=rgba" pngs/LayDown1_%d.png
```
The command above uses same input-output width, but pads the output height with a top transparent section such that the output height is fixed to 188px.
Similarly to crop a gif into pngs.
```
ffmpeg -vsync vfr -i Idle1.gif -vf "crop=70:ih:(iw-ow-10):0" pngs/Idle1_%d.png
```

BIN
charts/ServerClients.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

View File

@@ -0,0 +1 @@
This module is no longer useful, as we can now use GopherJs+OfflineMap to visualize experimental game dynamics.

View File

@@ -4,8 +4,10 @@ go 1.18
require (
resolv v0.0.0
jsexport v0.0.0
)
replace (
resolv => ../resolv_tailored
jsexport => ../jsexport
)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "c7c2ac6e-f1ea-4233-b6a4-aa5b96b61e17",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,55 @@
{
"__type__": "cc.AnimationClip",
"_name": "Fireball1Explosion",
"_objFlags": 0,
"_native": "",
"_duration": 0.26666666666666666,
"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.15,
"value": {
"__uuid__": "8b566f26-b34d-4da6-bdaa-078358a5b685"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "6ec5f75d-307e-4292-b667-cbbb5a52c2f6"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "d89977f1-d927-4a08-9591-9feb1daf68c8"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "7941215a-2b8c-4798-954b-4f1b16d5f6f5",
"subMetas": {}
}

View File

@@ -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": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "954a2924-89df-4df4-93fc-36d2b22e7619",
"subMetas": {}
}

View File

@@ -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": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "5bd304eb-c8ba-426f-a9ab-5698ac62de85",
"subMetas": {}
}

View File

@@ -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": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "5054633c-a588-4506-b4ac-eef29b1d8511",
"subMetas": {}
}

View File

@@ -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>

View File

@@ -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": {}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -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": {}
}

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "b07a911d-2d61-486d-9edc-1b3ba53c9911",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,145 @@
{
"__type__": "cc.AnimationClip",
"_name": "Fireball1",
"_objFlags": 0,
"_native": "",
"_duration": 0.35,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "dbe67025-9878-4e13-8f3d-81e04734810a"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "e92702d5-d5fd-49e6-ab6b-2296b43fa6d6"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "e1a89340-0b92-4e6b-93f2-e983302d70ce"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "b0bb4a7a-4ae3-48fc-9913-3b6d1d36c56f"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "b44d585b-8e18-4767-b263-ed3a53cd3250"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "a87a9ea8-2d84-4a3b-83e3-a4d7b8ac96b8"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "a1604f9d-c0ea-4f92-b09b-3608245bda8e"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "4372818f-1e44-4180-a0ce-4a34cee4fc5b"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "dbe67025-9878-4e13-8f3d-81e04734810a"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "5d867617-7f50-4fa8-804d-ce28c47ea407"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "824c9bee-42b7-4a94-86f8-6356f11aee16"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "6389164e-93bb-4d4d-9740-5e2d5cdb1029"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "d184a083-6043-4ca6-bd14-8db1b6be1d2e"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "361b1722-e362-46e5-939e-e2d1666df374"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "662fbe4f-a1f4-46f7-83e4-eafd021432da"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "5e509118-a44b-4e7f-9686-c6bb0b30f0b0"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "bc1110c7-4423-4c43-965c-0cb3dd8e31ff"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "33cc8d11-1568-47a7-b4f1-cef4888302e5"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "83bb5dd3-510c-4fce-b393-840f14efb8cd"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "1db706f5-366a-421c-843f-a4bb016f80ec"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "41a4f35a-01c0-4a22-b5cc-7bfe25ed4501"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "ba12416b-eec3-4260-8402-7fc25b125624",
"subMetas": {}
}

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "15043c55-01a9-408c-b985-910c5de144c7",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.6,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "6b2a1a09-8236-4972-8aee-1781b6547d4e"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "5b269b2e-0800-4bf5-b5db-055b78cf318d"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "e184f831-3f90-47cb-8ca5-ad9446ba0398"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "f260f82b-10cf-49af-b46c-cd8dc7a3503f"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "09f43e75-0986-4b8f-907b-e5a5a73b7c54"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "d7432402-fcbd-4e2e-b2c1-33364f31948b"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "8acf1c5a-6910-47d6-aa18-1e6f07546d7a"
}
},
{
"frame": 0.38333333333333336,
"value": {
"__uuid__": "76120dbd-6390-4706-9580-dcec9687e83e"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "f9a7a04a-2369-4946-8313-c2da896da51e"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "c8fb14e2-745e-4a2b-b235-d43195052652"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "1f23e0e5-830c-4d07-8f80-cbb98a2a1954"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "4c512398-4290-4fdf-bb21-2b0062a9071b"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "829b17c6-9365-4e97-b14f-fa266bd5ecbe",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk2",
"_objFlags": 0,
"_native": "",
"_duration": 1.0166666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "60f9f7d4-5cf7-4098-9455-0f6a74963fc6"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "dd9a00aa-ddbc-4b01-a7cb-3c43c3a655b6"
}
},
{
"frame": 0.11666666666666667,
"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": {
"__uuid__": "e80d3a01-5048-42b7-a280-cb6aa01602c2"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "d899088c-be62-47b4-9ebf-0a89a2261565"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "5b1e5aa7-fd82-47ae-a5b2-6d4983d848ed"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "c2945988-b4bb-4583-a5ef-2fa02b23a347"
}
},
{
"frame": 0.5666666666666667,
"value": {
"__uuid__": "070ea1e3-9c07-4735-8b94-515ef70216ad"
}
},
{
"frame": 0.6666666666666666,
"value": {
"__uuid__": "3b8bc5c0-26df-4218-b7dc-134a36080a35"
}
},
{
"frame": 1,
"value": {
"__uuid__": "3898259f-a3b0-490d-b260-f86ab5109dfe"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "52b8e47d-715c-4c12-a2c9-6f553e14dc42",
"subMetas": {}
}

View File

@@ -0,0 +1,79 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk3",
"_objFlags": 0,
"_native": "",
"_duration": 1.0166666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "51ab185b-2271-48b5-a897-af79721d566c"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "c29fd95d-7467-4138-9e01-6421af63dd68"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "3285b5eb-c6be-4cb9-ac60-c506645fee4b"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "13fd4a87-71f4-4b69-a5b3-413d564c35e6"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "7189e229-00d6-427a-8ea1-d05fbd97824f"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "d9ccfe33-3db7-4b3a-807c-adb2121fb7c7"
}
},
{
"frame": 0.6833333333333333,
"value": {
"__uuid__": "a51cbc29-0826-46f7-a38b-8b0f996fbace"
}
},
{
"frame": 0.8833333333333333,
"value": {
"__uuid__": "7e9f3a24-6abc-4b49-a5c5-a0c100865ffc"
}
},
{
"frame": 0.95,
"value": {
"__uuid__": "ecbaeb43-1118-483a-91c9-ff1ff01b7b33"
}
},
{
"frame": 1,
"value": {
"__uuid__": "58afa365-a916-4ec6-aab3-1c87f5332b12"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "9b500cb0-8048-4715-81db-cc975c914225",
"subMetas": {}
}

View File

@@ -0,0 +1,43 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.26666666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "9b90ae89-7fbe-4bb6-ab15-fc08462f54c5"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "aeb3553a-6de4-4197-9f06-d7cc3fa7c4cf"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "07650461-a7c0-4638-92fc-fa436752c045"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "ca22d473-83aa-4146-b732-89d0246a2968"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "2a50c853-000b-46f3-ae59-1dfb793de814",
"subMetas": {}
}

View File

@@ -0,0 +1,43 @@
{
"__type__": "cc.AnimationClip",
"_name": "BlownUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.4166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "0ea84f61-4a2f-4ca2-a0b8-b580e027c142"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "a3a31fcd-a162-456a-9c26-1f32413f87f3"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "da4ee0a0-ba66-455c-99d3-9c803a3d0f17"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "4c058d60-e727-4438-b058-6e51969df458"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "0892a3ea-9da1-4157-825b-0c8ef1c73eeb",
"subMetas": {}
}

View File

@@ -0,0 +1,61 @@
{
"__type__": "cc.AnimationClip",
"_name": "Dashing",
"_objFlags": 0,
"_native": "",
"_duration": 0.35,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "cf396dac-50c9-4389-90c0-55f49fd3276d"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "b9e4b5d5-c296-48c8-aa60-d22db0e5a632"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "e456c710-69f5-4dcc-9f5d-dd486a9198a1"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "ec6df76f-0004-4216-9b83-449487fe0cda"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "26032d0f-845c-4b96-89a6-d88113ed7827"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "e3e0169c-3c56-4206-a20e-35e4d0471873"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "80b98036-c5de-492b-b0e8-f1703f3a7d20"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "38b2c892-347b-4009-93f8-65b2ab1614f0",
"subMetas": {}
}

View File

@@ -0,0 +1,61 @@
{
"__type__": "cc.AnimationClip",
"_name": "GetUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.5166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "3f26b0a4-db13-4a14-b885-5a812073eccf"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "23eb42d6-52a2-458d-98a3-2f692dd79398"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "7bd4428c-44f9-4ff8-8d00-d3448a27a0c4"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "57640cd8-17eb-4279-a118-1ea40174da3c"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "56a2c954-6d04-433c-8ae4-f1bc7a0e9469"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "b4dc81a3-eb90-4722-9296-5158f004fd4c"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "c156fa2c-0c4e-4413-80c1-accf8fea4779"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "7d69868f-d474-4d86-a262-01f1cdd49021",
"subMetas": {}
}

View File

@@ -0,0 +1,109 @@
{
"__type__": "cc.AnimationClip",
"_name": "Idle1",
"_objFlags": 0,
"_native": "",
"_duration": 2.0166666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "51ede1f1-5e65-4b69-8fbc-5b7df2a7c90f"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "b0f1ecf7-be41-46a8-bccb-92ee53b4ef88"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "944adaee-5e11-4c55-9573-1d529f21ed4b"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "ede36130-8312-46a2-abe5-ba102bc97822"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "32dbb977-301c-4fbd-a19c-14a5ce0e2f5b"
}
},
{
"frame": 0.6,
"value": {
"__uuid__": "581c7ab1-451d-46b0-9eeb-24cf3b898924"
}
},
{
"frame": 0.7666666666666667,
"value": {
"__uuid__": "27005132-eda8-4c3f-9f4a-3a6004245e9f"
}
},
{
"frame": 0.9166666666666666,
"value": {
"__uuid__": "2b339657-aa80-4ab6-a4dd-83e9c12b6a54"
}
},
{
"frame": 1.0666666666666667,
"value": {
"__uuid__": "08e25a99-158d-4159-8152-6c9047fe9d54"
}
},
{
"frame": 1.2166666666666666,
"value": {
"__uuid__": "ab739541-39b5-4758-9b93-6681d6038730"
}
},
{
"frame": 1.3833333333333333,
"value": {
"__uuid__": "9ecbf97e-34bc-4c5e-b9e8-4d885a02e0d3"
}
},
{
"frame": 1.5333333333333334,
"value": {
"__uuid__": "e7d9a7c9-47ec-4335-97c9-19ed6ee3d9ce"
}
},
{
"frame": 1.7,
"value": {
"__uuid__": "cf258753-3900-4de4-a0bb-09158500fd9a"
}
},
{
"frame": 1.85,
"value": {
"__uuid__": "be7bedfe-7054-4092-89fc-ca397460f140"
}
},
{
"frame": 2,
"value": {
"__uuid__": "b1b467dd-1757-4ff1-9909-3449f74463d8"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "5afe50e0-d03f-4d48-a7c0-a350c36e14d4",
"subMetas": {}
}

View File

@@ -0,0 +1,55 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.38333333333333336,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "e6a3099f-b4c3-425f-a66b-9b992ae1c7b0"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "cade5a52-282e-47e5-aca9-5abb4f6afd14"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "96b0b028-3045-4a04-bf9c-c957f8c9e9ab"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "567f6bb7-c764-4c1d-bfec-f5c0c9812192"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "5d0c32b4-52ce-4157-9b91-dd400a7ed07a"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "fcef9c9b-dc71-459c-a541-9273b6e3923a"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "0e7468cc-b90d-4f68-91ce-0be126b406dd",
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.08333333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "01e8b938-03cb-4519-a417-384c31131a27"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "d7970a18-f3af-44c6-b216-ee55b9a1b32c"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "c86debde-118b-46b8-b483-f5ccec337315",
"subMetas": {}
}

View File

@@ -0,0 +1,79 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1ByJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.4666666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "6ff7b4e6-80ec-4673-b47b-e0bba7567c3c"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "4ff35932-9869-4c78-9f75-b304eee46647"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "6b1355c5-a750-4e37-9018-de1b84238f6c"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "01193448-adb0-4364-94f3-ca810897f397"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "f4f0cd5d-835b-44c3-8cc9-2651dd00cd37"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "4c32b2d6-346f-4d6e-a92e-6678e4c4b1ad"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "30ef09b2-366a-4946-b556-2c0fac359c0b"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "6ab33993-124f-429e-ba4c-b0f6824ea6c7"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "e0612a37-a743-40fe-83ff-f189971f1992"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "6ff230eb-44e8-4ca9-97d0-1b059aa1e21b"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "c4ddf3ea-2292-4511-a320-5486934ac361",
"subMetas": {}
}

View File

@@ -0,0 +1,25 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1NoJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.016666666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "6ff230eb-44e8-4ca9-97d0-1b059aa1e21b"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "bc461a02-4d1a-46a4-9f3c-7370adc6c1c8",
"subMetas": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View File

@@ -0,0 +1,12 @@
{
"ver": "2.3.3",
"uuid": "385b0a2b-765c-43fc-9243-977baccfd37a",
"type": "raw",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"platformSettings": {},
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "LayDown1",
"_objFlags": 0,
"_native": "",
"_duration": 0.06666666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "4e8a4f3c-5406-4700-9230-b2abc29a1093"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "1ae5e6f6-ba82-485d-b3c7-59fd16ece3d5"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "0a6478a6-f4cc-47cb-a1c6-761cf9141eb2",
"subMetas": {}
}

View File

@@ -0,0 +1,37 @@
{
"__type__": "cc.AnimationClip",
"_name": "OnWall",
"_objFlags": 0,
"_native": "",
"_duration": 0.26666666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c18886db-8116-4602-84f2-51652a90269a"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "0d81cbf0-dff8-4672-99b3-2ec8055c6931"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "a183e740-3c2d-4890-8430-39a00f55f446"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "411f964a-4dd8-424c-b2e2-d92b10474ce2",
"subMetas": {}
}

View File

@@ -0,0 +1,97 @@
{
"__type__": "cc.AnimationClip",
"_name": "Walking",
"_objFlags": 0,
"_native": "",
"_duration": 1.5166666666666666,
"sample": 60,
"speed": 1.2,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c3b14ecc-a6d9-4cb3-8637-ca7b407a0f5c"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "9435195e-4560-495e-b1ae-083c0c87e8a0"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "ec048360-7a17-4f22-ba52-eb86ec1acae8"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "82bb81e3-667c-4280-8710-211f4904ef2f"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "f958fb7f-ef5a-4918-81f3-564004572f45"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "8a0ecf92-db26-4206-9a80-20e749055def"
}
},
{
"frame": 0.65,
"value": {
"__uuid__": "942f2e02-a700-4fbf-877e-08c93e4d4010"
}
},
{
"frame": 0.7666666666666667,
"value": {
"__uuid__": "30546064-1a11-499e-8523-a82c83951c73"
}
},
{
"frame": 0.9,
"value": {
"__uuid__": "515bb75f-7a1f-4500-8aa9-c895915ce19f"
}
},
{
"frame": 1.0333333333333334,
"value": {
"__uuid__": "9100da6b-7582-4afb-9698-3d67d3b2012d"
}
},
{
"frame": 1.2166666666666666,
"value": {
"__uuid__": "1257f72d-0cb3-4750-ae70-13c2d8eb2269"
}
},
{
"frame": 1.3833333333333333,
"value": {
"__uuid__": "1d34b6db-27ba-4e26-864d-0f00d501765e"
}
},
{
"frame": 1.5,
"value": {
"__uuid__": "c317a75a-52c0-4c38-9300-a064cbf4efb3"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "f7f60d3f-32c0-4b56-901e-6eec9f73fa83",
"subMetas": {}
}

View File

@@ -0,0 +1,7 @@
{
"ver": "1.0.1",
"uuid": "e0e9bbc6-e22a-4277-b674-1308432d9734",
"isSubpackage": false,
"subpackageName": "",
"subMetas": {}
}

View File

@@ -0,0 +1,61 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.5,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "c7107ebe-c5c1-4ba6-8ef4-6eb768f7faf9"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "e0e20918-ff59-43bc-aeaf-035087934092"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "5896a135-36da-4fa9-9257-a9042ba4b546"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "4a16667a-f3b3-405c-8565-d65a4281cfc8"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "5ad9858c-52aa-4742-be68-d680210e0d0a"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "e54dbc94-3eeb-450a-9206-655e960771d2"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "f79260b7-7702-4f15-8f12-eb19f018aff1"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "d044ab74-be6a-49a2-85ab-eba41922c2cd",
"subMetas": {}
}

View File

@@ -0,0 +1,103 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk2",
"_objFlags": 0,
"_native": "",
"_duration": 0.6166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "549e581f-5121-4cbb-96e9-b3b8b5b0f227"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "0355243d-755f-497b-b1ff-4ec105f4efe7"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "22386328-484b-441e-9675-6553ede6118c"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "1ed0eb22-5a20-405f-a15e-8a66348bd025"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "6e12225f-2300-4e0e-bcf6-00049bfbc48f"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "08e1ec2a-500f-4a16-a19d-383de218cc14"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "024b3ae9-7d24-4057-83d7-4b58f8651ce0"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "57f241ae-ce40-49ed-bf63-71d016e41e2f"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "d2685f61-3365-4c14-9fb1-d7b2311871c4"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "59587d34-25af-42bd-ba0c-747c5f5fa697"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "3bceacb5-309a-41e0-bdad-26e85bcf859a"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "57f6da9e-f131-4fab-9a3d-f2e894d203aa"
}
},
{
"frame": 0.55,
"value": {
"__uuid__": "c35454f3-535b-4aec-b408-b8174a74556a"
}
},
{
"frame": 0.6,
"value": {
"__uuid__": "24f5b898-42dc-4f67-b6fc-946cdb5e369f"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "2cab337d-df23-476d-8a98-b5f115a52d04",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk3",
"_objFlags": 0,
"_native": "",
"_duration": 0.5333333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "d97f6a5f-8e63-40d7-bd14-9dc71e15e5db"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "196bcbf9-e89f-4b26-b736-73e2fa787e50"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "3229e023-e63d-4a4e-af72-2b1409ea43c5"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "e2d6e8b8-b468-4edb-b8c3-860bd85ebeae"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "318745eb-06b1-4e7f-88d1-e23e02d99e67"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "bba6f088-0e1f-4a12-9872-41670be1152a"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "2c5de5b2-9009-48fa-bef4-ae34cc94f876"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "6f27b252-6eaf-4b4b-9c5a-46ba899e4845"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "4ebd5c60-efa6-4950-a4c8-74a7a8517333"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "a207290f-4556-4adb-8a11-e1d5ba342550"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "e9d442d2-981d-437d-87c0-085162017de7"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "9b4d5c8c-5ec0-4fd7-a45e-6b0bc8ff9119"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "504dd9c8-7850-44e8-a944-bbdb2260b18a",
"subMetas": {}
}

View File

@@ -0,0 +1,115 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk4",
"_objFlags": 0,
"_native": "",
"_duration": 0.6833333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "a4f724de-140f-472a-be83-731520d3da38"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "3594a12d-5b5c-4dc6-8138-1b48eacf0798"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "cdef413d-f009-45d3-aeb6-423652fc366d"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "688682c4-ea77-4d2c-b1e4-079f5880d3cd"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "ca9f0a44-9977-4b24-8243-ac5536f14bc8"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "6b4dbc7c-a872-40d6-be0e-4d1a96eddd44"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "b43c8a38-1d55-4d6b-b6a1-fc888a9e53b5"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "0eb3d73a-a724-46f3-b1f1-56d315150320"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "ddac83f4-f0bf-460e-9a83-cc75c69ef024"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "8e673fdc-2cc8-435c-8a0d-38dcfc7b8600"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "7a345895-6501-4388-88f6-984992a3799b"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "99b4e340-52ca-4f3e-a86f-ca385ff8797a"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "554d0862-0d1c-4f61-8d47-03362cd9eb1d"
}
},
{
"frame": 0.5666666666666667,
"value": {
"__uuid__": "cd15a283-cf0d-48d4-9162-2d72202baf82"
}
},
{
"frame": 0.6166666666666667,
"value": {
"__uuid__": "b2bb7fdf-2532-408f-a3d1-fe8bf0e34f61"
}
},
{
"frame": 0.6666666666666666,
"value": {
"__uuid__": "435c0195-a5c3-4a8f-9d44-e6f026649b70"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "7e0a1e98-ee5a-446f-bec2-7d72b6916503",
"subMetas": {}
}

View File

@@ -0,0 +1,85 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atk5",
"_objFlags": 0,
"_native": "",
"_duration": 1.0166666666666666,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "6aa88bb9-0427-496f-ae7d-dc06410e904e"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "cdc65f83-c526-48b6-8a96-758b098568fe"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "927636af-2d1d-4801-a546-857f5eeb256d"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "2aeeb833-9151-4160-9775-9e08a376fd63"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "2bd1de9e-30e5-4bc5-b6c3-5c286754b0b7"
}
},
{
"frame": 0.4666666666666667,
"value": {
"__uuid__": "15a6ebb3-289a-46fb-ac94-f6efa0d90510"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "6ca922c0-cb62-4b1b-8773-79685a58bbd6"
}
},
{
"frame": 0.7,
"value": {
"__uuid__": "d60ceb6f-3a45-47dd-8d3f-bcfe8c919d85"
}
},
{
"frame": 0.8,
"value": {
"__uuid__": "c313f6a1-e0fa-4321-8336-c32f471b2592"
}
},
{
"frame": 0.9,
"value": {
"__uuid__": "bb886d03-7f3e-45c8-acfd-393091f09adb"
}
},
{
"frame": 1,
"value": {
"__uuid__": "1be255c3-f8c9-43ae-be68-2e500e7f1125"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "0abbd156-980e-475e-9994-3c958bd913fc",
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "Atked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.06666666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "7ceb8a79-f5bf-4918-afa1-d76a85a571b0"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "23ce7632-8b44-4138-b3b2-3e296ba9184c"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "488ad635-2683-4884-9e93-d1ee67bd0e49",
"subMetas": {}
}

View File

@@ -0,0 +1,133 @@
{
"__type__": "cc.AnimationClip",
"_name": "BlownUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.55,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "ba708108-b18f-4ec0-81f6-0e516e4f832b"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "aeeaa976-f3b4-4b77-a18b-b08ddd28d812"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "89d06edf-8838-4ab4-adbd-059acf21dc8c"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "c2f38b89-f7a0-477b-921c-f56ee385b737"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "90186972-a736-449d-8e64-d15c4ebcbfd1"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "1d64b1f5-5f08-4247-a43c-ffe2d58e09df"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "cf158505-bb9c-4836-b45f-2b253dfef117"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "a2984de9-99db-40bf-9969-0b163a97d9eb"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "66f0b5dc-4e0e-4597-a7f9-b9ee6752bc98"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "3cf0f5bd-0104-4315-a750-55b5fb26e1ec"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "a31b8683-ca31-4268-80d6-5b117af86ee6"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "a7ab4cb1-2221-4aba-8ced-dc93d8dca2f3"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "2ac3a00d-059a-4e15-a9cb-378bd671c9f3"
}
},
{
"frame": 0.38333333333333336,
"value": {
"__uuid__": "2b5cab9a-420c-406a-bef4-6aaee4ae6e8f"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "6df0a35f-062b-49ec-aa73-146f8b2207a7"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "afaac620-4293-4336-9a44-bf7927c6751c"
}
},
{
"frame": 0.48333333333333334,
"value": {
"__uuid__": "410823b3-14e4-475b-b658-dc4d5325f307"
}
},
{
"frame": 0.5166666666666667,
"value": {
"__uuid__": "34a43c48-497b-4495-97c9-8de53cbcc229"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "c7ffc314-70ae-4a2b-9238-db1778a336d1"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "8e17dfc6-68d0-47fe-af06-d30dc2790a6b",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "GetUp1",
"_objFlags": 0,
"_native": "",
"_duration": 0.5166666666666667,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "ec0d05f4-3c30-4107-b9b4-3ccff5fb9a02"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "3e0fa075-ffdc-490f-872c-b77e202df224"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "f3c8e924-c86a-426b-a3de-ffc6e19060f3"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "35b847f0-f3f7-4ec9-ba93-5616f763d658"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "a018eecc-27e6-4d60-973f-ed9fe86a147e"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "3d70f10e-a3f7-4b7a-aedb-a010ad946abe"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "b860cb8a-2445-49bc-96f0-aac4396be922"
}
},
{
"frame": 0.2833333333333333,
"value": {
"__uuid__": "bddec025-747e-4602-9352-6fc3bf921dc0"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "22053496-5240-40d3-98bd-49e16d05f7f9"
}
},
{
"frame": 0.4,
"value": {
"__uuid__": "9de8f787-3059-403d-bdcb-f7d4bd59ba65"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "471de8d2-34ee-4605-b8c5-9f3983db8a04"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "a4cb5179-60eb-41f8-bcef-56ce3299da19"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "da6a7cc1-9709-42f4-b6d0-17c1917a08a3",
"subMetas": {}
}

View File

@@ -0,0 +1,67 @@
{
"__type__": "cc.AnimationClip",
"_name": "Idle1",
"_objFlags": 0,
"_native": "",
"_duration": 0.8333333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "2c5f2d24-01f1-4a0f-8ddc-eacfbc9b6208"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "fd29846b-1998-49ba-89f6-f665b9ea7002"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "e3b30506-3a86-462e-b265-e7f6c7c09dc5"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "84f15682-b73e-443d-8d9f-f530f152bcce"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "45249fea-e7e7-4b68-8971-49d825960248"
}
},
{
"frame": 0.6166666666666667,
"value": {
"__uuid__": "ca561428-9e45-41a9-8d66-c0468d4c85d9"
}
},
{
"frame": 0.7166666666666667,
"value": {
"__uuid__": "062f3bd5-beca-435a-8d82-524fd51a88a0"
}
},
{
"frame": 0.8166666666666667,
"value": {
"__uuid__": "23068811-a6e5-4ef5-960f-7e6dea328c84"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "2d402c67-e47d-4de0-8a80-40bc12073ffc",
"subMetas": {}
}

View File

@@ -0,0 +1,79 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtk1",
"_objFlags": 0,
"_native": "",
"_duration": 0.6,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "70adb814-3dca-492f-a0fe-36d4d6b37e01"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "7c67ab61-96e0-4c43-a2d8-742fa1021107"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "beb4bc62-b6bf-4a07-973e-1b91e3942ab3"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "422441bd-8551-46d3-9383-162553035080"
}
},
{
"frame": 0.3,
"value": {
"__uuid__": "312f8dd2-7d02-4a80-a960-17d197c96da4"
}
},
{
"frame": 0.35,
"value": {
"__uuid__": "42597d6a-b982-43aa-90bd-2e9a01063628"
}
},
{
"frame": 0.45,
"value": {
"__uuid__": "487b65c3-44e3-4b0e-9350-e0d1c952785b"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "9a5357ae-a160-4198-a6d5-cc9631fde754"
}
},
{
"frame": 0.5333333333333333,
"value": {
"__uuid__": "d08fc3b2-f6e8-4ff8-bba4-69ce3eb771df"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "9f8ef3e0-6f56-41d2-97d1-ac7f3cc690ee"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "5035ddfe-ff75-4dff-a506-89cbb26220da",
"subMetas": {}
}

View File

@@ -0,0 +1,49 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirAtked1",
"_objFlags": 0,
"_native": "",
"_duration": 0.25,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "39c94369-a78d-459d-9305-13a2b9c15225"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "c85b7940-7bb2-4597-a309-155b7a116f94"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "78f498f8-6517-4e28-91f9-b70ee87beff9"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "02247899-3345-411a-aaa3-65e2f5e0b3e6"
}
},
{
"frame": 0.23333333333333334,
"value": {
"__uuid__": "bec5291d-8f6e-426c-8e16-1d0239a69bad"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "ac0fa38d-d3ad-4dff-841d-4d98ee5017db",
"subMetas": {}
}

View File

@@ -0,0 +1,91 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1ByJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.5833333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "493a132d-af22-4621-842a-9fdc645b3e43"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "06d18871-0cb6-41eb-a484-5c6a4c04d5d5"
}
},
{
"frame": 0.06666666666666667,
"value": {
"__uuid__": "f298ff82-ad9d-4945-ab19-14c3e3d54c95"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "bb5924a6-40cf-4e43-8c94-e51b27861656"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "fc4b5181-77af-44ec-836e-c14eec8d20c4"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "5ddd3db3-79b2-4f0c-bb76-2446801ff665"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "032785ce-c911-479b-be1c-2e0899a586d0"
}
},
{
"frame": 0.31666666666666665,
"value": {
"__uuid__": "d651269d-1c08-49f8-bc38-d301bf26b0e1"
}
},
{
"frame": 0.36666666666666664,
"value": {
"__uuid__": "e270563e-d98d-4a80-82db-837183053ae3"
}
},
{
"frame": 0.43333333333333335,
"value": {
"__uuid__": "aec31ef8-46dc-4f0e-9cba-18f6c96c5c33"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "e64b3a8d-41a9-45f6-9aeb-9e49b6317080"
}
},
{
"frame": 0.5666666666666667,
"value": {
"__uuid__": "cf886091-24a9-4cfb-8cb9-e3db977035ab"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "a4315723-e7b6-40e7-9a3c-bac959378b90",
"subMetas": {}
}

View File

@@ -0,0 +1,31 @@
{
"__type__": "cc.AnimationClip",
"_name": "InAirIdle1NoJump",
"_objFlags": 0,
"_native": "",
"_duration": 0.2833333333333333,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "e64b3a8d-41a9-45f6-9aeb-9e49b6317080"
}
},
{
"frame": 0.26666666666666666,
"value": {
"__uuid__": "cf886091-24a9-4cfb-8cb9-e3db977035ab"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "53b0ae11-f77f-4c3a-9e6d-76159d135c2c",
"subMetas": {}
}

View File

@@ -0,0 +1,97 @@
{
"__type__": "cc.AnimationClip",
"_name": "LayDown1",
"_objFlags": 0,
"_native": "",
"_duration": 0.23333333333333334,
"sample": 60,
"speed": 1,
"wrapMode": 1,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "b521e99d-b206-4453-bcb7-55d0049a229a"
}
},
{
"frame": 0.016666666666666666,
"value": {
"__uuid__": "04656482-51fb-4a3d-aa3a-28c682ff4852"
}
},
{
"frame": 0.03333333333333333,
"value": {
"__uuid__": "44b85e26-64bb-47d9-90ba-4ae8c10fd9f1"
}
},
{
"frame": 0.05,
"value": {
"__uuid__": "2afb056b-e83a-4074-ac6c-ac6edaa0ff37"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "0ca0d5ca-01d3-4013-8819-1f79be60fa91"
}
},
{
"frame": 0.1,
"value": {
"__uuid__": "50902f57-47ef-4e07-beec-f633a96c5116"
}
},
{
"frame": 0.11666666666666667,
"value": {
"__uuid__": "78914b1e-5202-4b2a-86b8-696bc989d43a"
}
},
{
"frame": 0.13333333333333333,
"value": {
"__uuid__": "5dd8649a-7fd4-4c82-b4c9-17739901e637"
}
},
{
"frame": 0.15,
"value": {
"__uuid__": "76fcd7e0-0841-4308-a152-a561aec76659"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "32b61366-3f7e-4e83-88f1-9c63d6fb45de"
}
},
{
"frame": 0.18333333333333332,
"value": {
"__uuid__": "8b692f1c-570e-4c35-a40d-e3b6b5973396"
}
},
{
"frame": 0.2,
"value": {
"__uuid__": "756ff6b2-3c2d-4a5b-87f3-1e37073d80e5"
}
},
{
"frame": 0.21666666666666667,
"value": {
"__uuid__": "dc43217f-afeb-42fb-bdea-04b18ffee56f"
}
}
]
}
}
},
"events": []
}

View File

@@ -0,0 +1,5 @@
{
"ver": "2.1.0",
"uuid": "e4faa04d-28f5-40b0-b1a5-99cd902e5fd6",
"subMetas": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

View File

@@ -0,0 +1,12 @@
{
"ver": "2.3.3",
"uuid": "6e1dbec7-ad55-413b-8108-0ac881c76a8b",
"type": "raw",
"wrapMode": "clamp",
"filterMode": "bilinear",
"premultiplyAlpha": false,
"genMipmaps": false,
"packable": true,
"platformSettings": {},
"subMetas": {}
}

View File

@@ -0,0 +1,85 @@
{
"__type__": "cc.AnimationClip",
"_name": "Walking",
"_objFlags": 0,
"_native": "",
"_duration": 0.85,
"sample": 60,
"speed": 1,
"wrapMode": 2,
"curveData": {
"comps": {
"cc.Sprite": {
"spriteFrame": [
{
"frame": 0,
"value": {
"__uuid__": "a47f518e-62fb-4549-8897-4f2d387bd145"
}
},
{
"frame": 0.08333333333333333,
"value": {
"__uuid__": "2b694de4-addf-4960-a765-b422da36e3a7"
}
},
{
"frame": 0.16666666666666666,
"value": {
"__uuid__": "7cc4b946-7646-4377-b2ac-b75c047dfe1c"
}
},
{
"frame": 0.25,
"value": {
"__uuid__": "758814fe-7feb-4daa-8ecf-f0ba412f87dc"
}
},
{
"frame": 0.3333333333333333,
"value": {
"__uuid__": "3794c342-1ddb-423e-85ca-09f14fbd2cfb"
}
},
{
"frame": 0.4166666666666667,
"value": {
"__uuid__": "c3899480-a64e-4e16-897b-562b76d0d85c"
}
},
{
"frame": 0.5,
"value": {
"__uuid__": "509a8985-2442-4326-9cd9-d77cad6e4e66"
}
},
{
"frame": 0.5833333333333334,
"value": {
"__uuid__": "bdb51693-f9cc-4828-ab25-e131939b358d"
}
},
{
"frame": 0.6666666666666666,
"value": {
"__uuid__": "c47e6d89-5e15-4f9c-a4ee-ec10e3b04295"
}
},
{
"frame": 0.75,
"value": {
"__uuid__": "e919100a-50ba-46ce-9ddb-e29f524da610"
}
},
{
"frame": 0.8333333333333334,
"value": {
"__uuid__": "c6e2cfeb-1d9d-4793-86fa-bc9a2f80f67a"
}
}
]
}
}
},
"events": []
}

Some files were not shown because too many files have changed in this diff Show More