completed animation setup and code based solely on LDTK settings

This commit is contained in:
Thomas von Dein 2024-04-03 19:39:08 +02:00
parent 001b67f97a
commit f844058bf9
13 changed files with 262 additions and 172 deletions

18
TODO.md
View File

@ -29,24 +29,6 @@
- Player can collect collectible hidden under obstacle (should be - Player can collect collectible hidden under obstacle (should be
fixed when above is fixed) fixed when above is fixed)
- Get rid of particle system, rather add an animation component, which
determines if an animation must be played according to LDTK entity
settings. Say, something like a boolean value "DetonateAfterHit", if
true, we load the sprites specified in the string value
"AnimationSpritesPattern", where we could have something like
"collectible-detonating*.png" or we could use an animation map and
specify a list of coordinates, etcpp.
- Part I of the above: DONE.
- Part II:
- grid/grid.go:
- add Animation component to mappers
- check if the tile has tile.AnimateOnDestruct (or any other
triggers) set and configure animation compontent accordingly
- check if the tile has tile.AnimationSpriteSheet, assign to Animation.Tiles[]
- do it for any entity not just collectible so that any entity can have an animation
- rename Animation.Tiles to Sprites
- change animation_system to use this stuff instead of any hardcoded values.
## Collider Rework [abandoned: see branch collider-system, fails] ## Collider Rework [abandoned: see branch collider-system, fails]

View File

