Compare commits
No commits in common. "1d22c11cde12798dbbda9ec80e9999831786bffd" and "12e58b3fc08a599057d9a13c82f275fffe361f9e" have entirely different histories.
1d22c11cde
...
12e58b3fc0
16 changed files with 344 additions and 768 deletions
147
Cargo.lock
generated
147
Cargo.lock
generated
|
@ -208,9 +208,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy"
|
name = "bevy"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fea147ef1ebb92d41294cfad804c40de151b174c711ce6e0a4a40eba23eae1a4"
|
checksum = "55f08528a4e59d607460513a823b40f602d013c1a00f57b824f1075d5d48c3cd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_internal",
|
"bevy_internal",
|
||||||
]
|
]
|
||||||
|
@ -241,9 +241,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_animation"
|
name = "bevy_animation"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4365465fca7bd78295eb81d0a04afc049399852793d562eb017849bb5d6c55e"
|
checksum = "e243169af495ad616ff701247c0d3e40078a26ed8de231cf9e54bde6b3c4bb45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_asset",
|
"bevy_asset",
|
||||||
|
@ -259,9 +259,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_app"
|
name = "bevy_app"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e4ae0a6ed2adf3b153511b4645241660a93f747c05ecd1e5a909dafc803cad4"
|
checksum = "53d26d6ffdf493609d2fedc1018a2ef0cb4d8e48f6d3bcea56fa2df81867e464"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_derive",
|
"bevy_derive",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -274,9 +274,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_asset"
|
name = "bevy_asset"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2ec773c861a7e9d9978771f59f385500ec6da3a1ab5487705cddb054393d3d19"
|
checksum = "3d8fb95306d5f18fa70df40632cd984993aeb71e91ce059ae99699098a4f9ce9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -302,9 +302,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_audio"
|
name = "bevy_audio"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e5cf4713a24f318841f73a9e030854cfd5bad46bc81fa1acc9590cdab053c6f"
|
checksum = "eee08ac575397ce17477dd291862bafa15226334bdfb82c02bbc3d10bad7bdb8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -316,23 +316,11 @@ dependencies = [
|
||||||
"rodio",
|
"rodio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bevy_common_assets"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f7be9ee39085d8319d5cd853447b0b5c4f8b4bfd647aec91e2bd996e9db67ef"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"bevy",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_core"
|
name = "bevy_core"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c53172003d5cde7780870b5403c66c8ede3581faf3e510e916d8b4baa5b538d2"
|
checksum = "c6712146d54fff9e1865362e9f39a7b63c7b037ddb72a3d7bb05b959213fb61e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -345,9 +333,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_core_pipeline"
|
name = "bevy_core_pipeline"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e60efd10d593f6d122f2687f74c09ad55835a8f999c35bed6380ddd8e6ff7f2"
|
checksum = "080bb00399b6d7697e505f871d67c6de8b52eb06b47b0cda2be80c2396805983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_asset",
|
"bevy_asset",
|
||||||
|
@ -363,9 +351,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_derive"
|
name = "bevy_derive"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e6345431bbe6d7b6c165cd860ecd0b35da929779571259c5df970ac256d45f9"
|
checksum = "a4b8f0786d1fc7e0d35297917be463db3d0886f7bd8d4221ca3d565502579ffb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_macro_utils",
|
"bevy_macro_utils",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -374,9 +362,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_diagnostic"
|
name = "bevy_diagnostic"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58ac9f4c2815f412be4b6e21e4b299cdafa710f651d064f6d40b2a8377a0d17c"
|
checksum = "adab74ee5375fbf5d2b1d3da41de8d1491a8a706d17441b5e31214b65349d692"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -387,9 +375,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_ecs"
|
name = "bevy_ecs"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c174066a24ed8a14d15ea58b0aea1c1f5c763f4bb36ebdc2b1dc78026007d0f5"
|
checksum = "a5643dc27b7d6778e3a66c8e0f6ad1fd33309aa2fa61d935f360ccc85b7be6a2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"bevy_ecs_macros",
|
"bevy_ecs_macros",
|
||||||
|
@ -406,9 +394,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_ecs_macros"
|
name = "bevy_ecs_macros"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc50c39e49e8febccc74e8e731680adb0cb4aef1f53275740cbaa95c6da71f4f"
|
checksum = "a5f2f12677f8725d40930d0a19652f007fe0ef5ac38e23817cfc4930c61f5680"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_macro_utils",
|
"bevy_macro_utils",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -431,9 +419,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_encase_derive"
|
name = "bevy_encase_derive"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68bc194009c5e9b97da64a08142dd183c264885d99c985cf849868103018adf1"
|
checksum = "76a767adc36ce1fc917a736843b026d4de7069d90ed5e669c852481ef69fd5aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_macro_utils",
|
"bevy_macro_utils",
|
||||||
"encase_derive_impl",
|
"encase_derive_impl",
|
||||||
|
@ -441,9 +429,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_gilrs"
|
name = "bevy_gilrs"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb15a3427d9707be92b457e5d66900b02d853b475c21dd8662bdda387ba9f24e"
|
checksum = "963940426127533164af2a556971a03c493143c0afb95afadb4a070b6ab8c3df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -454,9 +442,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_gltf"
|
name = "bevy_gltf"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79db7d7e71b47a69953fbe8407ded5c6308eaeecf9a05efd5dfb42992f400a16"
|
checksum = "150cc6782c4472600c2ade5d78c6ce481c992690f0499e63765aba752d7e0f04"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
@ -483,9 +471,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_hierarchy"
|
name = "bevy_hierarchy"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5eb1ec76099ea5a716de08ea42ff41f036ebe2502df1d569168b58f16458a85e"
|
checksum = "8e2e4c20d7c843cd26ef3c5d7b4c20e3e32c275943e2437ecaca1cfd6cfe3b30"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -496,9 +484,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_input"
|
name = "bevy_input"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1821c4b760ba6ddb4fe61806e9cc33f40b09a884557aca4553a29b8c7d73c6b4"
|
checksum = "a11c70573fb4d4c056ba32cfa553daa7e6e1245cb876ccfbe322640928b7ee1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -508,9 +496,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_internal"
|
name = "bevy_internal"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee63ad1e3f95a26ff2c227fadb1534a7bfe3a098e0e45c347f2f2575a573d9bc"
|
checksum = "0d603b597772130782eab6e604706cbb764fb037f9cf0a1904b6f342845b6f44"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_animation",
|
"bevy_animation",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -546,9 +534,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_log"
|
name = "bevy_log"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "092daf498887814a064331dfcd1cf487a5ddab01fd38629b84a35b8b664462a1"
|
checksum = "8cafb12fc84734236e36f407ab62c72d5d4279fa4777e40a95d7cc973cbabcd1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_log-sys",
|
"android_log-sys",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -561,9 +549,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_macro_utils"
|
name = "bevy_macro_utils"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43fb5137e5198302d7c6c33d1e454cf48a586e7c6fd12f4860f12863951e16b9"
|
checksum = "4d081af83b701e16cad209255ba6b383744dfa49efa99eb6505989f293305ab3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -572,18 +560,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_math"
|
name = "bevy_math"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "531f2b90c7e861a96f418b3d560131b3354c5e67a67eba3953a45a56ea0114d2"
|
checksum = "db5394e86c5708d3aa506c6e98ec4ed2a4083a7a018c6693d9ac0e77ebfabfc2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_mikktspace"
|
name = "bevy_mikktspace"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "941e7d3d4e1dbb735f040e4cdc1558be1d3c38d43f1d9fdbb039c39a7849a00b"
|
checksum = "40b299a61175a6f7e7398f83cd5b50920fd8bad4df674e614ad94f25f8426509"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
]
|
]
|
||||||
|
@ -611,9 +599,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_ptr"
|
name = "bevy_ptr"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9960c19e582b43cebe1894b6679520a4f50802d1cc5b6fa432f8d685ed232f09"
|
checksum = "d92d5679e89602a18682a37846573dcd1979410179e14204280460ba9fb8713a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_rapier2d"
|
name = "bevy_rapier2d"
|
||||||
|
@ -630,9 +618,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_reflect"
|
name = "bevy_reflect"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fc689dd7a7df3b3768884a4754711d406aa302ea48da483c03b52715fa95045"
|
checksum = "08798e67f2d4e6898ef117d8c99cf3b50a8eebc8da4159e6dad2657a0fbe9a4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_ptr",
|
"bevy_ptr",
|
||||||
"bevy_reflect_derive",
|
"bevy_reflect_derive",
|
||||||
|
@ -649,9 +637,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_reflect_derive"
|
name = "bevy_reflect_derive"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c36fa5100832c787c10558d31632ddc454c221e8dfacbbef836938f59614754"
|
checksum = "19209a7f0238053802b7de04e6724bd90d4ed7d90e87101dbd1b64cca64ff694"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_macro_utils",
|
"bevy_macro_utils",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -662,9 +650,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_render"
|
name = "bevy_render"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "600bcef85c7efac6e38ed725707f0e5b7c59b510430034ba2f743f472493f845"
|
checksum = "bb49530388ef17cff3fb8bd5e47372fb3cfeb4befc73e3036f6462ac20f049ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -705,9 +693,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_render_macros"
|
name = "bevy_render_macros"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1be90adc9e5d5808833e363670818da5fe68ccafd7ca983a457f90957d2a430b"
|
checksum = "e7d0b7a51fa819c20c64f43856c5aaea40f853050bbb09b9ba3672e5ff2688a5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_macro_utils",
|
"bevy_macro_utils",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -717,9 +705,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_scene"
|
name = "bevy_scene"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a045d575d2c8f776d8ea965363c81660243fefbfc3712ead938b00dfd6797216"
|
checksum = "0064d73ebb0de39901478b493604a1a6d448fd337b66803004c60f41f1fa6c37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -765,9 +753,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_tasks"
|
name = "bevy_tasks"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b753acb3d5b9dbfd77038560fe1893c17d4ee0a4242c2ee70da9d59430537"
|
checksum = "ff874c91a36eaac3ef957c6f3b590fb71332d9d136671cc858847d56fe9f80a3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"async-executor",
|
"async-executor",
|
||||||
|
@ -780,9 +768,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_text"
|
name = "bevy_text"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c265b7515faf55a3b92fd6ce0ab65dd246f247e11d737d6f5cdaf49c2be42c63"
|
checksum = "ef05a788c2c04aaa5db95b22a8f0fff0d3a0b08a7bcd1a71f050a628b38eec6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -803,9 +791,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_time"
|
name = "bevy_time"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22830665b8476292b861216383fd79922aef2b540f9fd09d49144e3e5e94550e"
|
checksum = "74ec681d641371df81d7bfbcb0eea725ed873f38a094f34b5f7b436f0889e77c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -816,9 +804,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_transform"
|
name = "bevy_transform"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4bb8760f03e9667e7499a5ceec1f7630fc3e45702781ac0df56cb969e8ae668"
|
checksum = "42e1528e35f30bede46a50ee4134f150efc01f5c1002c340b3b2e6a0bfcb8aa5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
"bevy_ecs",
|
"bevy_ecs",
|
||||||
|
@ -857,9 +845,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_utils"
|
name = "bevy_utils"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6e9aa1866c1cf7ee000f281ce9e90d02d701f5c7380a107252017e58e2f5246"
|
checksum = "8bda6dada53e546845887ae7357eec57b8d547ef71627b716b33839b4a98b687"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
|
@ -886,9 +874,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_winit"
|
name = "bevy_winit"
|
||||||
version = "0.8.1"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98b15fee4b75472e3441b0c7221467303e4ce59b342a94a328e447e7cdb5a43c"
|
checksum = "57537a56ac4f4e1ffcad95227bcab37cd17b51770dacff82374a2d88be376322"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx",
|
"approx",
|
||||||
"bevy_app",
|
"bevy_app",
|
||||||
|
@ -910,15 +898,12 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy-inspector-egui",
|
"bevy-inspector-egui",
|
||||||
"bevy_common_assets",
|
|
||||||
"bevy_rapier2d",
|
"bevy_rapier2d",
|
||||||
"cpal 0.14.0",
|
"cpal 0.14.0",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"hexodsp",
|
"hexodsp",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"rapier2d",
|
|
||||||
"serde",
|
|
||||||
"ticktock",
|
"ticktock",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,12 @@ license = "AGPL-3.0-only"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = "0.8.1"
|
bevy = "0.8.0"
|
||||||
bevy_common_assets = { version = "0.3.0", features = ["json"] }
|
|
||||||
bevy-inspector-egui = "0.12.1"
|
bevy-inspector-egui = "0.12.1"
|
||||||
bevy_rapier2d = "0.16.2"
|
bevy_rapier2d = "0.16.2"
|
||||||
crossbeam-channel = "0.5.6"
|
crossbeam-channel = "0.5.6"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rand_distr = "0.4.3"
|
rand_distr = "0.4.3"
|
||||||
rapier2d = "0.14.0"
|
|
||||||
serde = { version = "1.0.144", features = ["derive"] }
|
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies]
|
[target."cfg(not(target_arch = \"wasm32\"))".dependencies]
|
||||||
cpal = "0.14.0"
|
cpal = "0.14.0"
|
||||||
|
|
|
@ -5,19 +5,16 @@
|
||||||
* **Move**: arrows
|
* **Move**: arrows
|
||||||
* **Switch character**: Tab
|
* **Switch character**: Tab
|
||||||
* **Level up**: Enter (when character is white)
|
* **Level up**: Enter (when character is white)
|
||||||
* **Reset**: R
|
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
* name
|
* name
|
||||||
* more filters
|
* color filters
|
||||||
* despawn black characters
|
|
||||||
* despawn character when too far
|
|
||||||
* level design
|
* level design
|
||||||
|
* (?) can jump only from a surface (no mid-air jump)
|
||||||
* (?) multiplayer
|
* (?) multiplayer
|
||||||
|
* level reset
|
||||||
* more audio
|
* more audio
|
||||||
* "jumpable" component to avoid jumping on sensors
|
|
||||||
* bug: in level2, move the blue character to win, then reset. The characters are lighter than expected.
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
|
BIN
assets/bevy.png
BIN
assets/bevy.png
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB |
|
@ -1,119 +0,0 @@
|
||||||
{
|
|
||||||
"levels": [
|
|
||||||
{
|
|
||||||
"comment": "Movement tutorial",
|
|
||||||
"platforms": [
|
|
||||||
{"pos": [0, -256], "size": [800, 16]}
|
|
||||||
],
|
|
||||||
"characters": [
|
|
||||||
{"pos": [0, -192], "color": [1,0,0,1]},
|
|
||||||
{"pos": [-128, -192], "color": [0,1,0,1]},
|
|
||||||
{"pos": [128, -192], "color": [0,0,1,1]}
|
|
||||||
],
|
|
||||||
"absorbing_filters": [],
|
|
||||||
"rotating_filters": [],
|
|
||||||
"texts": [
|
|
||||||
{
|
|
||||||
"pos": [0, 0],
|
|
||||||
"font_size": 32,
|
|
||||||
"text": "Combine the colors to synthetize a white light.\nUse arrows to move."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Switch tutorial",
|
|
||||||
"platforms": [
|
|
||||||
{"pos": [0, -256], "size": [800, 16]},
|
|
||||||
{"pos": [128, 256], "size": [96, 16]}
|
|
||||||
],
|
|
||||||
"characters": [
|
|
||||||
{"pos": [0, -192], "color": [0,1,0,1]},
|
|
||||||
{"pos": [-128, -192], "color": [1,0,0,1]},
|
|
||||||
{"pos": [128, 320], "color": [0,0,1,1]}
|
|
||||||
],
|
|
||||||
"absorbing_filters": [],
|
|
||||||
"rotating_filters": [],
|
|
||||||
"texts": [
|
|
||||||
{
|
|
||||||
"pos": [0, 0],
|
|
||||||
"font_size": 32,
|
|
||||||
"text": "Press Tab to switch."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Absorbing filter tutorial",
|
|
||||||
"platforms": [
|
|
||||||
{"pos": [0, -256], "size": [800, 16]},
|
|
||||||
{"pos": [0, -128], "size": [800, 16]}
|
|
||||||
],
|
|
||||||
"characters": [
|
|
||||||
{"pos": [-128, -192], "color": [1,0.64,0,1]},
|
|
||||||
{"pos": [128, -192], "color": [0,0.37,1,1]}
|
|
||||||
],
|
|
||||||
"absorbing_filters": [
|
|
||||||
{
|
|
||||||
"pos": [0, -192],
|
|
||||||
"size": [16, 112],
|
|
||||||
"color": [1,0,0,1]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rotating_filters": [],
|
|
||||||
"texts": [
|
|
||||||
{
|
|
||||||
"pos": [0, 0],
|
|
||||||
"font_size": 32,
|
|
||||||
"text": "Press R to reset."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Rotating filter tutorial",
|
|
||||||
"platforms": [
|
|
||||||
{"pos": [0, -256], "size": [800, 16]}
|
|
||||||
],
|
|
||||||
"characters": [
|
|
||||||
{"pos": [0, -192], "color": [1,0,0,1]},
|
|
||||||
{"pos": [-128, -192], "color": [1,0,0,1]},
|
|
||||||
{"pos": [128, -192], "color": [1,0,0,1]}
|
|
||||||
],
|
|
||||||
"absorbing_filters": [],
|
|
||||||
"rotating_filters": [
|
|
||||||
{
|
|
||||||
"pos": [0, -64],
|
|
||||||
"angle": 45
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"texts": [
|
|
||||||
{
|
|
||||||
"pos": [0, 0],
|
|
||||||
"font_size": 32,
|
|
||||||
"text": "Let's rotate the hue!"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Game over",
|
|
||||||
"platforms": [
|
|
||||||
{"pos": [0, -256], "size": [800, 16]}
|
|
||||||
],
|
|
||||||
"characters": [
|
|
||||||
{"pos": [0, -64], "color": [1,0,0,1]}
|
|
||||||
],
|
|
||||||
"absorbing_filters": [],
|
|
||||||
"rotating_filters": [],
|
|
||||||
"texts": [
|
|
||||||
{
|
|
||||||
"pos": [0, 128],
|
|
||||||
"font_size": 48,
|
|
||||||
"text": "Thank you for playing!"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"pos": [0, 0],
|
|
||||||
"font_size": 32,
|
|
||||||
"text": "There is no more light to combine."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,6 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>Bevyjam</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
|
16
src/audio.rs
16
src/audio.rs
|
@ -33,18 +33,9 @@ pub fn setup(event_channel: Receiver<AudioMsg>) {
|
||||||
let color_mix_b_gain = color_mix.inp_param("gain3").unwrap();
|
let color_mix_b_gain = color_mix.inp_param("gain3").unwrap();
|
||||||
let jump_ad = NodeId::Ad(0);
|
let jump_ad = NodeId::Ad(0);
|
||||||
let jump_ad_trig = jump_ad.inp_param("trig").unwrap();
|
let jump_ad_trig = jump_ad.inp_param("trig").unwrap();
|
||||||
let switch_ad = NodeId::Ad(1);
|
|
||||||
let switch_ad_trig = switch_ad.inp_param("trig").unwrap();
|
|
||||||
let fusion_ad = NodeId::Ad(2);
|
|
||||||
let fusion_ad_trig = fusion_ad.inp_param("trig").unwrap();
|
|
||||||
let fusion_ad2 = NodeId::Ad(3);
|
|
||||||
let fusion_ad2_trig = fusion_ad2.inp_param("trig").unwrap();
|
|
||||||
|
|
||||||
for (_tick, _now) in Clock::framerate(20.0).iter() {
|
for (_tick, _now) in Clock::framerate(10.0).iter() {
|
||||||
matrix.set_param(jump_ad_trig, (0.0).into());
|
matrix.set_param(jump_ad_trig, (0.0).into());
|
||||||
matrix.set_param(switch_ad_trig, (0.0).into());
|
|
||||||
matrix.set_param(fusion_ad_trig, (0.0).into());
|
|
||||||
matrix.set_param(fusion_ad2_trig, (0.0).into());
|
|
||||||
|
|
||||||
if let Ok(msg) = event_channel.try_recv() {
|
if let Ok(msg) = event_channel.try_recv() {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -53,12 +44,7 @@ pub fn setup(event_channel: Receiver<AudioMsg>) {
|
||||||
matrix.set_param(color_mix_g_gain, g.into());
|
matrix.set_param(color_mix_g_gain, g.into());
|
||||||
matrix.set_param(color_mix_b_gain, b.into());
|
matrix.set_param(color_mix_b_gain, b.into());
|
||||||
}
|
}
|
||||||
AudioMsg::Fusion => {
|
|
||||||
matrix.set_param(fusion_ad_trig, (1.0).into());
|
|
||||||
matrix.set_param(fusion_ad2_trig, (1.0).into());
|
|
||||||
}
|
|
||||||
AudioMsg::Jump => matrix.set_param(jump_ad_trig, (1.0).into()),
|
AudioMsg::Jump => matrix.set_param(jump_ad_trig, (1.0).into()),
|
||||||
AudioMsg::Switch => matrix.set_param(switch_ad_trig, (1.0).into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
use crate::game::Level;
|
|
||||||
|
|
||||||
use bevy::prelude::{shape::Quad, *};
|
|
||||||
use bevy_rapier2d::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub enum PassThroughFilter {
|
|
||||||
/// Absorbs this color (ignoring alpha)
|
|
||||||
Absorbing(Color),
|
|
||||||
/// Rotates hue by this angle (in degrees)
|
|
||||||
Rotating(f32),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PassThroughFilter {
|
|
||||||
pub fn apply(&self, color: Color) -> Color {
|
|
||||||
match self {
|
|
||||||
PassThroughFilter::Absorbing(filter_color) => Vec4::from(color)
|
|
||||||
.mul_add(
|
|
||||||
-Vec4::from(*filter_color) * Vec4::from([1., 1., 1., 0.]),
|
|
||||||
Vec4::from(color),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
PassThroughFilter::Rotating(filter_angle) => {
|
|
||||||
let mut hsla = color.as_hsla_f32();
|
|
||||||
hsla[0] = (hsla[0] + filter_angle) % 360.;
|
|
||||||
Color::hsla(hsla[0], hsla[1], hsla[2], hsla[3])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Bundle)]
|
|
||||||
pub struct AbsorbingFilter {
|
|
||||||
#[bundle]
|
|
||||||
pub mesh: ColorMesh2dBundle,
|
|
||||||
pub collider: Collider,
|
|
||||||
pub sensor: Sensor,
|
|
||||||
pub filter: PassThroughFilter,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_absorbing_filter(
|
|
||||||
commands: &mut Commands,
|
|
||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
||||||
|
|
||||||
transform: Transform,
|
|
||||||
size: Vec2,
|
|
||||||
color: Color,
|
|
||||||
) {
|
|
||||||
let mut material_color = color;
|
|
||||||
material_color.set_a(0.5);
|
|
||||||
commands
|
|
||||||
.spawn_bundle(AbsorbingFilter {
|
|
||||||
mesh: ColorMesh2dBundle {
|
|
||||||
mesh: meshes.add(Mesh::from(Quad { size, flip: false })).into(),
|
|
||||||
material: materials.add(material_color.into()),
|
|
||||||
transform,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
collider: Collider::cuboid(size.x / 2., size.y / 2.),
|
|
||||||
sensor: Sensor,
|
|
||||||
filter: PassThroughFilter::Absorbing(color),
|
|
||||||
})
|
|
||||||
.insert(Level);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Bundle)]
|
|
||||||
pub struct RotatingFilter {
|
|
||||||
#[bundle]
|
|
||||||
pub sprite: SpriteBundle,
|
|
||||||
pub collider: Collider,
|
|
||||||
pub sensor: Sensor,
|
|
||||||
pub filter: PassThroughFilter,
|
|
||||||
pub velocity: Velocity,
|
|
||||||
pub rigid_body: RigidBody,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_rotating_filter(
|
|
||||||
commands: &mut Commands,
|
|
||||||
asset_server: &Res<AssetServer>,
|
|
||||||
|
|
||||||
transform: Transform,
|
|
||||||
angle: f32,
|
|
||||||
) {
|
|
||||||
commands
|
|
||||||
.spawn_bundle(RotatingFilter {
|
|
||||||
sprite: SpriteBundle {
|
|
||||||
texture: asset_server.get_handle("bevy.png"),
|
|
||||||
transform,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
collider: Collider::ball(32.),
|
|
||||||
sensor: Sensor,
|
|
||||||
filter: PassThroughFilter::Rotating(angle),
|
|
||||||
velocity: Velocity::angular(1.),
|
|
||||||
rigid_body: RigidBody::KinematicVelocityBased,
|
|
||||||
})
|
|
||||||
.insert(Level);
|
|
||||||
}
|
|
289
src/game.rs
289
src/game.rs
|
@ -1,28 +1,20 @@
|
||||||
#![allow(clippy::precedence)]
|
#![allow(clippy::precedence)]
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
pub use crate::filters::*;
|
|
||||||
|
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::system::EntityCommands,
|
|
||||||
input::{keyboard::KeyCode, Input},
|
input::{keyboard::KeyCode, Input},
|
||||||
prelude::{shape::Quad, *},
|
prelude::{shape::Quad, *},
|
||||||
sprite::Mesh2dHandle,
|
sprite::Mesh2dHandle, ecs::system::EntityCommands,
|
||||||
};
|
};
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
use rapier2d::geometry::CollisionEventFlags;
|
|
||||||
|
|
||||||
pub enum AudioMsg {
|
pub enum AudioMsg {
|
||||||
Color([f32; 3]),
|
Color([f32; 3]),
|
||||||
Fusion,
|
|
||||||
Jump,
|
Jump,
|
||||||
Switch,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FirstLevel(pub LevelId);
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
pub struct LevelId(pub u32);
|
pub struct LevelId(pub u32);
|
||||||
|
|
||||||
|
@ -43,14 +35,12 @@ impl Plugin for GamePlugin {
|
||||||
.with_system(crate::levels::post_setup_level)
|
.with_system(crate::levels::post_setup_level)
|
||||||
.with_system(change_character_system)
|
.with_system(change_character_system)
|
||||||
.with_system(player_movement_system)
|
.with_system(player_movement_system)
|
||||||
.with_system(level_keyboard_system)
|
|
||||||
.with_system(move_camera)
|
.with_system(move_camera)
|
||||||
.with_system(character_particle_effect_system),
|
.with_system(character_particle_effect_system),
|
||||||
)
|
)
|
||||||
.add_system_set(
|
.add_system_set(
|
||||||
SystemSet::on_update(AppState::Win)
|
SystemSet::on_update(AppState::Win)
|
||||||
.with_system(player_movement_system)
|
.with_system(player_movement_system)
|
||||||
.with_system(level_keyboard_system)
|
|
||||||
.with_system(move_camera)
|
.with_system(move_camera)
|
||||||
.with_system(character_particle_effect_system),
|
.with_system(character_particle_effect_system),
|
||||||
)
|
)
|
||||||
|
@ -60,7 +50,7 @@ impl Plugin for GamePlugin {
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
pub struct LevelStartupEvent;
|
pub struct LevelStartupEvent(pub Entity);
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
|
|
||||||
|
@ -95,41 +85,52 @@ pub struct CharacterColor(pub Color);
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Player;
|
pub struct Player;
|
||||||
|
|
||||||
#[derive(Component)]
|
|
||||||
pub struct CollisionCount(usize);
|
|
||||||
|
|
||||||
// Systems
|
// Systems
|
||||||
|
|
||||||
fn setup(
|
fn setup(
|
||||||
first_level: Res<FirstLevel>,
|
mut commands: Commands,
|
||||||
mut current_level: ResMut<CurrentLevel>,
|
mut current_level: ResMut<CurrentLevel>,
|
||||||
mut level_startup_event: EventWriter<LevelStartupEvent>,
|
mut level_startup_event: EventWriter<LevelStartupEvent>,
|
||||||
mut camera_query: Query<&mut Transform, With<Camera>>,
|
mut camera_query: Query<&mut Transform, With<Camera>>,
|
||||||
) {
|
) {
|
||||||
if current_level.0.is_none() {
|
let level_id = LevelId(current_level.0.map_or(0, |level_id| level_id.0 + 1));
|
||||||
current_level.0 = Some(first_level.0);
|
crate::levels::setup_level(
|
||||||
|
&mut commands,
|
||||||
|
&mut current_level,
|
||||||
|
&mut level_startup_event,
|
||||||
|
&mut camera_query,
|
||||||
|
level_id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::levels::setup_level(&mut level_startup_event, &mut camera_query);
|
pub fn spawn_characters(
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>(
|
|
||||||
commands: &mut Commands,
|
commands: &mut Commands,
|
||||||
character_meshes: &Res<CharacterMeshes>,
|
character_meshes: &Res<CharacterMeshes>,
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
|
||||||
characters: I,
|
transforms: &mut Vec<Transform>,
|
||||||
|
colors: &Vec<Color>,
|
||||||
) {
|
) {
|
||||||
for (i, (transform, color)) in characters.into_iter().enumerate() {
|
|
||||||
spawn_character(
|
spawn_character(
|
||||||
commands,
|
commands,
|
||||||
character_meshes,
|
character_meshes,
|
||||||
materials,
|
materials,
|
||||||
audio,
|
audio,
|
||||||
transform,
|
transforms[0],
|
||||||
color,
|
colors[0],
|
||||||
i == 0,
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
for c in 1 .. transforms.len() {
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
transforms[c],
|
||||||
|
colors[c],
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +160,7 @@ pub fn spawn_character(
|
||||||
.insert(CharacterColor(color))
|
.insert(CharacterColor(color))
|
||||||
.insert(RigidBody::Dynamic)
|
.insert(RigidBody::Dynamic)
|
||||||
.insert(Collider::cuboid(32., 32.))
|
.insert(Collider::cuboid(32., 32.))
|
||||||
|
.insert(ExternalForce::default())
|
||||||
.insert(Velocity::default())
|
.insert(Velocity::default())
|
||||||
.insert(GravityScale(10.0))
|
.insert(GravityScale(10.0))
|
||||||
.insert(LockedAxes::ROTATION_LOCKED)
|
.insert(LockedAxes::ROTATION_LOCKED)
|
||||||
|
@ -167,16 +169,8 @@ pub fn spawn_character(
|
||||||
linear_damping: 0.5,
|
linear_damping: 0.5,
|
||||||
angular_damping: 0.5,
|
angular_damping: 0.5,
|
||||||
})
|
})
|
||||||
.insert(ActiveEvents::COLLISION_EVENTS)
|
.insert(ExternalImpulse::default())
|
||||||
.with_children(|c| {
|
.insert(ActiveEvents::COLLISION_EVENTS);
|
||||||
c.spawn_bundle(TransformBundle::from_transform(Transform::from_xyz(
|
|
||||||
0., -33., 0.,
|
|
||||||
)))
|
|
||||||
.insert(Sensor)
|
|
||||||
.insert(Collider::cuboid(30., 0.5))
|
|
||||||
.insert(ActiveEvents::COLLISION_EVENTS)
|
|
||||||
.insert(CollisionCount(0));
|
|
||||||
});
|
|
||||||
|
|
||||||
if is_player {
|
if is_player {
|
||||||
entity_commands.insert(Player);
|
entity_commands.insert(Player);
|
||||||
|
@ -186,62 +180,24 @@ pub fn spawn_character(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_platforms<I: IntoIterator<Item = (Transform, Vec2)>>(
|
|
||||||
commands: &mut Commands,
|
|
||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
||||||
|
|
||||||
platforms: I,
|
|
||||||
) {
|
|
||||||
for (transform, size) in platforms.into_iter() {
|
|
||||||
spawn_platform(commands, meshes, materials, transform, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_platform(
|
|
||||||
commands: &mut Commands,
|
|
||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
||||||
|
|
||||||
transform: Transform,
|
|
||||||
size: Vec2,
|
|
||||||
) {
|
|
||||||
commands
|
|
||||||
.spawn_bundle(ColorMesh2dBundle {
|
|
||||||
mesh: meshes.add(Mesh::from(Quad { size, flip: false })).into(),
|
|
||||||
material: materials.add(ColorMaterial::from(Color::GRAY)),
|
|
||||||
transform,
|
|
||||||
..default()
|
|
||||||
})
|
|
||||||
.insert(Collider::cuboid(size.x / 2., size.y / 2.))
|
|
||||||
.insert(Level);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collision_event_system(
|
fn collision_event_system(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
character_meshes: Res<CharacterMeshes>,
|
character_meshes: Res<CharacterMeshes>,
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
mut collision_events: EventReader<CollisionEvent>,
|
mut collision_events: EventReader<CollisionEvent>,
|
||||||
mut character_query: Query<(
|
character_query: Query<(&CharacterColor, &Transform, Option<&Player>)>,
|
||||||
&mut CharacterColor,
|
|
||||||
&Transform,
|
|
||||||
&mut Handle<ColorMaterial>,
|
|
||||||
Option<&Player>,
|
|
||||||
)>,
|
|
||||||
pass_through_filter_query: Query<&PassThroughFilter>,
|
|
||||||
mut collision_counter_query: Query<&mut CollisionCount>,
|
|
||||||
mut app_state: ResMut<State<AppState>>,
|
mut app_state: ResMut<State<AppState>>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
) {
|
) {
|
||||||
for collision_event in collision_events.iter() {
|
for collision_event in collision_events.iter() {
|
||||||
match collision_event {
|
if let CollisionEvent::Started(e1, e2, flags) = collision_event {
|
||||||
CollisionEvent::Started(e1, e2, flags) => {
|
|
||||||
if flags.is_empty() {
|
if flags.is_empty() {
|
||||||
if let (
|
if let (
|
||||||
Ok((c1_color, c1_transform, _c1_material, c1_player)),
|
Ok((c1_color, c1_transform, c1_player)),
|
||||||
Ok((c2_color, c2_transform, _c2_material, c2_player)),
|
Ok((c2_color, c2_transform, c2_player))) =
|
||||||
) = (character_query.get(*e1), character_query.get(*e2))
|
(character_query.get(*e1), character_query.get(*e2))
|
||||||
{
|
{
|
||||||
|
// TODO completely remove particles
|
||||||
commands.entity(*e1).despawn_recursive();
|
commands.entity(*e1).despawn_recursive();
|
||||||
commands.entity(*e2).despawn_recursive();
|
commands.entity(*e2).despawn_recursive();
|
||||||
|
|
||||||
|
@ -256,87 +212,26 @@ fn collision_event_system(
|
||||||
}
|
}
|
||||||
|
|
||||||
// position character based on current player location
|
// position character based on current player location
|
||||||
|
if let Some(_player) = c1_player {
|
||||||
spawn_character(
|
spawn_character(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
&character_meshes,
|
&character_meshes,
|
||||||
&mut materials,
|
&mut materials,
|
||||||
&audio,
|
&audio,
|
||||||
if c1_player.is_some() {
|
*c1_transform,
|
||||||
*c1_transform
|
|
||||||
} else if c2_player.is_some() {
|
|
||||||
*c2_transform
|
|
||||||
} else {
|
|
||||||
Transform::identity().with_translation(
|
|
||||||
(c1_transform.translation + c2_transform.translation) / 2.,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
new_color.into(),
|
new_color.into(),
|
||||||
c1_player.is_some() || c2_player.is_some(),
|
true,
|
||||||
|
);
|
||||||
|
} else if let Some(_player) = c2_player {
|
||||||
|
spawn_character(
|
||||||
|
&mut commands,
|
||||||
|
&character_meshes,
|
||||||
|
&mut materials,
|
||||||
|
&audio,
|
||||||
|
*c2_transform,
|
||||||
|
new_color.into(),
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
audio.send(AudioMsg::Fusion).ok();
|
|
||||||
}
|
|
||||||
} else if *flags == CollisionEventFlags::SENSOR {
|
|
||||||
if let (Ok((mut c_color, _c_transform, mut c_material, c_player)), Ok(filter)) = (
|
|
||||||
character_query.get_mut(*e1),
|
|
||||||
pass_through_filter_query.get(*e2),
|
|
||||||
) {
|
|
||||||
c_color.0 = filter.apply(c_color.0);
|
|
||||||
*c_material = materials.add(ColorMaterial::from(c_color.0));
|
|
||||||
|
|
||||||
if c_player.is_some() {
|
|
||||||
audio
|
|
||||||
.send(AudioMsg::Color([
|
|
||||||
c_color.0.r(),
|
|
||||||
c_color.0.g(),
|
|
||||||
c_color.0.b(),
|
|
||||||
]))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
} else if let (
|
|
||||||
Ok((mut c_color, _c_transform, mut c_material, c_player)),
|
|
||||||
Ok(filter),
|
|
||||||
) = (
|
|
||||||
character_query.get_mut(*e2),
|
|
||||||
pass_through_filter_query.get(*e1),
|
|
||||||
) {
|
|
||||||
c_color.0 = filter.apply(c_color.0);
|
|
||||||
*c_material = materials.add(ColorMaterial::from(c_color.0));
|
|
||||||
|
|
||||||
if c_player.is_some() {
|
|
||||||
audio
|
|
||||||
.send(AudioMsg::Color([
|
|
||||||
c_color.0.r(),
|
|
||||||
c_color.0.g(),
|
|
||||||
c_color.0.b(),
|
|
||||||
]))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
} else if let (Ok(mut collision_count), Err(_)) = (
|
|
||||||
collision_counter_query.get_mut(*e1),
|
|
||||||
character_query.get_mut(*e2),
|
|
||||||
) {
|
|
||||||
collision_count.0 += 1;
|
|
||||||
} else if let (Ok(mut collision_count), Err(_)) = (
|
|
||||||
collision_counter_query.get_mut(*e2),
|
|
||||||
character_query.get_mut(*e1),
|
|
||||||
) {
|
|
||||||
collision_count.0 += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CollisionEvent::Stopped(e1, e2, flags) => {
|
|
||||||
if *flags == CollisionEventFlags::SENSOR {
|
|
||||||
if let (Ok(mut collision_count), Err(_)) = (
|
|
||||||
collision_counter_query.get_mut(*e1),
|
|
||||||
character_query.get_mut(*e2),
|
|
||||||
) {
|
|
||||||
collision_count.0 = collision_count.0.saturating_sub(1);
|
|
||||||
} else if let (Ok(mut collision_count), Err(_)) = (
|
|
||||||
collision_counter_query.get_mut(*e2),
|
|
||||||
character_query.get_mut(*e1),
|
|
||||||
) {
|
|
||||||
collision_count.0 = collision_count.0.saturating_sub(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,16 +246,14 @@ fn change_character_system(
|
||||||
characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
|
characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
) {
|
) {
|
||||||
if !keyboard_input.just_pressed(KeyCode::Tab) {
|
if !keyboard_input.just_pressed(KeyCode::Tab) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut player_idx: usize = 0;
|
let mut player_idx: usize = 0;
|
||||||
let mut player_count: usize = 0;
|
let mut player_count: usize = 0;
|
||||||
|
|
||||||
// find player idx
|
// find player idx
|
||||||
for (_entity, _color, player) in characters.iter() {
|
for (_entity, _color, player) in characters.iter() {
|
||||||
if player.is_some() {
|
if let Some(_player) = player {
|
||||||
player_idx = player_count;
|
player_idx = player_count;
|
||||||
}
|
}
|
||||||
player_count += 1;
|
player_count += 1;
|
||||||
|
@ -381,7 +274,7 @@ fn change_character_system(
|
||||||
audio
|
audio
|
||||||
.send(AudioMsg::Color([color.0.r(), color.0.g(), color.0.b()]))
|
.send(AudioMsg::Color([color.0.r(), color.0.g(), color.0.b()]))
|
||||||
.ok();
|
.ok();
|
||||||
audio.send(AudioMsg::Switch).ok();
|
audio.send(AudioMsg::Jump).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
player_count += 1;
|
player_count += 1;
|
||||||
|
@ -390,69 +283,53 @@ fn change_character_system(
|
||||||
|
|
||||||
fn player_movement_system(
|
fn player_movement_system(
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
mut characters: Query<(&mut Velocity, &Children), With<Player>>,
|
mut characters: Query<&mut Velocity, With<Player>>,
|
||||||
collision_counter_query: Query<&CollisionCount>,
|
mut app_state: ResMut<State<AppState>>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
let right_pressed: bool =
|
let right_pressed: bool =
|
||||||
keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D);
|
keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D);
|
||||||
let left_pressed: bool =
|
let left_pressed: bool =
|
||||||
keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A);
|
keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A);
|
||||||
|
|
||||||
for (mut velocity, children) in characters.iter_mut() {
|
for mut velocity in characters.iter_mut() {
|
||||||
velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32;
|
velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32;
|
||||||
|
|
||||||
if keyboard_input.just_pressed(KeyCode::Space)
|
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||||
&& collision_counter_query.get(children[0]).unwrap().0 != 0
|
|
||||||
{
|
|
||||||
audio.send(AudioMsg::Jump).ok();
|
audio.send(AudioMsg::Jump).ok();
|
||||||
velocity.linvel.y = 700.;
|
velocity.linvel.y = 500.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) {
|
||||||
|
app_state.replace(AppState::Game).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn character_particle_effect_system(
|
fn character_particle_effect_system(
|
||||||
player_character: Query<(&Transform, &CharacterColor), With<Player>>,
|
characters: Query<(&Transform, &CharacterColor), With<Player>>,
|
||||||
mut particle_effect: ResMut<crate::particle_effect::ParticleEffectResource>,
|
mut particle_effect: ResMut<crate::particle_effect::ParticleEffectResource>,
|
||||||
) {
|
) {
|
||||||
if let Ok((transform, color)) = player_character.get_single() {
|
for (transform, color) in characters.iter() {
|
||||||
particle_effect.translation = transform.translation;
|
particle_effect.translation = transform.translation;
|
||||||
particle_effect.color = color.0;
|
particle_effect.color = color.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn win_setup(
|
fn win_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
mut commands: Commands,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
||||||
asset_server: Res<AssetServer>,
|
|
||||||
) {
|
|
||||||
let font = asset_server.get_handle("UacariLegacy-Thin.ttf");
|
let font = asset_server.get_handle("UacariLegacy-Thin.ttf");
|
||||||
commands
|
|
||||||
.spawn_bundle(ColorMesh2dBundle {
|
|
||||||
mesh: meshes
|
|
||||||
.add(Mesh::from(Quad {
|
|
||||||
size: Vec2 { x: 512., y: 64. },
|
|
||||||
flip: false,
|
|
||||||
}))
|
|
||||||
.into(),
|
|
||||||
material: materials.add(ColorMaterial::from(Color::rgba(0., 0., 0., 0.9))),
|
|
||||||
transform: Transform::from_xyz(0., 0., 3.),
|
|
||||||
..default()
|
|
||||||
})
|
|
||||||
.insert(Level);
|
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(Text2dBundle {
|
.spawn_bundle(Text2dBundle {
|
||||||
text: Text::from_section(
|
text: Text::from_section(
|
||||||
"Press ENTER to level up",
|
"Press ENTER to level up",
|
||||||
TextStyle {
|
TextStyle {
|
||||||
font,
|
font,
|
||||||
font_size: 36.0,
|
font_size: 32.0,
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_alignment(TextAlignment::CENTER),
|
.with_alignment(TextAlignment::CENTER),
|
||||||
transform: Transform::from_xyz(0., 0., 4.),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.insert(Level);
|
.insert(Level);
|
||||||
|
@ -467,13 +344,13 @@ fn move_camera(
|
||||||
const FOLLOW_SPEED: f32 = std::f32::consts::PI;
|
const FOLLOW_SPEED: f32 = std::f32::consts::PI;
|
||||||
|
|
||||||
for character_transform in characters.iter() {
|
for character_transform in characters.iter() {
|
||||||
let (camera, mut camera_transform) = camera_query.single_mut();
|
let (camera, mut camera_transform) =
|
||||||
|
camera_query.single_mut();
|
||||||
|
|
||||||
let size: Vec2 = camera.logical_viewport_size().unwrap();
|
let size: Vec2 = camera.logical_viewport_size().unwrap();
|
||||||
let half_height: f32 = size.y * 0.5;
|
let half_height: f32 = size.y * 0.5;
|
||||||
camera_transform.translation = camera_transform.translation.lerp(
|
camera_transform.translation = camera_transform.translation.lerp(
|
||||||
character_transform.translation,
|
character_transform.translation, time.delta_seconds() * FOLLOW_SPEED
|
||||||
time.delta_seconds() * FOLLOW_SPEED,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// prevent camera from going too low
|
// prevent camera from going too low
|
||||||
|
@ -482,29 +359,3 @@ fn move_camera(
|
||||||
camera_transform.translation.z = 999.0;
|
camera_transform.translation.z = 999.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn level_keyboard_system(
|
|
||||||
mut commands: Commands,
|
|
||||||
mut current_level: ResMut<CurrentLevel>,
|
|
||||||
mut level_startup_event: EventWriter<LevelStartupEvent>,
|
|
||||||
mut camera_query: Query<&mut Transform, With<Camera>>,
|
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
|
||||||
level_query: Query<Entity, With<Level>>,
|
|
||||||
mut app_state: ResMut<State<AppState>>,
|
|
||||||
) {
|
|
||||||
if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) {
|
|
||||||
current_level.0 = Some(LevelId(
|
|
||||||
current_level.0.map_or(0, |level_id| level_id.0 + 1),
|
|
||||||
));
|
|
||||||
app_state.replace(AppState::Game).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if keyboard_input.just_pressed(KeyCode::R) {
|
|
||||||
for entity in level_query.iter() {
|
|
||||||
commands.entity(entity).despawn_recursive();
|
|
||||||
}
|
|
||||||
if app_state.replace(AppState::Game).is_err() {
|
|
||||||
crate::levels::setup_level(&mut level_startup_event, &mut camera_query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
169
src/levels.rs
169
src/levels.rs
|
@ -1,17 +1,29 @@
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
|
mod game_over;
|
||||||
|
mod level0;
|
||||||
|
mod level1;
|
||||||
|
|
||||||
use crate::game::*;
|
use crate::game::*;
|
||||||
|
|
||||||
use bevy::{prelude::*, reflect::TypeUuid};
|
use bevy::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
pub fn setup_level(
|
pub fn setup_level(
|
||||||
|
commands: &mut Commands,
|
||||||
|
current_level: &mut ResMut<CurrentLevel>,
|
||||||
level_startup_event: &mut EventWriter<LevelStartupEvent>,
|
level_startup_event: &mut EventWriter<LevelStartupEvent>,
|
||||||
camera_query: &mut Query<&mut Transform, With<Camera>>,
|
camera_query: &mut Query<&mut Transform, With<Camera>>,
|
||||||
|
level_id: LevelId,
|
||||||
) {
|
) {
|
||||||
|
let level_entity = commands
|
||||||
|
.spawn()
|
||||||
|
.insert(Level)
|
||||||
|
.id();
|
||||||
|
current_level.0 = Some(level_id);
|
||||||
|
|
||||||
camera_query.single_mut().translation = Default::default();
|
camera_query.single_mut().translation = Default::default();
|
||||||
|
|
||||||
level_startup_event.send(LevelStartupEvent);
|
level_startup_event.send(LevelStartupEvent(level_entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn despawn_level(mut commands: Commands, level_query: Query<Entity, With<Level>>) {
|
pub fn despawn_level(mut commands: Commands, level_query: Query<Entity, With<Level>>) {
|
||||||
|
@ -24,158 +36,29 @@ pub fn despawn_level(mut commands: Commands, level_query: Query<Entity, With<Lev
|
||||||
pub fn post_setup_level(
|
pub fn post_setup_level(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
character_meshes: Res<CharacterMeshes>,
|
character_meshes: Res<CharacterMeshes>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
current_level: Res<CurrentLevel>,
|
current_level: Res<CurrentLevel>,
|
||||||
mut level_startup_event: EventReader<LevelStartupEvent>,
|
mut level_startup_event: EventReader<LevelStartupEvent>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
stored_levels_assets: Res<Assets<StoredLevels>>,
|
|
||||||
stored_levels_handle: Res<Handle<StoredLevels>>,
|
|
||||||
) {
|
) {
|
||||||
for _ in level_startup_event.iter() {
|
for LevelStartupEvent(level_entity) in level_startup_event.iter() {
|
||||||
if let Some(level_id) = current_level.0 {
|
if let Some(level_id) = current_level.0 {
|
||||||
if let Some(stored_level) = stored_levels_assets
|
match level_id.0 {
|
||||||
.get(&stored_levels_handle)
|
0 => level0::setup(
|
||||||
.unwrap()
|
|
||||||
.levels
|
|
||||||
.get(level_id.0 as usize)
|
|
||||||
{
|
|
||||||
spawn_stored_level(
|
|
||||||
&mut commands,
|
&mut commands,
|
||||||
&character_meshes,
|
&character_meshes,
|
||||||
&mut meshes,
|
|
||||||
&mut materials,
|
&mut materials,
|
||||||
&asset_server,
|
|
||||||
&audio,
|
&audio,
|
||||||
stored_level,
|
),
|
||||||
);
|
1 => level1::setup(
|
||||||
|
&mut commands,
|
||||||
|
&character_meshes,
|
||||||
|
&mut materials,
|
||||||
|
&audio,
|
||||||
|
),
|
||||||
|
_ => game_over::setup(&mut commands, &asset_server),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "1fbba930-644b-0d62-2514-4b302b945327"]
|
|
||||||
pub struct StoredLevels {
|
|
||||||
levels: Vec<StoredLevel>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "a1464a30-1f57-a654-d56c-ded41032af0b"]
|
|
||||||
pub struct StoredLevel {
|
|
||||||
pub comment: String,
|
|
||||||
pub characters: Vec<StoredCharacter>,
|
|
||||||
pub platforms: Vec<StoredPlatform>,
|
|
||||||
pub absorbing_filters: Vec<StoredAbsorbingFilter>,
|
|
||||||
pub rotating_filters: Vec<StoredRotatingFilter>,
|
|
||||||
pub texts: Vec<StoredText>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "1c798f8c-ef15-c528-693e-76becdef6b10"]
|
|
||||||
pub struct StoredCharacter {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub color: Vec4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "31696095-59de-93be-b5e9-333c2afbc900"]
|
|
||||||
pub struct StoredPlatform {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub size: Vec2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "bcad7fff-0605-c4e3-3cd4-42d5bbaad926"]
|
|
||||||
pub struct StoredAbsorbingFilter {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub size: Vec2,
|
|
||||||
pub color: Vec4,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "fa2843f2-6e34-601b-6c46-4827b0370b3f"]
|
|
||||||
pub struct StoredRotatingFilter {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub angle: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, TypeUuid)]
|
|
||||||
#[uuid = "72f6321a-f01f-6eea-9b17-3159837a2fd3"]
|
|
||||||
pub struct StoredText {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub font_size: f32,
|
|
||||||
pub text: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_stored_level(
|
|
||||||
commands: &mut Commands,
|
|
||||||
character_meshes: &Res<CharacterMeshes>,
|
|
||||||
meshes: &mut ResMut<Assets<Mesh>>,
|
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
||||||
asset_server: &Res<AssetServer>,
|
|
||||||
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
|
||||||
|
|
||||||
stored_level: &StoredLevel,
|
|
||||||
) {
|
|
||||||
let font = asset_server.get_handle("UacariLegacy-Thin.ttf");
|
|
||||||
spawn_platforms(
|
|
||||||
commands,
|
|
||||||
meshes,
|
|
||||||
materials,
|
|
||||||
stored_level.platforms.iter().map(|platform| {
|
|
||||||
(
|
|
||||||
Transform::from_xyz(platform.pos.x, platform.pos.y, 0.),
|
|
||||||
platform.size,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
spawn_characters(
|
|
||||||
commands,
|
|
||||||
character_meshes,
|
|
||||||
materials,
|
|
||||||
audio,
|
|
||||||
stored_level.characters.iter().map(|character| {
|
|
||||||
(
|
|
||||||
Transform::from_xyz(character.pos.x, character.pos.y, 0.),
|
|
||||||
character.color.into(),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
for absorbing_filter in stored_level.absorbing_filters.iter() {
|
|
||||||
spawn_absorbing_filter(
|
|
||||||
commands,
|
|
||||||
meshes,
|
|
||||||
materials,
|
|
||||||
Transform::from_xyz(absorbing_filter.pos.x, absorbing_filter.pos.y, 2.),
|
|
||||||
absorbing_filter.size,
|
|
||||||
absorbing_filter.color.into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for rotating_filter in stored_level.rotating_filters.iter() {
|
|
||||||
spawn_rotating_filter(
|
|
||||||
commands,
|
|
||||||
asset_server,
|
|
||||||
Transform::from_xyz(rotating_filter.pos.x, rotating_filter.pos.y, 2.),
|
|
||||||
rotating_filter.angle,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for text in stored_level.texts.iter() {
|
|
||||||
commands
|
|
||||||
.spawn_bundle(Text2dBundle {
|
|
||||||
text: Text::from_section(
|
|
||||||
&text.text,
|
|
||||||
TextStyle {
|
|
||||||
font: font.clone(),
|
|
||||||
font_size: text.font_size,
|
|
||||||
color: Color::WHITE,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.with_alignment(TextAlignment::CENTER),
|
|
||||||
transform: Transform::from_xyz(text.pos.x, text.pos.y, 0.),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.insert(Level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
36
src/levels/game_over.rs
Normal file
36
src/levels/game_over.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::game::*;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
pub fn setup(commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||||
|
let font = asset_server.get_handle("UacariLegacy-Thin.ttf");
|
||||||
|
commands
|
||||||
|
.spawn_bundle(Text2dBundle {
|
||||||
|
text: Text::from_section(
|
||||||
|
"GAME OVER",
|
||||||
|
TextStyle {
|
||||||
|
font: font.clone(),
|
||||||
|
font_size: 48.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with_alignment(TextAlignment::CENTER),
|
||||||
|
transform: Transform::from_xyz(0., 128.0, 0.),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.insert(Level);
|
||||||
|
commands
|
||||||
|
.spawn_bundle(Text2dBundle {
|
||||||
|
text: Text::from_section(
|
||||||
|
"There is no more light to combine.",
|
||||||
|
TextStyle {
|
||||||
|
font,
|
||||||
|
font_size: 32.0,
|
||||||
|
color: Color::WHITE,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.with_alignment(TextAlignment::CENTER),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.insert(Level);
|
||||||
|
}
|
46
src/levels/level0.rs
Normal file
46
src/levels/level0.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
use crate::game::*;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
|
pub fn setup(
|
||||||
|
commands: &mut Commands,
|
||||||
|
character_meshes: &Res<CharacterMeshes>,
|
||||||
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
|
// selected_character_id: &mut Mut<SelectedCharacterId>,
|
||||||
|
// character_id_list: &mut Mut<CharacterIdList>,
|
||||||
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
) {
|
||||||
|
commands
|
||||||
|
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, -256.0, 0.0)))
|
||||||
|
.insert(Collider::cuboid(400., 10.))
|
||||||
|
.insert(Level);
|
||||||
|
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(-128., -64., 0.),
|
||||||
|
Color::RED,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(0., -64., 0.),
|
||||||
|
Color::GREEN,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(128., -64., 0.),
|
||||||
|
Color::BLUE,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
50
src/levels/level1.rs
Normal file
50
src/levels/level1.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use crate::game::*;
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
|
pub fn setup(
|
||||||
|
commands: &mut Commands,
|
||||||
|
character_meshes: &Res<CharacterMeshes>,
|
||||||
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
) {
|
||||||
|
commands
|
||||||
|
.spawn_bundle(TransformBundle::from(Transform::from_xyz(0.0, -256.0, 0.0)))
|
||||||
|
.insert(Collider::cuboid(400., 10.))
|
||||||
|
.insert(Level);
|
||||||
|
commands
|
||||||
|
.spawn_bundle(TransformBundle::from(Transform::from_xyz(
|
||||||
|
256.0, -128.0, 0.0,
|
||||||
|
)))
|
||||||
|
.insert(Collider::cuboid(200., 10.))
|
||||||
|
.insert(Level);
|
||||||
|
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(128., 64., 0.),
|
||||||
|
Color::BLUE,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(-128., -128., 0.),
|
||||||
|
Color::RED,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
spawn_character(
|
||||||
|
commands,
|
||||||
|
character_meshes,
|
||||||
|
materials,
|
||||||
|
audio,
|
||||||
|
Transform::from_xyz(0., -128., 0.),
|
||||||
|
Color::GREEN,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
66
src/main.rs
66
src/main.rs
|
@ -1,16 +1,11 @@
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod audio;
|
mod audio;
|
||||||
mod filters;
|
|
||||||
mod game;
|
mod game;
|
||||||
mod levels;
|
mod levels;
|
||||||
mod menu;
|
mod menu;
|
||||||
mod particle_effect;
|
mod particle_effect;
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*};
|
||||||
prelude::*,
|
|
||||||
window::{WindowId, WindowMode},
|
|
||||||
};
|
|
||||||
use bevy_common_assets::json::JsonAssetPlugin;
|
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
|
@ -27,66 +22,35 @@ fn main() {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
std::thread::spawn(move || audio::setup(audio_event_receiver));
|
std::thread::spawn(move || audio::setup(audio_event_receiver));
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
let first_level = game::LevelId(
|
|
||||||
std::env::args()
|
|
||||||
.nth(1)
|
|
||||||
.map_or(0, |s| s.parse().unwrap_or(0)),
|
|
||||||
);
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
let first_level = game::LevelId(0);
|
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.insert_resource(Msaa { samples: 4 })
|
|
||||||
.insert_resource(audio_event_sender)
|
.insert_resource(audio_event_sender)
|
||||||
.add_state(AppState::Menu)
|
.add_state(AppState::Menu)
|
||||||
.insert_resource(game::FirstLevel(first_level))
|
|
||||||
.insert_resource(ClearColor(Color::BLACK))
|
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_plugin(JsonAssetPlugin::<levels::StoredLevels>::new(&[
|
|
||||||
"levels.json",
|
|
||||||
]))
|
|
||||||
.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(64.0))
|
.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(64.0))
|
||||||
//.add_plugin(RapierDebugRenderPlugin::default())
|
.add_plugin(RapierDebugRenderPlugin::default())
|
||||||
.add_plugin(menu::MenuPlugin)
|
.add_plugin(menu::MenuPlugin)
|
||||||
.add_plugin(game::GamePlugin)
|
.add_plugin(game::GamePlugin)
|
||||||
.add_plugin(particle_effect::ParticleEffectPlugin)
|
.add_plugin(particle_effect::ParticleEffectPlugin)
|
||||||
//.add_plugin(bevy_inspector_egui::WorldInspectorPlugin::new())
|
.add_plugin(bevy_inspector_egui::WorldInspectorPlugin::new())
|
||||||
.add_system(keyboard_util_system)
|
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(mut commands: Commands, mut windows: ResMut<Windows>, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
windows
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
.get_mut(WindowId::primary())
|
let font: Handle<Font> = asset_server.load("UacariLegacy-Thin.ttf");
|
||||||
.unwrap()
|
#[cfg(target_arch = "wasm32")]
|
||||||
.set_title(String::from("Bevyjam"));
|
let font: Handle<Font> = asset_server.load("UacariLegacy-Thin.ttf");
|
||||||
|
commands.insert_resource(font);
|
||||||
|
|
||||||
commands.insert_resource(asset_server.load::<levels::StoredLevels, _>("game.levels.json"));
|
commands.spawn_bundle(Camera2dBundle {
|
||||||
commands.insert_resource(asset_server.load::<Font, _>("UacariLegacy-Thin.ttf"));
|
camera_2d: Camera2d {
|
||||||
commands.insert_resource(asset_server.load::<Image, _>("bevy.png"));
|
clear_color: ClearColorConfig::Custom(Color::BLACK),
|
||||||
|
},
|
||||||
commands.spawn_bundle(Camera2dBundle::default());
|
..Default::default()
|
||||||
|
});
|
||||||
commands.insert_resource(AmbientLight {
|
commands.insert_resource(AmbientLight {
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
brightness: 0.6,
|
brightness: 0.6,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keyboard_util_system(keyboard_input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
{
|
|
||||||
if keyboard_input.just_released(KeyCode::Escape) {
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
if keyboard_input.just_pressed(KeyCode::F11) {
|
|
||||||
if let Some(window) = windows.get_primary_mut() {
|
|
||||||
window.set_mode(match window.mode() {
|
|
||||||
WindowMode::Windowed => WindowMode::Fullscreen,
|
|
||||||
_ => WindowMode::Windowed,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
"BEVYJAM",
|
"BEVYJAM",
|
||||||
TextStyle {
|
TextStyle {
|
||||||
font: font.clone(),
|
font: font.clone(),
|
||||||
font_size: 96.0,
|
font_size: 48.0,
|
||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue