From ef1bd9e234595c93abc727b95bad834f9f35959f Mon Sep 17 00:00:00 2001 From: jusax23 Date: Fri, 28 Jul 2023 21:04:54 +0200 Subject: [PATCH] init --- .gitignore | 1 + Cargo.lock | 730 +++++ Cargo.toml | 14 + assets/images/avatar.png | Bin 0 -> 81849 bytes assets/models/Kirche.obj | 3765 ++++++++++++++++++++++ assets/models/test.obj | 358 ++ assets/shader/default.fsh.glsl | 22 + assets/shader/default.vsh.glsl | 30 + bots/MyBot.class | Bin 0 -> 833 bytes bots/MyBot.java | 39 + javaState/Bot.class | Bin 0 -> 476 bytes javaState/Bot.java | 13 + javaState/Controller.class | Bin 0 -> 798 bytes javaState/Controller.java | 10 + javaState/GameState.class | Bin 0 -> 274 bytes javaState/GameState.java | 7 + javaState/Player$PlayerType.class | Bin 0 -> 1025 bytes javaState/Player.class | Bin 0 -> 524 bytes javaState/Player.java | 20 + src/game.rs | 61 + src/game/bots.rs | 75 + src/game/player.rs | 27 + src/main.rs | 48 + src/no_stage.rs | 22 + src/render_tools.rs | 12 + src/render_tools/default_solid_shader.rs | 28 + src/render_tools/graphics.rs | 182 ++ src/stage.rs | 283 ++ src/tools.rs | 43 + 29 files changed, 5790 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 assets/images/avatar.png create mode 100644 assets/models/Kirche.obj create mode 100644 assets/models/test.obj create mode 100644 assets/shader/default.fsh.glsl create mode 100644 assets/shader/default.vsh.glsl create mode 100644 bots/MyBot.class create mode 100644 bots/MyBot.java create mode 100644 javaState/Bot.class create mode 100644 javaState/Bot.java create mode 100644 javaState/Controller.class create mode 100644 javaState/Controller.java create mode 100644 javaState/GameState.class create mode 100644 javaState/GameState.java create mode 100644 javaState/Player$PlayerType.class create mode 100644 javaState/Player.class create mode 100644 javaState/Player.java create mode 100644 src/game.rs create mode 100644 src/game/bots.rs create mode 100644 src/game/player.rs create mode 100644 src/main.rs create mode 100644 src/no_stage.rs create mode 100644 src/render_tools.rs create mode 100644 src/render_tools/default_solid_shader.rs create mode 100644 src/render_tools/graphics.rs create mode 100644 src/stage.rs create mode 100644 src/tools.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..2008c32 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,730 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gl_matrix" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df64d0245c589931a0b5a385a63e7db2aeff209bdd471df0417e0f230a4c33ae" +dependencies = [ + "rand", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "j4rs" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81d7d940f91519a518dd367b0711e6fcb9250a4eccfba98229f40f0d506c4af6" +dependencies = [ + "cesu8", + "dirs", + "dunce", + "fs_extra", + "futures", + "glob", + "java-locator", + "jni-sys", + "lazy_static", + "libc", + "libloading", + "log", + "serde", + "serde_json", + "sha2", +] + +[[package]] +name = "j_game" +version = "0.1.0" +dependencies = [ + "gl_matrix", + "j4rs", + "miniquad", + "png", + "serde", +] + +[[package]] +name = "java-locator" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90003f2fd9c52f212c21d8520f1128da0080bad6fff16b68fe6e7f2f0c3780c2" +dependencies = [ + "glob", + "lazy_static", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "miniquad" +version = "0.3.15" +dependencies = [ + "libc", + "ndk-sys", + "objc", + "winapi", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "ndk-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "png" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.10", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "syn" +version = "2.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c6587ef --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "j_game" +version = "0.1.0" +edition = "2021" +crate-type = ["cdylib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +gl_matrix = "0.0.2" +j4rs = "0.17.0" +miniquad = { path = '../jucraft/miniquad' } +png = "0.17.9" +serde = "1.0.177" diff --git a/assets/images/avatar.png b/assets/images/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..eefcd63716108d456007a814bce75d562c021898 GIT binary patch literal 81849 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 HguV9{nRl6Q literal 0 HcmV?d00001 diff --git a/bots/MyBot.java b/bots/MyBot.java new file mode 100644 index 0000000..7f1f6a2 --- /dev/null +++ b/bots/MyBot.java @@ -0,0 +1,39 @@ +package bots; + +import javaState.Bot; +import javaState.Controller; +import javaState.GameState; + +public class MyBot extends Bot { + + float dir = 0; + + @Override + public String getStudentName() { + return "Max Mustermann"; + } + + @Override + public int getMatrikel() { + return 1337; + } + + @Override + public String getName() { + return "example Bot"; + } + + @Override + public void init(GameState state) { + + } + + @Override + public Controller executeTurn(GameState state, Controller controller) { + dir+=0.01; + controller.dirX = Math.cos(dir); + controller.dirY = Math.sin(dir); + + return controller; + } +} \ No newline at end of file diff --git a/javaState/Bot.class b/javaState/Bot.class new file mode 100644 index 0000000000000000000000000000000000000000..ba39c3177c11ffd0c1d985a027c3df5466435ff0 GIT binary patch literal 476 zcmaJ-(MkeA6g^j0SJzdutSplVde9#70}QEzKrjhbdLMI;t#yrc4E(F=CFr3K=%b>u z7AQS54|C?8d(O<6`}y_$0icblg9MT`EEg%H1snJ3NqI&Y-Mk6ZLPvu1nIHP5ElAcI zw^?M6wc)tP!4*{h%8!3sgTNo z8U|zvV{JS$AL-Ea)r3U3-dJAW3{*I7dM5J2aZ8Y+?pm>W(7`e{bJ*m5VjcdP*1x%y zn|{Ze&Z9eh<;Ra^nCUc5C~&)BsH0AxW-~pbZ1q{|2zgF2UKS*tCHEq$8c~R;lQ+l< z51cXgxD6yNK?$4m2)0lrQ^GcO*o&=7MyGpzQ{E8ob& BWn=&V literal 0 HcmV?d00001 diff --git a/javaState/Bot.java b/javaState/Bot.java new file mode 100644 index 0000000..f20f2cf --- /dev/null +++ b/javaState/Bot.java @@ -0,0 +1,13 @@ +package javaState; + +public abstract class Bot extends Player{ + + public abstract String getStudentName(); + + public abstract int getMatrikel(); + + @Override + public final PlayerType getType() { + return PlayerType.AI; + } +} diff --git a/javaState/Controller.class b/javaState/Controller.class new file mode 100644 index 0000000000000000000000000000000000000000..0790087649a097797d18d542ad00a418695f0775 GIT binary patch literal 798 zcmaJ<+iuf95IvKGI5BQqN}-fXX(266RN)T@>O&J%AO(0x#YGhln`G6xad#toQ>lN# zXB4RjsSkVrAB8#_N5qH-S)QF8pEGmDGrxXc{{*myhKmA<4oV(wp-fml73U(1g*p!3 z_fO@(5X!G26`4IkF=%|KqJpXe*TZdigjEag8DV7D*2*M0j%7k94Wr}}fjSmm^Wa;o z4SrtXs&_oB;4We9OpGMc2Eu%d%n5s`5z3^5`$4DE=+33|OcJT%7UyW|p(Oa-NXd7T zv%X9YML*_9#pn#gnu3K?x2Gq`KpsRE?$6b}v}L&QeXUJu5;1-&&50hSei@HlJi&&8 zr&jPLp*~j>sdGJ&VOBHi;Xn+GPA&*vgPimkFiZMcs9`MAdRObwWZcTZW*z1te-RHa z#&QAtD2LC+)ynriOVJi_+>4BCRq%|*c|^OL^o8KPQA#H5Sfr^;9c&Y}|LJd$YzHq0 z8~=xLnXE@_@dgxl=mn5n8TR<^Pfr`+onyPo(GW%U0KfSI)U17nW6jdHDd8U58Uw&@ ziJvMHc}uW1Bkyp`l55Q?=3Qaw8q2`tAFeF|7E;6mJ_}gK!|9#yh`(&%Ip19N>exYm F^&6dnz^(uQ literal 0 HcmV?d00001 diff --git a/javaState/Controller.java b/javaState/Controller.java new file mode 100644 index 0000000..df9b769 --- /dev/null +++ b/javaState/Controller.java @@ -0,0 +1,10 @@ +package javaState; + +public class Controller { + public double dirX = 0; + public double dirY = 0; + + public String toString() { + return "[" + dirX + ", " + dirY + "]"; + } +} diff --git a/javaState/GameState.class b/javaState/GameState.class new file mode 100644 index 0000000000000000000000000000000000000000..f85c2267cf4578bb84cc23be45f2e02a7d336dec GIT binary patch literal 274 zcmX|5!ES<35S#@RK?+p;0dLBo{6NE{MlYs4*fe^4;ERDMGzk5#9vTx5en3B}ao05F zJ?|cD}VC2GpX~Xi+L6;B~>Py9YRqo=qw9r{Y=sxFV-XsKbGW~GSgJZ+> z(1%ADihb3nM#l?v&^JV|KC9!JKr?as9s;q7xZ(CvZ8afS=B0jZ52>!-Rk~-zT~%$J z>3J^1zo$LP28=n#;DZg2EM~+J|DEJ=<{_&wOh!Nuoj{TQ16#_&_if;jtIr1TxA-|c KNEk3TFuVeSWG$@# literal 0 HcmV?d00001 diff --git a/javaState/GameState.java b/javaState/GameState.java new file mode 100644 index 0000000..1d97eb6 --- /dev/null +++ b/javaState/GameState.java @@ -0,0 +1,7 @@ +package javaState; + +public class GameState { + public double posX = 0; + public double posY = 0; + +} diff --git a/javaState/Player$PlayerType.class b/javaState/Player$PlayerType.class new file mode 100644 index 0000000000000000000000000000000000000000..d2ce18dc936ce0d2ac9542720c453a4d34c474fe GIT binary patch literal 1025 zcmaJi4h>19RLts_ zLz)V=+@9w!Wb%f9nXc`%&6DPZ(+Y|jGI*?FUdI9!84|p=VZxyocB$y4?S{_D2Zq=A zG4z3J_xr`MfED;1uU#CkzzGC@R>v|{7^0<)*9poD^W#(_WX)*A5YcGfYz%R3H+5`b zo6jwJ=re5Ojp>t9jX$}{LGL{cove2}=Q!*(9skU3x)j;}Pw`>f4;-<`5VtyQ&kjPL z@N(X0(2YthcQlPTwgx_PN%#+um5ENXdZFKP-gJ0BGef!T^34TWV=#Wkp2LgZ7X=z>r{}2+RV-_t7r0vd+frY~;`CDd?de(2t7l z>~IX9>`dyH4-S(8%eI z$?bFDz&5bM(jZRtgl?VBcQ(_*-?wj~H6gaW@f20H|_ezltBAFzVu<+^` z?;Jk=ggpfa`xhKH`F6@EZ1(a4;++YPakOP1@393`0LCqBXIMoo!yW9}4(xHvp^kk< QkEagMU{=bQkE5H$FHEU^^Z)<= literal 0 HcmV?d00001 diff --git a/javaState/Player.java b/javaState/Player.java new file mode 100644 index 0000000..1c13b00 --- /dev/null +++ b/javaState/Player.java @@ -0,0 +1,20 @@ +package javaState; + +public abstract class Player { + + enum PlayerType{ + Human, + AI + } + + public abstract String getName(); + + public abstract void init(GameState state); + + public abstract Controller executeTurn(GameState state, Controller controller); + + public abstract PlayerType getType(); + + +} + diff --git a/src/game.rs b/src/game.rs new file mode 100644 index 0000000..606b5fd --- /dev/null +++ b/src/game.rs @@ -0,0 +1,61 @@ +use std::collections::HashMap; +use std::vec; + +use self::bots::*; +use self::player::Player; + +mod bots; +mod player; + +pub struct Game { + bots: Vec, + bot_names: HashMap, + pub players: Vec +} + +impl Game { + pub fn new() -> Self { + let mut out = Self { + bots: vec![], + players: vec![], + bot_names: HashMap::new() + }; + + out.load_bots(".".to_string()); + + out + } + + pub fn load_bots(&mut self, classpath: String) { + for cl in list_bot_classes() { + let bot = Bot::new(&cl, &classpath); + if bot.is_ok() { + let mut bot: Bot = bot.unwrap(); + let name = bot.get_name(); + if !self.bot_names.contains_key(&name) { + println!("Loaded Bot: „{}”", name); + self.bot_names.insert(name, self.bots.len()); + self.bots.push(bot); + + } + } + } + } + + pub fn add_player(&mut self, bot: usize) { + self.players.push(Player::new(bot)); + } + + pub fn tick(&mut self){ + for p in self.players.iter_mut(){ + let state = GameState{ + posX: p.x, + posY: p.y, + }; + let cont = self.bots[p.get_bot()].tick(&state); + p.dir_x = cont.dirX; + p.dir_y = cont.dirY; + p.move_player(0.05); + } + } +} diff --git a/src/game/bots.rs b/src/game/bots.rs new file mode 100644 index 0000000..ab23ef9 --- /dev/null +++ b/src/game/bots.rs @@ -0,0 +1,75 @@ +use j4rs::{errors::J4RsError, *}; +use serde::{Deserialize, Serialize}; +use std::fs; + +pub struct Bot { + jvm: Jvm, + bot: Instance, +} + +#[derive(Serialize, Deserialize, Debug)] +#[allow(non_snake_case)] +pub struct Controller { + pub dirX: f64, + pub dirY: f64, +} + +#[derive(Serialize, Deserialize, Debug)] +#[allow(non_snake_case)] +pub struct GameState { + pub posX: f64, + pub posY: f64, +} + +impl Bot { + pub fn new(name: &String, classpath: &String) -> Result { + let jvm = JvmBuilder::new() + .classpath_entries(vec![ + ClasspathEntry::new(classpath), + ClasspathEntry::new("./javaState.jar"), + ]) + .build()?; + let bot = jvm.create_instance(&name, &[])?; + jvm.cast(&bot, "javaState.Bot")?; + Ok(Bot { jvm, bot }) + } + + pub fn get_name(&mut self) -> String { + let result = self.jvm.invoke(&self.bot, "getName", &[]).unwrap(); + self.jvm.to_rust(result).unwrap() + } + pub fn tick(&mut self, state: &GameState) -> Controller { + + let controller = Controller { + dirX: 1.0, + dirY: 0.0, + }; + let j_controller = InvocationArg::new(&controller, "javaState.Controller"); + let j_gamestate = InvocationArg::new(state, "javaState.GameState"); + + let j_ret_controller = self.jvm + .invoke(&self.bot, "executeTurn", &[j_gamestate, j_controller]) + .unwrap(); + let controller2: Controller = self.jvm.to_rust(j_ret_controller).unwrap(); + controller2 + } +} + +pub fn list_bot_classes() -> Vec { + let mut out: Vec = vec![]; + + if let Ok(paths) = fs::read_dir("./bots") { + for path in paths { + if let Ok(p) = path { + if p.path().is_file() { + if p.path().extension().unwrap() == "class" { + let mut str = String::from("bots."); + str.push_str(p.path().file_stem().unwrap().to_str().unwrap()); + out.push(str); + } + } + } + } + } + out +} diff --git a/src/game/player.rs b/src/game/player.rs new file mode 100644 index 0000000..50eca3e --- /dev/null +++ b/src/game/player.rs @@ -0,0 +1,27 @@ +pub struct Player { + pub x: f64, + pub y: f64, + pub dir_x: f64, + pub dir_y: f64, + bot: usize, +} + +impl Player { + pub fn new(bot: usize) -> Self { + Self { + x: 0., + y: 0., + dir_x: 0., + dir_y: 0., + bot + } + } + pub fn move_player(&mut self, delta: f64) { + self.x += self.dir_x * delta; + self.y += self.dir_y * delta; + } + + pub fn get_bot(&self) -> usize{ + self.bot + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4bcb8b5 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,48 @@ +use std::env; + +use game::Game; +use j4rs::{ + jni_sys::{jint, JavaVM}, + prelude::jobject, +}; +use miniquad::*; +use no_stage::NoStage; +use stage::Stage; +use tools::parse_arg; + +mod game; +mod no_stage; +mod stage; +mod tools; +mod render_tools; + +fn main() { + let args = parse_arg(env::args().collect()); + let mut game = Game::new(); + + game.add_player(0); + + if args.contains_key("n") { + let mut no_stage = NoStage::new(game); + no_stage.run(); + } else { + start( + conf::Conf { + window_title: "Jucraft".to_string(), + window_height: 900, + window_width: 900 * 16 / 9, + ..Default::default() + }, + move |mut ctx| Box::new(Stage::new(&mut ctx, game)), + ); + } +} + +const JNI_VERSION_1_6: jint = 0x00010006; + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn jni_onload(env: *mut JavaVM, _reserved: jobject) -> jint { + j4rs::set_java_vm(env); + JNI_VERSION_1_6 +} diff --git a/src/no_stage.rs b/src/no_stage.rs new file mode 100644 index 0000000..3141c60 --- /dev/null +++ b/src/no_stage.rs @@ -0,0 +1,22 @@ +use crate::game::Game; + + + +pub struct NoStage { + game: Game +} + +impl NoStage{ + pub fn new(game: Game) -> Self { + Self { + game + } + } +} + + +impl NoStage{ + pub fn run(&mut self){ + + } +} \ No newline at end of file diff --git a/src/render_tools.rs b/src/render_tools.rs new file mode 100644 index 0000000..8def567 --- /dev/null +++ b/src/render_tools.rs @@ -0,0 +1,12 @@ +use gl_matrix::common::{Vec3, Vec2}; + +pub mod graphics; +pub mod default_solid_shader; + +#[derive(Debug)] +#[repr(C)] +pub struct Vertex { + pub pos: Vec3, + pub normal: Vec3, + pub uv: Vec2 +} \ No newline at end of file diff --git a/src/render_tools/default_solid_shader.rs b/src/render_tools/default_solid_shader.rs new file mode 100644 index 0000000..ac66523 --- /dev/null +++ b/src/render_tools/default_solid_shader.rs @@ -0,0 +1,28 @@ +use gl_matrix::common::*; +use miniquad::*; + +pub const VERTEX: &str = include_str!(concat!("../../assets/shader/default.vsh.glsl")); + +pub const FRAGMENT: &str = include_str!(concat!("../../assets/shader/default.fsh.glsl")); + +pub fn meta() -> ShaderMeta { + ShaderMeta { + images: vec!["u_image0".to_string()], + uniforms: UniformBlockLayout { + uniforms: vec![ + UniformDesc::new("view", UniformType::Mat4), + UniformDesc::new("proj", UniformType::Mat4), + UniformDesc::new("fog", UniformType::Float2), + UniformDesc::new("wpos", UniformType::Float3), + ], + }, + } +} + +#[repr(C)] +pub struct Uniforms { + pub view: Mat4, + pub proj: Mat4, + pub fog: Vec2, + pub wpos: Vec3, +} diff --git a/src/render_tools/graphics.rs b/src/render_tools/graphics.rs new file mode 100644 index 0000000..2b1c7d4 --- /dev/null +++ b/src/render_tools/graphics.rs @@ -0,0 +1,182 @@ +use std::collections::HashMap; + +use gl_matrix::common::{Vec2, Vec3}; +use miniquad::*; + +use super::Vertex; + +#[derive(Debug)] +pub struct Graphics { + pub textures: HashMap, + pub pipelines: HashMap, + pub models: HashMap, +} + +impl Graphics { + pub fn new() -> Self { + Graphics { + textures: HashMap::new(), + pipelines: HashMap::new(), + models: HashMap::new(), + } + } + pub fn load_texture(&mut self, ctx: &mut Context, bytes: &[u8], id: String) -> Texture { + let decoder = png::Decoder::new(bytes); + let mut reader = decoder.read_info().unwrap(); + let mut buf = vec![0; reader.output_buffer_size()]; + let info = reader.next_frame(&mut buf).unwrap(); + let bytes = &buf[..info.buffer_size()]; + let text = Texture::from_data_and_format( + ctx, + bytes, + TextureParams { + format: TextureFormat::RGBA8, + wrap: TextureWrap::Repeat, + filter: FilterMode::Nearest, + width: info.width, + height: info.height, + }, + ); + + //text.set_filter_min_mag(ctx, FilterMode::Linear, FilterMode::Nearest); + + self.textures.insert(id, text); + + text + } + pub fn add_pipeline(&mut self, pipeline: Pipeline, id: String) { + self.pipelines.insert(id, pipeline); + } + pub fn add_model( + &mut self, + ctx: &mut Context, + vertices: Vec, + indices: Vec, + id: String, + ) { + let vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &vertices); + let index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &indices); + self.models + .insert(id, (vertex_buffer, index_buffer, indices.len())); + } + + pub fn add_model_obj(&mut self, ctx: &mut Context, txt: String, id: String) { + let mut vertices: Vec = vec![]; + let mut indices: Vec = vec![]; + let mut verts: Vec = vec![]; + let mut texts: Vec = vec![]; + let mut normals: Vec = vec![]; + 'lloop: for line in txt.lines() { + if line.starts_with("v ") { + verts.push(parse_vec3(String::from(line))); + } else if line.starts_with("vt ") { + texts.push(parse_vec2(String::from(line))); + } else if line.starts_with("vn ") { + normals.push(parse_vec3(String::from(line))); + } else if line.starts_with("f ") { + let words: Vec<&str> = line.split(" ").collect(); + if words.len() < 4 { + continue; + } + let mut local_verts: Vec = vec![]; + + for i in 1..words.len() { + let vert = parse_vertex(String::from(words[i]), &verts, &texts, &normals); + if vert.is_none() { + println!("err"); + continue 'lloop; + } + local_verts.push(vert.unwrap()); + } + if local_verts.len() != 3 { + println!("Skipp not triangulated Face"); + continue; + } + let index_offset = vertices.len() as i32; + let index_amount = local_verts.len() as i32; + for vert in local_verts { + vertices.push(vert); + } + for i in 0..index_amount { + indices.push(index_offset + i); + } + } + } + //println!("verts: {:?}", vertices); + //println!("indecies: {:?}", indices); + let vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &vertices); + let index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &indices); + self.models + .insert(id, (vertex_buffer, index_buffer, indices.len())); + } +} + +fn parse_vertex( + text: String, + verts: &Vec, + texts: &Vec, + normals: &Vec, +) -> Option { + let words: Vec<&str> = text.split("/").collect(); + let mut out: Vertex = Vertex { + pos: [0.0; 3], + normal: [0.0; 3], + uv: [0.0; 2], + }; + if words.len() == 1 || words.len() == 3 { + let v_index: isize = words[0].parse().unwrap_or(-1); + if v_index < 0 { + println!("pos err"); + return None; + } + out.pos = verts.get(v_index as usize - 1).unwrap_or(&[0.0; 3]).clone(); + + if words.len() == 3 && words[1].len() > 0 { + let v_index: isize = words[1].parse().unwrap_or(-1); + //println!("m: {}", v_index); + if v_index < 0 { + println!("uv err"); + return None; + } + out.uv = texts.get(v_index as usize - 1).unwrap_or(&[0.0; 2]).clone(); + } + if words.len() == 3 { + let v_index: isize = words[2].parse().unwrap_or(-1); + if v_index < 0 { + println!("normal err"); + return None; + } + out.normal = normals + .get(v_index as usize - 1) + .unwrap_or(&[0.0; 3]) + .clone(); + } + } else { + return None; + } + Some(out) +} + +fn parse_vec2(line: String) -> Vec2 { + let words: Vec<&str> = line.split(" ").collect(); + let mut out: Vec2 = [0.0; 2]; + for i in 0..2 { + if i >= words.len() { + continue; + } + out[i] = words[i + 1].parse().unwrap_or(0.0); + } + out[1] = -out[1] + 1.; + out +} +fn parse_vec3(line: String) -> Vec3 { + let words: Vec<&str> = line.split(" ").collect(); + let mut out: Vec3 = [0.0; 3]; + for i in 0..3 { + if i >= words.len() { + continue; + } + out[i] = words[i + 1].parse().unwrap_or(0.0); + } + out +} diff --git a/src/stage.rs b/src/stage.rs new file mode 100644 index 0000000..8a5accd --- /dev/null +++ b/src/stage.rs @@ -0,0 +1,283 @@ +use gl_matrix::common::{Vec2, Vec3, PI}; +use gl_matrix::mat4; +use miniquad::*; + +use crate::game::Game; + +use crate::render_tools::default_solid_shader; +use crate::render_tools::graphics::Graphics; +use crate::tools::Sides; + +pub struct Player { + pub rot: Vec2, + pub pos: Vec3, +} + +pub struct Stage { + game: Game, + graphics: Graphics, + pipeline: Pipeline, + player: Player, + mouse_grab: bool, + fullscreen: bool, + s_move: Sides, +} + +impl Stage { + pub fn new(ctx: &mut Context, game: Game) -> Self { + let mut graphics = Graphics::new(); + + graphics.add_model_obj( + ctx, + String::from(include_str!(concat!("../assets/models/Kirche.obj"))), + "test".to_string(), + ); + + graphics.load_texture( + ctx, + include_bytes!(concat!("../assets/images/avatar.png")), + "avatar".to_string(), + ); + + let shader = Shader::new( + ctx, + default_solid_shader::VERTEX, + default_solid_shader::FRAGMENT, + default_solid_shader::meta(), + ) + .unwrap(); + + let pipeline = Pipeline::with_params( + ctx, + &[BufferLayout::default()], + &[ + VertexAttribute::with_buffer("pos", VertexFormat::Float3, 0), + VertexAttribute::with_buffer("normal", VertexFormat::Float3, 0), + VertexAttribute::with_buffer("uv", VertexFormat::Float2, 0), + ], + shader, + PipelineParams { + depth_test: Comparison::LessOrEqual, + depth_write: true, + cull_face: CullFace::Back, + front_face_order: FrontFaceOrder::CounterClockwise, + color_blend: Some(BlendState::new( + Equation::Add, + BlendFactor::One, + BlendFactor::OneMinusValue(BlendValue::SourceAlpha), + )), + alpha_blend: Some(BlendState::new( + Equation::Add, + BlendFactor::One, + BlendFactor::Zero, + )), + + ..Default::default() + }, + ); + + Self { + game, + graphics, + pipeline, + player: Player { + rot: [0., 0.], + pos: [0., 0., -4.], + }, + s_move: Sides::all(false), + mouse_grab: false, + fullscreen: false, + } + } +} + +impl EventHandler for Stage { + fn update(&mut self, ctx: &mut Context) { + let delta_s = 1. / 60.; + + if self.s_move.top { + self.player.pos[1] += delta_s * 10.0; + } + if self.s_move.bottom { + self.player.pos[1] -= delta_s * 10.0; + } + if self.s_move.front { + self.player.pos[2] += self.player.rot[1].to_radians().cos() * delta_s * 10.0; + self.player.pos[0] -= self.player.rot[1].to_radians().sin() * delta_s * 10.0; + } + if self.s_move.back { + self.player.pos[2] -= self.player.rot[1].to_radians().cos() * delta_s * 10.0; + self.player.pos[0] += self.player.rot[1].to_radians().sin() * delta_s * 10.0; + } + if self.s_move.left { + self.player.pos[2] += self.player.rot[1].to_radians().sin() * delta_s * 10.0; + self.player.pos[0] += self.player.rot[1].to_radians().cos() * delta_s * 10.0; + } + if self.s_move.right { + self.player.pos[2] -= self.player.rot[1].to_radians().sin() * delta_s * 10.0; + self.player.pos[0] -= self.player.rot[1].to_radians().cos() * delta_s * 10.0; + } + self.game.tick(); + } + + fn draw(&mut self, ctx: &mut Context) { + ctx.begin_default_pass(PassAction::clear_color(0.75, 0.85, 0.8, 1.0)); + + //render + ctx.apply_pipeline(&self.pipeline); + let (w, h) = ctx.screen_size(); + let mut proj_matrix = mat4::create(); + mat4::perspective( + &mut proj_matrix, + 90.0f32.to_radians(), + w as f32 / h as f32, + 0.1, + Some(10000.0), + ); + + let mut cammat = mat4::create(); + let mut cammat1 = mat4::create(); + + mat4::identity(&mut cammat); + mat4::rotate_x(&mut cammat1, &cammat, -(self.player.rot[0] / 180. * PI)); + mat4::rotate_y(&mut cammat, &cammat1, self.player.rot[1] / 180. * PI); + mat4::translate( + &mut cammat1, + &cammat, + &[ + self.player.pos[0], + -self.player.pos[1], // - self.player.eyes, + self.player.pos[2], + ], + ); + + let mut view_matrix = mat4::create(); + mat4::look_at( + &mut view_matrix, + &[0., 0., 0.], + &[0., 0., 0.], + &[0., 0., 0.], + ); + mat4::multiply(&mut cammat, &cammat1, &view_matrix); + + ctx.apply_uniforms(&default_solid_shader::Uniforms { + proj: proj_matrix, + view: cammat, + fog: [140.0, 160.0], + wpos: [ + self.game.players[0].x as f32, + 0., + self.game.players[0].y as f32, + ], + }); + + ctx.apply_bindings(&Bindings { + vertex_buffers: vec![self.graphics.models["test"].0].clone(), + index_buffer: self.graphics.models["test"].1, + images: vec![self.graphics.textures["avatar"]], + }); + ctx.draw(0, self.graphics.models["test"].2 as i32, 1); + + ctx.end_render_pass(); + ctx.commit_frame(); + } + + fn key_down_event( + &mut self, + _ctx: &mut Context, + keycode: KeyCode, + _keymods: KeyMods, + _repeatt: bool, + ) { + if keycode == KeyCode::Space { + self.s_move.top = true; + } else if keycode == KeyCode::LeftShift { + self.s_move.bottom = true; + } else if keycode == KeyCode::W { + self.s_move.front = true; + } else if keycode == KeyCode::A { + self.s_move.left = true; + } else if keycode == KeyCode::S { + self.s_move.back = true; + } else if keycode == KeyCode::D { + self.s_move.right = true; + } else if keycode == KeyCode::K { + } + } + + fn key_up_event(&mut self, ctx: &mut Context, keycode: KeyCode, _keymods: KeyMods) { + if keycode == KeyCode::F11 { + if self.fullscreen { + ctx.set_fullscreen(false); + ctx.set_window_size(1000, 800); + self.fullscreen = false; + } else { + ctx.set_fullscreen(true); + self.fullscreen = true; + } + if self.mouse_grab { + //println!("reloc"); + ctx.set_cursor_grab(false); + ctx.show_mouse(true); + self.mouse_grab = false; + } + } else if keycode == KeyCode::Escape { + ctx.set_cursor_grab(false); + ctx.show_mouse(true); + self.mouse_grab = false; + } else if keycode == KeyCode::Space { + self.s_move.top = false; + } else if keycode == KeyCode::LeftShift { + self.s_move.bottom = false; + } else if keycode == KeyCode::W { + self.s_move.front = false; + } else if keycode == KeyCode::A { + self.s_move.left = false; + } else if keycode == KeyCode::S { + self.s_move.back = false; + } else if keycode == KeyCode::D { + self.s_move.right = false; + } + } + + fn window_minimized_event(&mut self, ctx: &mut Context) { + ctx.set_cursor_grab(false); + ctx.show_mouse(true); + self.mouse_grab = false; + } + + fn mouse_button_down_event( + &mut self, + ctx: &mut Context, + button: MouseButton, + _x: f32, + _y: f32, + ) { + if button == MouseButton::Left { + if !self.mouse_grab { + ctx.set_cursor_grab(true); + ctx.show_mouse(false); + self.mouse_grab = true; + } + } + } + + fn raw_mouse_motion(&mut self, _ctx: &mut Context, x: f32, y: f32) { + if self.mouse_grab { + self.player.rot[0] -= y / 10.0; + self.player.rot[1] += x / 10.0; + } + if self.player.rot[0] > 90.0 { + self.player.rot[0] = 90.; + } + if self.player.rot[0] < -90.0 { + self.player.rot[0] = -90.; + } + if self.player.rot[1] > 180.0 { + self.player.rot[1] -= 360.; + } + if self.player.rot[1] < -180.0 { + self.player.rot[1] += 360.; + } + } +} diff --git a/src/tools.rs b/src/tools.rs new file mode 100644 index 0000000..1d96130 --- /dev/null +++ b/src/tools.rs @@ -0,0 +1,43 @@ +use std::collections::HashMap; + +pub fn parse_arg(args: Vec) -> HashMap { + let mut map: HashMap = HashMap::new(); + let mut index = String::new(); + + for val in args { + if val.starts_with('-') { + if !index.is_empty() { + map.insert(String::from(&index), String::from("")); + index.clear(); + } + index = val[1..].to_string(); + } else if !index.is_empty() { + map.insert(index.clone(), val); + index.clear(); + } + } + if !index.is_empty() { + map.insert(index, String::from("")); + } + + map +} + +#[derive(Debug)] +pub struct Sides { + pub top: T, + pub bottom: T, + pub left: T, + pub right: T, + pub front: T, + pub back: T, +} + +impl Sides { + pub fn all(v: T) -> Sides { + Sides { top: v, bottom: v, left: v, right: v, front: v, back: v } + } + pub fn are_all(&self, v:T) -> bool { + self.top == v && self.bottom == v && self.left == v && self.right == v && self.front == v && self.back == v + } +} \ No newline at end of file