@ -11,7 +11,7 @@
"iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52", "iid": "267e9380-d7b0-11ee-a97e-35bec9c19d52",
"jsonVersion": "1.5.3", "jsonVersion": "1.5.3",
"appBuildId": 473703, "appBuildId": 473703,
"nextUid": 78, "nextUid": 81,
"identifierStyle": "Capitalize", "identifierStyle": "Capitalize",
"toc": [], "toc": [],
"worldLayout": "Free", "worldLayout": "Free",
@ -295,6 +295,46 @@
"allowedRefsEntityUid": null, "allowedRefsEntityUid": null,
"allowedRefTags": [], "allowedRefTags": [],
"tilesetUid": null "tilesetUid": null
},
{
"identifier": "AnimationTrigger",
"doc": null,
"__type": "LocalEnum.AnimationTrigger",
"uid": 80,
"type": "F_Enum(78)",
"isArray": false,
"canBeNull": false,
"arrayMinLength": null,
"arrayMaxLength": null,
"editorDisplayMode": "Hidden",
"editorDisplayScale": 1,
"editorDisplayPos": "Above",
"editorLinkStyle": "StraightArrow",
"editorDisplayColor": null,
"editorAlwaysShow": false,
"editorShowInWorld": true,
"editorCutLongValues": true,
"editorTextSuffix": null,
"editorTextPrefix": null,
"useForSmartColor": false,
"exportToToc": false,
"searchable": false,
"min": null,
"max": null,
"regex": null,
"acceptFileTypes": null,
"defaultOverride": {
"id": "V_String",
"params": ["OnDestruct"]
},
"textLanguageMode": null,
"symmetricalRef": false,
"autoChainRef": true,
"allowOutOfLevelRef": true,
"allowedRefs": "OnlySame",
"allowedRefsEntityUid": null,
"allowedRefTags": [],
"tilesetUid": null
} }
] ]
}, },
@ -1275,7 +1315,11 @@
"averageColors": "1b47987d687d3b3507430a531a7419745c355c355c355c350ba40b851b851a753c96faa8f166f29907430a531ca81ba8f5b7f853f799f7770ba40b851cb91ca9f222f888f444f7650a630b831dcb1dcbf555f532e866ab850ca50b851ddb1dcb5a7500003743aa9509640a742ddc2ddc00000000000000000b950a752ddc2ddc00000000000000001a740a742dca1dcb00000000000000001b951a751ddb2cba00000000000000001a741a741a741a7400000000000000001b951a751b951a7500000000000000001a741a751a741a7400000000000000001b951a751b951a75" "averageColors": "1b47987d687d3b3507430a531a7419745c355c355c355c350ba40b851b851a753c96faa8f166f29907430a531ca81ba8f5b7f853f799f7770ba40b851cb91ca9f222f888f444f7650a630b831dcb1dcbf555f532e866ab850ca50b851ddb1dcb5a7500003743aa9509640a742ddc2ddc00000000000000000b950a752ddc2ddc00000000000000001a740a742dca1dcb00000000000000001b951a751ddb2cba00000000000000001a741a741a741a7400000000000000001b951a751b951a7500000000000000001a741a751a741a7400000000000000001b951a751b951a75"
} }
} }
], "enums": [], "externalEnums": [], "levelFields": [ ], "enums": [{ "identifier": "AnimationTrigger", "uid": 78, "values": [
{ "id": "OnDestruct", "tileRect": null, "color": 12470831 },
{ "id": "OnIdle", "tileRect": null, "color": 4098376 },
{ "id": "OnCollision", "tileRect": null, "color": 1199753 }
], "iconTilesetUid": null, "externalRelPath": null, "externalFileChecksum": null, "tags": [] }], "externalEnums": [], "levelFields": [
{ {
"identifier": "level", "identifier": "level",
"doc": null, "doc": null,
@ -1512,7 +1556,11 @@
"px": [352,224], "px": [352,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [{
"id": "V_String",
"params": ["OnDestruct"]
}] }
], ],
"__worldX": 128, "__worldX": 128,
"__worldY": 224 "__worldY": 224
@ -1531,7 +1579,11 @@
"px": [288,160], "px": [288,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [{
"id": "V_String",
"params": ["OnDestruct"]
}] }
], ],
"__worldX": 64, "__worldX": 64,
"__worldY": 160 "__worldY": 160
@ -1550,7 +1602,11 @@
"px": [384,160], "px": [384,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [{
"id": "V_String",
"params": ["OnDestruct"]
}] }
], ],
"__worldX": 160, "__worldX": 160,
"__worldY": 160 "__worldY": 160
@ -1705,7 +1761,8 @@
"px": [128,288], "px": [128,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 608, "__worldX": 608,
"__worldY": 288 "__worldY": 288
@ -1724,7 +1781,8 @@
"px": [480,192], "px": [480,192],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 960, "__worldX": 960,
"__worldY": 192 "__worldY": 192
@ -1884,7 +1942,8 @@
"px": [96,160], "px": [96,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1280, "__worldX": 1280,
"__worldY": 160 "__worldY": 160
@ -2007,7 +2066,8 @@
"px": [448,128], "px": [448,128],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2336, "__worldX": 2336,
"__worldY": 128 "__worldY": 128
@ -2026,7 +2086,8 @@
"px": [128,384], "px": [128,384],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2016, "__worldX": 2016,
"__worldY": 384 "__worldY": 384
@ -2202,7 +2263,8 @@
"px": [288,224], "px": [288,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 64, "__worldX": 64,
"__worldY": 768 "__worldY": 768
@ -2269,7 +2331,8 @@
"px": [352,224], "px": [352,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 128, "__worldX": 128,
"__worldY": 768 "__worldY": 768
@ -2462,7 +2525,8 @@
"px": [288,224], "px": [288,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 768, "__worldX": 768,
"__worldY": 768 "__worldY": 768
@ -2687,7 +2751,8 @@
"px": [96,160], "px": [96,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1280, "__worldX": 1280,
"__worldY": 704 "__worldY": 704
@ -2738,7 +2803,8 @@
"px": [320,352], "px": [320,352],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1504, "__worldX": 1504,
"__worldY": 896 "__worldY": 896
@ -2773,7 +2839,8 @@
"px": [128,128], "px": [128,128],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1312, "__worldX": 1312,
"__worldY": 672 "__worldY": 672
@ -2956,7 +3023,8 @@
"px": [224,160], "px": [224,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2112, "__worldX": 2112,
"__worldY": 704 "__worldY": 704
@ -2991,7 +3059,8 @@
"px": [416,224], "px": [416,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2304, "__worldX": 2304,
"__worldY": 768 "__worldY": 768
@ -3042,7 +3111,8 @@
"px": [288,288], "px": [288,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2176, "__worldX": 2176,
"__worldY": 832 "__worldY": 832
@ -3223,7 +3293,8 @@
"px": [160,224], "px": [160,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": -64, "__worldX": -64,
"__worldY": 1312 "__worldY": 1312
@ -3242,7 +3313,8 @@
"px": [192,288], "px": [192,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": -32, "__worldX": -32,
"__worldY": 1376 "__worldY": 1376
@ -3449,7 +3521,8 @@
"px": [352,288], "px": [352,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 832, "__worldX": 832,
"__worldY": 1376 "__worldY": 1376
@ -3704,7 +3777,8 @@
"px": [416,288], "px": [416,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1600, "__worldX": 1600,
"__worldY": 1376 "__worldY": 1376
@ -3755,7 +3829,8 @@
"px": [416,160], "px": [416,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1600, "__worldX": 1600,
"__worldY": 1248 "__worldY": 1248
@ -4066,7 +4141,8 @@
"px": [192,256], "px": [192,256],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2080, "__worldX": 2080,
"__worldY": 1344 "__worldY": 1344
@ -4265,7 +4341,8 @@
"px": [320,192], "px": [320,192],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 96, "__worldX": 96,
"__worldY": 1824 "__worldY": 1824
@ -4284,7 +4361,8 @@
"px": [288,256], "px": [288,256],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 64, "__worldX": 64,
"__worldY": 1888 "__worldY": 1888
@ -4303,7 +4381,8 @@
"px": [352,256], "px": [352,256],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 128, "__worldX": 128,
"__worldY": 1888 "__worldY": 1888
@ -4530,7 +4609,8 @@
"px": [160,320], "px": [160,320],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 640, "__worldX": 640,
"__worldY": 1952 "__worldY": 1952
@ -4549,7 +4629,8 @@
"px": [192,320], "px": [192,320],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 672, "__worldX": 672,
"__worldY": 1952 "__worldY": 1952
@ -4584,7 +4665,8 @@
"px": [416,224], "px": [416,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 896, "__worldX": 896,
"__worldY": 1856 "__worldY": 1856
@ -4793,7 +4875,8 @@
"px": [480,320], "px": [480,320],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1664, "__worldX": 1664,
"__worldY": 1952 "__worldY": 1952
@ -4828,7 +4911,8 @@
"px": [288,192], "px": [288,192],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1472, "__worldX": 1472,
"__worldY": 1824 "__worldY": 1824
@ -4863,7 +4947,8 @@
"px": [352,128], "px": [352,128],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1536, "__worldX": 1536,
"__worldY": 1760 "__worldY": 1760
@ -4882,7 +4967,8 @@
"px": [192,288], "px": [192,288],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1376, "__worldX": 1376,
"__worldY": 1920 "__worldY": 1920
@ -5288,7 +5374,8 @@
"px": [224,192], "px": [224,192],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2112, "__worldX": 2112,
"__worldY": 1824 "__worldY": 1824
@ -5454,7 +5541,8 @@
"px": [256,224], "px": [256,224],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 32, "__worldX": 32,
"__worldY": 2432 "__worldY": 2432
@ -5713,7 +5801,8 @@
"px": [384,256], "px": [384,256],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 896, "__worldX": 896,
"__worldY": 2464 "__worldY": 2464
@ -5796,7 +5885,8 @@
"px": [352,192], "px": [352,192],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 864, "__worldX": 864,
"__worldY": 2400 "__worldY": 2400
@ -5961,7 +6051,8 @@
"px": [320,256], "px": [320,256],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1536, "__worldX": 1536,
"__worldY": 2464 "__worldY": 2464
@ -5980,7 +6071,8 @@
"px": [224,128], "px": [224,128],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1440, "__worldX": 1440,
"__worldY": 2336 "__worldY": 2336
@ -5999,7 +6091,8 @@
"px": [384,320], "px": [384,320],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 1600, "__worldX": 1600,
"__worldY": 2528 "__worldY": 2528
@ -6200,7 +6293,8 @@
"px": [416,352], "px": [416,352],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2304, "__worldX": 2304,
"__worldY": 2560 "__worldY": 2560
@ -6219,7 +6313,8 @@
"px": [160,128], "px": [160,128],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": 2048, "__worldX": 2048,
"__worldY": 2336 "__worldY": 2336
@ -6464,7 +6559,8 @@
"px": [160,160], "px": [160,160],
"fieldInstances": [ "fieldInstances": [
{ "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] }, { "__identifier": "AnimateOnDestruct", "__type": "Bool", "__value": true, "__tile": null, "defUid": 76, "realEditorValues": [] },
{ "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] } { "__identifier": "AnimateSpriteSheet", "__type": "String", "__value": "collectible-detonating", "__tile": null, "defUid": 77, "realEditorValues": [] },
{ "__identifier": "AnimationTrigger", "__type": "LocalEnum.AnimationTrigger", "__value": "OnDestruct", "__tile": null, "defUid": 80, "realEditorValues": [] }
], ],
"__worldX": -64, "__worldX": -64,
"__worldY": 2912 "__worldY": 2912

View File

@ -39,6 +39,7 @@ type Tile struct {
Door bool // a door, can be manipulated by a switch Door bool // a door, can be manipulated by a switch
Switch bool // opens|closes a door Switch bool // opens|closes a door
AnimateOnDestruct bool // wether to animate destruction AnimateOnDestruct bool // wether to animate destruction
AnimationTrigger string // dynamically configured via LDTP
AnimationSpriteSheet AnimationSet // which sprites to use (refers to an entry in assets.Animations[name]) AnimationSpriteSheet AnimationSet // which sprites to use (refers to an entry in assets.Animations[name])
} }
@ -68,6 +69,7 @@ func (tile *Tile) Clone() *Tile {
Switch: tile.Switch, Switch: tile.Switch,
AnimateOnDestruct: tile.AnimateOnDestruct, AnimateOnDestruct: tile.AnimateOnDestruct,
AnimationSpriteSheet: tile.AnimationSpriteSheet, AnimationSpriteSheet: tile.AnimationSpriteSheet,
AnimationTrigger: tile.AnimationTrigger,
} }
return newtile return newtile

View File

@ -11,7 +11,6 @@ import (
"path" "path"
"strings" "strings"
"github.com/alecthomas/repr"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
@ -114,24 +113,24 @@ func LoadImages() (AssetRegistry, AnimationRegistry) {
animationset := AnimationSet{} animationset := AnimationSet{}
animationset.File = strings.TrimSuffix(animation.Meta.Name, ".png") animationset.File = strings.TrimSuffix(animation.Meta.Name, ".png")
animationset.Width = animation.Meta.Geo.Width
animationset.Height = animation.Meta.Geo.Height
for _, frame := range animation.Frames { for _, frame := range animation.Frames {
sprite := images[animationset.File].SubImage( sprite := images[animationset.File].SubImage(
image.Rect( image.Rect(
frame.Position.X, frame.Position.X,
frame.Position.Y, frame.Position.Y,
frame.Position.Width, frame.Position.X+frame.Position.Width,
frame.Position.Height, frame.Position.Y+frame.Position.Height,
)).(*ebiten.Image) )).(*ebiten.Image)
animationset.Sprites = append(animationset.Sprites, sprite) animationset.Sprites = append(animationset.Sprites, sprite)
} }
animationset.Width = animationset.Sprites[0].Bounds().Dx()
animationset.Height = animationset.Sprites[0].Bounds().Dy()
animations[animationset.File] = animationset animations[animationset.File] = animationset
} }
repr.Println(animations)
return images, animations return images, animations
} }

View File

@ -1,11 +0,0 @@
package components
import "github.com/hajimehoshi/ebiten/v2"
type Animation struct {
Show bool
Index int
Loop bool
Tiles []*ebiten.Image
Width, Height int // single sprite measurements
}

View File

@ -1,19 +1,5 @@
package components package components
import (
"github.com/hajimehoshi/ebiten/v2"
)
// virtual location, aka tile address
type Renderable struct {
Pos *Position // just for debugging, will not used as positiion!
Image *ebiten.Image
DamageImage *ebiten.Image
Damaged int
Shader *ebiten.Shader
}
// only tile entities will have those // only tile entities will have those
type Tilish struct{} type Tilish struct{}
type Solid struct{} type Solid struct{}

43
components/renderable.go Normal file
View File

@ -0,0 +1,43 @@
package components
import (
"openquell/config"
"github.com/hajimehoshi/ebiten/v2"
)
// virtual location, aka tile address
type Animation struct {
Active bool // animation is running
Loop bool // remove the entity if false, loop endless otherwise
Index int // where we are currently
Tiles []*ebiten.Image
Width, Height int // single sprite measurements
Timer Timer
Trigger string
}
type Renderable struct {
Pos *Position // just for debugging, will not used as positiion!
Image *ebiten.Image
DamageImage *ebiten.Image // FIXME: put into its own struct
Damaged int
Shader *ebiten.Shader
Animate Animation
Hidden bool
}
func (render *Renderable) StartAnimation() {
render.Hidden = true
render.Animate.Active = true
render.Animate.Timer.Start(config.ANIMATION_STARTWAIT)
switch render.Animate.Trigger {
case "OnCollision":
fallthrough
case "OnDestruct":
render.Animate.Loop = false
case "OnIdle":
render.Animate.Loop = true
}
}

View File

@ -43,7 +43,7 @@ func NewLevel(game *Game, cellsize int, plan *ldtkgo.Level) *Level {
systems.NewGridSystem(game.World, game.ScreenWidth, game.ScreenHeight, cellsize, systems.NewGridSystem(game.World, game.ScreenWidth, game.ScreenHeight, cellsize,
assets.Assets[plan.PropertyByIdentifier("background").AsString()])) assets.Assets[plan.PropertyByIdentifier("background").AsString()]))
systemlist = append(systemlist, systems.NewCollectibleSystem(game.World)) systemlist = append(systemlist, systems.NewCollectibleSystem(game.World, cellsize))
systemlist = append(systemlist, systems.NewObstacleSystem(game.World, gridcontainer)) systemlist = append(systemlist, systems.NewObstacleSystem(game.World, gridcontainer))
@ -198,9 +198,13 @@ func LevelToSlice(game *Game, level *ldtkgo.Level, tilesize int) (Map, Map) {
} }
tileRect := entity.TileRect tileRect := entity.TileRect
animateondestruct := util.GetPropertyBool(entity, "AnimateOnDestruct") animationtrigger := util.GetPropertyString(entity, "AnimationTrigger")
slog.Debug("got trigger", "trigger", animationtrigger)
//animateondestruct := util.GetPropertyBool(entity, "AnimateOnDestruct")
// FIXME: also check for AnimationLoop and other animation reasons // FIXME: also check for AnimationLoop and other animation reasons
if animateondestruct { // if animateondestruct {
if animationtrigger != "" {
tile.AnimateOnDestruct = true tile.AnimateOnDestruct = true
animation := util.GetPropertyString(entity, "AnimateSpriteSheet") animation := util.GetPropertyString(entity, "AnimateSpriteSheet")
@ -212,6 +216,7 @@ func LevelToSlice(game *Game, level *ldtkgo.Level, tilesize int) (Map, Map) {
} }
tile.AnimationSpriteSheet = assets.Animations[animation] tile.AnimationSpriteSheet = assets.Animations[animation]
tile.AnimationTrigger = animationtrigger
} }
tile.Sprite = tileset.SubImage( tile.Sprite = tileset.SubImage(

View File

@ -159,6 +159,15 @@ func NewGrid(world *ecs.World,
render.Image = tile.Sprite render.Image = tile.Sprite
render.Pos = pos render.Pos = pos
//if tile.AnimateOnDestruct {
if tile.AnimationTrigger != "" {
// FIXME: be more generic, use LDTK enum
render.Animate.Tiles = tile.AnimationSpriteSheet.Sprites
render.Animate.Width = tile.AnimationSpriteSheet.Width
render.Animate.Height = tile.AnimationSpriteSheet.Height
render.Animate.Trigger = tile.AnimationTrigger
}
default: default:
// empty cell, this is where the player[s] move. No // empty cell, this is where the player[s] move. No
// sprite required since every level has a background // sprite required since every level has a background

View File

@ -11,13 +11,13 @@ import (
type AnimationSystem struct { type AnimationSystem struct {
World *ecs.World World *ecs.World
Selector *generic.Filter3[Position, Animation, Timer] Selector *generic.Filter2[Position, Renderable]
Cellsize int Cellsize int
} }
func NewAnimationSystem(world *ecs.World, cellsize int) System { func NewAnimationSystem(world *ecs.World, cellsize int) System {
system := &AnimationSystem{ system := &AnimationSystem{
Selector: generic.NewFilter3[Position, Animation, Timer](), Selector: generic.NewFilter2[Position, Renderable](),
World: world, World: world,
Cellsize: cellsize, Cellsize: cellsize,
} }
@ -26,31 +26,31 @@ func NewAnimationSystem(world *ecs.World, cellsize int) System {
} }
func (system *AnimationSystem) Update() error { func (system *AnimationSystem) Update() error {
// display debris after collecting
EntitiesToRemove := []ecs.Entity{} EntitiesToRemove := []ecs.Entity{}
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
// we loop, but it's only one anyway _, render := query.Get()
_, animation, timer := query.Get() if render.Animate.Active {
if render.Animate.Timer.IsReady() {
animation.Show = true switch {
// animation shows from earlier tick, animate
if timer.IsReady() { case render.Animate.Index > -1 && render.Animate.Index < len(render.Animate.Tiles)-1:
switch { render.Animate.Index += 1
// animation shows from earlier tick, animate render.Animate.Timer.Start(config.ANIMATION_LOOPWAIT)
case animation.Index > -1 && animation.Index < len(animation.Tiles)-1: default:
animation.Index++ // last sprite reached
timer.Start(config.ANIMATION_LOOPWAIT) if render.Animate.Loop {
default: render.Animate.Index = 0
// last sprite reached, remove it } else {
EntitiesToRemove = append(EntitiesToRemove, query.Entity()) EntitiesToRemove = append(EntitiesToRemove, query.Entity())
}
}
} else {
render.Animate.Timer.Update()
} }
} else {
timer.Update()
} }
} }
for _, entity := range EntitiesToRemove { for _, entity := range EntitiesToRemove {
@ -66,12 +66,12 @@ func (system *AnimationSystem) Draw(screen *ebiten.Image) {
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
for query.Next() { for query.Next() {
pos, animation, _ := query.Get() pos, render := query.Get()
if animation.Show { if render.Animate.Active {
op.GeoM.Reset() op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y)) op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(animation.Tiles[animation.Index], op) screen.DrawImage(render.Animate.Tiles[render.Animate.Index], op)
} }
} }
} }

View File

@ -1,10 +1,9 @@
package systems package systems
import ( import (
"openquell/assets" "log/slog"
"openquell/components" "openquell/components"
. "openquell/components" . "openquell/components"
"openquell/config"
. "openquell/config" . "openquell/config"
"openquell/observers" "openquell/observers"
@ -15,13 +14,15 @@ import (
type CollectibleSystem struct { type CollectibleSystem struct {
World *ecs.World World *ecs.World
Cellsize int
Selector *generic.Filter3[Position, Collectible, Renderable] Selector *generic.Filter3[Position, Collectible, Renderable]
} }
func NewCollectibleSystem(world *ecs.World) System { func NewCollectibleSystem(world *ecs.World, cellsize int) System {
system := &CollectibleSystem{ system := &CollectibleSystem{
Selector: generic.NewFilter3[Position, Collectible, Renderable](), Selector: generic.NewFilter3[Position, Collectible, Renderable](),
World: world, World: world,
Cellsize: cellsize,
} }
return system return system
@ -33,9 +34,6 @@ func (system *CollectibleSystem) Update() error {
posID := ecs.ComponentID[components.Position](system.World) posID := ecs.ComponentID[components.Position](system.World)
veloID := ecs.ComponentID[components.Velocity](system.World) veloID := ecs.ComponentID[components.Velocity](system.World)
animationpositions := []*components.Position{}
EntitiesToRemove := []ecs.Entity{}
query := system.Selector.Query(system.World) query := system.Selector.Query(system.World)
numcollectibles := query.Count() numcollectibles := query.Count()
@ -45,7 +43,7 @@ func (system *CollectibleSystem) Update() error {
} }
for query.Next() { for query.Next() {
colposition, _, _ := query.Get() colposition, _, render := query.Get()
for _, player := range observer.GetPlayers() { for _, player := range observer.GetPlayers() {
if !system.World.Alive(player) { if !system.World.Alive(player) {
@ -56,23 +54,22 @@ func (system *CollectibleSystem) Update() error {
playervelocity := (*Velocity)(system.World.Get(player, veloID)) playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, _ := colposition.Intersects(playerposition, playervelocity) ok, _ := colposition.Intersects(playerposition, playervelocity)
if ok { if ok && !render.Hidden {
//slog.Debug("bumped into collectible", "collectible", collectible) slog.Debug("bumped into collectible", "colpos", colposition)
animationpositions = append(animationpositions, colposition)
EntitiesToRemove = append(EntitiesToRemove, query.Entity()) render.StartAnimation()
// position the animation relative to the middle of the current entity
colposition.Update(
colposition.X-(system.Cellsize/2),
colposition.Y-(system.Cellsize/2),
64,
)
numcollectibles--
} }
} }
} }
for _, pos := range animationpositions {
system.AddAnimation(pos)
}
for _, entity := range EntitiesToRemove {
system.World.RemoveEntity(entity)
numcollectibles--
}
if numcollectibles == 0 { if numcollectibles == 0 {
// winner, winner, chicken dinner! // winner, winner, chicken dinner!
timer := observers.GetGameObserver(system.World).StopTimer timer := observers.GetGameObserver(system.World).StopTimer
@ -92,36 +89,11 @@ func (system *CollectibleSystem) Draw(screen *ebiten.Image) {
for query.Next() { for query.Next() {
pos, _, sprite := query.Get() pos, _, sprite := query.Get()
op.GeoM.Reset() if !sprite.Hidden {
op.GeoM.Translate(float64(pos.X), float64(pos.Y)) op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(sprite.Image, op) screen.DrawImage(sprite.Image, op)
}
} }
} }
func (system *CollectibleSystem) AddAnimation(position *components.Position) {
observer := observers.GetGameObserver(system.World)
ptmapper := generic.NewMap3[
components.Position,
components.Animation,
components.Timer,
](system.World)
animationID := ecs.ComponentID[components.Animation](system.World)
entity := ptmapper.New()
pos, animation, timer := ptmapper.Get(entity)
observer.AddEntity(entity, animationID)
animation.Index = assets.Tiles["Animation"].Animation
animation.Tiles = assets.Tiles["Animation"].Tiles
pos.Update(
position.X-(16), // FIXME: use global tilesize!
position.Y-(16),
64,
)
timer.Start(config.ANIMATION_STARTWAIT)
}

View File

@ -1,7 +1,6 @@
package systems package systems
import ( import (
"log/slog"
. "openquell/components" . "openquell/components"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
@ -58,7 +57,6 @@ func (system *GridSystem) Draw(screen *ebiten.Image) {
counter++ counter++
op.GeoM.Reset() op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y)) op.GeoM.Translate(float64(pos.X), float64(pos.Y))
slog.Debug("rendering tile", "sprite", sprite)
system.Cache.DrawImage(sprite.Image, op) system.Cache.DrawImage(sprite.Image, op)
} }

View File

@ -54,6 +54,15 @@ func GetPropertyBool(entity *ldtkgo.Entity, property string) bool {
return false return false
} }
func GetPropertyEnum(entity *ldtkgo.Entity, property string) string {
ref := entity.PropertyByIdentifier(property)
if ref != nil {
return ref.AsString()
}
return ""
}
func GetPropertyToggleTile(entity *ldtkgo.Entity) *TileSetSubRect { func GetPropertyToggleTile(entity *ldtkgo.Entity) *TileSetSubRect {
ref := entity.PropertyByIdentifier(config.LDTK_Toggle_Tile) ref := entity.PropertyByIdentifier(config.LDTK_Toggle_Tile)
if ref != nil { if ref != nil {