diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..67df35c0b081715e14ff23bdc8cc1f368ed4418f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# https://editorconfig.org +root = true + +[*] +indent_style = space +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{java,scala,groovy,kt,kts}] +indent_size = 4 + +[*.gradle] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..6c84be07dc0c449be375816e3707020e6c9018df --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto eol=lf +*.bat text=auto eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fc300f7ac5096e6e5722b32fc57c9acf109e0446 --- /dev/null +++ b/.gitignore @@ -0,0 +1,165 @@ +## Gradle: +.gradle/ +gradle-app.setting +/gradle/gradle-daemon-jvm.properties +/build/ +/android/build/ +/core/build/ +/lwjgl2/build/ +/lwjgl3/build/ +/html/build/ +/teavm/build/ +/ios/build/ +/ios-moe/build/ +/headless/build/ +/server/build/ +/shared/build/ + +## Java: +*.class +*.war +*.ear +hs_err_pid* +.attach_pid* + +## Android: +/android/libs/armeabi-v7a/ +/android/libs/arm64-v8a/ +/android/libs/x86/ +/android/libs/x86_64/ +/android/gen/ +/android/out/ +local.properties +com_crashlytics_export_strings.xml + +## Robovm: +/ios/robovm-build/ + +## iOS: +/ios/xcode/*.xcodeproj/* +!/ios/xcode/*.xcodeproj/xcshareddata +!/ios/xcode/*.xcodeproj/project.pbxproj +/ios/xcode/native/ +/ios/IOSLauncher.app +/ios/IOSLauncher.app.dSYM + +## GWT: +/html/war/ +/html/gwt-unitCache/ +.apt_generated/ +/html/war/WEB-INF/deploy/ +/html/war/WEB-INF/classes/ +.gwt/ +gwt-unitCache/ +www-test/ +.gwt-tmp/ + +## TeaVM: +# Not sure yet... + +## IntelliJ, Android Studio: +.idea/ +*.ipr +*.iws +*.iml + +## Eclipse: +.classpath +.project +.metadata/ +/android/bin/ +/core/bin/ +/lwjgl2/bin/ +/lwjgl3/bin/ +/html/bin/ +/teavm/bin/ +/ios/bin/ +/ios-moe/bin/ +/headless/bin/ +/server/bin/ +/shared/bin/ +*.tmp +*.bak +*.swp +*~.nib +.settings/ +.loadpath +.externalToolBuilders/ +*.launch + + +## NetBeans: + +/nbproject/private/ +/android/nbproject/private/ +/core/nbproject/private/ +/lwjgl2/nbproject/private/ +/lwjgl3/nbproject/private/ +/html/nbproject/private/ +/teavm/nbproject/private/ +/ios/nbproject/private/ +/ios-moe/nbproject/private/ +/headless/nbproject/private/ +/server/nbproject/private/ +/shared/nbproject/private/ + +/nbbuild/ +/android/nbbuild/ +/core/nbbuild/ +/lwjgl2/nbbuild/ +/lwjgl3/nbbuild/ +/html/nbbuild/ +/teavm/nbbuild/ +/ios/nbbuild/ +/ios-moe/nbbuild/ +/headless/nbbuild/ +/server/nbbuild/ +/shared/nbbuild/ + +/dist/ +/android/dist/ +/core/dist/ +/lwjgl2/dist/ +/lwjgl3/dist/ +/html/dist/ +/teavm/dist/ +/ios/dist/ +/ios-moe/dist/ +/headless/dist/ +/server/dist/ +/shared/dist/ + +/nbdist/ +/android/nbdist/ +/core/nbdist/ +/lwjgl2/nbdist/ +/lwjgl3/nbdist/ +/html/nbdist/ +/teavm/nbdist/ +/ios/nbdist/ +/ios-moe/nbdist/ +/headless/nbdist/ +/server/nbdist/ +/shared/nbdist/ + +nbactions.xml +nb-configuration.xml + +## OS-Specific: +.DS_Store +Thumbs.db + +## Miscellaneous: +*~ +*.*# +*#*# +/.kotlin/ +/assets/assets.txt + +## Special cases: + +## There is a resource-config.json file generated by nativeimage.gradle if you use Graal Native Image. +## Some usage may need extra resource configuration in a different file with the same name. +## You could also add that configuration to the text in nativeimage.gradle . +## You should delete or comment out the next line if you have configuration in a different resource-config.json . +**/resource-config.json diff --git a/README.md b/README.md index 1e2e213cdccce23ee53dabb65027a55c83f93fdf..1e2dd7516bec61e97bf9634156bcc7506bc79cc1 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,39 @@ -# GardenMadness - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.vsb.cz/jez04/GardenMadness.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.vsb.cz/jez04/GardenMadness/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +# GardenMadnes + +A [libGDX](https://libgdx.com/) project generated with [gdx-liftoff](https://github.com/libgdx/gdx-liftoff). + +This project was generated with a template including simple application launchers and an `ApplicationAdapter` extension that draws libGDX logo. + +## Platforms + +- `core`: Main module with the application logic shared by all platforms. +- `lwjgl3`: Primary desktop platform using LWJGL3; was called 'desktop' in older docs. +- `html`: Web platform using GWT and WebGL. Supports only Java projects. +- `teavm`: Experimental web platform using TeaVM and WebGL. + +## Gradle + +This project uses [Gradle](https://gradle.org/) to manage dependencies. +The Gradle wrapper was included, so you can run Gradle tasks using `gradlew.bat` or `./gradlew` commands. +Useful Gradle tasks and flags: + +- `--continue`: when using this flag, errors will not stop the tasks from running. +- `--daemon`: thanks to this flag, Gradle daemon will be used to run chosen tasks. +- `--offline`: when using this flag, cached dependency archives will be used. +- `--refresh-dependencies`: this flag forces validation of all dependencies. Useful for snapshot versions. +- `build`: builds sources and archives of every project. +- `cleanEclipse`: removes Eclipse project data. +- `cleanIdea`: removes IntelliJ project data. +- `clean`: removes `build` folders, which store compiled classes and built archives. +- `eclipse`: generates Eclipse project data. +- `html:dist`: compiles GWT sources. The compiled application can be found at `html/build/dist`: you can use any HTTP server to deploy it. +- `html:superDev`: compiles GWT sources and runs the application in SuperDev mode. It will be available at [localhost:8080/html](http://localhost:8080/html). Use only during development. +- `idea`: generates IntelliJ project data. +- `lwjgl3:jar`: builds application's runnable jar, which can be found at `lwjgl3/build/libs`. +- `lwjgl3:run`: starts the application. +- `teavm:build`: builds the JavaScript application into the build/dist/webapp folder. +- `teavm:run`: serves the JavaScript application at http://localhost:8080 via a local Jetty server. +- `test`: runs unit tests (if any). + +Note that most tasks that are not specific to a single project can be run with `name:` prefix, where the `name` should be replaced with the ID of a specific project. +For example, `core:clean` removes `build` folder only from the `core` project. diff --git a/assets/bucket.png b/assets/bucket.png new file mode 100644 index 0000000000000000000000000000000000000000..6ac5d0f796baa49e943c45d8fc4062626e4f170f Binary files /dev/null and b/assets/bucket.png differ diff --git a/assets/drop.png b/assets/drop.png new file mode 100644 index 0000000000000000000000000000000000000000..61a4a2b52aef6b1972fdef4de3d709c81dc45b5b Binary files /dev/null and b/assets/drop.png differ diff --git a/assets/garden.png b/assets/garden.png new file mode 100644 index 0000000000000000000000000000000000000000..6d62d7d5b90f20a2592eba8673177f2356da1122 Binary files /dev/null and b/assets/garden.png differ diff --git a/assets/libgdx.png b/assets/libgdx.png new file mode 100644 index 0000000000000000000000000000000000000000..6c7bfca2af8281213496bb32eb5352293bacacd6 Binary files /dev/null and b/assets/libgdx.png differ diff --git a/assets/red-font.fnt b/assets/red-font.fnt new file mode 100644 index 0000000000000000000000000000000000000000..65cb21d14b69e19383be43857466737361c4a891 --- /dev/null +++ b/assets/red-font.fnt @@ -0,0 +1,480 @@ +info face="URW Chancery L Medium Italic" size=54 bold=1 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=-2,-2 +common lineHeight=72 base=54 scaleW=512 scaleH=512 pages=4 packed=0 +page id=0 file="red-font1.png" +page id=1 file="red-font2.png" +page id=2 file="red-font3.png" +page id=3 file="red-font4.png" +chars count=473 +char id=0 x=0 y=0 width=0 height=0 xoffset=-2 yoffset=0 xadvance=29 page=0 chnl=0 +char id=36 x=82 y=409 width=30 height=52 xoffset=0 yoffset=13 xadvance=27 page=0 chnl=0 +char id=40 x=112 y=409 width=31 height=52 xoffset=4 yoffset=14 xadvance=17 page=0 chnl=0 +char id=41 x=484 y=69 width=27 height=51 xoffset=-2 yoffset=14 xadvance=15 page=0 chnl=0 +char id=47 x=381 y=302 width=48 height=53 xoffset=-3 yoffset=13 xadvance=21 page=0 chnl=0 +char id=78 x=143 y=409 width=66 height=52 xoffset=-1 yoffset=13 xadvance=41 page=0 chnl=0 +char id=81 x=0 y=462 width=61 height=49 xoffset=3 yoffset=18 xadvance=35 page=0 chnl=0 +char id=82 x=61 y=462 width=62 height=49 xoffset=-1 yoffset=16 xadvance=35 page=0 chnl=0 +char id=93 x=209 y=409 width=31 height=52 xoffset=-3 yoffset=14 xadvance=20 page=0 chnl=0 +char id=102 x=365 y=130 width=59 height=57 xoffset=-8 yoffset=13 xadvance=20 page=0 chnl=0 +char id=106 x=463 y=246 width=42 height=54 xoffset=-10 yoffset=16 xadvance=15 page=0 chnl=0 +char id=124 x=496 y=409 width=10 height=45 xoffset=14 yoffset=11 xadvance=31 page=0 chnl=0 +char id=125 x=485 y=356 width=26 height=51 xoffset=-2 yoffset=14 xadvance=16 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-2 yoffset=0 xadvance=14 page=0 chnl=0 +char id=161 x=490 y=130 width=21 height=40 xoffset=0 yoffset=27 xadvance=18 page=0 chnl=0 +char id=166 x=488 y=189 width=10 height=45 xoffset=14 yoffset=11 xadvance=31 page=0 chnl=0 +char id=182 x=240 y=409 width=49 height=52 xoffset=-1 yoffset=18 xadvance=30 page=0 chnl=0 +char id=192 x=289 y=409 width=48 height=52 xoffset=-2 yoffset=5 xadvance=36 page=0 chnl=0 +char id=195 x=421 y=462 width=54 height=48 xoffset=-2 yoffset=9 xadvance=36 page=0 chnl=0 +char id=196 x=123 y=462 width=49 height=49 xoffset=-2 yoffset=8 xadvance=36 page=0 chnl=0 +char id=199 x=429 y=302 width=43 height=53 xoffset=2 yoffset=18 xadvance=31 page=0 chnl=0 +char id=203 x=172 y=462 width=42 height=49 xoffset=1 yoffset=8 xadvance=36 page=0 chnl=0 +char id=207 x=214 y=462 width=38 height=49 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=0 +char id=209 x=424 y=130 width=66 height=57 xoffset=-1 yoffset=8 xadvance=41 page=0 chnl=0 +char id=210 x=337 y=409 width=39 height=52 xoffset=3 yoffset=5 xadvance=35 page=0 chnl=0 +char id=211 x=376 y=409 width=39 height=52 xoffset=3 yoffset=5 xadvance=35 page=0 chnl=0 +char id=212 x=415 y=409 width=39 height=52 xoffset=3 yoffset=5 xadvance=35 page=0 chnl=0 +char id=213 x=252 y=462 width=42 height=49 xoffset=3 yoffset=8 xadvance=35 page=0 chnl=0 +char id=216 x=0 y=302 width=41 height=54 xoffset=3 yoffset=11 xadvance=39 page=0 chnl=0 +char id=217 x=0 y=356 width=45 height=53 xoffset=4 yoffset=5 xadvance=43 page=0 chnl=0 +char id=218 x=45 y=356 width=45 height=53 xoffset=4 yoffset=5 xadvance=43 page=0 chnl=0 +char id=219 x=90 y=356 width=45 height=53 xoffset=4 yoffset=5 xadvance=43 page=0 chnl=0 +char id=221 x=0 y=130 width=58 height=59 xoffset=-1 yoffset=5 xadvance=33 page=0 chnl=0 +char id=223 x=0 y=189 width=52 height=57 xoffset=-10 yoffset=13 xadvance=26 page=0 chnl=0 +char id=253 x=299 y=189 width=37 height=56 xoffset=-2 yoffset=14 xadvance=25 page=0 chnl=0 +char id=254 x=52 y=189 width=37 height=57 xoffset=-4 yoffset=13 xadvance=27 page=0 chnl=0 +char id=255 x=41 y=302 width=36 height=54 xoffset=-2 yoffset=16 xadvance=25 page=0 chnl=0 +char id=262 x=197 y=246 width=43 height=55 xoffset=2 yoffset=5 xadvance=31 page=0 chnl=0 +char id=264 x=58 y=130 width=43 height=59 xoffset=2 yoffset=1 xadvance=31 page=0 chnl=0 +char id=266 x=336 y=189 width=43 height=56 xoffset=2 yoffset=4 xadvance=31 page=0 chnl=0 +char id=268 x=240 y=246 width=47 height=55 xoffset=2 yoffset=5 xadvance=31 page=0 chnl=0 +char id=276 x=135 y=356 width=43 height=53 xoffset=1 yoffset=4 xadvance=36 page=0 chnl=0 +char id=278 x=294 y=462 width=42 height=49 xoffset=1 yoffset=8 xadvance=36 page=0 chnl=0 +char id=282 x=454 y=409 width=42 height=52 xoffset=1 yoffset=5 xadvance=36 page=0 chnl=0 +char id=284 x=0 y=0 width=40 height=69 xoffset=4 yoffset=1 xadvance=36 page=0 chnl=0 +char id=285 x=211 y=130 width=46 height=58 xoffset=-7 yoffset=11 xadvance=25 page=0 chnl=0 +char id=286 x=249 y=0 width=40 height=62 xoffset=4 yoffset=7 xadvance=36 page=0 chnl=0 +char id=287 x=178 y=356 width=46 height=53 xoffset=-7 yoffset=16 xadvance=25 page=0 chnl=0 +char id=288 x=40 y=0 width=40 height=66 xoffset=4 yoffset=4 xadvance=36 page=0 chnl=0 +char id=289 x=287 y=246 width=46 height=55 xoffset=-7 yoffset=14 xadvance=25 page=0 chnl=0 +char id=290 x=77 y=302 width=41 height=54 xoffset=4 yoffset=18 xadvance=36 page=0 chnl=0 +char id=291 x=333 y=246 width=46 height=55 xoffset=-7 yoffset=14 xadvance=25 page=0 chnl=0 +char id=292 x=348 y=0 width=68 height=61 xoffset=-2 yoffset=-4 xadvance=40 page=0 chnl=0 +char id=293 x=416 y=0 width=42 height=61 xoffset=1 yoffset=-3 xadvance=27 page=0 chnl=0 +char id=303 x=475 y=462 width=24 height=48 xoffset=1 yoffset=16 xadvance=16 page=0 chnl=0 +char id=307 x=118 y=302 width=34 height=54 xoffset=2 yoffset=16 xadvance=28 page=0 chnl=0 +char id=308 x=458 y=0 width=40 height=61 xoffset=-3 yoffset=2 xadvance=25 page=0 chnl=0 +char id=309 x=244 y=69 width=46 height=60 xoffset=-10 yoffset=10 xadvance=15 page=0 chnl=0 +char id=311 x=89 y=189 width=49 height=57 xoffset=2 yoffset=14 xadvance=27 page=0 chnl=0 +char id=314 x=472 y=302 width=39 height=53 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=0 +char id=316 x=257 y=130 width=42 height=58 xoffset=-3 yoffset=14 xadvance=16 page=0 chnl=0 +char id=323 x=290 y=69 width=66 height=60 xoffset=-1 yoffset=5 xadvance=41 page=0 chnl=0 +char id=325 x=299 y=130 width=66 height=58 xoffset=-1 yoffset=13 xadvance=41 page=0 chnl=0 +char id=327 x=356 y=69 width=66 height=60 xoffset=-1 yoffset=5 xadvance=41 page=0 chnl=0 +char id=334 x=224 y=356 width=42 height=53 xoffset=3 yoffset=4 xadvance=35 page=0 chnl=0 +char id=340 x=422 y=69 width=62 height=60 xoffset=-1 yoffset=5 xadvance=35 page=0 chnl=0 +char id=342 x=379 y=189 width=62 height=56 xoffset=-1 yoffset=16 xadvance=35 page=0 chnl=0 +char id=344 x=0 y=69 width=62 height=61 xoffset=-1 yoffset=4 xadvance=35 page=0 chnl=0 +char id=346 x=379 y=246 width=39 height=55 xoffset=-3 yoffset=5 xadvance=28 page=0 chnl=0 +char id=348 x=101 y=130 width=37 height=59 xoffset=-3 yoffset=1 xadvance=28 page=0 chnl=0 +char id=350 x=266 y=356 width=37 height=53 xoffset=-3 yoffset=18 xadvance=28 page=0 chnl=0 +char id=352 x=441 y=189 width=47 height=56 xoffset=-3 yoffset=4 xadvance=28 page=0 chnl=0 +char id=354 x=152 y=302 width=53 height=54 xoffset=1 yoffset=14 xadvance=30 page=0 chnl=0 +char id=364 x=303 y=356 width=45 height=53 xoffset=4 yoffset=4 xadvance=43 page=0 chnl=0 +char id=368 x=348 y=356 width=49 height=53 xoffset=4 yoffset=5 xadvance=43 page=0 chnl=0 +char id=372 x=62 y=69 width=64 height=61 xoffset=3 yoffset=-3 xadvance=51 page=0 chnl=0 +char id=374 x=80 y=0 width=57 height=64 xoffset=-1 yoffset=0 xadvance=33 page=0 chnl=0 +char id=375 x=138 y=130 width=36 height=59 xoffset=-2 yoffset=11 xadvance=25 page=0 chnl=0 +char id=376 x=138 y=189 width=58 height=57 xoffset=-1 yoffset=7 xadvance=33 page=0 chnl=0 +char id=377 x=397 y=356 width=43 height=53 xoffset=1 yoffset=6 xadvance=36 page=0 chnl=0 +char id=381 x=205 y=302 width=43 height=54 xoffset=1 yoffset=5 xadvance=36 page=0 chnl=0 +char id=383 x=196 y=189 width=59 height=57 xoffset=-8 yoffset=13 xadvance=20 page=0 chnl=0 +char id=1026 x=418 y=246 width=45 height=55 xoffset=1 yoffset=14 xadvance=38 page=0 chnl=0 +char id=1027 x=196 y=0 width=53 height=63 xoffset=0 yoffset=-1 xadvance=34 page=0 chnl=0 +char id=1036 x=289 y=0 width=59 height=62 xoffset=1 yoffset=2 xadvance=39 page=0 chnl=0 +char id=1037 x=0 y=246 width=61 height=56 xoffset=5 yoffset=1 xadvance=40 page=0 chnl=0 +char id=1038 x=126 y=69 width=59 height=61 xoffset=-2 yoffset=3 xadvance=33 page=0 chnl=0 +char id=1039 x=440 y=356 width=45 height=53 xoffset=4 yoffset=18 xadvance=43 page=0 chnl=0 +char id=1092 x=255 y=189 width=44 height=57 xoffset=2 yoffset=13 xadvance=40 page=0 chnl=0 +char id=1112 x=248 y=302 width=42 height=54 xoffset=-10 yoffset=16 xadvance=15 page=0 chnl=0 +char id=1116 x=290 y=302 width=50 height=54 xoffset=1 yoffset=10 xadvance=27 page=0 chnl=0 +char id=1118 x=340 y=302 width=41 height=54 xoffset=-2 yoffset=16 xadvance=25 page=0 chnl=0 +char id=1234 x=336 y=462 width=49 height=49 xoffset=-2 yoffset=8 xadvance=36 page=0 chnl=0 +char id=1238 x=0 y=409 width=43 height=53 xoffset=1 yoffset=4 xadvance=36 page=0 chnl=0 +char id=1258 x=43 y=409 width=39 height=53 xoffset=3 yoffset=4 xadvance=35 page=0 chnl=0 +char id=1260 x=61 y=246 width=41 height=56 xoffset=1 yoffset=4 xadvance=31 page=0 chnl=0 +char id=1262 x=102 y=246 width=59 height=56 xoffset=-2 yoffset=8 xadvance=33 page=0 chnl=0 +char id=1264 x=185 y=69 width=59 height=61 xoffset=-2 yoffset=3 xadvance=33 page=0 chnl=0 +char id=1265 x=161 y=246 width=36 height=56 xoffset=-2 yoffset=14 xadvance=25 page=0 chnl=0 +char id=1266 x=137 y=0 width=59 height=64 xoffset=-2 yoffset=0 xadvance=33 page=0 chnl=0 +char id=1267 x=174 y=130 width=37 height=59 xoffset=-2 yoffset=11 xadvance=25 page=0 chnl=0 +char id=8225 x=385 y=462 width=36 height=49 xoffset=2 yoffset=16 xadvance=29 page=0 chnl=0 +char id=58 x=493 y=478 width=18 height=29 xoffset=3 yoffset=28 xadvance=17 page=1 chnl=0 +char id=60 x=0 y=478 width=32 height=32 xoffset=4 yoffset=25 xadvance=31 page=1 chnl=0 +char id=62 x=32 y=478 width=32 height=32 xoffset=4 yoffset=25 xadvance=31 page=1 chnl=0 +char id=70 x=282 y=205 width=53 height=47 xoffset=0 yoffset=15 xadvance=34 page=1 chnl=0 +char id=71 x=460 y=0 width=40 height=51 xoffset=4 yoffset=18 xadvance=36 page=1 chnl=0 +char id=72 x=0 y=346 width=67 height=44 xoffset=-1 yoffset=13 xadvance=40 page=1 chnl=0 +char id=74 x=450 y=300 width=40 height=44 xoffset=-3 yoffset=19 xadvance=25 page=1 chnl=0 +char id=75 x=164 y=300 width=59 height=45 xoffset=1 yoffset=19 xadvance=39 page=1 chnl=0 +char id=77 x=67 y=346 width=69 height=44 xoffset=0 yoffset=13 xadvance=48 page=1 chnl=0 +char id=86 x=136 y=346 width=53 height=44 xoffset=3 yoffset=13 xadvance=38 page=1 chnl=0 +char id=87 x=189 y=346 width=64 height=44 xoffset=3 yoffset=14 xadvance=51 page=1 chnl=0 +char id=89 x=335 y=205 width=58 height=47 xoffset=-1 yoffset=17 xadvance=33 page=1 chnl=0 +char id=91 x=62 y=52 width=38 height=51 xoffset=0 yoffset=14 xadvance=16 page=1 chnl=0 +char id=104 x=253 y=346 width=34 height=44 xoffset=1 yoffset=14 xadvance=27 page=1 chnl=0 +char id=107 x=307 y=104 width=49 height=50 xoffset=2 yoffset=14 xadvance=27 page=1 chnl=0 +char id=109 x=448 y=478 width=45 height=30 xoffset=1 yoffset=28 xadvance=36 page=1 chnl=0 +char id=113 x=324 y=253 width=34 height=46 xoffset=2 yoffset=24 xadvance=25 page=1 chnl=0 +char id=118 x=89 y=478 width=33 height=31 xoffset=2 yoffset=26 xadvance=27 page=1 chnl=0 +char id=119 x=122 y=478 width=46 height=31 xoffset=2 yoffset=26 xadvance=40 page=1 chnl=0 +char id=122 x=168 y=478 width=31 height=31 xoffset=0 yoffset=26 xadvance=27 page=1 chnl=0 +char id=123 x=100 y=52 width=32 height=51 xoffset=3 yoffset=14 xadvance=16 page=1 chnl=0 +char id=162 x=393 y=205 width=25 height=47 xoffset=4 yoffset=14 xadvance=27 page=1 chnl=0 +char id=165 x=418 y=205 width=52 height=47 xoffset=-4 yoffset=17 xadvance=27 page=1 chnl=0 +char id=167 x=358 y=253 width=32 height=46 xoffset=0 yoffset=19 xadvance=26 page=1 chnl=0 +char id=169 x=287 y=346 width=48 height=44 xoffset=5 yoffset=14 xadvance=43 page=1 chnl=0 +char id=171 x=199 y=478 width=26 height=31 xoffset=3 yoffset=27 xadvance=21 page=1 chnl=0 +char id=174 x=335 y=346 width=48 height=44 xoffset=5 yoffset=14 xadvance=43 page=1 chnl=0 +char id=187 x=64 y=478 width=25 height=32 xoffset=2 yoffset=26 xadvance=24 page=1 chnl=0 +char id=193 x=132 y=52 width=48 height=51 xoffset=-2 yoffset=6 xadvance=36 page=1 chnl=0 +char id=194 x=180 y=52 width=48 height=51 xoffset=-2 yoffset=6 xadvance=36 page=1 chnl=0 +char id=197 x=356 y=104 width=48 height=50 xoffset=-2 yoffset=7 xadvance=36 page=1 chnl=0 +char id=200 x=228 y=52 width=42 height=51 xoffset=1 yoffset=6 xadvance=36 page=1 chnl=0 +char id=201 x=270 y=52 width=42 height=51 xoffset=1 yoffset=6 xadvance=36 page=1 chnl=0 +char id=202 x=312 y=52 width=42 height=51 xoffset=1 yoffset=6 xadvance=36 page=1 chnl=0 +char id=204 x=354 y=52 width=38 height=51 xoffset=0 yoffset=5 xadvance=24 page=1 chnl=0 +char id=205 x=392 y=52 width=38 height=51 xoffset=0 yoffset=5 xadvance=24 page=1 chnl=0 +char id=206 x=430 y=52 width=38 height=51 xoffset=0 yoffset=5 xadvance=24 page=1 chnl=0 +char id=214 x=404 y=104 width=39 height=50 xoffset=3 yoffset=7 xadvance=35 page=1 chnl=0 +char id=220 x=0 y=104 width=45 height=51 xoffset=4 yoffset=7 xadvance=43 page=1 chnl=0 +char id=230 x=225 y=478 width=36 height=31 xoffset=2 yoffset=26 xadvance=32 page=1 chnl=0 +char id=240 x=383 y=346 width=42 height=44 xoffset=2 yoffset=13 xadvance=25 page=1 chnl=0 +char id=248 x=390 y=253 width=29 height=46 xoffset=2 yoffset=20 xadvance=27 page=1 chnl=0 +char id=256 x=419 y=253 width=57 height=46 xoffset=-2 yoffset=11 xadvance=36 page=1 chnl=0 +char id=258 x=443 y=104 width=53 height=50 xoffset=-2 yoffset=7 xadvance=36 page=1 chnl=0 +char id=260 x=0 y=300 width=48 height=46 xoffset=-2 yoffset=18 xadvance=36 page=1 chnl=0 +char id=265 x=476 y=253 width=33 height=46 xoffset=2 yoffset=11 xadvance=21 page=1 chnl=0 +char id=270 x=45 y=104 width=46 height=51 xoffset=1 yoffset=5 xadvance=41 page=1 chnl=0 +char id=271 x=425 y=346 width=50 height=44 xoffset=2 yoffset=13 xadvance=30 page=1 chnl=0 +char id=274 x=48 y=300 width=42 height=46 xoffset=1 yoffset=11 xadvance=36 page=1 chnl=0 +char id=277 x=0 y=390 width=42 height=44 xoffset=2 yoffset=13 xadvance=21 page=1 chnl=0 +char id=280 x=0 y=253 width=42 height=47 xoffset=1 yoffset=18 xadvance=36 page=1 chnl=0 +char id=294 x=42 y=390 width=68 height=44 xoffset=-2 yoffset=13 xadvance=40 page=1 chnl=0 +char id=295 x=475 y=346 width=34 height=44 xoffset=1 yoffset=14 xadvance=27 page=1 chnl=0 +char id=296 x=91 y=104 width=44 height=51 xoffset=0 yoffset=6 xadvance=24 page=1 chnl=0 +char id=298 x=90 y=300 width=44 height=46 xoffset=0 yoffset=10 xadvance=24 page=1 chnl=0 +char id=300 x=0 y=0 width=46 height=52 xoffset=0 yoffset=5 xadvance=24 page=1 chnl=0 +char id=301 x=110 y=390 width=40 height=44 xoffset=2 yoffset=13 xadvance=16 page=1 chnl=0 +char id=302 x=223 y=300 width=38 height=45 xoffset=0 yoffset=19 xadvance=24 page=1 chnl=0 +char id=304 x=404 y=155 width=38 height=48 xoffset=0 yoffset=8 xadvance=24 page=1 chnl=0 +char id=306 x=150 y=390 width=50 height=44 xoffset=0 yoffset=19 xadvance=35 page=1 chnl=0 +char id=310 x=46 y=0 width=59 height=52 xoffset=1 yoffset=19 xadvance=39 page=1 chnl=0 +char id=313 x=468 y=52 width=43 height=51 xoffset=-2 yoffset=5 xadvance=34 page=1 chnl=0 +char id=315 x=105 y=0 width=43 height=52 xoffset=-2 yoffset=19 xadvance=34 page=1 chnl=0 +char id=318 x=200 y=390 width=39 height=44 xoffset=2 yoffset=13 xadvance=19 page=1 chnl=0 +char id=320 x=239 y=390 width=26 height=44 xoffset=2 yoffset=13 xadvance=28 page=1 chnl=0 +char id=324 x=265 y=390 width=34 height=44 xoffset=2 yoffset=14 xadvance=28 page=1 chnl=0 +char id=328 x=299 y=390 width=34 height=44 xoffset=2 yoffset=14 xadvance=28 page=1 chnl=0 +char id=329 x=333 y=390 width=34 height=44 xoffset=2 yoffset=14 xadvance=28 page=1 chnl=0 +char id=332 x=470 y=205 width=40 height=47 xoffset=3 yoffset=10 xadvance=35 page=1 chnl=0 +char id=335 x=367 y=390 width=39 height=44 xoffset=2 yoffset=13 xadvance=25 page=1 chnl=0 +char id=336 x=148 y=0 width=40 height=52 xoffset=3 yoffset=5 xadvance=35 page=1 chnl=0 +char id=341 x=406 y=390 width=33 height=44 xoffset=2 yoffset=14 xadvance=19 page=1 chnl=0 +char id=345 x=439 y=390 width=36 height=44 xoffset=2 yoffset=14 xadvance=19 page=1 chnl=0 +char id=349 x=134 y=300 width=30 height=46 xoffset=0 yoffset=11 xadvance=20 page=1 chnl=0 +char id=355 x=42 y=253 width=32 height=47 xoffset=0 yoffset=22 xadvance=20 page=1 chnl=0 +char id=356 x=188 y=0 width=53 height=52 xoffset=1 yoffset=4 xadvance=30 page=1 chnl=0 +char id=357 x=0 y=434 width=37 height=44 xoffset=1 yoffset=13 xadvance=20 page=1 chnl=0 +char id=360 x=135 y=104 width=45 height=51 xoffset=4 yoffset=6 xadvance=43 page=1 chnl=0 +char id=362 x=442 y=155 width=47 height=48 xoffset=4 yoffset=10 xadvance=43 page=1 chnl=0 +char id=365 x=37 y=434 width=41 height=44 xoffset=1 yoffset=13 xadvance=28 page=1 chnl=0 +char id=366 x=180 y=104 width=45 height=51 xoffset=4 yoffset=7 xadvance=43 page=1 chnl=0 +char id=370 x=74 y=253 width=45 height=47 xoffset=4 yoffset=18 xadvance=43 page=1 chnl=0 +char id=373 x=0 y=205 width=46 height=48 xoffset=2 yoffset=9 xadvance=40 page=1 chnl=0 +char id=379 x=225 y=104 width=43 height=51 xoffset=1 yoffset=8 xadvance=36 page=1 chnl=0 +char id=916 x=261 y=300 width=40 height=45 xoffset=-3 yoffset=11 xadvance=36 page=1 chnl=0 +char id=1024 x=241 y=0 width=42 height=52 xoffset=1 yoffset=5 xadvance=36 page=1 chnl=0 +char id=1025 x=0 y=155 width=42 height=50 xoffset=1 yoffset=7 xadvance=36 page=1 chnl=0 +char id=1031 x=42 y=155 width=38 height=50 xoffset=0 yoffset=7 xadvance=24 page=1 chnl=0 +char id=1032 x=78 y=434 width=40 height=44 xoffset=-3 yoffset=19 xadvance=25 page=1 chnl=0 +char id=1034 x=118 y=434 width=59 height=44 xoffset=-2 yoffset=13 xadvance=49 page=1 chnl=0 +char id=1035 x=177 y=434 width=48 height=44 xoffset=1 yoffset=14 xadvance=41 page=1 chnl=0 +char id=1043 x=119 y=253 width=54 height=47 xoffset=0 yoffset=15 xadvance=33 page=1 chnl=0 +char id=1048 x=225 y=434 width=61 height=44 xoffset=5 yoffset=13 xadvance=40 page=1 chnl=0 +char id=1049 x=80 y=155 width=58 height=50 xoffset=5 yoffset=7 xadvance=43 page=1 chnl=0 +char id=1050 x=301 y=300 width=59 height=45 xoffset=1 yoffset=19 xadvance=39 page=1 chnl=0 +char id=1052 x=286 y=434 width=69 height=44 xoffset=0 yoffset=13 xadvance=48 page=1 chnl=0 +char id=1053 x=355 y=434 width=68 height=44 xoffset=-2 yoffset=13 xadvance=40 page=1 chnl=0 +char id=1055 x=138 y=155 width=66 height=50 xoffset=-1 yoffset=13 xadvance=39 page=1 chnl=0 +char id=1059 x=173 y=253 width=59 height=47 xoffset=-2 yoffset=17 xadvance=33 page=1 chnl=0 +char id=1062 x=46 y=205 width=44 height=48 xoffset=4 yoffset=18 xadvance=43 page=1 chnl=0 +char id=1065 x=90 y=205 width=62 height=48 xoffset=4 yoffset=18 xadvance=60 page=1 chnl=0 +char id=1073 x=360 y=300 width=37 height=45 xoffset=2 yoffset=12 xadvance=27 page=1 chnl=0 +char id=1084 x=261 y=478 width=48 height=31 xoffset=-3 yoffset=26 xadvance=36 page=1 chnl=0 +char id=1085 x=309 y=478 width=33 height=31 xoffset=2 yoffset=27 xadvance=29 page=1 chnl=0 +char id=1106 x=204 y=155 width=30 height=50 xoffset=1 yoffset=14 xadvance=27 page=1 chnl=0 +char id=1107 x=152 y=205 width=33 height=48 xoffset=2 yoffset=10 xadvance=21 page=1 chnl=0 +char id=1114 x=342 y=478 width=36 height=31 xoffset=2 yoffset=27 xadvance=34 page=1 chnl=0 +char id=1115 x=475 y=390 width=34 height=44 xoffset=1 yoffset=14 xadvance=27 page=1 chnl=0 +char id=1117 x=232 y=253 width=35 height=47 xoffset=1 yoffset=10 xadvance=28 page=1 chnl=0 +char id=1198 x=267 y=253 width=57 height=47 xoffset=-1 yoffset=17 xadvance=33 page=1 chnl=0 +char id=1211 x=378 y=478 width=34 height=31 xoffset=2 yoffset=28 xadvance=28 page=1 chnl=0 +char id=1217 x=283 y=0 width=67 height=52 xoffset=-3 yoffset=5 xadvance=43 page=1 chnl=0 +char id=1218 x=397 y=300 width=53 height=45 xoffset=-2 yoffset=13 xadvance=45 page=1 chnl=0 +char id=1232 x=234 y=155 width=53 height=50 xoffset=-2 yoffset=7 xadvance=36 page=1 chnl=0 +char id=1237 x=412 y=478 width=36 height=31 xoffset=2 yoffset=26 xadvance=32 page=1 chnl=0 +char id=1239 x=423 y=434 width=42 height=44 xoffset=2 yoffset=13 xadvance=21 page=1 chnl=0 +char id=1244 x=350 y=0 width=67 height=52 xoffset=-3 yoffset=5 xadvance=43 page=1 chnl=0 +char id=1246 x=287 y=155 width=33 height=50 xoffset=-3 yoffset=10 xadvance=28 page=1 chnl=0 +char id=1250 x=185 y=205 width=61 height=48 xoffset=5 yoffset=9 xadvance=40 page=1 chnl=0 +char id=1252 x=320 y=155 width=45 height=50 xoffset=4 yoffset=7 xadvance=43 page=1 chnl=0 +char id=1254 x=365 y=155 width=39 height=50 xoffset=3 yoffset=7 xadvance=35 page=1 chnl=0 +char id=1263 x=268 y=104 width=39 height=51 xoffset=-2 yoffset=19 xadvance=25 page=1 chnl=0 +char id=1268 x=417 y=0 width=43 height=52 xoffset=4 yoffset=5 xadvance=41 page=1 chnl=0 +char id=1272 x=0 y=52 width=62 height=52 xoffset=1 yoffset=5 xadvance=51 page=1 chnl=0 +char id=1273 x=465 y=434 width=40 height=44 xoffset=2 yoffset=14 xadvance=32 page=1 chnl=0 +char id=8218 x=496 y=104 width=14 height=19 xoffset=-1 yoffset=43 xadvance=13 page=1 chnl=0 +char id=8224 x=246 y=205 width=36 height=48 xoffset=2 yoffset=16 xadvance=28 page=1 chnl=0 +char id=8249 x=490 y=300 width=19 height=31 xoffset=3 yoffset=27 xadvance=16 page=1 chnl=0 +char id=8250 x=489 y=155 width=19 height=31 xoffset=2 yoffset=26 xadvance=17 page=1 chnl=0 +char id=33 x=456 y=214 width=24 height=40 xoffset=3 yoffset=17 xadvance=18 page=2 chnl=0 +char id=34 x=288 y=489 width=22 height=17 xoffset=6 yoffset=18 xadvance=15 page=2 chnl=0 +char id=35 x=0 y=255 width=46 height=40 xoffset=0 yoffset=18 xadvance=27 page=2 chnl=0 +char id=37 x=92 y=295 width=36 height=39 xoffset=6 yoffset=18 xadvance=40 page=2 chnl=0 +char id=38 x=265 y=451 width=50 height=37 xoffset=4 yoffset=20 xadvance=45 page=2 chnl=0 +char id=39 x=310 y=489 width=18 height=17 xoffset=6 yoffset=18 xadvance=12 page=2 chnl=0 +char id=44 x=489 y=295 width=18 height=22 xoffset=-2 yoffset=40 xadvance=15 page=2 chnl=0 +char id=45 x=460 y=489 width=20 height=10 xoffset=3 yoffset=37 xadvance=18 page=2 chnl=0 +char id=46 x=328 y=489 width=14 height=15 xoffset=3 yoffset=42 xadvance=15 page=2 chnl=0 +char id=48 x=200 y=374 width=30 height=38 xoffset=3 yoffset=19 xadvance=27 page=2 chnl=0 +char id=49 x=230 y=374 width=28 height=38 xoffset=1 yoffset=18 xadvance=27 page=2 chnl=0 +char id=50 x=128 y=295 width=31 height=39 xoffset=0 yoffset=19 xadvance=27 page=2 chnl=0 +char id=51 x=315 y=451 width=30 height=37 xoffset=-1 yoffset=19 xadvance=27 page=2 chnl=0 +char id=52 x=480 y=214 width=29 height=40 xoffset=1 yoffset=18 xadvance=27 page=2 chnl=0 +char id=53 x=53 y=0 width=41 height=43 xoffset=1 yoffset=14 xadvance=27 page=2 chnl=0 +char id=54 x=159 y=295 width=35 height=39 xoffset=3 yoffset=18 xadvance=27 page=2 chnl=0 +char id=55 x=216 y=172 width=34 height=41 xoffset=6 yoffset=17 xadvance=27 page=2 chnl=0 +char id=56 x=258 y=374 width=31 height=38 xoffset=2 yoffset=19 xadvance=27 page=2 chnl=0 +char id=57 x=289 y=374 width=32 height=38 xoffset=-1 yoffset=19 xadvance=27 page=2 chnl=0 +char id=59 x=488 y=335 width=23 height=34 xoffset=-2 yoffset=28 xadvance=16 page=2 chnl=0 +char id=61 x=202 y=489 width=29 height=18 xoffset=3 yoffset=32 xadvance=31 page=2 chnl=0 +char id=63 x=194 y=295 width=32 height=39 xoffset=4 yoffset=18 xadvance=24 page=2 chnl=0 +char id=64 x=46 y=255 width=45 height=40 xoffset=3 yoffset=18 xadvance=41 page=2 chnl=0 +char id=65 x=226 y=295 width=48 height=39 xoffset=-2 yoffset=18 xadvance=36 page=2 chnl=0 +char id=66 x=91 y=255 width=40 height=40 xoffset=1 yoffset=16 xadvance=35 page=2 chnl=0 +char id=67 x=262 y=87 width=43 height=42 xoffset=2 yoffset=18 xadvance=31 page=2 chnl=0 +char id=68 x=131 y=255 width=46 height=40 xoffset=1 yoffset=16 xadvance=41 page=2 chnl=0 +char id=69 x=274 y=295 width=42 height=39 xoffset=1 yoffset=18 xadvance=36 page=2 chnl=0 +char id=73 x=345 y=451 width=38 height=37 xoffset=0 yoffset=19 xadvance=24 page=2 chnl=0 +char id=76 x=383 y=451 width=43 height=37 xoffset=-2 yoffset=19 xadvance=34 page=2 chnl=0 +char id=79 x=316 y=295 width=39 height=39 xoffset=3 yoffset=18 xadvance=35 page=2 chnl=0 +char id=80 x=355 y=295 width=46 height=39 xoffset=-2 yoffset=17 xadvance=32 page=2 chnl=0 +char id=83 x=305 y=87 width=37 height=42 xoffset=-3 yoffset=18 xadvance=28 page=2 chnl=0 +char id=84 x=342 y=87 width=53 height=42 xoffset=1 yoffset=14 xadvance=30 page=2 chnl=0 +char id=85 x=177 y=255 width=45 height=40 xoffset=4 yoffset=18 xadvance=43 page=2 chnl=0 +char id=88 x=401 y=295 width=50 height=39 xoffset=-3 yoffset=18 xadvance=33 page=2 chnl=0 +char id=90 x=395 y=87 width=43 height=42 xoffset=1 yoffset=17 xadvance=36 page=2 chnl=0 +char id=92 x=485 y=413 width=24 height=37 xoffset=7 yoffset=19 xadvance=29 page=2 chnl=0 +char id=94 x=111 y=489 width=22 height=19 xoffset=8 yoffset=13 xadvance=31 page=2 chnl=0 +char id=96 x=231 y=489 width=16 height=18 xoffset=7 yoffset=14 xadvance=15 page=2 chnl=0 +char id=98 x=94 y=0 width=30 height=43 xoffset=2 yoffset=14 xadvance=26 page=2 chnl=0 +char id=100 x=124 y=0 width=47 height=43 xoffset=2 yoffset=14 xadvance=27 page=2 chnl=0 +char id=103 x=250 y=172 width=46 height=41 xoffset=-7 yoffset=28 xadvance=25 page=2 chnl=0 +char id=105 x=480 y=130 width=23 height=41 xoffset=2 yoffset=16 xadvance=16 page=2 chnl=0 +char id=108 x=171 y=0 width=37 height=43 xoffset=2 yoffset=14 xadvance=16 page=2 chnl=0 +char id=112 x=438 y=87 width=37 height=42 xoffset=-4 yoffset=28 xadvance=27 page=2 chnl=0 +char id=120 x=426 y=451 width=43 height=37 xoffset=1 yoffset=28 xadvance=26 page=2 chnl=0 +char id=121 x=208 y=0 width=36 height=43 xoffset=-2 yoffset=27 xadvance=25 page=2 chnl=0 +char id=126 x=415 y=489 width=31 height=14 xoffset=2 yoffset=34 xadvance=31 page=2 chnl=0 +char id=163 x=296 y=172 width=30 height=41 xoffset=-2 yoffset=19 xadvance=27 page=2 chnl=0 +char id=168 x=342 y=489 width=23 height=15 xoffset=7 yoffset=16 xadvance=22 page=2 chnl=0 +char id=172 x=0 y=489 width=36 height=22 xoffset=0 yoffset=33 xadvance=31 page=2 chnl=0 +char id=176 x=36 y=489 width=20 height=20 xoffset=8 yoffset=19 xadvance=25 page=2 chnl=0 +char id=180 x=247 y=489 width=23 height=18 xoffset=8 yoffset=14 xadvance=19 page=2 chnl=0 +char id=181 x=0 y=130 width=39 height=42 xoffset=-3 yoffset=27 xadvance=28 page=2 chnl=0 +char id=183 x=446 y=489 width=14 height=13 xoffset=3 yoffset=35 xadvance=15 page=2 chnl=0 +char id=184 x=270 y=489 width=18 height=18 xoffset=-1 yoffset=50 xadvance=19 page=2 chnl=0 +char id=186 x=489 y=374 width=22 height=24 xoffset=3 yoffset=19 xadvance=17 page=2 chnl=0 +char id=188 x=451 y=295 width=38 height=39 xoffset=2 yoffset=18 xadvance=39 page=2 chnl=0 +char id=189 x=222 y=255 width=38 height=40 xoffset=2 yoffset=18 xadvance=39 page=2 chnl=0 +char id=190 x=0 y=335 width=40 height=39 xoffset=1 yoffset=18 xadvance=39 page=2 chnl=0 +char id=191 x=40 y=335 width=27 height=39 xoffset=1 yoffset=27 xadvance=25 page=2 chnl=0 +char id=198 x=321 y=374 width=51 height=38 xoffset=-1 yoffset=19 xadvance=43 page=2 chnl=0 +char id=208 x=260 y=255 width=46 height=40 xoffset=1 yoffset=16 xadvance=41 page=2 chnl=0 +char id=222 x=372 y=374 width=44 height=38 xoffset=-2 yoffset=18 xadvance=32 page=2 chnl=0 +char id=224 x=244 y=0 width=32 height=43 xoffset=2 yoffset=14 xadvance=26 page=2 chnl=0 +char id=225 x=276 y=0 width=32 height=43 xoffset=2 yoffset=14 xadvance=26 page=2 chnl=0 +char id=226 x=475 y=87 width=32 height=42 xoffset=2 yoffset=15 xadvance=26 page=2 chnl=0 +char id=227 x=306 y=255 width=34 height=40 xoffset=2 yoffset=17 xadvance=26 page=2 chnl=0 +char id=228 x=326 y=172 width=32 height=41 xoffset=2 yoffset=16 xadvance=26 page=2 chnl=0 +char id=229 x=358 y=172 width=32 height=41 xoffset=2 yoffset=16 xadvance=26 page=2 chnl=0 +char id=231 x=340 y=255 width=27 height=40 xoffset=0 yoffset=28 xadvance=21 page=2 chnl=0 +char id=232 x=308 y=0 width=25 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=233 x=333 y=0 width=29 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=234 x=39 y=130 width=27 height=42 xoffset=2 yoffset=15 xadvance=21 page=2 chnl=0 +char id=235 x=390 y=172 width=29 height=41 xoffset=2 yoffset=16 xadvance=21 page=2 chnl=0 +char id=236 x=362 y=0 width=23 height=43 xoffset=2 yoffset=14 xadvance=16 page=2 chnl=0 +char id=237 x=385 y=0 width=28 height=43 xoffset=2 yoffset=14 xadvance=16 page=2 chnl=0 +char id=238 x=66 y=130 width=26 height=42 xoffset=2 yoffset=15 xadvance=16 page=2 chnl=0 +char id=239 x=419 y=172 width=28 height=41 xoffset=2 yoffset=16 xadvance=16 page=2 chnl=0 +char id=241 x=447 y=172 width=34 height=41 xoffset=2 yoffset=17 xadvance=28 page=2 chnl=0 +char id=242 x=413 y=0 width=28 height=43 xoffset=2 yoffset=14 xadvance=25 page=2 chnl=0 +char id=243 x=441 y=0 width=29 height=43 xoffset=2 yoffset=14 xadvance=25 page=2 chnl=0 +char id=244 x=92 y=130 width=28 height=42 xoffset=2 yoffset=15 xadvance=25 page=2 chnl=0 +char id=245 x=367 y=255 width=33 height=40 xoffset=2 yoffset=17 xadvance=25 page=2 chnl=0 +char id=246 x=481 y=172 width=29 height=41 xoffset=2 yoffset=16 xadvance=25 page=2 chnl=0 +char id=249 x=470 y=0 width=35 height=43 xoffset=1 yoffset=14 xadvance=28 page=2 chnl=0 +char id=250 x=0 y=44 width=35 height=43 xoffset=1 yoffset=14 xadvance=28 page=2 chnl=0 +char id=251 x=120 y=130 width=35 height=42 xoffset=1 yoffset=15 xadvance=28 page=2 chnl=0 +char id=252 x=0 y=214 width=35 height=41 xoffset=1 yoffset=16 xadvance=28 page=2 chnl=0 +char id=257 x=416 y=374 width=36 height=38 xoffset=2 yoffset=19 xadvance=26 page=2 chnl=0 +char id=259 x=35 y=214 width=36 height=41 xoffset=2 yoffset=16 xadvance=26 page=2 chnl=0 +char id=261 x=469 y=451 width=32 height=37 xoffset=2 yoffset=28 xadvance=26 page=2 chnl=0 +char id=263 x=35 y=44 width=33 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=267 x=68 y=44 width=29 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=269 x=97 y=44 width=34 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=272 x=260 y=255 width=46 height=40 xoffset=1 yoffset=16 xadvance=41 page=2 chnl=0 +char id=273 x=131 y=44 width=47 height=43 xoffset=2 yoffset=14 xadvance=27 page=2 chnl=0 +char id=275 x=452 y=374 width=37 height=38 xoffset=2 yoffset=19 xadvance=21 page=2 chnl=0 +char id=279 x=71 y=214 width=25 height=41 xoffset=2 yoffset=16 xadvance=21 page=2 chnl=0 +char id=283 x=178 y=44 width=37 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=297 x=155 y=130 width=34 height=42 xoffset=2 yoffset=15 xadvance=16 page=2 chnl=0 +char id=299 x=0 y=413 width=37 height=38 xoffset=1 yoffset=19 xadvance=16 page=2 chnl=0 +char id=317 x=37 y=413 width=50 height=38 xoffset=-2 yoffset=18 xadvance=34 page=2 chnl=0 +char id=319 x=87 y=413 width=43 height=38 xoffset=-2 yoffset=19 xadvance=34 page=2 chnl=0 +char id=322 x=215 y=44 width=42 height=43 xoffset=0 yoffset=14 xadvance=19 page=2 chnl=0 +char id=326 x=257 y=44 width=34 height=43 xoffset=2 yoffset=28 xadvance=28 page=2 chnl=0 +char id=333 x=130 y=413 width=35 height=38 xoffset=2 yoffset=19 xadvance=25 page=2 chnl=0 +char id=337 x=291 y=44 width=39 height=43 xoffset=2 yoffset=14 xadvance=25 page=2 chnl=0 +char id=338 x=67 y=335 width=51 height=39 xoffset=3 yoffset=18 xadvance=47 page=2 chnl=0 +char id=343 x=330 y=44 width=33 height=43 xoffset=-1 yoffset=28 xadvance=19 page=2 chnl=0 +char id=347 x=363 y=44 width=36 height=43 xoffset=0 yoffset=14 xadvance=20 page=2 chnl=0 +char id=351 x=400 y=255 width=33 height=40 xoffset=-4 yoffset=28 xadvance=20 page=2 chnl=0 +char id=353 x=399 y=44 width=38 height=43 xoffset=0 yoffset=14 xadvance=20 page=2 chnl=0 +char id=358 x=189 y=130 width=53 height=42 xoffset=1 yoffset=14 xadvance=30 page=2 chnl=0 +char id=361 x=242 y=130 width=39 height=42 xoffset=1 yoffset=15 xadvance=28 page=2 chnl=0 +char id=363 x=165 y=413 width=37 height=38 xoffset=1 yoffset=19 xadvance=28 page=2 chnl=0 +char id=367 x=96 y=214 width=35 height=41 xoffset=1 yoffset=16 xadvance=28 page=2 chnl=0 +char id=369 x=437 y=44 width=37 height=43 xoffset=1 yoffset=14 xadvance=28 page=2 chnl=0 +char id=371 x=202 y=413 width=35 height=38 xoffset=1 yoffset=27 xadvance=28 page=2 chnl=0 +char id=378 x=281 y=130 width=35 height=42 xoffset=0 yoffset=15 xadvance=27 page=2 chnl=0 +char id=380 x=433 y=255 width=31 height=40 xoffset=0 yoffset=17 xadvance=27 page=2 chnl=0 +char id=382 x=474 y=44 width=37 height=43 xoffset=0 yoffset=14 xadvance=27 page=2 chnl=0 +char id=1028 x=316 y=130 width=43 height=42 xoffset=2 yoffset=18 xadvance=31 page=2 chnl=0 +char id=1029 x=359 y=130 width=37 height=42 xoffset=-3 yoffset=18 xadvance=28 page=2 chnl=0 +char id=1030 x=237 y=413 width=38 height=38 xoffset=0 yoffset=19 xadvance=24 page=2 chnl=0 +char id=1033 x=118 y=335 width=54 height=39 xoffset=-2 yoffset=18 xadvance=44 page=2 chnl=0 +char id=1040 x=172 y=335 width=48 height=39 xoffset=-2 yoffset=18 xadvance=36 page=2 chnl=0 +char id=1041 x=396 y=130 width=51 height=42 xoffset=1 yoffset=15 xadvance=35 page=2 chnl=0 +char id=1042 x=131 y=214 width=40 height=41 xoffset=1 yoffset=16 xadvance=35 page=2 chnl=0 +char id=1044 x=464 y=255 width=46 height=40 xoffset=1 yoffset=16 xadvance=41 page=2 chnl=0 +char id=1045 x=220 y=335 width=42 height=39 xoffset=1 yoffset=18 xadvance=36 page=2 chnl=0 +char id=1046 x=275 y=413 width=67 height=38 xoffset=-3 yoffset=19 xadvance=43 page=2 chnl=0 +char id=1047 x=447 y=130 width=33 height=42 xoffset=-3 yoffset=18 xadvance=28 page=2 chnl=0 +char id=1051 x=262 y=335 width=48 height=39 xoffset=-2 yoffset=18 xadvance=36 page=2 chnl=0 +char id=1054 x=310 y=335 width=39 height=39 xoffset=3 yoffset=18 xadvance=35 page=2 chnl=0 +char id=1056 x=349 y=335 width=46 height=39 xoffset=-2 yoffset=17 xadvance=32 page=2 chnl=0 +char id=1057 x=0 y=172 width=43 height=42 xoffset=2 yoffset=18 xadvance=31 page=2 chnl=0 +char id=1058 x=43 y=172 width=53 height=42 xoffset=1 yoffset=14 xadvance=30 page=2 chnl=0 +char id=1060 x=342 y=413 width=42 height=38 xoffset=0 yoffset=19 xadvance=32 page=2 chnl=0 +char id=1061 x=395 y=335 width=50 height=39 xoffset=-3 yoffset=18 xadvance=33 page=2 chnl=0 +char id=1063 x=445 y=335 width=43 height=39 xoffset=4 yoffset=18 xadvance=41 page=2 chnl=0 +char id=1064 x=0 y=295 width=62 height=40 xoffset=4 yoffset=18 xadvance=60 page=2 chnl=0 +char id=1066 x=171 y=214 width=38 height=41 xoffset=1 yoffset=16 xadvance=35 page=2 chnl=0 +char id=1067 x=384 y=413 width=62 height=38 xoffset=1 yoffset=19 xadvance=51 page=2 chnl=0 +char id=1068 x=446 y=413 width=39 height=38 xoffset=1 yoffset=19 xadvance=34 page=2 chnl=0 +char id=1069 x=96 y=172 width=41 height=42 xoffset=1 yoffset=18 xadvance=31 page=2 chnl=0 +char id=1070 x=0 y=374 width=65 height=39 xoffset=-2 yoffset=18 xadvance=56 page=2 chnl=0 +char id=1071 x=0 y=451 width=55 height=38 xoffset=-7 yoffset=19 xadvance=32 page=2 chnl=0 +char id=1074 x=62 y=295 width=30 height=40 xoffset=2 yoffset=17 xadvance=25 page=2 chnl=0 +char id=1076 x=0 y=87 width=30 height=43 xoffset=2 yoffset=14 xadvance=25 page=2 chnl=0 +char id=1081 x=209 y=214 width=35 height=41 xoffset=1 yoffset=16 xadvance=28 page=2 chnl=0 +char id=1088 x=30 y=87 width=37 height=43 xoffset=-4 yoffset=28 xadvance=27 page=2 chnl=0 +char id=1091 x=67 y=87 width=36 height=43 xoffset=-2 yoffset=27 xadvance=25 page=2 chnl=0 +char id=1104 x=103 y=87 width=25 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=1105 x=244 y=214 width=29 height=41 xoffset=2 yoffset=16 xadvance=21 page=2 chnl=0 +char id=1110 x=273 y=214 width=23 height=41 xoffset=2 yoffset=16 xadvance=16 page=2 chnl=0 +char id=1111 x=296 y=214 width=28 height=41 xoffset=2 yoffset=16 xadvance=16 page=2 chnl=0 +char id=1119 x=137 y=172 width=35 height=42 xoffset=1 yoffset=27 xadvance=28 page=2 chnl=0 +char id=1199 x=128 y=87 width=36 height=43 xoffset=-2 yoffset=27 xadvance=25 page=2 chnl=0 +char id=1210 x=65 y=374 width=45 height=39 xoffset=3 yoffset=19 xadvance=43 page=2 chnl=0 +char id=1216 x=55 y=451 width=38 height=38 xoffset=0 yoffset=19 xadvance=24 page=2 chnl=0 +char id=1233 x=324 y=214 width=36 height=41 xoffset=2 yoffset=16 xadvance=26 page=2 chnl=0 +char id=1235 x=360 y=214 width=32 height=41 xoffset=2 yoffset=16 xadvance=26 page=2 chnl=0 +char id=1236 x=93 y=451 width=51 height=38 xoffset=-1 yoffset=19 xadvance=43 page=2 chnl=0 +char id=1245 x=0 y=0 width=53 height=44 xoffset=-2 yoffset=14 xadvance=45 page=2 chnl=0 +char id=1247 x=144 y=451 width=34 height=38 xoffset=2 yoffset=19 xadvance=21 page=2 chnl=0 +char id=1251 x=178 y=451 width=40 height=38 xoffset=1 yoffset=19 xadvance=28 page=2 chnl=0 +char id=1253 x=392 y=214 width=35 height=41 xoffset=1 yoffset=16 xadvance=28 page=2 chnl=0 +char id=1255 x=427 y=214 width=29 height=41 xoffset=2 yoffset=16 xadvance=25 page=2 chnl=0 +char id=1256 x=110 y=374 width=39 height=39 xoffset=3 yoffset=18 xadvance=35 page=2 chnl=0 +char id=1259 x=164 y=87 width=33 height=43 xoffset=2 yoffset=14 xadvance=25 page=2 chnl=0 +char id=1261 x=197 y=87 width=30 height=43 xoffset=2 yoffset=14 xadvance=21 page=2 chnl=0 +char id=1269 x=227 y=87 width=35 height=43 xoffset=1 yoffset=14 xadvance=28 page=2 chnl=0 +char id=8216 x=56 y=489 width=24 height=20 xoffset=10 yoffset=13 xadvance=16 page=2 chnl=0 +char id=8217 x=133 y=489 width=21 height=19 xoffset=9 yoffset=18 xadvance=16 page=2 chnl=0 +char id=8220 x=80 y=489 width=31 height=20 xoffset=10 yoffset=13 xadvance=21 page=2 chnl=0 +char id=8221 x=154 y=489 width=27 height=19 xoffset=9 yoffset=13 xadvance=22 page=2 chnl=0 +char id=8222 x=181 y=489 width=21 height=19 xoffset=-1 yoffset=43 xadvance=18 page=2 chnl=0 +char id=8230 x=365 y=489 width=50 height=15 xoffset=3 yoffset=42 xadvance=57 page=2 chnl=0 +char id=8240 x=149 y=374 width=51 height=39 xoffset=6 yoffset=18 xadvance=55 page=2 chnl=0 +char id=8260 x=218 y=451 width=47 height=38 xoffset=-9 yoffset=18 xadvance=6 page=2 chnl=0 +char id=8364 x=172 y=172 width=44 height=42 xoffset=-5 yoffset=18 xadvance=27 page=2 chnl=0 +char id=42 x=231 y=97 width=27 height=23 xoffset=9 yoffset=13 xadvance=26 page=3 chnl=0 +char id=43 x=43 y=67 width=29 height=29 xoffset=3 yoffset=27 xadvance=31 page=3 chnl=0 +char id=95 x=370 y=97 width=33 height=9 xoffset=-2 yoffset=55 xadvance=30 page=3 chnl=0 +char id=97 x=72 y=67 width=32 height=29 xoffset=2 yoffset=28 xadvance=26 page=3 chnl=0 +char id=99 x=104 y=67 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=101 x=129 y=67 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=110 x=412 y=0 width=34 height=30 xoffset=2 yoffset=28 xadvance=28 page=3 chnl=0 +char id=111 x=154 y=67 width=28 height=29 xoffset=2 yoffset=28 xadvance=25 page=3 chnl=0 +char id=114 x=446 y=0 width=30 height=30 xoffset=2 yoffset=28 xadvance=19 page=3 chnl=0 +char id=115 x=182 y=67 width=28 height=29 xoffset=0 yoffset=28 xadvance=20 page=3 chnl=0 +char id=116 x=320 y=0 width=31 height=35 xoffset=1 yoffset=22 xadvance=20 page=3 chnl=0 +char id=117 x=476 y=0 width=35 height=30 xoffset=1 yoffset=27 xadvance=28 page=3 chnl=0 +char id=164 x=0 y=37 width=32 height=30 xoffset=0 yoffset=23 xadvance=27 page=3 chnl=0 +char id=170 x=208 y=97 width=23 height=24 xoffset=2 yoffset=19 xadvance=17 page=3 chnl=0 +char id=175 x=403 y=97 width=32 height=9 xoffset=6 yoffset=19 xadvance=27 page=3 chnl=0 +char id=177 x=383 y=0 width=29 height=34 xoffset=3 yoffset=22 xadvance=31 page=3 chnl=0 +char id=178 x=106 y=97 width=27 height=27 xoffset=2 yoffset=20 xadvance=17 page=3 chnl=0 +char id=179 x=157 y=97 width=26 height=25 xoffset=1 yoffset=20 xadvance=17 page=3 chnl=0 +char id=185 x=133 y=97 width=24 height=27 xoffset=1 yoffset=18 xadvance=17 page=3 chnl=0 +char id=215 x=210 y=67 width=29 height=29 xoffset=3 yoffset=27 xadvance=31 page=3 chnl=0 +char id=247 x=32 y=37 width=29 height=30 xoffset=3 yoffset=26 xadvance=31 page=3 chnl=0 +char id=281 x=0 y=0 width=25 height=37 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=305 x=239 y=67 width=23 height=29 xoffset=2 yoffset=28 xadvance=16 page=3 chnl=0 +char id=312 x=25 y=0 width=50 height=37 xoffset=1 yoffset=27 xadvance=27 page=3 chnl=0 +char id=321 x=75 y=0 width=43 height=37 xoffset=-2 yoffset=19 xadvance=34 page=3 chnl=0 +char id=339 x=262 y=67 width=37 height=29 xoffset=2 yoffset=28 xadvance=33 page=3 chnl=0 +char id=359 x=351 y=0 width=32 height=35 xoffset=0 yoffset=22 xadvance=20 page=3 chnl=0 +char id=1072 x=299 y=67 width=32 height=29 xoffset=2 yoffset=28 xadvance=26 page=3 chnl=0 +char id=1075 x=61 y=37 width=26 height=30 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1077 x=331 y=67 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1078 x=87 y=37 width=53 height=30 xoffset=-2 yoffset=28 xadvance=45 page=3 chnl=0 +char id=1079 x=356 y=67 width=27 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1080 x=140 y=37 width=35 height=30 xoffset=1 yoffset=27 xadvance=28 page=3 chnl=0 +char id=1082 x=118 y=0 width=48 height=37 xoffset=1 yoffset=27 xadvance=29 page=3 chnl=0 +char id=1083 x=383 y=67 width=41 height=29 xoffset=-3 yoffset=27 xadvance=30 page=3 chnl=0 +char id=1086 x=424 y=67 width=28 height=29 xoffset=2 yoffset=28 xadvance=25 page=3 chnl=0 +char id=1087 x=175 y=37 width=34 height=30 xoffset=2 yoffset=28 xadvance=28 page=3 chnl=0 +char id=1089 x=452 y=67 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1090 x=209 y=37 width=45 height=30 xoffset=1 yoffset=28 xadvance=36 page=3 chnl=0 +char id=1093 x=166 y=0 width=43 height=37 xoffset=1 yoffset=28 xadvance=26 page=3 chnl=0 +char id=1094 x=209 y=0 width=35 height=37 xoffset=1 yoffset=27 xadvance=28 page=3 chnl=0 +char id=1095 x=254 y=37 width=35 height=30 xoffset=1 yoffset=27 xadvance=28 page=3 chnl=0 +char id=1096 x=289 y=37 width=45 height=30 xoffset=1 yoffset=27 xadvance=38 page=3 chnl=0 +char id=1097 x=244 y=0 width=45 height=37 xoffset=1 yoffset=27 xadvance=38 page=3 chnl=0 +char id=1098 x=334 y=37 width=30 height=30 xoffset=-3 yoffset=28 xadvance=23 page=3 chnl=0 +char id=1099 x=364 y=37 width=40 height=30 xoffset=2 yoffset=28 xadvance=32 page=3 chnl=0 +char id=1100 x=404 y=37 width=25 height=30 xoffset=2 yoffset=28 xadvance=23 page=3 chnl=0 +char id=1101 x=477 y=67 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1102 x=429 y=37 width=40 height=30 xoffset=1 yoffset=28 xadvance=35 page=3 chnl=0 +char id=1103 x=469 y=37 width=42 height=30 xoffset=-1 yoffset=27 xadvance=31 page=3 chnl=0 +char id=1108 x=0 y=97 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1109 x=25 y=97 width=28 height=29 xoffset=0 yoffset=28 xadvance=20 page=3 chnl=0 +char id=1113 x=0 y=67 width=43 height=30 xoffset=-3 yoffset=27 xadvance=36 page=3 chnl=0 +char id=1241 x=53 y=97 width=25 height=29 xoffset=2 yoffset=28 xadvance=21 page=3 chnl=0 +char id=1243 x=289 y=0 width=31 height=37 xoffset=2 yoffset=20 xadvance=21 page=3 chnl=0 +char id=1257 x=78 y=97 width=28 height=29 xoffset=2 yoffset=28 xadvance=25 page=3 chnl=0 +char id=8211 x=258 y=97 width=42 height=10 xoffset=-1 yoffset=37 xadvance=30 page=3 chnl=0 +char id=8212 x=300 y=97 width=70 height=10 xoffset=-2 yoffset=37 xadvance=57 page=3 chnl=0 +char id=8226 x=183 y=97 width=25 height=25 xoffset=10 yoffset=20 xadvance=35 page=3 chnl=0 diff --git a/assets/red-font1.png b/assets/red-font1.png new file mode 100644 index 0000000000000000000000000000000000000000..8719530ece5c5731859eae02a6de8cfaa88be962 Binary files /dev/null and b/assets/red-font1.png differ diff --git a/assets/red-font2.png b/assets/red-font2.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f059cf4b8a610659aca0ee163f76232ac596ce Binary files /dev/null and b/assets/red-font2.png differ diff --git a/assets/red-font3.png b/assets/red-font3.png new file mode 100644 index 0000000000000000000000000000000000000000..9ead658286eee670d6319e07b490ea86616d9039 Binary files /dev/null and b/assets/red-font3.png differ diff --git a/assets/red-font4.png b/assets/red-font4.png new file mode 100644 index 0000000000000000000000000000000000000000..a9beaff7d818ac7d42173cd91067ade8674ce985 Binary files /dev/null and b/assets/red-font4.png differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..ba00ba8966038763e7db83dee8570afb9014136b --- /dev/null +++ b/build.gradle @@ -0,0 +1,74 @@ +buildscript { + repositories { + mavenCentral() + maven { url 'https://s01.oss.sonatype.org' } + gradlePluginPortal() + mavenLocal() + google() + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' } + } + dependencies { + + + } +} + +allprojects { + apply plugin: 'eclipse' + apply plugin: 'idea' + + // This allows you to "Build and run using IntelliJ IDEA", an option in IDEA's Settings. + idea { + module { + outputDir file('build/classes/java/main') + testOutputDir file('build/classes/java/test') + } + } +} + +configure(subprojects) { + apply plugin: 'java-library' + sourceCompatibility = 11 + + // From https://lyze.dev/2021/04/29/libGDX-Internal-Assets-List/ + // The article can be helpful when using assets.txt in your project. + tasks.register('generateAssetList') { + inputs.dir("${project.rootDir}/assets/") + // projectFolder/assets + File assetsFolder = new File("${project.rootDir}/assets/") + // projectFolder/assets/assets.txt + File assetsFile = new File(assetsFolder, "assets.txt") + // delete that file in case we've already created it + assetsFile.delete() + + // iterate through all files inside that folder + // convert it to a relative path + // and append it to the file assets.txt + fileTree(assetsFolder).collect { assetsFolder.relativePath(it) }.sort().each { + assetsFile.append(it + "\n") + } + } + processResources.dependsOn 'generateAssetList' + + compileJava { + options.incremental = true + } +} + +subprojects { + version = '$projectVersion' + ext.appName = 'GardenMadnes' + repositories { + mavenCentral() + maven { url 'https://s01.oss.sonatype.org' } + // You may want to remove the following line if you have errors downloading dependencies. + mavenLocal() + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' } + maven { url 'https://jitpack.io' } + maven { url 'https://teavm.org/maven/repository/' } + } +} + +eclipse.project.name = 'GardenMadnes' + '-parent' diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..688052262a7e1883606614fec8a55def6726f4cb --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,13 @@ +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +eclipse.project.name = appName + '-core' + +dependencies { + api "com.badlogicgames.gdx-controllers:gdx-controllers-core:$gdxControllersVersion" + api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" + api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + api "com.badlogicgames.gdx:gdx:$gdxVersion" + + if(enableGraalNative == 'true') { + implementation "io.github.berstanio:gdx-svmhelper-annotations:$graalHelperVersion" + } +} diff --git a/core/src/main/java/cz/vsb/kp/Bucket.java b/core/src/main/java/cz/vsb/kp/Bucket.java new file mode 100644 index 0000000000000000000000000000000000000000..132c8bbe131a3f9f156d769b932000664df9149a --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/Bucket.java @@ -0,0 +1,121 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.PolygonShape; +import com.badlogic.gdx.physics.box2d.World; + +public class Bucket { + + private Sprite sprite; + private Body body; + public Fixture dnoFixture; + private Texture img; + private float centerX; + private float centerY; + private World world; + + public Bucket(Texture img, float centerX, float centerY, World world) { + this.img = img; + sprite = new Sprite(img); + sprite.setOriginBasedPosition(img.getWidth() / 200f, img.getHeight() / 200f); + sprite.setOrigin(0, 0); + sprite.setSize(img.getWidth() / 100f, img.getHeight() / 100f); + this.centerX = centerX - 1; + this.centerY = centerY; + this.world = world; + createBody(); + setVelocity(10); + } + + private void createBody() { + int vyskaUchaKbeliku = 100; + PolygonShape dno = new PolygonShape(); + dno.setAsBox(img.getWidth() / 200f, 0.02f, new Vector2(0, -img.getHeight() / 200f), 0); + PolygonShape stenaPrava = new PolygonShape(); + stenaPrava.setAsBox(0.02f, (img.getHeight() - vyskaUchaKbeliku) / 200f, + new Vector2(img.getWidth() / 200f, -vyskaUchaKbeliku / 200f), 0); + PolygonShape stenaLeva = new PolygonShape(); + stenaLeva.setAsBox(0.02f, (img.getHeight() - vyskaUchaKbeliku) / 200f, + new Vector2(-img.getWidth() / 200f, -vyskaUchaKbeliku / 200f), 0); + PolygonShape vnitrek = new PolygonShape(); + vnitrek.setAsBox((img.getWidth() - 8) / 200f, ((img.getHeight() - vyskaUchaKbeliku) / 400f), + new Vector2(0, -vyskaUchaKbeliku / 200f - (img.getHeight() - vyskaUchaKbeliku) / 400f + 0.04f), 0); + FixtureDef detekceObsahu = new FixtureDef(); + detekceObsahu.isSensor = true; + detekceObsahu.shape = vnitrek; + BodyDef def = new BodyDef(); + def.type = BodyDef.BodyType.KinematicBody; + body = world.createBody(def); + dnoFixture = body.createFixture(dno, 0); + body.createFixture(stenaPrava, 0); + body.createFixture(stenaLeva, 0); + body.createFixture(detekceObsahu); + body.setTransform(centerX, centerY, 0); + dno.dispose(); + stenaLeva.dispose(); + stenaPrava.dispose(); + vnitrek.dispose(); + } + + public float getX() { + return body.getPosition().x; + } + + public float getY() { + return body.getPosition().y; + } + + public float getWidth() { + return sprite.getWidth(); + } + + public float getHeigh() { + return sprite.getHeight(); + } + + public void setVelocity(float v) { + if (v < 5 && v > -5) { + body.setLinearVelocity(v, 0); + } + System.out.println(getVelocity()); + } + + public float getVelocity() { + return body.getLinearVelocity().x; + } + + public void draw(SpriteBatch batch) { + sprite.setCenter(body.getPosition().x, body.getPosition().y); + sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2); + sprite.setRotation((float) (180 / Math.PI * body.getAngle())); + sprite.draw(batch); +// batch.draw(img, getX()-getWidth()/2, getY()-getHeigh()/2); + } + + public void draw(ShapeRenderer shapeRenderer) { +// Color c = new Color(0, 1, 0, 0.5f); +// shapeRenderer.setColor(c); +// shapeRenderer.rect(body.getPosition().x-getWidth()/2, body.getPosition().y - getHeigh()/2, getWidth(), getHeigh()); +// Color c1 = new Color(1, 1, 0, 0.5f); +// shapeRenderer.setColor(c1); +// shapeRenderer.rect(body.getPosition().x-getWidth()/2 + 10, body.getPosition().y - getHeigh()/2 + 10, getWidth() - 20, getHeigh() - 20); + + } + + public boolean isInside(Drop drop) { + Rectangle bucket = new Rectangle(centerX - getWidth() / 2, centerY / getHeigh() / 2, getWidth(), getHeigh()); + Rectangle dropRect = new Rectangle(centerX, centerY, centerY, centerX); + return bucket.overlaps(dropRect); + } + +} diff --git a/core/src/main/java/cz/vsb/kp/ContactDetector.java b/core/src/main/java/cz/vsb/kp/ContactDetector.java new file mode 100644 index 0000000000000000000000000000000000000000..a6bef053d44bc565d91dacb6f994d3094ae4f190 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/ContactDetector.java @@ -0,0 +1,53 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.physics.box2d.Contact; +import com.badlogic.gdx.physics.box2d.ContactImpulse; +import com.badlogic.gdx.physics.box2d.ContactListener; +import com.badlogic.gdx.physics.box2d.Manifold; + +public class ContactDetector implements ContactListener { + + @Override + public void beginContact(Contact contact) { + Drop kapka = isDropInContactWithSenzor(contact); + if (kapka != null) { + kapka.setZmensovani(true); + } + + } + + private Drop isDropInContactWithSenzor(Contact contact) { + if (contact.getFixtureA().isSensor() || contact.getFixtureB().isSensor()) { + if (contact.getFixtureA().getBody().getUserData() instanceof Drop) { + Drop d = (Drop) contact.getFixtureA().getBody().getUserData(); + return (Drop) contact.getFixtureA().getBody().getUserData(); + } + if (contact.getFixtureB().getBody().getUserData() instanceof Drop) { + return (Drop) contact.getFixtureB().getBody().getUserData(); + } + System.out.println("kontak"); + } + return null; + } + + @Override + public void endContact(Contact contact) { + Drop kapka = isDropInContactWithSenzor(contact); + if (kapka != null) { + kapka.setZmensovani(false); + } + } + + @Override + public void preSolve(Contact contact, Manifold oldManifold) { + // TODO Auto-generated method stub + + } + + @Override + public void postSolve(Contact contact, ContactImpulse impulse) { + // TODO Auto-generated method stub + + } + +} diff --git a/core/src/main/java/cz/vsb/kp/Drop.java b/core/src/main/java/cz/vsb/kp/Drop.java new file mode 100644 index 0000000000000000000000000000000000000000..87dd5a3638344780d6228549cebbd416e43d6ddc --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/Drop.java @@ -0,0 +1,147 @@ +package cz.vsb.kp; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.utils.Array; + +public class Drop { + + private static final Random random = new Random(); + + private List<String> imgNames = Arrays.asList("aa", "sddd"); + + private Body body; + private Texture dropImg; + private Sprite sprite; + private float centerX; + private float centerY; + private World world; + private float radius; + private boolean zmensovani = false; + private FruitType fruitType; + + public Drop(Texture dropImg, float centerX, + float centerY, World world) { + int points = 8447; + int tisice = points/1000; + +// Integer.toString(he) +// FruitType[] arrayOfFruitsType = FruitType.values(); +// int fruitTypeSize =arrayOfFruitsType.length; +// int randomIndexOfFruit = random.nextInt(fruitTypeSize); +// fruitType = arrayOfFruitsType[randomIndexOfFruit]; + this.dropImg = dropImg; + radius = 0.2f; +// radius = fruitType.getSize() / 20f; + sprite = new Sprite(dropImg); + sprite.setOriginBasedPosition(dropImg.getWidth() / 200f, dropImg.getHeight() / 200f); + sprite.setOrigin(0, 0); + this.centerX = centerX; + this.centerY = centerY; + this.world = world; + createBody(); + body.setLinearVelocity(2 - random.nextFloat() * 2, 0); + } + + private void createBody() { + BodyDef def = new BodyDef(); + def.type = BodyDef.BodyType.DynamicBody; + body = world.createBody(def); + createNewBodyFixture(radius); + body.setTransform(centerX, centerY, 0); +// body.setGravityScale(0); + body.setUserData(this); + body.setGravityScale(0.1f); + } + + private void createNewBodyFixture(float radius) { + CircleShape poly = new CircleShape(); + poly.setRadius(radius); + FixtureDef fixtureDef = new FixtureDef(); + fixtureDef.shape = poly; + fixtureDef.density = 5.5f; + fixtureDef.friction = 0.1f; + fixtureDef.restitution = 0.2f; // Make it bounce a little bit + body.createFixture(fixtureDef); + poly.dispose(); + } + + public void switchGravityOff() { + body.setGravityScale(0); + } + public void switchGravityOn() { + body.setGravityScale(0.1f); + } + + + public void update() { + if(zmensovani) { + zmensi(); + } + } + + public boolean isZmensovani() { + return zmensovani; + } + + public void setZmensovani(boolean zmensovani) { + this.zmensovani = zmensovani; + } + + public void zmensi() { +// for (Fixture fixture : body.getFixtureList()) { +// body.destroyFixture(fixture); +// } + CircleShape c = (CircleShape)body.getFixtureList().get(0).getShape(); + c.setRadius(c.getRadius()- 0.005f); + radius = radius - 0.005f; +// System.out.println("zmenseni" + radius); +// if(Math.random()> 0.95) { +// c.setRadius(c.getRadius()+0.5f); +// } + if (radius <0.08) { +// System.out.println("destroy"); + world.destroyBody(body); + } + } + + public float getX() { + return body.getPosition().x; + } + + public float getY() { + return body.getPosition().y; + } + + public float getWidth() { + return dropImg.getWidth(); + } + + public float getHeigh() { + return dropImg.getHeight(); + } + + public void draw(SpriteBatch batch) { + sprite.setSize(radius*2, radius*2); + sprite.setCenter(body.getPosition().x, body.getPosition().y); + sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2); + sprite.setRotation((float) (180 / Math.PI * body.getAngle())); + sprite.draw(batch); +// batch.draw(dropImg, getX() - getWidth()/2, getY() - getHeigh()/2); + } + +} diff --git a/core/src/main/java/cz/vsb/kp/DropGame.java b/core/src/main/java/cz/vsb/kp/DropGame.java new file mode 100644 index 0000000000000000000000000000000000000000..a53c787a29b5cc02aefc46767a760b14cddf3cf1 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/DropGame.java @@ -0,0 +1,37 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.World; + +public class DropGame extends Game { + SpriteBatch batch; + BitmapFont font; + + ShapeRenderer shapeRenderer; + + @Override + public void create() { + + font = new BitmapFont(Gdx.files.internal("red-font.fnt")); + font.getData().setScale(1f); + batch = new SpriteBatch(); + shapeRenderer = new ShapeRenderer(); + + setScreen(new MainMenuScreen(this)); + + } + + @Override + public void dispose() { + batch.dispose(); + font.dispose(); + shapeRenderer.dispose(); + } +} diff --git a/core/src/main/java/cz/vsb/kp/Food.java b/core/src/main/java/cz/vsb/kp/Food.java new file mode 100644 index 0000000000000000000000000000000000000000..aa2bcd3ac6548e949313f6cd5ebff92fb4766f48 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/Food.java @@ -0,0 +1,22 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Rectangle; + +public class Food { + + Rectangle rect; + + public Food(int x, int y) { + rect = new Rectangle(x, y, 48, 48); + } + + public void fallDown() { + rect.y = rect.y - 1; + } + + + public static void main(String[] args) { + new Food(MathUtils.random(0), 480); + } +} diff --git a/core/src/main/java/cz/vsb/kp/FruitType.java b/core/src/main/java/cz/vsb/kp/FruitType.java new file mode 100644 index 0000000000000000000000000000000000000000..03f4bffa543f279173c94f162eb1928b0562307d --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/FruitType.java @@ -0,0 +1,33 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.graphics.Texture; + +public enum FruitType { + CHERRY(25, "chery.png"), APPLE(30, "apple.png"); + + private final int size; + private final String imgName; + private Texture img; + + private FruitType(int size, String imgName) { + this.size = size; + this.imgName = imgName; + } + + public int getSize() { + return size; + } + + public String getImgName() { + return imgName; + } + + + public Texture getImg() { + if(img == null) { + img = new Texture(imgName); + } + return img; + } + +} diff --git a/core/src/main/java/cz/vsb/kp/GardenScreen.java b/core/src/main/java/cz/vsb/kp/GardenScreen.java new file mode 100644 index 0000000000000000000000000000000000000000..227e0cbd40c9ce957775428aa50536438b687e21 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/GardenScreen.java @@ -0,0 +1,181 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.Input.Buttons; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.World; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ScreenUtils; +import com.badlogic.gdx.utils.TimeUtils; + +public class GardenScreen implements Screen { + + private final DropGame dropGame; + + private float garderWidth = 8; + private float garderHeight = 4.8f; + + private OrthographicCamera camera; + private Texture bucketImg; + private Texture dropImg; + private Texture gardenImg; + private Array<Drop> raindrops; + private long lastDropTime; + private Bucket bucket; + + static private boolean projectionMatrixSet; + + World world; + Box2DDebugRenderer debugRenderer; + + public GardenScreen(final DropGame dropGame) { + this.dropGame = dropGame; + projectionMatrixSet = false; + camera = new OrthographicCamera(); + camera.setToOrtho(false, garderWidth, garderHeight); + world = new World(new Vector2(0, -10), true); + world.setContactListener(new ContactDetector()); + debugRenderer = new Box2DDebugRenderer(); + + bucketImg = new Texture(Gdx.files.internal("bucket.png")); + dropImg = new Texture(Gdx.files.internal("drop.png")); + gardenImg = new Texture(Gdx.files.internal("garden.png")); + + bucket = new Bucket(bucketImg, (int) (camera.viewportWidth / 2 - bucketImg.getWidth() / 200), 1.35f, world); + dropGame.shapeRenderer.setProjectionMatrix(dropGame.batch.getProjectionMatrix()); + + raindrops = new Array<>(); + spawnRaindrop(); + + } + + @Override + public void show() { + } + + @Override + public void render(float delta) { + ScreenUtils.clear(1, 0, 0, 1); + camera.update(); + dropGame.batch.setProjectionMatrix(camera.combined); + myRender(); + debugRenderer.render(world, camera.combined); + world.step(delta, 6, 2); + if (TimeUtils.nanoTime() - lastDropTime > 1000000000) { + spawnRaindrop(); + } + } + + private int hp = 3; + + private void myRender() { + dropGame.batch.begin(); + dropGame.batch.draw(gardenImg, 0, 0, camera.viewportWidth, camera.viewportHeight); + for(int i=0; i<hp; i++) { + dropGame.batch.draw(dropImg, 0+i*garderWidth/10*1.2f, garderWidth - garderWidth/10, garderWidth/10, garderWidth/10); + } + bucket.draw(dropGame.batch); + for (Drop raindrop : raindrops) { + raindrop.update(); + raindrop.draw(dropGame.batch); + } + Matrix4 originalMatrix = dropGame.batch.getProjectionMatrix().cpy(); // cpy() needed to properly set afterwards because calling set() seems to modify kept matrix, not replaces it + dropGame.batch.setProjectionMatrix(originalMatrix.cpy().scale(1/120f, 1/120f, 1)); + dropGame.font.draw(dropGame.batch, "Body: " + 5, 10, 40); + dropGame.batch.setProjectionMatrix(originalMatrix); //revert projection + dropGame.batch.end(); + + Gdx.gl.glEnable(GL20.GL_BLEND); + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + if (!projectionMatrixSet) { + dropGame.shapeRenderer.setProjectionMatrix(dropGame.batch.getProjectionMatrix()); + projectionMatrixSet = true; + } +// Vector3 mouse = new Vector3(x, y, 0); +// camera.unproject(mouse); + dropGame.shapeRenderer.begin(ShapeType.Filled); + bucket.draw(dropGame.shapeRenderer); + dropGame.shapeRenderer.end(); + Gdx.gl.glDisable(GL20.GL_BLEND); + + if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) { + bucket.setVelocity(bucket.getVelocity()-1f); + } + if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { + bucket.setVelocity(bucket.getVelocity() + 1f); + } + if (!Gdx.input.isKeyPressed(Input.Keys.LEFT) && !Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { + bucket.setVelocity(bucket.getVelocity()*0.8f); + } + if (bucket.getX() < bucket.getWidth()/2 && bucket.getVelocity() < 0) { + bucket.setVelocity(0); + } + if (bucket.getX() > 8 - bucket.getWidth()/2 && bucket.getVelocity() > 0) { + bucket.setVelocity(0); + } + if (TimeUtils.nanoTime() - lastDropTime > 500000000) { + spawnRaindrop(); + } +// for (Iterator<Drop> iter = raindrops.iterator(); iter.hasNext();) { +// Drop raindrop = iter.next(); +// raindrop.y -= 200 * Gdx.graphics.getDeltaTime(); +// if (raindrop.y + 161 < 0) +// iter.remove(); +// if (raindrop.overlaps(bucket)) { +// iter.remove(); +// } +// } + if (Gdx.input.isKeyJustPressed(Input.Keys.F)) { + if (!Gdx.graphics.isFullscreen()) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else { + Gdx.graphics.setWindowedMode(800, 600); + } + } + } + + private void spawnRaindrop() { + Drop raindrop = new Drop(dropImg, MathUtils.random(0, 800-6)/100f, 4.8f, world); + raindrops.add(raindrop); + lastDropTime = TimeUtils.nanoTime(); + } + + @Override + public void resize(int width, int height) { + /* nothing to do */ + } + + @Override + public void pause() { + /* nothing to do */ + } + + @Override + public void resume() { + /* nothing to do */ + } + + @Override + public void hide() { + /* nothing to do */ + } + + @Override + public void dispose() { + dropImg.dispose(); + bucketImg.dispose(); + gardenImg.dispose(); + world.dispose(); + debugRenderer.dispose(); + } + +} diff --git a/core/src/main/java/cz/vsb/kp/Main.gwt.xml b/core/src/main/java/cz/vsb/kp/Main.gwt.xml new file mode 100644 index 0000000000000000000000000000000000000000..8dd504611a159adab47f91ec1a72e94c69b49a69 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/Main.gwt.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.11.0//EN" "https://www.gwtproject.org/doctype/2.11.0/gwt-module.dtd"> +<module> + <!-- Paths to source are relative to this file and separated by slashes ('/'). --> + <source path="" /> + <!-- Reflection includes may be needed for your code or library code. Each value is separated by periods ('.'). --> + <!-- You can include a full package by not including the name of a type at the end. --> + +</module> \ No newline at end of file diff --git a/core/src/main/java/cz/vsb/kp/Main.java b/core/src/main/java/cz/vsb/kp/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..f28fecd545ce0a495622ea54e74223e2d1944206 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/Main.java @@ -0,0 +1,34 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.ScreenUtils; + +/** {@link com.badlogic.gdx.ApplicationListener} implementation shared by all platforms. */ +public class Main extends ApplicationAdapter { + private SpriteBatch batch; + private Texture image; + + @Override + public void create() { + batch = new SpriteBatch(); + image = new Texture("libgdx.png"); + } + + @Override + public void render() { + ScreenUtils.clear(0.15f, 0.15f, 0.2f, 1f); + batch.begin(); + batch.draw(image, 140, 210); + batch.end(); + } + + @Override + public void dispose() { + batch.dispose(); + image.dispose(); + } +} diff --git a/core/src/main/java/cz/vsb/kp/MainMenuScreen.java b/core/src/main/java/cz/vsb/kp/MainMenuScreen.java new file mode 100644 index 0000000000000000000000000000000000000000..252c6b2f059b5e896e5ca12e65e06a473825d7a8 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/MainMenuScreen.java @@ -0,0 +1,72 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input.Buttons; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.utils.ScreenUtils; + +public class MainMenuScreen implements Screen { + + private final DropGame dropGame; + private OrthographicCamera camera; + private Texture gardenImg; + + public MainMenuScreen(final DropGame dropGame) { + this.dropGame = dropGame; + camera = new OrthographicCamera(); + camera.setToOrtho(false, 1920, 1080); + gardenImg = new Texture("garden.png"); + } + + @Override + public void show() { + // TODO Auto-generated method stub + } + + @Override + public void render(float delta) { + ScreenUtils.clear(0, 0, 0.2f, 1); + + camera.update(); + dropGame.batch.setProjectionMatrix(camera.combined); + + dropGame.batch.begin(); + dropGame.batch.draw(gardenImg, 0, 0); + dropGame.font.draw(dropGame.batch, "Welcome to Drop!!! ", 100, 150); + dropGame.font.draw(dropGame.batch, "Tap anywhere to begin!", 100, 100); + dropGame.batch.end(); + + if (Gdx.input.isButtonJustPressed(Buttons.LEFT)) { + dropGame.setScreen(new GardenScreen(dropGame)); + dispose(); + } + } + + @Override + public void resize(int width, int height) { + + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + gardenImg.dispose(); + } + +} diff --git a/core/src/main/java/cz/vsb/kp/PhysicsGame.java b/core/src/main/java/cz/vsb/kp/PhysicsGame.java new file mode 100644 index 0000000000000000000000000000000000000000..e4264ba4c97b6011e048e8139ca2d1ca5e42b20d --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/PhysicsGame.java @@ -0,0 +1,115 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.InputAdapter; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer; +import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.EdgeShape; +import com.badlogic.gdx.physics.box2d.PolygonShape; +import com.badlogic.gdx.physics.box2d.World; + +public class PhysicsGame extends ApplicationAdapter { + World world; + OrthographicCamera camera; + Box2DDebugRenderer debugRenderer; + + @Override + public void create () { + world = new World(new Vector2(0, -10), true); + camera = new OrthographicCamera(50, 25); + debugRenderer = new Box2DDebugRenderer(); + + // ground + createEdge(BodyDef.BodyType.StaticBody, -20, -10f, 20, -10f, 0); + // left wall + createEdge(BodyDef.BodyType.StaticBody, -20, -10, -20, 10, 0); + // right wall + createEdge(BodyDef.BodyType.StaticBody, 20, -10, 20, 10, 0); + + createCircle(BodyDef.BodyType.DynamicBody, 0, 0, 1, 3); + + Gdx.input.setInputProcessor(new InputAdapter() { + + @Override + public boolean touchDown (int x, int y, int pointer, int button) { + + Vector3 touchedPoint = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0); + camera.unproject(touchedPoint); + + if(MathUtils.randomBoolean()) { + createBox(BodyDef.BodyType.DynamicBody, touchedPoint.x, touchedPoint.y, 1, 1, 1); + } + else{ + createCircle(BodyDef.BodyType.DynamicBody, touchedPoint.x, touchedPoint.y, 1, 3); + } + + return true; + } + }); + } + + @Override + public void render () { + Gdx.gl.glClearColor(.125f, .125f, .125f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + debugRenderer.render(world, camera.combined); + world.step(1 / 60f, 6, 2); + } + + @Override + public void dispose () { + world.dispose(); + debugRenderer.dispose(); + } + + private Body createBox(BodyDef.BodyType type, float x, float y, float width, float height, float density) { + PolygonShape poly = new PolygonShape(); + poly.setAsBox(width, height); + + BodyDef def = new BodyDef(); + def.type = type; + Body body = world.createBody(def); + body.createFixture(poly, density); + body.setTransform(x, y, 0); + poly.dispose(); + + return body; + } + + private Body createEdge(BodyDef.BodyType type, float x1, float y1, float x2, float y2, float density) { + EdgeShape poly = new EdgeShape(); + poly.set(new Vector2(0, 0), new Vector2(x2 - x1, y2 - y1)); + + BodyDef def = new BodyDef(); + def.type = type; + Body body = world.createBody(def); + body.createFixture(poly, density); + body.setTransform(x1, y1, 0); + poly.dispose(); + + return body; + } + + private Body createCircle(BodyDef.BodyType type, float x, float y, float radius, float density) { + CircleShape poly = new CircleShape(); + poly.setRadius(radius); + + BodyDef def = new BodyDef(); + def.type = type; + Body body = world.createBody(def); + body.createFixture(poly, density); + body.setTransform(x, y, 0); + poly.dispose(); + + return body; + } +} \ No newline at end of file diff --git a/core/src/main/java/cz/vsb/kp/RenderableItem.java b/core/src/main/java/cz/vsb/kp/RenderableItem.java new file mode 100644 index 0000000000000000000000000000000000000000..de070b25f25433240394d90228303cf892ae7077 --- /dev/null +++ b/core/src/main/java/cz/vsb/kp/RenderableItem.java @@ -0,0 +1,8 @@ +package cz.vsb.kp; + +import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +public interface RenderableItem { + + public void draw(SpriteBatch batch); +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..9c5f5682ed7f0f86f5edf4b1cf3f2d0cecc5e5cd --- /dev/null +++ b/gradle.properties @@ -0,0 +1,12 @@ +org.gradle.daemon=false +org.gradle.jvmargs=-Xms512M -Xmx1G -Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8 +org.gradle.configureondemand=false +gdxControllersVersion=2.2.3 +graalHelperVersion=2.0.1 +enableGraalNative=false +gwtFrameworkVersion=2.11.0 +gwtPluginVersion=1.1.29 +gdxTeaVMVersion=1.0.5 +teaVMVersion=0.11.0 +gdxVersion=1.13.1 +projectVersion=1.0.0 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..a4b76b9530d66f5e68d973ea569d8e19de379189 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..cea7a793a84b44ca4cfb911a13deaab8ea20589f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000000000000000000000000000000000..f3b75f3b0d4faeb4b1c8a02b5c47007e6efb7dcd --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100755 index 0000000000000000000000000000000000000000..9d21a21834d5195c278ba17baec3115b2aaab06e --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/html/build.gradle b/html/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..309890a239b09728c1806490aee559371f10ae7e --- /dev/null +++ b/html/build.gradle @@ -0,0 +1,160 @@ + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.gretty:gretty:3.1.0' + classpath "org.docstr:gwt-gradle-plugin:$gwtPluginVersion" + + } +} +apply plugin: "gwt" +apply plugin: "war" +apply plugin: "org.gretty" + +gwt { + gwtVersion = "$gwtFrameworkVersion" // Should match the version used for building the GWT backend. See gradle.properties. + maxHeapSize = '1G' // Default 256m is not enough for the GWT compiler. GWT is HUNGRY. + minHeapSize = '1G' + + src = files(file('src/main/java')) // Needs to be in front of "modules" below. + modules 'cz.vsb.kp.GdxDefinition' + devModules 'cz.vsb.kp.GdxDefinitionSuperdev' + project.webAppDirName = 'webapp' + + compiler.strict = true + compiler.disableCastChecking = true + //// The next line can be useful to uncomment if you want output that hasn't been obfuscated. +// compiler.style = org.docstr.gradle.plugins.gwt.Style.DETAILED + + sourceLevel = 1.11 +} + +dependencies { + implementation "com.badlogicgames.gdx-controllers:gdx-controllers-core:$gdxControllersVersion:sources" + implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion" + implementation "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources" + implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion:sources" + implementation "com.badlogicgames.gdx:gdx:$gdxVersion:sources" + implementation project(':core') + implementation("com.badlogicgames.gdx-controllers:gdx-controllers-gwt:$gdxControllersVersion:sources"){exclude group: "com.badlogicgames.gdx", module: "gdx-backend-gwt"} + implementation("com.badlogicgames.gdx:gdx-box2d-gwt:$gdxVersion:sources") {exclude group: "com.google.gwt", module: "gwt-user"} + +} + +import org.akhikhl.gretty.AppBeforeIntegrationTestTask +import org.docstr.gradle.plugins.gwt.GwtSuperDev + +gretty.httpPort = 8080 +// The line below will need to be changed only if you change the build directory to something other than "build". +gretty.resourceBase = "${project.layout.buildDirectory.asFile.get().absolutePath}/gwt/draftOut" +gretty.contextPath = "/" +gretty.portPropertiesFileName = "TEMP_PORTS.properties" + +task startHttpServer (dependsOn: [draftCompileGwt]) { + doFirst { + copy { + from "webapp" + into gretty.resourceBase + } + copy { + from "war" + into gretty.resourceBase + } + } +} +task beforeRun(type: AppBeforeIntegrationTestTask, dependsOn: startHttpServer) { + // The next line allows ports to be reused instead of + // needing a process to be manually terminated. + file("build/TEMP_PORTS.properties").delete() + // Somewhat of a hack; uses Gretty's support for wrapping a task in + // a start and then stop of a Jetty server that serves files while + // also running the SuperDev code server. + integrationTestTask 'superDev' + + interactive false +} + +task superDev(type: GwtSuperDev) { + doFirst { + gwt.modules = gwt.devModules + } +} + +//// We delete the (temporary) war/ folder because if any extra files get into it, problems occur. +//// The war/ folder shouldn't be committed to version control. +clean.delete += [file("war")] + +// This next line can be changed if you want to, for instance, always build into the +// docs/ folder of a Git repo, which can be set to automatically publish on GitHub Pages. +// This is relative to the html/ folder. +var outputPath = "build/dist/" + +task dist(dependsOn: [clean, compileGwt]) { + doLast { + // Uncomment the next line if you have changed outputPath and know that its contents + // should be replaced by a new dist build. Some large JS files are not cleaned up by + // default unless the outputPath is inside build/ (then the clean task removes them). + // Do not uncomment the next line if you changed outputPath to a folder that has + // non-generated files that you want to keep! + //delete(file(outputPath)) + + file(outputPath).mkdirs() + copy { + from("build/gwt/out"){ + exclude '**/*.symbolMap' // Not used by a dist, and these can be large. + } + into outputPath + } + copy { + from("webapp") { + exclude 'index.html' // We edit this HTML file later. + exclude 'refresh.png' // We don't need this button; this saves some bytes. + } + into outputPath + } + copy { + from("webapp") { + // These next two lines take the index.html page and remove the superdev refresh button. + include 'index.html' + filter { String line -> line.replaceAll('<a class="superdev" .+', '') } + // This does not modify the original index.html, only the copy in the dist. + // If you decide to manually remove or comment out the superdev button from index.html, you should also + // either remove or comment out only the "filter" line above this. + } + into outputPath + } + copy { + from "war" + into outputPath + } + } +} + +task addSource { + doLast { + sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs) + sourceSets.main.compileClasspath += files("../core/build/generated/sources/annotationProcessor/java/main") + + } +} + +task distZip(type: Zip, dependsOn: dist){ + //// This uses the output of the dist task, which removes the superdev button from index.html . + from(outputPath) + archiveVersion = projectVersion + archiveBaseName.set("${appName}-dist") + //// The result will be in html/build/ with a name containing "-dist". + destinationDirectory.set(file("build")) +} + +tasks.compileGwt.dependsOn(addSource) +tasks.draftCompileGwt.dependsOn(addSource) +tasks.checkGwt.dependsOn(addSource) + +java.sourceCompatibility = JavaVersion.VERSION_11 +java.targetCompatibility = JavaVersion.VERSION_11 +sourceSets.main.java.srcDirs = [ "src/main/java/" ] + +eclipse.project.name = appName + "-html" diff --git a/html/src/main/java/cz/vsb/kp/GdxDefinition.gwt.xml b/html/src/main/java/cz/vsb/kp/GdxDefinition.gwt.xml new file mode 100644 index 0000000000000000000000000000000000000000..b206ac1e00072c76885c485337d8b786f8596b53 --- /dev/null +++ b/html/src/main/java/cz/vsb/kp/GdxDefinition.gwt.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.11.0//EN" "https://www.gwtproject.org/doctype/2.11.0/gwt-module.dtd"> +<module rename-to="html"> + <!-- Paths to source are relative to this file and separated by slashes ('/'). --> + <source path="" /> + + <!-- "Inherits" lines are how GWT knows where to look for code and configuration in other projects or libraries. --> + <inherits name="com.badlogic.gdx.backends.gdx_backends_gwt" /> + <inherits name="com.badlogic.gdx.controllers" /> + <inherits name="com.badlogic.gdx.controllers.controllers-gwt" /> + <inherits name="com.badlogic.gdx.physics.box2d.box2d-gwt" /> + <inherits name="cz.vsb.kp.Main" /> + + <!-- You must change this if you rename packages later, or rename GwtLauncher. --> + <entry-point class="cz.vsb.kp.gwt.GwtLauncher" /> + + <!-- Reflection includes may be needed for your code or library code. Each value is separated by periods ('.'). --> + <!-- You can include a full package by not including the name of a type at the end. --> + <!-- This is a feature of libGDX, so these lines go after the above "inherits" that brings in libGDX. --> + <!-- <extend-configuration-property name="gdx.reflect.include" value="fully.qualified.TypeName" /> --> + + <!-- Rarely, projects may need to include files but do not have access to the complete assets. --> + <!-- This happens for libraries and shared projects, typically, and the configuration goes in that project. --> + <!-- The value is a path, separated by forward slashes, where the root is your html project's resources root. --> + <!-- You can include individual files like this, and access them with Gdx.files.classpath("path/to/file.png") : --> + <!-- This is also a feature of libGDX, so these lines go after the above "inherits" that brings in libGDX. --> + <!-- <extend-configuration-property name="gdx.files.classpath" value="path/to/file.png" /> --> + + <!-- You usually won't need to make changes to the rest of this. --> + <set-configuration-property name="gdx.assetpath" value="../assets" /> + <set-configuration-property name="xsiframe.failIfScriptTag" value="FALSE"/> + <!-- These two lines reduce the work GWT has to do during compilation and also shrink output size. --> + <set-property name="user.agent" value="gecko1_8, safari"/> + <collapse-property name="user.agent" values="*" /> + <!-- Remove the "user.agent" lines above if you encounter issues with Safari or other Gecko browsers. --> +</module> \ No newline at end of file diff --git a/html/src/main/java/cz/vsb/kp/GdxDefinitionSuperdev.gwt.xml b/html/src/main/java/cz/vsb/kp/GdxDefinitionSuperdev.gwt.xml new file mode 100644 index 0000000000000000000000000000000000000000..26e5c56b3daa15d271da924ae3e4435a6547fa44 --- /dev/null +++ b/html/src/main/java/cz/vsb/kp/GdxDefinitionSuperdev.gwt.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.11.0//EN" "https://www.gwtproject.org/doctype/2.11.0/gwt-module.dtd"> +<module rename-to="html"> + <inherits name="cz.vsb.kp.GdxDefinition" /> + <collapse-all-properties /> + <add-linker name="xsiframe"/> + <set-configuration-property name="devModeRedirectEnabled" value="true"/> + <set-configuration-property name="xsiframe.failIfScriptTag" value="FALSE"/> +</module> \ No newline at end of file diff --git a/html/src/main/java/cz/vsb/kp/gwt/GwtLauncher.java b/html/src/main/java/cz/vsb/kp/gwt/GwtLauncher.java new file mode 100644 index 0000000000000000000000000000000000000000..754be82fbc774dfc7819c474a54c93ca4ea6c3aa --- /dev/null +++ b/html/src/main/java/cz/vsb/kp/gwt/GwtLauncher.java @@ -0,0 +1,26 @@ +package cz.vsb.kp.gwt; + +import com.badlogic.gdx.ApplicationListener; +import com.badlogic.gdx.backends.gwt.GwtApplication; +import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration; +import cz.vsb.kp.Main; + +/** Launches the GWT application. */ +public class GwtLauncher extends GwtApplication { + @Override + public GwtApplicationConfiguration getConfig () { + // Resizable application, uses available space in browser with no padding: + GwtApplicationConfiguration cfg = new GwtApplicationConfiguration(true); + cfg.padVertical = 0; + cfg.padHorizontal = 0; + return cfg; + // If you want a fixed size application, comment out the above resizable section, + // and uncomment below: + //return new GwtApplicationConfiguration(640, 480); + } + + @Override + public ApplicationListener createApplicationListener () { + return new Main(); + } +} diff --git a/html/webapp/WEB-INF/web.xml b/html/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..4301df2483bb501c3c72079c65b160578721412f --- /dev/null +++ b/html/webapp/WEB-INF/web.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" ?> +<web-app> +</web-app> \ No newline at end of file diff --git a/html/webapp/index.html b/html/webapp/index.html new file mode 100644 index 0000000000000000000000000000000000000000..347a8ea61a0ab43ed8758fc85ab2fb8d10d20629 --- /dev/null +++ b/html/webapp/index.html @@ -0,0 +1,31 @@ +<!doctype html> +<html> +<head> + <title>GardenMadnes</title> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <meta id="gameViewport" name="viewport" content="width=device-width initial-scale=1"> + <link href="styles.css" rel="stylesheet" type="text/css"> +</head> + +<body> +<a class="superdev" href="javascript:%7B%20window.__gwt_bookmarklet_params%20%3D%20%7B'server_url'%3A'http%3A%2F%2Flocalhost%3A9876%2F'%7D%3B%20var%20s%20%3D%20document.createElement('script')%3B%20s.src%20%3D%20'http%3A%2F%2Flocalhost%3A9876%2Fdev_mode_on.js'%3B%20void(document.getElementsByTagName('head')%5B0%5D.appendChild(s))%3B%7D">↻</a> +<div align="center" id="embed-html"></div> +<script type="text/javascript" src="html/html.nocache.js"></script> +</body> + +<script> +function handleMouseDown(evt) { + evt.preventDefault(); + evt.stopPropagation(); + window.focus(); +} + +function handleMouseUp(evt) { + evt.preventDefault(); + evt.stopPropagation(); +} +document.addEventListener('contextmenu', event => event.preventDefault()); +document.getElementById('embed-html').addEventListener('mousedown', handleMouseDown, false); +document.getElementById('embed-html').addEventListener('mouseup', handleMouseUp, false); +</script> +</html> diff --git a/html/webapp/refresh.png b/html/webapp/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..aab1e3872e5fc840acc6e880a17c3e42f5a6cc3a Binary files /dev/null and b/html/webapp/refresh.png differ diff --git a/html/webapp/styles.css b/html/webapp/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..e768a3964ff3d7140b0749b83e23c4dde02aaf46 --- /dev/null +++ b/html/webapp/styles.css @@ -0,0 +1,53 @@ +canvas { + cursor: default; + outline: none; +} + +body { + background-color: #222222; +} + +p { + text-align: center; + color: #eeeeee; +} + +a { + text-align: center; + color: #bbbbff; +} + +.superdev { + color: rgb(37,37,37); + text-shadow: 0px 1px 1px rgba(250,250,250,0.1); + font-size: 50pt; + display: block; + position: relative; + text-decoration: none; + background-color: rgb(83,87,93); + box-shadow: 0px 3px 0px 0px rgb(34,34,34), + 0px 7px 10px 0px rgb(17,17,17), + inset 0px 1px 1px 0px rgba(250, 250, 250, .2), + inset 0px -12px 35px 0px rgba(0, 0, 0, .5); + width: 70px; + height: 70px; + border: 0; + border-radius: 35px; + text-align: center; + line-height: 68px; +} + +.superdev:active { + box-shadow: 0px 0px 0px 0px rgb(34,34,34), + 0px 3px 7px 0px rgb(17,17,17), + inset 0px 1px 1px 0px rgba(250, 250, 250, .2), + inset 0px -10px 35px 5px rgba(0, 0, 0, .5); + background-color: rgb(83,87,93); + top: 3px; + color: #fff; + text-shadow: 0px 0px 3px rgb(250,250,250); +} + +.superdev:hover { + background-color: rgb(100,100,100); +} diff --git a/lwjgl3/build.gradle b/lwjgl3/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..000c3405e64c20e04e839e1244c61a579f3790af --- /dev/null +++ b/lwjgl3/build.gradle @@ -0,0 +1,140 @@ + +buildscript { + repositories { + gradlePluginPortal() + } + dependencies { + classpath "io.github.fourlastor:construo:1.5.1" + if(enableGraalNative == 'true') { + classpath "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.9.28" + } + } +} +plugins { + id "application" +} +apply plugin: 'io.github.fourlastor.construo' + + +import io.github.fourlastor.construo.Target + +sourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ] +mainClassName = 'cz.vsb.kp.lwjgl3.Lwjgl3Launcher' +application.setMainClass(mainClassName) +eclipse.project.name = appName + '-lwjgl3' +java.sourceCompatibility = 11 +java.targetCompatibility = 11 +if (JavaVersion.current().isJava9Compatible()) { + compileJava.options.release.set(17) +} + +dependencies { + implementation "com.badlogicgames.gdx-controllers:gdx-controllers-desktop:$gdxControllersVersion" + implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" + implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + implementation project(':core') + + if(enableGraalNative == 'true') { + implementation "io.github.berstanio:gdx-svmhelper-backend-lwjgl3:$graalHelperVersion" + implementation "io.github.berstanio:gdx-svmhelper-extension-box2d:$graalHelperVersion" + implementation "io.github.berstanio:gdx-svmhelper-extension-freetype:$graalHelperVersion" + } + +} + +def os = System.properties['os.name'].toLowerCase() + +run { + workingDir = rootProject.file('assets').path + setIgnoreExitValue(true) + + if (os.contains('mac')) jvmArgs += "-XstartOnFirstThread" +} + +jar { +// sets the name of the .jar file this produces to the name of the game or app, with the version after. + archiveFileName.set("${appName}-${projectVersion}.jar") +// the duplicatesStrategy matters starting in Gradle 7.0; this setting works. + duplicatesStrategy(DuplicatesStrategy.EXCLUDE) + dependsOn configurations.runtimeClasspath + from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } +// these "exclude" lines remove some unnecessary duplicate files in the output JAR. + exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') + dependencies { + exclude('META-INF/INDEX.LIST', 'META-INF/maven/**') + } +// setting the manifest makes the JAR runnable. + manifest { + attributes 'Main-Class': project.mainClassName + } +// this last step may help on some OSes that need extra instruction to make runnable JARs. + doLast { + file(archiveFile).setExecutable(true, false) + } +} + +construo { + // name of the executable + name.set(appName) + // human-readable name, used for example in the `.app` name for macOS + humanName.set(appName) + // Optional, defaults to project version property + version.set("$projectVersion") + + targets.configure { + create("linuxX64", Target.Linux) { + architecture.set(Target.Architecture.X86_64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.12%2B7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.12_7.tar.gz") + } + create("macM1", Target.MacOs) { + architecture.set(Target.Architecture.AARCH64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.12%2B7/OpenJDK17U-jdk_aarch64_mac_hotspot_17.0.12_7.tar.gz") + // macOS needs an identifier + identifier.set("cz.vsb.kp." + appName) + // Optional: icon for macOS + macIcon.set(project.file("icons/logo.icns")) + } + create("macX64", Target.MacOs) { + architecture.set(Target.Architecture.X86_64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.12%2B7/OpenJDK17U-jdk_x64_mac_hotspot_17.0.12_7.tar.gz") + // macOS needs an identifier + identifier.set("cz.vsb.kp." + appName) + // Optional: icon for macOS + macIcon.set(project.file("icons/logo.icns")) + } + create("winX64", Target.Windows) { + architecture.set(Target.Architecture.X86_64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.12%2B7/OpenJDK17U-jdk_x64_windows_hotspot_17.0.12_7.zip") + // Uncomment the next line to show a console when the game runs, to print messages. + //useConsole.set(true) + } + } +} + +// Equivalent to the jar task; here for compatibility with gdx-setup. +tasks.register('dist') { + dependsOn 'jar' +} + +distributions { + main { + contents { + into('libs') { + project.configurations.runtimeClasspath.files.findAll { file -> + file.getName() != project.tasks.jar.outputs.files.singleFile.name + }.each { file -> + exclude file.name + } + } + } + } +} + +startScripts.dependsOn(':lwjgl3:jar') +startScripts.classpath = project.tasks.jar.outputs.files + +if(enableGraalNative == 'true') { + apply from: file("nativeimage.gradle") +} diff --git a/lwjgl3/icons/logo.icns b/lwjgl3/icons/logo.icns new file mode 100644 index 0000000000000000000000000000000000000000..5e41ad7c1af69bbc1ea082c61fccd833abc5c4ff Binary files /dev/null and b/lwjgl3/icons/logo.icns differ diff --git a/lwjgl3/icons/logo.ico b/lwjgl3/icons/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..c4f2d5ed4db3bff2b63ce23d3a775f5c28e1b343 Binary files /dev/null and b/lwjgl3/icons/logo.ico differ diff --git a/lwjgl3/icons/logo.png b/lwjgl3/icons/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..788f542c3aadf54dbd321809619843391619acb8 Binary files /dev/null and b/lwjgl3/icons/logo.png differ diff --git a/lwjgl3/nativeimage.gradle b/lwjgl3/nativeimage.gradle new file mode 100644 index 0000000000000000000000000000000000000000..ff349fd19dc9387867fa5097d79db4a70ee8c940 --- /dev/null +++ b/lwjgl3/nativeimage.gradle @@ -0,0 +1,54 @@ + +project(":lwjgl3") { + apply plugin: "org.graalvm.buildtools.native" + + graalvmNative { + binaries { + main { + imageName = appName + mainClass = project.mainClassName + requiredVersion = '23.0' + buildArgs.add("-march=compatibility") + jvmArgs.addAll("-Dfile.encoding=UTF8") + sharedLibrary = false + resources.autodetect() + } + } + } + + run { + doNotTrackState("Running the app should not be affected by Graal.") + } + + // Modified from https://lyze.dev/2021/04/29/libGDX-Internal-Assets-List/ ; thanks again, Lyze! + // This creates a resource-config.json file based on the contents of the assets folder (and the libGDX icons). + // This file is used by Graal Native to embed those specific files. + // This has to run before nativeCompile, so it runs at the start of an unrelated resource-handling command. + generateResourcesConfigFile.doFirst { + def assetsFolder = new File("${project.rootDir}/assets/") + def lwjgl3 = project(':lwjgl3') + def resFolder = new File("${lwjgl3.projectDir}/src/main/resources/META-INF/native-image/${lwjgl3.ext.appName}") + resFolder.mkdirs() + def resFile = new File(resFolder, "resource-config.json") + resFile.delete() + resFile.append( + """{ + "resources":{ + "includes":[ + { + "pattern": ".*(""") + // This adds every filename in the assets/ folder to a pattern that adds those files as resources. + fileTree(assetsFolder).each { + // The backslash-Q and backslash-E escape the start and end of a literal string, respectively. + resFile.append("\\\\Q${it.name}\\\\E|") + } + // We also match all of the window icon images this way and the font files that are part of libGDX. + resFile.append( + """libgdx.+\\\\.png|lsans.+)" + } + ]}, + "bundles":[] +}""" + ) + } +} diff --git a/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/Lwjgl3Launcher.java b/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/Lwjgl3Launcher.java new file mode 100644 index 0000000000000000000000000000000000000000..fb17c0d6194c95f37cb98069c75eb30314ea82b6 --- /dev/null +++ b/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/Lwjgl3Launcher.java @@ -0,0 +1,37 @@ +package cz.vsb.kp.lwjgl3; + +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; + +import cz.vsb.kp.DropGame; +import cz.vsb.kp.Main; + +/** Launches the desktop (LWJGL3) application. */ +public class Lwjgl3Launcher { + public static void main(String[] args) { + if (StartupHelper.startNewJvmIfRequired()) return; // This handles macOS support and helps on Windows. + createApplication(); + } + + private static Lwjgl3Application createApplication() { + return new Lwjgl3Application(new DropGame(), getDefaultConfiguration()); + } + + private static Lwjgl3ApplicationConfiguration getDefaultConfiguration() { + Lwjgl3ApplicationConfiguration configuration = new Lwjgl3ApplicationConfiguration(); + configuration.setTitle("GardenMadnes"); + //// Vsync limits the frames per second to what your hardware can display, and helps eliminate + //// screen tearing. This setting doesn't always work on Linux, so the line after is a safeguard. + configuration.useVsync(true); + //// Limits FPS to the refresh rate of the currently active monitor, plus 1 to try to match fractional + //// refresh rates. The Vsync setting above should limit the actual FPS to match the monitor. + configuration.setForegroundFPS(Lwjgl3ApplicationConfiguration.getDisplayMode().refreshRate + 1); + //// If you remove the above line and set Vsync to false, you can get unlimited FPS, which can be + //// useful for testing performance, but can also be very stressful to some hardware. + //// You may also need to configure GPU drivers to fully disable Vsync; this can cause screen tearing. + configuration.setWindowedMode(640, 480); + //// You can change these files; they are in lwjgl3/src/main/resources/ . + configuration.setWindowIcon("libgdx128.png", "libgdx64.png", "libgdx32.png", "libgdx16.png"); + return configuration; + } +} \ No newline at end of file diff --git a/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/StartupHelper.java b/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/StartupHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..fce06e4e9db919a4b518707d076b991213aac9b4 --- /dev/null +++ b/lwjgl3/src/main/java/cz/vsb/kp/lwjgl3/StartupHelper.java @@ -0,0 +1,179 @@ +/* + * Copyright 2020 damios + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//Note, the above license and copyright applies to this file only. + +package cz.vsb.kp.lwjgl3; + +import org.lwjgl.system.macosx.LibC; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; + +/** + * Adds some utilities to ensure that the JVM was started with the + * {@code -XstartOnFirstThread} argument, which is required on macOS for LWJGL 3 + * to function. Also helps on Windows when users have names with characters from + * outside the Latin alphabet, a common cause of startup crashes. + * <br> + * <a href="https://jvm-gaming.org/t/starting-jvm-on-mac-with-xstartonfirstthread-programmatically/57547">Based on this java-gaming.org post by kappa</a> + * @author damios + */ +public class StartupHelper { + + private static final String JVM_RESTARTED_ARG = "jvmIsRestarted"; + + private StartupHelper() { + throw new UnsupportedOperationException(); + } + + /** + * Starts a new JVM if the application was started on macOS without the + * {@code -XstartOnFirstThread} argument. This also includes some code for + * Windows, for the case where the user's home directory includes certain + * non-Latin-alphabet characters (without this code, most LWJGL3 apps fail + * immediately for those users). Returns whether a new JVM was started and + * thus no code should be executed. + * <p> + * <u>Usage:</u> + * + * <pre><code> + * public static void main(String... args) { + * if (StartupHelper.startNewJvmIfRequired(true)) return; // This handles macOS support and helps on Windows. + * // after this is the actual main method code + * } + * </code></pre> + * + * @param redirectOutput + * whether the output of the new JVM should be rerouted to the + * old JVM, so it can be accessed in the same place; keeps the + * old JVM running if enabled + * @return whether a new JVM was started and thus no code should be executed + * in this one + */ + public static boolean startNewJvmIfRequired(boolean redirectOutput) { + String osName = System.getProperty("os.name").toLowerCase(); + if (!osName.contains("mac")) { + if (osName.contains("windows")) { +// Here, we are trying to work around an issue with how LWJGL3 loads its extracted .dll files. +// By default, LWJGL3 extracts to the directory specified by "java.io.tmpdir", which is usually the user's home. +// If the user's name has non-ASCII (or some non-alphanumeric) characters in it, that would fail. +// By extracting to the relevant "ProgramData" folder, which is usually "C:\ProgramData", we avoid this. + System.setProperty("java.io.tmpdir", System.getenv("ProgramData") + "/libGDX-temp"); + } + return false; + } + + // There is no need for -XstartOnFirstThread on Graal native image + if (!System.getProperty("org.graalvm.nativeimage.imagecode", "").isEmpty()) { + return false; + } + + long pid = LibC.getpid(); + + // check whether -XstartOnFirstThread is enabled + if ("1".equals(System.getenv("JAVA_STARTED_ON_FIRST_THREAD_" + pid))) { + return false; + } + + // check whether the JVM was previously restarted + // avoids looping, but most certainly leads to a crash + if ("true".equals(System.getProperty(JVM_RESTARTED_ARG))) { + System.err.println( + "There was a problem evaluating whether the JVM was started with the -XstartOnFirstThread argument."); + return false; + } + + // Restart the JVM with -XstartOnFirstThread + ArrayList<String> jvmArgs = new ArrayList<>(); + String separator = System.getProperty("file.separator"); + // The following line is used assuming you target Java 8, the minimum for LWJGL3. + String javaExecPath = System.getProperty("java.home") + separator + "bin" + separator + "java"; + // If targeting Java 9 or higher, you could use the following instead of the above line: + //String javaExecPath = ProcessHandle.current().info().command().orElseThrow(); + + if (!(new File(javaExecPath)).exists()) { + System.err.println( + "A Java installation could not be found. If you are distributing this app with a bundled JRE, be sure to set the -XstartOnFirstThread argument manually!"); + return false; + } + + jvmArgs.add(javaExecPath); + jvmArgs.add("-XstartOnFirstThread"); + jvmArgs.add("-D" + JVM_RESTARTED_ARG + "=true"); + jvmArgs.addAll(ManagementFactory.getRuntimeMXBean().getInputArguments()); + jvmArgs.add("-cp"); + jvmArgs.add(System.getProperty("java.class.path")); + String mainClass = System.getenv("JAVA_MAIN_CLASS_" + pid); + if (mainClass == null) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); + if (trace.length > 0) { + mainClass = trace[trace.length - 1].getClassName(); + } else { + System.err.println("The main class could not be determined."); + return false; + } + } + jvmArgs.add(mainClass); + + try { + if (!redirectOutput) { + ProcessBuilder processBuilder = new ProcessBuilder(jvmArgs); + processBuilder.start(); + } else { + Process process = (new ProcessBuilder(jvmArgs)) + .redirectErrorStream(true).start(); + BufferedReader processOutput = new BufferedReader( + new InputStreamReader(process.getInputStream())); + String line; + + while ((line = processOutput.readLine()) != null) { + System.out.println(line); + } + + process.waitFor(); + } + } catch (Exception e) { + System.err.println("There was a problem restarting the JVM"); + e.printStackTrace(); + } + + return true; + } + + /** + * Starts a new JVM if the application was started on macOS without the + * {@code -XstartOnFirstThread} argument. Returns whether a new JVM was + * started and thus no code should be executed. Redirects the output of the + * new JVM to the old one. + * <p> + * <u>Usage:</u> + * + * <pre> + * public static void main(String... args) { + * if (StartupHelper.startNewJvmIfRequired()) return; // This handles macOS support and helps on Windows. + * // the actual main method code + * } + * </pre> + * + * @return whether a new JVM was started and thus no code should be executed + * in this one + */ + public static boolean startNewJvmIfRequired() { + return startNewJvmIfRequired(true); + } +} \ No newline at end of file diff --git a/lwjgl3/src/main/resources/libgdx128.png b/lwjgl3/src/main/resources/libgdx128.png new file mode 100644 index 0000000000000000000000000000000000000000..788f542c3aadf54dbd321809619843391619acb8 Binary files /dev/null and b/lwjgl3/src/main/resources/libgdx128.png differ diff --git a/lwjgl3/src/main/resources/libgdx16.png b/lwjgl3/src/main/resources/libgdx16.png new file mode 100644 index 0000000000000000000000000000000000000000..47af1899a83fa6e2a1ba3a9235e6f8ef49ee568f Binary files /dev/null and b/lwjgl3/src/main/resources/libgdx16.png differ diff --git a/lwjgl3/src/main/resources/libgdx32.png b/lwjgl3/src/main/resources/libgdx32.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf903a413d06e98b5dc38b76030b8d3826a3906 Binary files /dev/null and b/lwjgl3/src/main/resources/libgdx32.png differ diff --git a/lwjgl3/src/main/resources/libgdx64.png b/lwjgl3/src/main/resources/libgdx64.png new file mode 100644 index 0000000000000000000000000000000000000000..ebcd8f10385c7c5a6ee2b6d7a09a13ff7c96e409 Binary files /dev/null and b/lwjgl3/src/main/resources/libgdx64.png differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..36daa1fbdce23cf16071d62bb86d4544c12b8f37 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,4 @@ +// A list of which subprojects to load as part of the same larger project. +// You can remove Strings from the list and reload the Gradle project +// if you want to temporarily disable a subproject. +include 'lwjgl3', 'core', 'html'