sprite animations
This commit is contained in:
parent
6d142e863a
commit
827d817530
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1062,6 +1062,15 @@ dependencies = [
|
|||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy_smooth_pixel_camera"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b640e3e189e037377b260f5dc79c5ee4f51da09035390e3aacc9c02a2581f86"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bevy_sprite"
|
||||
version = "0.13.2"
|
||||
|
@ -1423,6 +1432,7 @@ dependencies = [
|
|||
"bevy_asset_loader",
|
||||
"bevy_ecs_ldtk",
|
||||
"bevy_editor_pls",
|
||||
"bevy_smooth_pixel_camera",
|
||||
"bevy_xpbd_2d",
|
||||
"leafwing-input-manager",
|
||||
"toml",
|
||||
|
|
|
@ -26,6 +26,7 @@ bevy_ecs_ldtk = { git = "https://github.com/Trouv/bevy_ecs_ldtk.git" }
|
|||
bevy_xpbd_2d = "0.4.2"
|
||||
benimator = "4.1.3"
|
||||
toml = "0.8.13"
|
||||
bevy_smooth_pixel_camera = "0.3.0"
|
||||
|
||||
[patch.crates-io]
|
||||
# Patch unstable version to resolve conflicting dependencies from bevy_ecs_ldtk
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"iid": "e1f10300-fec0-11ee-aa65-4dc22f7ac0b0",
|
||||
"jsonVersion": "1.5.3",
|
||||
"appBuildId": 476670,
|
||||
"nextUid": 84,
|
||||
"nextUid": 85,
|
||||
"identifierStyle": "Capitalize",
|
||||
"toc": [],
|
||||
"worldLayout": "Free",
|
||||
|
@ -730,8 +730,8 @@
|
|||
"exportToToc": false,
|
||||
"allowOutOfBounds": false,
|
||||
"doc": null,
|
||||
"width": 32,
|
||||
"height": 32,
|
||||
"width": 16,
|
||||
"height": 16,
|
||||
"resizableX": false,
|
||||
"resizableY": false,
|
||||
"minWidth": null,
|
||||
|
@ -890,7 +890,7 @@
|
|||
"renderMode": "Tile",
|
||||
"showName": true,
|
||||
"tilesetId": 8,
|
||||
"tileRenderMode": "Cover",
|
||||
"tileRenderMode": "FitInside",
|
||||
"tileRect": { "tilesetUid": 8, "x": 16, "y": 0, "w": 32, "h": 16 },
|
||||
"uiTileRect": null,
|
||||
"nineSliceBorders": [],
|
||||
|
@ -967,7 +967,7 @@
|
|||
"max": null,
|
||||
"regex": null,
|
||||
"acceptFileTypes": null,
|
||||
"defaultOverride": null,
|
||||
"defaultOverride": { "id": "V_Int", "params": [0] },
|
||||
"textLanguageMode": null,
|
||||
"symmetricalRef": false,
|
||||
"autoChainRef": true,
|
||||
|
@ -1346,10 +1346,10 @@
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,
|
||||
1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,
|
||||
0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,1,1,0,0,1,1,0,0,0,0,0,0,0,
|
||||
0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,1,1,0,0,1,1,0,0,0,0,0,1,1,
|
||||
0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,0,0,1,
|
||||
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,1,0,0,1,
|
||||
1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
],
|
||||
|
@ -1358,6 +1358,7 @@
|
|||
{ "px": [272,96], "src": [16,16], "f": 0, "t": 17, "d": [60,251], "a": 1 },
|
||||
{ "px": [336,128], "src": [16,16], "f": 0, "t": 17, "d": [60,333], "a": 1 },
|
||||
{ "px": [352,144], "src": [16,0], "f": 0, "t": 1, "d": [60,373], "a": 1 },
|
||||
{ "px": [384,160], "src": [16,16], "f": 0, "t": 17, "d": [60,414], "a": 1 },
|
||||
{ "px": [80,176], "src": [16,16], "f": 0, "t": 17, "d": [60,434], "a": 1 },
|
||||
{ "px": [96,176], "src": [16,0], "f": 0, "t": 1, "d": [60,435], "a": 1 },
|
||||
{ "px": [544,176], "src": [16,16], "f": 0, "t": 17, "d": [60,463], "a": 1 },
|
||||
|
@ -1372,8 +1373,11 @@
|
|||
{ "px": [160,80], "src": [16,0], "f": 1, "t": 1, "d": [59,205], "a": 1 },
|
||||
{ "px": [80,160], "src": [16,16], "f": 0, "t": 17, "d": [59,395], "a": 1 },
|
||||
{ "px": [96,160], "src": [16,0], "f": 1, "t": 1, "d": [59,396], "a": 1 },
|
||||
{ "px": [400,160], "src": [16,0], "f": 1, "t": 1, "d": [59,415], "a": 1 },
|
||||
{ "px": [528,160], "src": [16,16], "f": 0, "t": 17, "d": [59,423], "a": 1 },
|
||||
{ "px": [544,160], "src": [16,16], "f": 1, "t": 17, "d": [59,424], "a": 1 },
|
||||
{ "px": [384,176], "src": [16,16], "f": 0, "t": 17, "d": [59,453], "a": 1 },
|
||||
{ "px": [400,176], "src": [16,0], "f": 1, "t": 1, "d": [59,454], "a": 1 },
|
||||
{ "px": [528,176], "src": [0,16], "f": 0, "t": 16, "d": [59,462], "a": 1 },
|
||||
{ "px": [48,192], "src": [16,16], "f": 0, "t": 17, "d": [59,471], "a": 1 },
|
||||
{ "px": [144,192], "src": [16,16], "f": 1, "t": 17, "d": [59,477], "a": 1 },
|
||||
|
@ -1381,6 +1385,8 @@
|
|||
{ "px": [224,192], "src": [0,16], "f": 1, "t": 16, "d": [59,482], "a": 1 },
|
||||
{ "px": [272,192], "src": [0,16], "f": 0, "t": 16, "d": [59,485], "a": 1 },
|
||||
{ "px": [288,192], "src": [16,0], "f": 1, "t": 1, "d": [59,486], "a": 1 },
|
||||
{ "px": [384,192], "src": [0,16], "f": 0, "t": 16, "d": [59,492], "a": 1 },
|
||||
{ "px": [400,192], "src": [16,0], "f": 1, "t": 1, "d": [59,493], "a": 1 },
|
||||
{ "px": [528,192], "src": [16,16], "f": 0, "t": 17, "d": [59,501], "a": 1 },
|
||||
{ "px": [576,192], "src": [0,16], "f": 1, "t": 16, "d": [59,504], "a": 1 },
|
||||
{ "px": [160,96], "src": [0,16], "f": 0, "t": 16, "d": [58,244], "a": 1 },
|
||||
|
@ -1389,7 +1395,6 @@
|
|||
{ "px": [288,112], "src": [16,0], "f": 0, "t": 1, "d": [58,291], "a": 1 },
|
||||
{ "px": [320,128], "src": [16,16], "f": 0, "t": 17, "d": [58,332], "a": 1 },
|
||||
{ "px": [368,160], "src": [16,16], "f": 0, "t": 17, "d": [58,413], "a": 1 },
|
||||
{ "px": [384,160], "src": [0,16], "f": 0, "t": 16, "d": [58,414], "a": 1 },
|
||||
{ "px": [64,208], "src": [0,16], "f": 0, "t": 16, "d": [58,511], "a": 1 },
|
||||
{ "px": [80,208], "src": [16,0], "f": 0, "t": 1, "d": [58,512], "a": 1 },
|
||||
{ "px": [96,208], "src": [16,16], "f": 0, "t": 17, "d": [58,513], "a": 1 },
|
||||
|
@ -1413,13 +1418,14 @@
|
|||
{ "px": [304,128], "src": [0,16], "f": 0, "t": 16, "d": [56,331], "a": 1 },
|
||||
{ "px": [336,144], "src": [0,16], "f": 0, "t": 16, "d": [56,372], "a": 1 },
|
||||
{ "px": [352,160], "src": [16,16], "f": 0, "t": 17, "d": [56,412], "a": 1 },
|
||||
{ "px": [400,160], "src": [16,16], "f": 1, "t": 17, "d": [56,415], "a": 1 },
|
||||
{ "px": [48,208], "src": [0,16], "f": 0, "t": 16, "d": [56,510], "a": 1 },
|
||||
{ "px": [144,208], "src": [0,16], "f": 1, "t": 16, "d": [56,516], "a": 1 },
|
||||
{ "px": [208,208], "src": [16,0], "f": 0, "t": 1, "d": [56,520], "a": 1 },
|
||||
{ "px": [224,208], "src": [16,0], "f": 1, "t": 1, "d": [56,521], "a": 1 },
|
||||
{ "px": [272,208], "src": [0,16], "f": 0, "t": 16, "d": [56,524], "a": 1 },
|
||||
{ "px": [288,208], "src": [0,16], "f": 1, "t": 16, "d": [56,525], "a": 1 },
|
||||
{ "px": [384,208], "src": [0,16], "f": 0, "t": 16, "d": [56,531], "a": 1 },
|
||||
{ "px": [400,208], "src": [16,0], "f": 1, "t": 1, "d": [56,532], "a": 1 },
|
||||
{ "px": [528,208], "src": [16,0], "f": 0, "t": 1, "d": [56,540], "a": 1 },
|
||||
{ "px": [576,208], "src": [0,16], "f": 1, "t": 16, "d": [56,543], "a": 1 },
|
||||
{ "px": [144,64], "src": [0,0], "f": 0, "t": 0, "d": [55,165], "a": 1 },
|
||||
|
|
0
assets/player.toml
Normal file
0
assets/player.toml
Normal file
2
crates/animation/.gitignore
vendored
Normal file
2
crates/animation/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
target/
|
||||
|
331
crates/animation/Cargo.lock
generated
Normal file
331
crates/animation/Cargo.lock
generated
Normal file
|
@ -0,0 +1,331 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "animation"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rstest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "relative-path"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"
|
||||
|
||||
[[package]]
|
||||
name = "rstest"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afd55a67069d6e434a95161415f5beeada95a01c7b815508a82dcb0e1593682"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"rstest_macros",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rstest_macros"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4165dfae59a39dd41d8dec720d3cbfbc71f69744efb480a3920f5d4e0cc6798d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"glob",
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"relative-path",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
9
crates/animation/Cargo.toml
Normal file
9
crates/animation/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "animation"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
rstest = "0.21.0"
|
165
crates/animation/src/lib.rs
Normal file
165
crates/animation/src/lib.rs
Normal file
|
@ -0,0 +1,165 @@
|
|||
use std::time::Duration;
|
||||
|
||||
#[cfg(feature = "f32")]
|
||||
pub type Float = f32;
|
||||
#[cfg(feature = "f32")]
|
||||
pub use std::f32 as floats;
|
||||
#[cfg(not(feature = "f32"))]
|
||||
pub type Float = f64;
|
||||
#[cfg(not(feature = "f32"))]
|
||||
pub use std::f64 as floats;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum Mode {
|
||||
Once,
|
||||
RepeatFrom(usize),
|
||||
PingPong,
|
||||
}
|
||||
|
||||
impl Default for Mode {
|
||||
fn default() -> Self {
|
||||
Self::RepeatFrom(0usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Frame {
|
||||
pub index: usize,
|
||||
pub duration: Duration,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn new(index: usize, duration: Duration) -> Self {
|
||||
assert!(!duration.is_zero(), "must be a non-zero duration");
|
||||
Self { index, duration }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Animation {
|
||||
pub(crate) frames: Vec<Frame>,
|
||||
pub(crate) mode: Mode,
|
||||
}
|
||||
|
||||
impl Animation {
|
||||
pub fn len(&self) -> usize {
|
||||
self.frames.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
pub fn from_indices(indices: impl Iterator<Item = usize>, frame_rate: FrameRate) -> Self {
|
||||
let duration = if frame_rate.is_total_duration {
|
||||
frame_rate.frame_duration.div_f64(indices.cloned().count() as f64)
|
||||
} else {
|
||||
frame_rate.frame_duration
|
||||
};
|
||||
|
||||
indices
|
||||
.map(|index| Frame::new(index, duration))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct FrameRate {
|
||||
frame_duration: Duration,
|
||||
is_total_duration: bool,
|
||||
}
|
||||
|
||||
impl FrameRate {
|
||||
pub fn from_fps(fps: Float) -> Self {
|
||||
assert!(fps.is_finite(), "FPS must be finite");
|
||||
Self::from_total_duration(Duration::from_secs(1).div_f64(fps))
|
||||
}
|
||||
|
||||
pub fn from_frame_duration(frame_duration: Duration) -> Self {
|
||||
Self {
|
||||
frame_duration,
|
||||
is_total_duration: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_total_duration(frame_duration: Duration) -> Self {
|
||||
Self {
|
||||
frame_duration,
|
||||
is_total_duration: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct State {
|
||||
animation_index: usize,
|
||||
sprite_index: usize,
|
||||
elapsed_time: Duration,
|
||||
is_reverse: bool,
|
||||
is_complete: bool,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn frame<'a>(&self, animation: &'a Animation) -> &'a Frame {
|
||||
&animation.frames[self.animation_index % animation.len()]
|
||||
}
|
||||
|
||||
pub fn update(&mut self, animation: &Animation, delta: Duration) {
|
||||
let mut current_frame = self.frame(animation);
|
||||
self.sprite_index = current_frame.index;
|
||||
self.elapsed_time += delta;
|
||||
while self.elapsed_time >= current_frame.duration {
|
||||
let is_last_frame = self.animation_index >= animation.len();
|
||||
|
||||
match animation.mode {
|
||||
Mode::Once if self.is_complete => {}
|
||||
Mode::Once if is_last_frame => self.is_complete = true,
|
||||
Mode::Once => self.animation_index += 1,
|
||||
Mode::RepeatFrom(start_frame) if is_last_frame => {
|
||||
self.animation_index = start_frame
|
||||
}
|
||||
Mode::RepeatFrom(_start_frame) => self.animation_index += 1,
|
||||
Mode::PingPong if self.is_reverse && self.animation_index == 0 => {
|
||||
self.is_reverse = false;
|
||||
self.animation_index += 1;
|
||||
}
|
||||
Mode::PingPong if is_last_frame => {
|
||||
self.is_reverse = true;
|
||||
self.animation_index += 1;
|
||||
}
|
||||
Mode::PingPong => self.animation_index += 1,
|
||||
}
|
||||
|
||||
self.elapsed_time -= current_frame.duration;
|
||||
current_frame = self.frame(animation);
|
||||
self.sprite_index = current_frame.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
#[rstest]
|
||||
#[should_panic(expected = "must be a non-zero duration")]
|
||||
fn should_panic_on_zero_duration_frame(#[values(0.0)] value: Float) {
|
||||
let _ = Frame::new(0usize, Duration::from_secs_f64(value));
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn state() -> State {
|
||||
State::new()
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn sixy_fps_4_frame_animation() -> Animation {
|
||||
Animation::f
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn update_sixty_fps(sixy_fps: Duration) {}
|
||||
}
|
52
src/animation/mod.rs
Normal file
52
src/animation/mod.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use std::time::Duration;
|
||||
|
||||
#[cfg(feature = "f32")]
|
||||
pub type Float = f32;
|
||||
#[cfg(feature = "f32")]
|
||||
pub use std::f32 as floats;
|
||||
#[cfg(not(feature = "f32"))]
|
||||
pub type Float = f64;
|
||||
#[cfg(not(feature = "f32"))]
|
||||
pub use std::f64 as floats;
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum Mode {
|
||||
Once,
|
||||
RepeatFrom(usize),
|
||||
PingPong
|
||||
}
|
||||
|
||||
impl Default for Mode {
|
||||
fn default() -> Self {
|
||||
Self::RepeatFrom(0usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Frame {
|
||||
pub index: usize,
|
||||
pub duration: Duration
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
pub fn new(index: usize, duration: Duration) -> Self {
|
||||
assert!(!duration.is_zero(), "must be a non-zero duration");
|
||||
Self { index, duration }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Animation {
|
||||
pub(crate) frames: Vec<Frame>,
|
||||
pub(crate) mode: Mode
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
se rstest::rstest;
|
||||
use super::Float;
|
||||
|
||||
#[rstest]
|
||||
fn test(#[values(0.0, -1.0)] time: Float) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_ecs_ldtk::prelude::*;
|
||||
use bevy_smooth_pixel_camera::{components::PixelCamera, viewport::ViewportSize};
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct Follow {
|
||||
|
@ -36,27 +37,47 @@ impl UnresolvedTargetRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct PixelCameraBundle {
|
||||
pixel_camera: PixelCamera,
|
||||
camera_2d_bundle: Camera2dBundle,
|
||||
}
|
||||
|
||||
impl Default for PixelCameraBundle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pixel_camera: PixelCamera::from_size(ViewportSize::PixelFixed(1)),
|
||||
camera_2d_bundle: Camera2dBundle::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Bundle, Default, LdtkEntity)]
|
||||
pub struct CameraEntity {
|
||||
#[with(UnresolvedTargetRef::from_field)]
|
||||
unresolved_target_ref: UnresolvedTargetRef,
|
||||
camera_2d_bundle: Camera2dBundle
|
||||
pixel_camera_bundle: PixelCameraBundle,
|
||||
}
|
||||
|
||||
pub struct CameraPlugin;
|
||||
impl Plugin for CameraPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, (follow_target, resolve_target_references, dynamic_scale)).register_ldtk_entity::<CameraEntity>("Camera");
|
||||
app.add_systems(
|
||||
Update,
|
||||
(follow_target, resolve_target_references, dynamic_scale),
|
||||
)
|
||||
.register_ldtk_entity::<CameraEntity>("Camera");
|
||||
}
|
||||
}
|
||||
|
||||
fn follow_target(
|
||||
mut follower_q: Query<(&mut Transform, &Follow)>,
|
||||
mut follower_q: Query<(&mut PixelCamera, &Follow)>,
|
||||
target_q: Query<&GlobalTransform, Without<Follow>>,
|
||||
) {
|
||||
for (mut transform, follow) in follower_q.iter_mut() {
|
||||
for (mut camera, follow) in follower_q.iter_mut() {
|
||||
if let Ok(target) = target_q.get(follow.target) {
|
||||
transform.translation = target.transform_point(follow.offset);
|
||||
let result = target.transform_point(follow.offset);
|
||||
camera.subpixel_pos = Vec2::new(result.x, result.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +108,6 @@ pub fn resolve_target_references(
|
|||
|
||||
pub fn dynamic_scale(mut query: Query<&mut OrthographicProjection>) {
|
||||
for mut projection in query.iter_mut() {
|
||||
projection.scale = 0.2;
|
||||
projection.scale = 0.5;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ impl ZIndex {
|
|||
Self(
|
||||
*instance
|
||||
.get_int_field("ZIndex")
|
||||
.expect("expected entity to have Z Index field")
|
||||
.expect("expected entity to have Z Index field"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -25,44 +25,56 @@ impl<T: Into<i32>> From<T> for ZIndex {
|
|||
pub struct Tile;
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct TileBundle {
|
||||
tile: Tile,
|
||||
pub struct ColliderBundle {
|
||||
collider: Collider,
|
||||
rigidbody: RigidBody,
|
||||
}
|
||||
|
||||
impl Default for TileBundle {
|
||||
impl Default for ColliderBundle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
tile: Tile,
|
||||
collider: Collider::rectangle(16., 16.),
|
||||
rigidbody: RigidBody::Static,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Bundle, LdtkIntCell)]
|
||||
pub struct TileIntCell {
|
||||
tile_bundle: TileBundle,
|
||||
impl From<&EntityInstance> for ColliderBundle {
|
||||
fn from(value: &EntityInstance) -> Self {
|
||||
let rigidbody = match value.get_enum_field("Collider") {
|
||||
Ok(_) => RigidBody::Kinematic,
|
||||
_ => RigidBody::Static,
|
||||
};
|
||||
|
||||
Self {
|
||||
rigidbody,
|
||||
collider: Collider::rectangle(value.width as f32, value.height as f32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Bundle, LdtkIntCell)]
|
||||
pub struct TileIntCell {
|
||||
tile: Tile,
|
||||
collider_bundle: ColliderBundle,
|
||||
}
|
||||
|
||||
#[derive(Default, Bundle, LdtkEntity)]
|
||||
pub struct PlatformEntity {
|
||||
#[with(ZIndex::from_field)]
|
||||
z_index: ZIndex,
|
||||
#[from_entity_instance]
|
||||
collider_bundle: ColliderBundle,
|
||||
#[sprite_sheet_bundle]
|
||||
sprite_sheet_bundle: SpriteSheetBundle
|
||||
sprite_sheet_bundle: SpriteSheetBundle,
|
||||
}
|
||||
|
||||
|
||||
pub struct LevelPlugin;
|
||||
impl Plugin for LevelPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
.register_type::<ZIndex>()
|
||||
app.register_type::<ZIndex>()
|
||||
.add_systems(Last, update_z_index)
|
||||
.register_ldtk_entity::<PlatformEntity>("Platforms")
|
||||
.register_ldtk_entity::<PlatformEntity>("OneWayPlatform")
|
||||
.register_default_ldtk_int_cell_for_layer::<TileIntCell>("Ground");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use assets::{ldtk::WorldConfig, AssetPlugin};
|
||||
use bevy::prelude::*;
|
||||
use bevy_smooth_pixel_camera::PixelCameraPlugin;
|
||||
use bevy_xpbd_2d::math::{Scalar, Vector};
|
||||
use camera::CameraPlugin;
|
||||
use debug::DebugPlugin;
|
||||
|
@ -13,6 +14,7 @@ mod debug;
|
|||
mod level;
|
||||
mod physics;
|
||||
mod player;
|
||||
mod animation;
|
||||
|
||||
#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum GameState {
|
||||
|
@ -29,10 +31,12 @@ pub struct GamePlugin;
|
|||
impl Plugin for GamePlugin {
|
||||
fn build(&self, app: &mut bevy::prelude::App) {
|
||||
app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||
.add_plugins(PixelCameraPlugin)
|
||||
.add_plugins((
|
||||
AssetPlugin,
|
||||
PhysicsPlugin,
|
||||
LevelPlugin,
|
||||
AnimationPlugin,
|
||||
PlayerPlugin,
|
||||
CameraPlugin,
|
||||
))
|
||||
|
|
|
@ -2,22 +2,17 @@ mod controller;
|
|||
mod input;
|
||||
mod movement;
|
||||
|
||||
use bevy::{prelude::*, render::view::RenderLayers};
|
||||
use bevy::prelude::*;
|
||||
use bevy_ecs_ldtk::prelude::*;
|
||||
use leafwing_input_manager::{action_state::ActionState, InputManagerBundle};
|
||||
|
||||
use self::{
|
||||
controller::{CharacterControllerBundle, CharacterControllerPlugin, Jumping},
|
||||
input::{InputPlugin, PlayerAction},
|
||||
movement::MovementDirection
|
||||
movement::MovementDirection,
|
||||
};
|
||||
use crate::level::ZIndex;
|
||||
use crate::{animation::*, level::ZIndex};
|
||||
|
||||
#[derive(Component, Deref)]
|
||||
pub struct Animation(benimator::Animation);
|
||||
|
||||
#[derive(Default, Component, Deref, DerefMut)]
|
||||
pub struct AnimationState(benimator::State);
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct Player;
|
||||
|
@ -27,8 +22,7 @@ pub struct PlayerBundle {
|
|||
player: Player,
|
||||
input_manager_bundle: InputManagerBundle<PlayerAction>,
|
||||
character_controller_bundle: CharacterControllerBundle,
|
||||
animation: Animation,
|
||||
animation_state: AnimationState,
|
||||
animation_bundle: AnimationBundle,
|
||||
}
|
||||
|
||||
impl Default for PlayerBundle {
|
||||
|
@ -37,11 +31,10 @@ impl Default for PlayerBundle {
|
|||
player: Player,
|
||||
input_manager_bundle: InputManagerBundle::with_map(PlayerAction::default_input_map()),
|
||||
character_controller_bundle: CharacterControllerBundle::default(),
|
||||
animation: Animation(benimator::Animation::from_indices(
|
||||
animation_bundle: AnimationBundle::from_animation(benimator::Animation::from_indices(
|
||||
0..4,
|
||||
benimator::FrameRate::from_fps(12.),
|
||||
)),
|
||||
animation_state: AnimationState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,14 +52,7 @@ pub struct PlayerPlugin;
|
|||
impl Plugin for PlayerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((InputPlugin, CharacterControllerPlugin))
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
apply_movement_input,
|
||||
apply_jumping_input,
|
||||
animate,
|
||||
),
|
||||
)
|
||||
.add_systems(Update, (apply_movement_input, apply_jumping_input))
|
||||
.register_ldtk_entity::<PlayerEntity>("Player");
|
||||
}
|
||||
}
|
||||
|
@ -92,14 +78,3 @@ fn apply_jumping_input(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn animate(
|
||||
time: Res<Time>,
|
||||
mut query: Query<(&mut AnimationState, &mut TextureAtlas, &Animation)>,
|
||||
) {
|
||||
let delta = time.delta();
|
||||
for (mut state, mut atlas, animation) in query.iter_mut() {
|
||||
state.update(animation, delta);
|
||||
atlas.index = state.frame_index();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue