diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..67df35c --- /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 0000000..6c84be0 --- /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 0000000..0cd31b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,81 @@ +# ═══════════════════════════════════════════════════════════════ +# GRADLE +# ═══════════════════════════════════════════════════════════════ +.gradle/ +build/ +!gradle/wrapper/gradle-wrapper.jar + +# ═══════════════════════════════════════════════════════════════ +# IDE +# ═══════════════════════════════════════════════════════════════ +# IntelliJ IDEA +.idea/ +*.iml +*.ipr +*.iws +out/ + +# Eclipse +.project +.classpath +.settings/ +bin/ + +# VS Code +.vscode/ + +# NetBeans +nbproject/ +nbbuild/ +nbdist/ + +# ═══════════════════════════════════════════════════════════════ +# OS +# ═══════════════════════════════════════════════════════════════ +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +desktop.ini + +# ═══════════════════════════════════════════════════════════════ +# JAVA +# ═══════════════════════════════════════════════════════════════ +*.class +*.jar +*.war +*.ear +*.log +hs_err_pid* + +# ═══════════════════════════════════════════════════════════════ +# LIBGDX +# ═══════════════════════════════════════════════════════════════ +# Android (if added later) +android/assets/ +android/libs/ +android/gen/ +android/bin/ +android/obj/ +android/local.properties + +# iOS (if added later) +ios/build/ +ios/libs/ + +# Native builds +libs/ +jniLibs/ + +# ═══════════════════════════════════════════════════════════════ +# MISC +# ═══════════════════════════════════════════════════════════════ +*.swp +*.swo +*~ +.env +.env.local +local.properties diff --git a/assets/DejaVuMathTeXGyre.ttf b/assets/DejaVuMathTeXGyre.ttf new file mode 100644 index 0000000..8a24f06 Binary files /dev/null and b/assets/DejaVuMathTeXGyre.ttf differ diff --git a/assets/DejaVuSans-Bold.ttf b/assets/DejaVuSans-Bold.ttf new file mode 100644 index 0000000..6d65fa7 Binary files /dev/null and b/assets/DejaVuSans-Bold.ttf differ diff --git a/assets/DejaVuSans-BoldOblique.ttf b/assets/DejaVuSans-BoldOblique.ttf new file mode 100644 index 0000000..753f2d8 Binary files /dev/null and b/assets/DejaVuSans-BoldOblique.ttf differ diff --git a/assets/DejaVuSans-ExtraLight.ttf b/assets/DejaVuSans-ExtraLight.ttf new file mode 100644 index 0000000..b09f32d Binary files /dev/null and b/assets/DejaVuSans-ExtraLight.ttf differ diff --git a/assets/DejaVuSans-Oblique.ttf b/assets/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000..999bac7 Binary files /dev/null and b/assets/DejaVuSans-Oblique.ttf differ diff --git a/assets/DejaVuSans.ttf b/assets/DejaVuSans.ttf new file mode 100644 index 0000000..e5f7eec Binary files /dev/null and b/assets/DejaVuSans.ttf differ diff --git a/assets/DejaVuSansCondensed-Bold.ttf b/assets/DejaVuSansCondensed-Bold.ttf new file mode 100644 index 0000000..22987c6 Binary files /dev/null and b/assets/DejaVuSansCondensed-Bold.ttf differ diff --git a/assets/DejaVuSansCondensed-BoldOblique.ttf b/assets/DejaVuSansCondensed-BoldOblique.ttf new file mode 100644 index 0000000..f5fa0ca Binary files /dev/null and b/assets/DejaVuSansCondensed-BoldOblique.ttf differ diff --git a/assets/DejaVuSansCondensed-Oblique.ttf b/assets/DejaVuSansCondensed-Oblique.ttf new file mode 100644 index 0000000..7fde907 Binary files /dev/null and b/assets/DejaVuSansCondensed-Oblique.ttf differ diff --git a/assets/DejaVuSansCondensed.ttf b/assets/DejaVuSansCondensed.ttf new file mode 100644 index 0000000..3259bc2 Binary files /dev/null and b/assets/DejaVuSansCondensed.ttf differ diff --git a/assets/DejaVuSansMono-Bold.ttf b/assets/DejaVuSansMono-Bold.ttf new file mode 100644 index 0000000..8184ced Binary files /dev/null and b/assets/DejaVuSansMono-Bold.ttf differ diff --git a/assets/DejaVuSansMono-BoldOblique.ttf b/assets/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 0000000..754dca7 Binary files /dev/null and b/assets/DejaVuSansMono-BoldOblique.ttf differ diff --git a/assets/DejaVuSansMono-Oblique.ttf b/assets/DejaVuSansMono-Oblique.ttf new file mode 100644 index 0000000..4c858d4 Binary files /dev/null and b/assets/DejaVuSansMono-Oblique.ttf differ diff --git a/assets/DejaVuSansMono.ttf b/assets/DejaVuSansMono.ttf new file mode 100644 index 0000000..f578602 Binary files /dev/null and b/assets/DejaVuSansMono.ttf differ diff --git a/assets/DejaVuSerif-Bold.ttf b/assets/DejaVuSerif-Bold.ttf new file mode 100644 index 0000000..3bb755f Binary files /dev/null and b/assets/DejaVuSerif-Bold.ttf differ diff --git a/assets/DejaVuSerif-BoldItalic.ttf b/assets/DejaVuSerif-BoldItalic.ttf new file mode 100644 index 0000000..a36dd4b Binary files /dev/null and b/assets/DejaVuSerif-BoldItalic.ttf differ diff --git a/assets/DejaVuSerif-Italic.ttf b/assets/DejaVuSerif-Italic.ttf new file mode 100644 index 0000000..805daf2 Binary files /dev/null and b/assets/DejaVuSerif-Italic.ttf differ diff --git a/assets/DejaVuSerif.ttf b/assets/DejaVuSerif.ttf new file mode 100644 index 0000000..0b803d2 Binary files /dev/null and b/assets/DejaVuSerif.ttf differ diff --git a/assets/DejaVuSerifCondensed-Bold.ttf b/assets/DejaVuSerifCondensed-Bold.ttf new file mode 100644 index 0000000..222bf13 Binary files /dev/null and b/assets/DejaVuSerifCondensed-Bold.ttf differ diff --git a/assets/DejaVuSerifCondensed-BoldItalic.ttf b/assets/DejaVuSerifCondensed-BoldItalic.ttf new file mode 100644 index 0000000..e446636 Binary files /dev/null and b/assets/DejaVuSerifCondensed-BoldItalic.ttf differ diff --git a/assets/DejaVuSerifCondensed-Italic.ttf b/assets/DejaVuSerifCondensed-Italic.ttf new file mode 100644 index 0000000..c529df3 Binary files /dev/null and b/assets/DejaVuSerifCondensed-Italic.ttf differ diff --git a/assets/DejaVuSerifCondensed.ttf b/assets/DejaVuSerifCondensed.ttf new file mode 100644 index 0000000..d3959b3 Binary files /dev/null and b/assets/DejaVuSerifCondensed.ttf differ diff --git a/assets/assets.txt b/assets/assets.txt new file mode 100644 index 0000000..e1f472b --- /dev/null +++ b/assets/assets.txt @@ -0,0 +1,40 @@ +DejaVuMathTeXGyre.ttf +DejaVuSans-Bold.ttf +DejaVuSans-BoldOblique.ttf +DejaVuSans-ExtraLight.ttf +DejaVuSans-Oblique.ttf +DejaVuSans.ttf +DejaVuSansCondensed-Bold.ttf +DejaVuSansCondensed-BoldOblique.ttf +DejaVuSansCondensed-Oblique.ttf +DejaVuSansCondensed.ttf +DejaVuSansMono-Bold.ttf +DejaVuSansMono-BoldOblique.ttf +DejaVuSansMono-Oblique.ttf +DejaVuSansMono.ttf +DejaVuSerif-Bold.ttf +DejaVuSerif-BoldItalic.ttf +DejaVuSerif-Italic.ttf +DejaVuSerif.ttf +DejaVuSerifCondensed-Bold.ttf +DejaVuSerifCondensed-BoldItalic.ttf +DejaVuSerifCondensed-Italic.ttf +DejaVuSerifCondensed.ttf +frog.png +house.png +libgdx.png +resident.png +symbol.png +ui/font-list.fnt +ui/font-subtitle.fnt +ui/font-window.fnt +ui/font.fnt +ui/uiskin.atlas +ui/uiskin.json +ui/uiskin.png +фон.png +фон1.png +фон2.png +фон3.png +фон4.png +фон5.png diff --git a/assets/frog.png b/assets/frog.png new file mode 100644 index 0000000..f475ec2 Binary files /dev/null and b/assets/frog.png differ diff --git a/assets/house.png b/assets/house.png new file mode 100644 index 0000000..02eb688 Binary files /dev/null and b/assets/house.png differ diff --git a/assets/libgdx.png b/assets/libgdx.png new file mode 100644 index 0000000..ac0d528 Binary files /dev/null and b/assets/libgdx.png differ diff --git a/assets/resident.png b/assets/resident.png new file mode 100644 index 0000000..a95b4ed Binary files /dev/null and b/assets/resident.png differ diff --git a/assets/symbol.png b/assets/symbol.png new file mode 100644 index 0000000..4b0fabf Binary files /dev/null and b/assets/symbol.png differ diff --git a/assets/ui/font-list.fnt b/assets/ui/font-list.fnt new file mode 100644 index 0000000..5fd54da --- /dev/null +++ b/assets/ui/font-list.fnt @@ -0,0 +1,198 @@ +info face="font-list" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0 +common lineHeight=15 base=11 scaleW=505 scaleH=30 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0 +page id=0 file="font-list.png" +chars count=193 +char id=0 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=11 xadvance=3 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=0 +char id=33 x=391 y=14 width=2 height=7 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=34 x=248 y=23 width=3 height=3 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=35 x=466 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=36 x=9 y=2 width=5 height=10 xoffset=-1 yoffset=3 xadvance=7 page=0 chnl=0 +char id=37 x=490 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=38 x=450 y=14 width=7 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=39 x=267 y=23 width=2 height=3 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=40 x=126 y=2 width=3 height=9 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=41 x=131 y=2 width=2 height=9 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=42 x=46 y=23 width=4 height=5 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=0 +char id=43 x=73 y=23 width=6 height=5 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=44 x=263 y=23 width=2 height=3 xoffset=-1 yoffset=9 xadvance=3 page=0 chnl=0 +char id=45 x=306 y=23 width=4 height=1 xoffset=-1 yoffset=8 xadvance=5 page=0 chnl=0 +char id=46 x=296 y=23 width=2 height=1 xoffset=-1 yoffset=10 xadvance=3 page=0 chnl=0 +char id=47 x=354 y=2 width=4 height=8 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=48 x=383 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=49 x=317 y=14 width=3 height=7 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=50 x=322 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=51 x=329 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=52 x=336 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=53 x=344 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=54 x=352 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=55 x=360 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=56 x=367 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=57 x=375 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=58 x=201 y=23 width=2 height=4 xoffset=-1 yoffset=7 xadvance=3 page=0 chnl=0 +char id=59 x=118 y=23 width=2 height=5 xoffset=-1 yoffset=7 xadvance=3 page=0 chnl=0 +char id=60 x=59 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=61 x=271 y=23 width=5 height=3 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=62 x=52 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=63 x=395 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=64 x=161 y=2 width=10 height=9 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=0 +char id=65 x=443 y=2 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=66 x=494 y=2 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=67 x=0 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=68 x=8 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=69 x=16 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=70 x=24 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=71 x=31 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=72 x=54 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=73 x=502 y=2 width=2 height=7 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=74 x=332 y=2 width=3 height=8 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=75 x=69 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=76 x=77 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=77 x=84 y=14 width=8 height=7 xoffset=-1 yoffset=4 xadvance=9 page=0 chnl=0 +char id=78 x=94 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=79 x=102 y=14 width=7 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=80 x=111 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=81 x=117 y=2 width=7 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=82 x=126 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=83 x=134 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=84 x=141 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=85 x=174 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=86 x=199 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=87 x=207 y=14 width=9 height=7 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=0 +char id=88 x=218 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=89 x=226 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=90 x=234 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=91 x=135 y=2 width=3 height=9 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=92 x=367 y=2 width=4 height=8 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=93 x=140 y=2 width=3 height=9 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=94 x=187 y=23 width=5 height=4 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=95 x=285 y=23 width=5 height=1 xoffset=0 yoffset=12 xadvance=7 page=0 chnl=0 +char id=96 x=258 y=23 width=3 height=3 xoffset=-1 yoffset=3 xadvance=3 page=0 chnl=0 +char id=97 x=88 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=98 x=241 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=99 x=95 y=23 width=4 height=5 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=100 x=248 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=101 x=101 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=102 x=255 y=14 width=4 height=7 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=103 x=261 y=14 width=5 height=7 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=104 x=268 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=105 x=275 y=14 width=2 height=7 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=106 x=4 y=2 width=3 height=10 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=107 x=279 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=108 x=286 y=14 width=2 height=7 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=109 x=108 y=23 width=8 height=5 xoffset=-1 yoffset=6 xadvance=9 page=0 chnl=0 +char id=110 x=122 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=111 x=129 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=112 x=290 y=14 width=5 height=7 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=113 x=297 y=14 width=5 height=7 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=114 x=15 y=23 width=4 height=6 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=115 x=136 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=116 x=304 y=14 width=4 height=7 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=117 x=143 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=118 x=150 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=119 x=157 y=23 width=8 height=5 xoffset=-1 yoffset=6 xadvance=9 page=0 chnl=0 +char id=120 x=167 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=121 x=310 y=14 width=5 height=7 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=122 x=174 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=123 x=145 y=2 width=4 height=9 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=0 +char id=124 x=157 y=2 width=2 height=9 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=125 x=151 y=2 width=4 height=9 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=0 +char id=126 x=278 y=23 width=5 height=2 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=11 xadvance=3 page=0 chnl=0 +char id=161 x=195 y=14 width=2 height=7 xoffset=-1 yoffset=6 xadvance=3 page=0 chnl=0 +char id=162 x=189 y=14 width=4 height=7 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=163 x=182 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=164 x=8 y=23 width=5 height=6 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=165 x=166 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=166 x=180 y=2 width=2 height=9 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=167 x=415 y=2 width=5 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=168 x=312 y=23 width=4 height=1 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=169 x=0 y=23 width=6 height=6 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=170 x=181 y=23 width=4 height=4 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=171 x=66 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=172 x=241 y=23 width=5 height=3 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=174 x=498 y=14 width=6 height=6 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=175 x=300 y=23 width=4 height=1 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=176 x=235 y=23 width=4 height=3 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=177 x=38 y=23 width=6 height=5 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=178 x=230 y=23 width=3 height=3 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=179 x=225 y=23 width=3 height=3 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=180 x=220 y=23 width=3 height=3 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=181 x=47 y=14 width=5 height=7 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=182 x=39 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=183 x=292 y=23 width=2 height=1 xoffset=-1 yoffset=8 xadvance=3 page=0 chnl=0 +char id=184 x=215 y=23 width=3 height=3 xoffset=-1 yoffset=10 xadvance=4 page=0 chnl=0 +char id=185 x=211 y=23 width=2 height=3 xoffset=-1 yoffset=3 xadvance=4 page=0 chnl=0 +char id=186 x=205 y=23 width=4 height=3 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 +char id=187 x=31 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=0 +char id=188 x=184 y=2 width=5 height=9 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=189 x=191 y=2 width=5 height=9 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=190 x=198 y=2 width=6 height=9 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=191 x=472 y=2 width=5 height=7 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=192 x=16 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=193 x=24 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=194 x=213 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=195 x=221 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=196 x=229 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=197 x=237 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=198 x=149 y=14 width=9 height=7 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=0 +char id=199 x=245 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=200 x=39 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=201 x=47 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=202 x=253 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=203 x=261 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=204 x=55 y=2 width=4 height=10 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 +char id=205 x=61 y=2 width=3 height=10 xoffset=-1 yoffset=1 xadvance=3 page=0 chnl=0 +char id=206 x=285 y=2 width=4 height=9 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=207 x=291 y=2 width=4 height=9 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=208 x=414 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=209 x=297 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=210 x=66 y=2 width=7 height=10 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 +char id=211 x=75 y=2 width=7 height=10 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 +char id=212 x=305 y=2 width=7 height=9 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=213 x=323 y=2 width=7 height=9 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=214 x=314 y=2 width=7 height=9 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=215 x=81 y=23 width=5 height=5 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=216 x=84 y=2 width=7 height=10 xoffset=-1 yoffset=3 xadvance=8 page=0 chnl=0 +char id=217 x=93 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=218 x=101 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 +char id=219 x=277 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=220 x=269 y=2 width=6 height=9 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=221 x=109 y=2 width=6 height=10 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 +char id=222 x=474 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=223 x=486 y=2 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=224 x=436 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=225 x=429 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=226 x=451 y=2 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=227 x=465 y=2 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=228 x=479 y=2 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=229 x=422 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=230 x=21 y=23 width=8 height=5 xoffset=-1 yoffset=6 xadvance=9 page=0 chnl=0 +char id=231 x=160 y=14 width=4 height=7 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=232 x=408 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=233 x=360 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=234 x=429 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=235 x=422 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=236 x=349 y=2 width=3 height=8 xoffset=-2 yoffset=3 xadvance=3 page=0 chnl=0 +char id=237 x=344 y=2 width=3 height=8 xoffset=-1 yoffset=3 xadvance=3 page=0 chnl=0 +char id=238 x=408 y=14 width=4 height=7 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=239 x=402 y=14 width=4 height=7 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=240 x=337 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=241 x=119 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=242 x=394 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=243 x=387 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=244 x=443 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=245 x=436 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=246 x=62 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=247 x=194 y=23 width=5 height=4 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=248 x=373 y=2 width=5 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=249 x=380 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=250 x=401 y=2 width=5 height=8 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=251 x=459 y=14 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=252 x=458 y=2 width=5 height=7 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=253 x=32 y=2 width=5 height=10 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=254 x=206 y=2 width=5 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=255 x=173 y=2 width=5 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=8226 x=253 y=23 width=3 height=3 xoffset=0 yoffset=7 xadvance=6 page=0 chnl=0 +char id=8364 x=482 y=14 width=6 height=7 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +kernings count=0 diff --git a/assets/ui/font-subtitle.fnt b/assets/ui/font-subtitle.fnt new file mode 100644 index 0000000..4351cfc --- /dev/null +++ b/assets/ui/font-subtitle.fnt @@ -0,0 +1,198 @@ +info face="font-subtitle" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0 +common lineHeight=18 base=13 scaleW=505 scaleH=36 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0 +page id=0 file="font-subtitle.png" +chars count=193 +char id=0 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=13 xadvance=3 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=0 +char id=33 x=9 y=27 width=1 height=8 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=34 x=351 y=27 width=4 height=3 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=35 x=46 y=27 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=36 x=7 y=2 width=6 height=12 xoffset=-1 yoffset=3 xadvance=7 page=0 chnl=0 +char id=37 x=117 y=16 width=7 height=9 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=38 x=28 y=27 width=8 height=8 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=39 x=370 y=27 width=2 height=3 xoffset=-1 yoffset=5 xadvance=2 page=0 chnl=0 +char id=40 x=39 y=2 width=3 height=11 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=41 x=44 y=2 width=3 height=11 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=42 x=270 y=27 width=5 height=5 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=43 x=164 y=27 width=7 height=6 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=44 x=379 y=27 width=2 height=3 xoffset=-1 yoffset=11 xadvance=2 page=0 chnl=0 +char id=45 x=410 y=27 width=5 height=1 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=0 +char id=46 x=436 y=27 width=2 height=1 xoffset=-1 yoffset=12 xadvance=2 page=0 chnl=0 +char id=47 x=341 y=2 width=5 height=10 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=48 x=0 y=27 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=49 x=441 y=16 width=4 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=50 x=447 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=51 x=455 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=52 x=463 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=53 x=472 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=54 x=480 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=55 x=55 y=16 width=5 height=9 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=56 x=489 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=57 x=498 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=58 x=277 y=27 width=2 height=5 xoffset=-1 yoffset=8 xadvance=2 page=0 chnl=0 +char id=59 x=112 y=27 width=2 height=7 xoffset=-1 yoffset=8 xadvance=3 page=0 chnl=0 +char id=60 x=148 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=61 x=362 y=27 width=6 height=3 xoffset=-1 yoffset=9 xadvance=7 page=0 chnl=0 +char id=62 x=139 y=27 width=7 height=6 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=63 x=12 y=27 width=5 height=8 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 +char id=64 x=348 y=2 width=12 height=10 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=0 +char id=65 x=145 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=66 x=154 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=67 x=162 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=68 x=171 y=16 width=7 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=69 x=180 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=70 x=188 y=16 width=5 height=8 xoffset=0 yoffset=5 xadvance=6 page=0 chnl=0 +char id=71 x=212 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=72 x=228 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=73 x=236 y=16 width=1 height=8 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=74 x=379 y=2 width=3 height=9 xoffset=-1 yoffset=5 xadvance=3 page=0 chnl=0 +char id=75 x=249 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=76 x=257 y=16 width=5 height=8 xoffset=0 yoffset=5 xadvance=6 page=0 chnl=0 +char id=77 x=264 y=16 width=8 height=8 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=78 x=274 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=79 x=282 y=16 width=8 height=8 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=80 x=292 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=81 x=323 y=2 width=8 height=10 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=82 x=300 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=83 x=308 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=84 x=316 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=85 x=325 y=16 width=6 height=8 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=86 x=333 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=87 x=342 y=16 width=10 height=8 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=0 +char id=88 x=354 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=89 x=363 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=90 x=372 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=91 x=49 y=2 width=3 height=11 xoffset=0 yoffset=4 xadvance=4 page=0 chnl=0 +char id=92 x=102 y=16 width=5 height=9 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=93 x=54 y=2 width=3 height=11 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=94 x=310 y=27 width=6 height=4 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=95 x=417 y=27 width=6 height=1 xoffset=0 yoffset=14 xadvance=8 page=0 chnl=0 +char id=96 x=388 y=27 width=3 height=2 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=97 x=124 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=98 x=384 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=99 x=132 y=27 width=5 height=6 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=100 x=392 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=101 x=156 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=102 x=400 y=2 width=4 height=9 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=103 x=414 y=2 width=6 height=9 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=104 x=453 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=105 x=416 y=16 width=2 height=8 xoffset=-1 yoffset=5 xadvance=2 page=0 chnl=0 +char id=106 x=34 y=2 width=3 height=11 xoffset=-2 yoffset=5 xadvance=2 page=0 chnl=0 +char id=107 x=494 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 +char id=108 x=502 y=2 width=1 height=9 xoffset=0 yoffset=4 xadvance=2 page=0 chnl=0 +char id=109 x=185 y=27 width=10 height=6 xoffset=-1 yoffset=7 xadvance=10 page=0 chnl=0 +char id=110 x=197 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=111 x=205 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=112 x=31 y=16 width=6 height=9 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=113 x=39 y=16 width=6 height=9 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=114 x=106 y=27 width=4 height=7 xoffset=-1 yoffset=6 xadvance=4 page=0 chnl=0 +char id=115 x=213 y=27 width=5 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=116 x=434 y=16 width=5 height=8 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=117 x=220 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=118 x=228 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=119 x=236 y=27 width=9 height=6 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=0 +char id=120 x=247 y=27 width=5 height=6 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=121 x=47 y=16 width=6 height=9 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=0 +char id=122 x=254 y=27 width=5 height=6 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=123 x=59 y=2 width=4 height=11 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=124 x=4 y=2 width=1 height=12 xoffset=0 yoffset=4 xadvance=2 page=0 chnl=0 +char id=125 x=65 y=2 width=4 height=11 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=126 x=393 y=27 width=6 height=2 xoffset=-1 yoffset=9 xadvance=7 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=13 xadvance=3 page=0 chnl=0 +char id=161 x=126 y=16 width=2 height=9 xoffset=-1 yoffset=7 xadvance=2 page=0 chnl=0 +char id=162 x=130 y=16 width=5 height=9 xoffset=0 yoffset=6 xadvance=7 page=0 chnl=0 +char id=163 x=221 y=16 width=5 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=164 x=89 y=27 width=6 height=7 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=165 x=203 y=16 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=166 x=15 y=2 width=1 height=12 xoffset=0 yoffset=4 xadvance=3 page=0 chnl=0 +char id=167 x=362 y=2 width=6 height=10 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=168 x=425 y=27 width=3 height=1 xoffset=-1 yoffset=5 xadvance=3 page=0 chnl=0 +char id=169 x=80 y=27 width=7 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=170 x=298 y=27 width=4 height=4 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=171 x=290 y=27 width=6 height=4 xoffset=-1 yoffset=8 xadvance=6 page=0 chnl=0 +char id=172 x=338 y=27 width=6 height=3 xoffset=-1 yoffset=9 xadvance=7 page=0 chnl=0 +char id=174 x=97 y=27 width=7 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=175 x=430 y=27 width=4 height=1 xoffset=-2 yoffset=5 xadvance=3 page=0 chnl=0 +char id=176 x=304 y=27 width=4 height=4 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=177 x=281 y=27 width=7 height=5 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=178 x=383 y=27 width=3 height=3 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=179 x=346 y=27 width=3 height=3 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=180 x=401 y=27 width=3 height=2 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=181 x=78 y=16 width=5 height=9 xoffset=0 yoffset=7 xadvance=7 page=0 chnl=0 +char id=182 x=19 y=27 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=183 x=406 y=27 width=2 height=1 xoffset=-1 yoffset=9 xadvance=2 page=0 chnl=0 +char id=184 x=357 y=27 width=3 height=3 xoffset=-1 yoffset=13 xadvance=3 page=0 chnl=0 +char id=185 x=374 y=27 width=3 height=3 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=186 x=332 y=27 width=4 height=4 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=187 x=324 y=27 width=6 height=4 xoffset=-1 yoffset=8 xadvance=6 page=0 chnl=0 +char id=188 x=79 y=2 width=6 height=11 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=189 x=87 y=2 width=6 height=11 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=0 +char id=190 x=95 y=2 width=7 height=11 xoffset=-1 yoffset=3 xadvance=7 page=0 chnl=0 +char id=191 x=8 y=16 width=5 height=9 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=192 x=104 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=193 x=113 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=194 x=122 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=195 x=131 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=196 x=140 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 +char id=197 x=370 y=2 width=7 height=10 xoffset=-1 yoffset=3 xadvance=7 page=0 chnl=0 +char id=198 x=404 y=16 width=10 height=8 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=0 +char id=199 x=149 y=2 width=7 height=11 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=200 x=158 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 +char id=201 x=166 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 +char id=202 x=174 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 +char id=203 x=182 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 +char id=204 x=190 y=2 width=4 height=11 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=205 x=196 y=2 width=3 height=11 xoffset=-1 yoffset=2 xadvance=3 page=0 chnl=0 +char id=206 x=201 y=2 width=5 height=11 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=207 x=208 y=2 width=4 height=11 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=208 x=239 y=16 width=8 height=8 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=209 x=214 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=210 x=222 y=2 width=8 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=211 x=232 y=2 width=8 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=212 x=242 y=2 width=8 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=213 x=252 y=2 width=8 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=214 x=262 y=2 width=8 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=215 x=116 y=27 width=6 height=6 xoffset=-1 yoffset=7 xadvance=7 page=0 chnl=0 +char id=216 x=313 y=2 width=8 height=11 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=217 x=305 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=218 x=297 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=219 x=289 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=220 x=281 y=2 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=221 x=272 y=2 width=7 height=11 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 +char id=222 x=38 y=27 width=6 height=8 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=223 x=85 y=16 width=7 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=224 x=94 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=225 x=137 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=226 x=469 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=227 x=380 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=228 x=388 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=229 x=406 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=230 x=173 y=27 width=10 height=6 xoffset=-1 yoffset=7 xadvance=10 page=0 chnl=0 +char id=231 x=422 y=2 width=5 height=9 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=232 x=429 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=233 x=437 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=234 x=445 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=235 x=396 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=236 x=477 y=2 width=3 height=9 xoffset=-2 yoffset=4 xadvance=2 page=0 chnl=0 +char id=237 x=482 y=2 width=4 height=9 xoffset=-1 yoffset=4 xadvance=2 page=0 chnl=0 +char id=238 x=488 y=2 width=4 height=9 xoffset=-2 yoffset=4 xadvance=2 page=0 chnl=0 +char id=239 x=420 y=16 width=4 height=8 xoffset=-2 yoffset=5 xadvance=2 page=0 chnl=0 +char id=240 x=0 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=241 x=426 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=242 x=15 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=243 x=23 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=244 x=109 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=245 x=63 y=27 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=246 x=55 y=27 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=247 x=261 y=27 width=7 height=5 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=248 x=333 y=2 width=6 height=10 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=249 x=70 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=250 x=62 y=16 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=251 x=461 y=2 width=6 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=252 x=195 y=16 width=6 height=8 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=253 x=26 y=2 width=6 height=12 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=254 x=18 y=2 width=6 height=12 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=255 x=71 y=2 width=6 height=11 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=8226 x=318 y=27 width=4 height=4 xoffset=0 yoffset=8 xadvance=6 page=0 chnl=0 +char id=8364 x=71 y=27 width=7 height=8 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +kernings count=0 diff --git a/assets/ui/font-window.fnt b/assets/ui/font-window.fnt new file mode 100644 index 0000000..763811f --- /dev/null +++ b/assets/ui/font-window.fnt @@ -0,0 +1,198 @@ +info face="font-window" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0 +common lineHeight=27 base=20 scaleW=506 scaleH=62 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0 +page id=0 file="font-window.png" +chars count=193 +char id=0 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=20 xadvance=4 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=-1 xadvance=4 page=0 chnl=0 +char id=33 x=276 y=38 width=2 height=12 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=34 x=293 y=52 width=5 height=4 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=35 x=370 y=38 width=10 height=12 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=36 x=175 y=2 width=8 height=16 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=37 x=62 y=22 width=10 height=14 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=0 +char id=38 x=343 y=38 width=13 height=12 xoffset=0 yoffset=8 xadvance=13 page=0 chnl=0 +char id=39 x=306 y=52 width=2 height=4 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=40 x=392 y=2 width=4 height=15 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=0 +char id=41 x=398 y=2 width=4 height=15 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 +char id=42 x=172 y=52 width=7 height=8 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=43 x=465 y=38 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=44 x=300 y=52 width=4 height=4 xoffset=-1 yoffset=18 xadvance=5 page=0 chnl=0 +char id=45 x=359 y=52 width=5 height=2 xoffset=0 yoffset=14 xadvance=7 page=0 chnl=0 +char id=46 x=330 y=52 width=2 height=3 xoffset=0 yoffset=17 xadvance=4 page=0 chnl=0 +char id=47 x=0 y=22 width=8 height=14 xoffset=-1 yoffset=7 xadvance=8 page=0 chnl=0 +char id=48 x=265 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=49 x=174 y=38 width=6 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=50 x=182 y=38 width=7 height=12 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=51 x=191 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=52 x=201 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=53 x=212 y=38 width=9 height=12 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=0 +char id=54 x=223 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=55 x=234 y=38 width=7 height=12 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=56 x=243 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=57 x=254 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=58 x=192 y=52 width=2 height=8 xoffset=0 yoffset=12 xadvance=4 page=0 chnl=0 +char id=59 x=444 y=38 width=4 height=10 xoffset=-1 yoffset=12 xadvance=4 page=0 chnl=0 +char id=60 x=0 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=61 x=204 y=52 width=8 height=6 xoffset=0 yoffset=12 xadvance=10 page=0 chnl=0 +char id=62 x=495 y=38 width=8 height=9 xoffset=1 yoffset=11 xadvance=11 page=0 chnl=0 +char id=63 x=280 y=38 width=7 height=12 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=0 +char id=64 x=157 y=2 width=16 height=16 xoffset=0 yoffset=8 xadvance=18 page=0 chnl=0 +char id=65 x=303 y=22 width=11 height=12 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=0 +char id=66 x=316 y=22 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=67 x=326 y=22 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=68 x=336 y=22 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=69 x=347 y=22 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=70 x=357 y=22 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=71 x=367 y=22 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=72 x=378 y=22 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=73 x=389 y=22 width=2 height=12 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=74 x=122 y=22 width=4 height=13 xoffset=-1 yoffset=8 xadvance=5 page=0 chnl=0 +char id=75 x=393 y=22 width=9 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=76 x=404 y=22 width=7 height=12 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=77 x=413 y=22 width=13 height=12 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=78 x=440 y=22 width=10 height=12 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=79 x=462 y=22 width=10 height=12 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=80 x=478 y=22 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=81 x=380 y=2 width=10 height=15 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=82 x=0 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=83 x=11 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=84 x=21 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=85 x=32 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=86 x=43 y=38 width=11 height=12 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=0 +char id=87 x=56 y=38 width=17 height=12 xoffset=-1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=88 x=75 y=38 width=11 height=12 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=0 +char id=89 x=88 y=38 width=10 height=12 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=0 +char id=90 x=100 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=91 x=404 y=2 width=5 height=15 xoffset=0 yoffset=7 xadvance=6 page=0 chnl=0 +char id=92 x=10 y=22 width=9 height=14 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=0 +char id=93 x=411 y=2 width=4 height=15 xoffset=0 yoffset=7 xadvance=6 page=0 chnl=0 +char id=94 x=222 y=52 width=10 height=6 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=0 +char id=95 x=349 y=52 width=8 height=2 xoffset=1 yoffset=21 xadvance=12 page=0 chnl=0 +char id=96 x=279 y=52 width=6 height=5 xoffset=-2 yoffset=6 xadvance=5 page=0 chnl=0 +char id=97 x=32 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=98 x=110 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=99 x=42 y=52 width=7 height=9 xoffset=0 yoffset=11 xadvance=8 page=0 chnl=0 +char id=100 x=120 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=101 x=51 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=102 x=130 y=38 width=6 height=12 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=103 x=158 y=22 width=8 height=13 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=104 x=138 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=105 x=148 y=38 width=2 height=12 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=106 x=147 y=2 width=4 height=16 xoffset=-2 yoffset=8 xadvance=4 page=0 chnl=0 +char id=107 x=152 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=108 x=162 y=38 width=2 height=12 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=109 x=61 y=52 width=12 height=9 xoffset=0 yoffset=11 xadvance=14 page=0 chnl=0 +char id=110 x=75 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=111 x=85 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=112 x=215 y=22 width=8 height=13 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=113 x=225 y=22 width=8 height=13 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=114 x=436 y=38 width=6 height=10 xoffset=0 yoffset=10 xadvance=7 page=0 chnl=0 +char id=115 x=95 y=52 width=7 height=9 xoffset=0 yoffset=11 xadvance=9 page=0 chnl=0 +char id=116 x=166 y=38 width=6 height=12 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=117 x=104 y=52 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=118 x=114 y=52 width=9 height=9 xoffset=-1 yoffset=11 xadvance=9 page=0 chnl=0 +char id=119 x=125 y=52 width=14 height=9 xoffset=-1 yoffset=11 xadvance=14 page=0 chnl=0 +char id=120 x=141 y=52 width=9 height=9 xoffset=-1 yoffset=11 xadvance=9 page=0 chnl=0 +char id=121 x=235 y=22 width=9 height=13 xoffset=-1 yoffset=11 xadvance=9 page=0 chnl=0 +char id=122 x=152 y=52 width=7 height=9 xoffset=0 yoffset=11 xadvance=9 page=0 chnl=0 +char id=123 x=417 y=2 width=6 height=15 xoffset=0 yoffset=7 xadvance=7 page=0 chnl=0 +char id=124 x=153 y=2 width=2 height=16 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=125 x=425 y=2 width=6 height=15 xoffset=0 yoffset=7 xadvance=7 page=0 chnl=0 +char id=126 x=320 y=52 width=8 height=3 xoffset=0 yoffset=14 xadvance=10 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=20 xadvance=4 page=0 chnl=0 +char id=161 x=474 y=22 width=2 height=12 xoffset=0 yoffset=11 xadvance=4 page=0 chnl=0 +char id=162 x=403 y=38 width=7 height=11 xoffset=1 yoffset=10 xadvance=10 page=0 chnl=0 +char id=163 x=452 y=22 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=164 x=21 y=52 width=9 height=9 xoffset=-1 yoffset=11 xadvance=9 page=0 chnl=0 +char id=165 x=428 y=22 width=10 height=12 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=0 +char id=166 x=185 y=2 width=2 height=16 xoffset=0 yoffset=8 xadvance=4 page=0 chnl=0 +char id=167 x=433 y=2 width=8 height=15 xoffset=0 yoffset=9 xadvance=10 page=0 chnl=0 +char id=168 x=341 y=52 width=6 height=2 xoffset=-1 yoffset=8 xadvance=5 page=0 chnl=0 +char id=169 x=424 y=38 width=10 height=10 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=0 +char id=170 x=250 y=52 width=6 height=5 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=171 x=161 y=52 width=9 height=8 xoffset=0 yoffset=12 xadvance=11 page=0 chnl=0 +char id=172 x=240 y=52 width=8 height=5 xoffset=0 yoffset=14 xadvance=10 page=0 chnl=0 +char id=174 x=412 y=38 width=10 height=10 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=0 +char id=175 x=334 y=52 width=5 height=2 xoffset=-1 yoffset=8 xadvance=5 page=0 chnl=0 +char id=176 x=196 y=52 width=6 height=6 xoffset=1 yoffset=7 xadvance=10 page=0 chnl=0 +char id=177 x=485 y=38 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=178 x=265 y=52 width=4 height=5 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=0 +char id=179 x=234 y=52 width=4 height=5 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=0 +char id=180 x=271 y=52 width=6 height=5 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=181 x=266 y=22 width=8 height=13 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=182 x=321 y=38 width=10 height=12 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=0 +char id=183 x=316 y=52 width=2 height=3 xoffset=0 yoffset=14 xadvance=4 page=0 chnl=0 +char id=184 x=310 y=52 width=4 height=4 xoffset=-1 yoffset=20 xadvance=5 page=0 chnl=0 +char id=185 x=287 y=52 width=4 height=5 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=186 x=214 y=52 width=6 height=6 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=187 x=181 y=52 width=9 height=8 xoffset=0 yoffset=12 xadvance=11 page=0 chnl=0 +char id=188 x=443 y=2 width=9 height=15 xoffset=-1 yoffset=7 xadvance=10 page=0 chnl=0 +char id=189 x=454 y=2 width=9 height=15 xoffset=-1 yoffset=7 xadvance=10 page=0 chnl=0 +char id=190 x=189 y=2 width=9 height=16 xoffset=-1 yoffset=6 xadvance=10 page=0 chnl=0 +char id=191 x=168 y=22 width=7 height=13 xoffset=0 yoffset=11 xadvance=8 page=0 chnl=0 +char id=192 x=27 y=2 width=11 height=17 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=193 x=40 y=2 width=11 height=17 xoffset=-1 yoffset=3 xadvance=11 page=0 chnl=0 +char id=194 x=222 y=2 width=11 height=16 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=0 +char id=195 x=235 y=2 width=11 height=16 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=0 +char id=196 x=248 y=2 width=12 height=16 xoffset=-2 yoffset=4 xadvance=10 page=0 chnl=0 +char id=197 x=465 y=2 width=12 height=15 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=0 +char id=198 x=489 y=22 width=15 height=12 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=199 x=262 y=2 width=8 height=16 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=200 x=53 y=2 width=8 height=17 xoffset=0 yoffset=3 xadvance=10 page=0 chnl=0 +char id=201 x=63 y=2 width=8 height=17 xoffset=0 yoffset=3 xadvance=10 page=0 chnl=0 +char id=202 x=272 y=2 width=8 height=16 xoffset=0 yoffset=4 xadvance=10 page=0 chnl=0 +char id=203 x=282 y=2 width=8 height=16 xoffset=0 yoffset=4 xadvance=10 page=0 chnl=0 +char id=204 x=73 y=2 width=6 height=17 xoffset=-2 yoffset=3 xadvance=4 page=0 chnl=0 +char id=205 x=81 y=2 width=6 height=17 xoffset=-2 yoffset=3 xadvance=4 page=0 chnl=0 +char id=206 x=292 y=2 width=8 height=16 xoffset=-3 yoffset=4 xadvance=4 page=0 chnl=0 +char id=207 x=302 y=2 width=6 height=16 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 +char id=208 x=358 y=38 width=10 height=12 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=209 x=310 y=2 width=10 height=16 xoffset=0 yoffset=4 xadvance=12 page=0 chnl=0 +char id=210 x=89 y=2 width=10 height=17 xoffset=0 yoffset=3 xadvance=12 page=0 chnl=0 +char id=211 x=101 y=2 width=10 height=17 xoffset=0 yoffset=3 xadvance=12 page=0 chnl=0 +char id=212 x=322 y=2 width=10 height=16 xoffset=0 yoffset=4 xadvance=12 page=0 chnl=0 +char id=213 x=334 y=2 width=10 height=16 xoffset=0 yoffset=4 xadvance=12 page=0 chnl=0 +char id=214 x=346 y=2 width=10 height=16 xoffset=0 yoffset=4 xadvance=12 page=0 chnl=0 +char id=215 x=10 y=52 width=9 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=216 x=4 y=2 width=10 height=18 xoffset=0 yoffset=5 xadvance=12 page=0 chnl=0 +char id=217 x=113 y=2 width=9 height=17 xoffset=0 yoffset=3 xadvance=11 page=0 chnl=0 +char id=218 x=124 y=2 width=9 height=17 xoffset=0 yoffset=3 xadvance=11 page=0 chnl=0 +char id=219 x=358 y=2 width=9 height=16 xoffset=0 yoffset=4 xadvance=11 page=0 chnl=0 +char id=220 x=369 y=2 width=9 height=16 xoffset=0 yoffset=4 xadvance=11 page=0 chnl=0 +char id=221 x=135 y=2 width=10 height=17 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=0 +char id=222 x=289 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=223 x=300 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=224 x=74 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=225 x=84 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=226 x=185 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=227 x=333 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=228 x=256 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=229 x=32 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=230 x=450 y=38 width=13 height=9 xoffset=0 yoffset=11 xadvance=15 page=0 chnl=0 +char id=231 x=276 y=22 width=7 height=13 xoffset=0 yoffset=11 xadvance=8 page=0 chnl=0 +char id=232 x=94 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=233 x=112 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=234 x=128 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=235 x=138 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=236 x=104 y=22 width=6 height=14 xoffset=-3 yoffset=6 xadvance=4 page=0 chnl=0 +char id=237 x=499 y=2 width=6 height=14 xoffset=-1 yoffset=6 xadvance=4 page=0 chnl=0 +char id=238 x=177 y=22 width=6 height=13 xoffset=-2 yoffset=7 xadvance=4 page=0 chnl=0 +char id=239 x=285 y=22 width=6 height=13 xoffset=-2 yoffset=7 xadvance=4 page=0 chnl=0 +char id=240 x=21 y=22 width=9 height=14 xoffset=0 yoffset=6 xadvance=11 page=0 chnl=0 +char id=241 x=382 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=242 x=489 y=2 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=243 x=479 y=2 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=244 x=148 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=245 x=311 y=38 width=8 height=12 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=246 x=246 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=247 x=475 y=38 width=8 height=9 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=0 +char id=248 x=205 y=22 width=8 height=13 xoffset=0 yoffset=9 xadvance=10 page=0 chnl=0 +char id=249 x=42 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=250 x=52 y=22 width=8 height=14 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=0 +char id=251 x=293 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=252 x=195 y=22 width=8 height=13 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=0 +char id=253 x=16 y=2 width=9 height=18 xoffset=-1 yoffset=6 xadvance=9 page=0 chnl=0 +char id=254 x=200 y=2 width=8 height=16 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=255 x=210 y=2 width=10 height=16 xoffset=-2 yoffset=8 xadvance=8 page=0 chnl=0 +char id=8226 x=258 y=52 width=5 height=5 xoffset=1 yoffset=13 xadvance=9 page=0 chnl=0 +char id=8364 x=392 y=38 width=9 height=12 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +kernings count=0 diff --git a/assets/ui/font.fnt b/assets/ui/font.fnt new file mode 100644 index 0000000..5fc7350 --- /dev/null +++ b/assets/ui/font.fnt @@ -0,0 +1,198 @@ +info face="font" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0 +common lineHeight=21 base=15 scaleW=504 scaleH=44 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0 +page id=0 file="font.png" +chars count=193 +char id=0 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=15 xadvance=3 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=0 +char id=33 x=393 y=18 width=1 height=10 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=34 x=458 y=30 width=3 height=3 xoffset=0 yoffset=5 xadvance=5 page=0 chnl=0 +char id=35 x=101 y=30 width=8 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=36 x=142 y=2 width=6 height=13 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=37 x=496 y=18 width=7 height=10 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=38 x=0 y=30 width=9 height=10 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=39 x=463 y=30 width=1 height=3 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=40 x=272 y=2 width=3 height=12 xoffset=0 yoffset=5 xadvance=4 page=0 chnl=0 +char id=41 x=277 y=2 width=3 height=12 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=42 x=369 y=30 width=6 height=5 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=43 x=315 y=30 width=7 height=7 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=44 x=435 y=30 width=3 height=3 xoffset=-1 yoffset=14 xadvance=3 page=0 chnl=0 +char id=45 x=497 y=30 width=5 height=1 xoffset=0 yoffset=11 xadvance=6 page=0 chnl=0 +char id=46 x=466 y=30 width=1 height=2 xoffset=0 yoffset=13 xadvance=3 page=0 chnl=0 +char id=47 x=446 y=2 width=6 height=11 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=48 x=120 y=30 width=7 height=9 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=0 +char id=49 x=41 y=30 width=4 height=9 xoffset=0 yoffset=6 xadvance=7 page=0 chnl=0 +char id=50 x=47 y=30 width=7 height=9 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 +char id=51 x=56 y=30 width=6 height=9 xoffset=0 yoffset=6 xadvance=8 page=0 chnl=0 +char id=52 x=64 y=30 width=8 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=53 x=74 y=30 width=7 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=54 x=83 y=30 width=7 height=9 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=0 +char id=55 x=385 y=18 width=6 height=10 xoffset=0 yoffset=6 xadvance=8 page=0 chnl=0 +char id=56 x=92 y=30 width=7 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=57 x=111 y=30 width=7 height=9 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=0 +char id=58 x=333 y=30 width=1 height=6 xoffset=0 yoffset=9 xadvance=3 page=0 chnl=0 +char id=59 x=164 y=30 width=3 height=8 xoffset=-1 yoffset=9 xadvance=3 page=0 chnl=0 +char id=60 x=214 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=61 x=449 y=30 width=7 height=3 xoffset=-1 yoffset=10 xadvance=8 page=0 chnl=0 +char id=62 x=206 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=63 x=396 y=18 width=6 height=10 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=64 x=128 y=2 width=12 height=13 xoffset=0 yoffset=5 xadvance=14 page=0 chnl=0 +char id=65 x=0 y=18 width=8 height=10 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=66 x=18 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=67 x=27 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=68 x=67 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=69 x=76 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=70 x=84 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=71 x=92 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=72 x=101 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=73 x=128 y=18 width=1 height=10 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=74 x=379 y=2 width=3 height=11 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=75 x=131 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=76 x=140 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=77 x=148 y=18 width=9 height=10 xoffset=0 yoffset=5 xadvance=11 page=0 chnl=0 +char id=78 x=159 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=79 x=168 y=18 width=8 height=10 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=80 x=178 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=81 x=262 y=2 width=8 height=12 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=82 x=195 y=18 width=8 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=83 x=205 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=84 x=213 y=18 width=7 height=10 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 +char id=85 x=222 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=86 x=231 y=18 width=8 height=10 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=87 x=241 y=18 width=12 height=10 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=0 +char id=88 x=260 y=18 width=8 height=10 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=89 x=270 y=18 width=9 height=10 xoffset=-2 yoffset=5 xadvance=7 page=0 chnl=0 +char id=90 x=281 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=91 x=282 y=2 width=3 height=12 xoffset=0 yoffset=5 xadvance=4 page=0 chnl=0 +char id=92 x=462 y=2 width=6 height=11 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=0 +char id=93 x=287 y=2 width=3 height=12 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=94 x=360 y=30 width=7 height=5 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=95 x=481 y=30 width=7 height=1 xoffset=0 yoffset=16 xadvance=9 page=0 chnl=0 +char id=96 x=423 y=30 width=4 height=3 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=97 x=198 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=98 x=296 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=99 x=222 y=30 width=5 height=7 xoffset=0 yoffset=8 xadvance=6 page=0 chnl=0 +char id=100 x=304 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=101 x=229 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=102 x=312 y=18 width=5 height=10 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=103 x=319 y=18 width=7 height=10 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=104 x=328 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=105 x=336 y=18 width=1 height=10 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=106 x=120 y=2 width=3 height=13 xoffset=-2 yoffset=5 xadvance=3 page=0 chnl=0 +char id=107 x=349 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=108 x=357 y=18 width=1 height=10 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=109 x=237 y=30 width=9 height=7 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=110 x=248 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=111 x=256 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=112 x=360 y=18 width=6 height=10 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=113 x=368 y=18 width=6 height=10 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=114 x=158 y=30 width=4 height=8 xoffset=0 yoffset=7 xadvance=5 page=0 chnl=0 +char id=115 x=264 y=30 width=5 height=7 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=116 x=34 y=30 width=5 height=9 xoffset=-1 yoffset=6 xadvance=5 page=0 chnl=0 +char id=117 x=271 y=30 width=5 height=7 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=118 x=278 y=30 width=7 height=7 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=119 x=287 y=30 width=11 height=7 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=0 +char id=120 x=300 y=30 width=6 height=7 xoffset=-1 yoffset=8 xadvance=6 page=0 chnl=0 +char id=121 x=376 y=18 width=7 height=10 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=122 x=308 y=30 width=5 height=7 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=123 x=292 y=2 width=5 height=12 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 +char id=124 x=125 y=2 width=1 height=13 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=125 x=299 y=2 width=5 height=12 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 +char id=126 x=469 y=30 width=7 height=2 xoffset=-1 yoffset=10 xadvance=8 page=0 chnl=0 +char id=160 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=15 xadvance=3 page=0 chnl=0 +char id=161 x=31 y=30 width=1 height=9 xoffset=0 yoffset=8 xadvance=3 page=0 chnl=0 +char id=162 x=289 y=18 width=5 height=10 xoffset=0 yoffset=7 xadvance=7 page=0 chnl=0 +char id=163 x=22 y=30 width=7 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +char id=164 x=189 y=30 width=7 height=7 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=165 x=11 y=30 width=9 height=9 xoffset=-2 yoffset=6 xadvance=7 page=0 chnl=0 +char id=166 x=150 y=2 width=1 height=13 xoffset=0 yoffset=5 xadvance=3 page=0 chnl=0 +char id=167 x=486 y=2 width=5 height=11 xoffset=0 yoffset=6 xadvance=7 page=0 chnl=0 +char id=168 x=0 y=42 width=4 height=1 xoffset=-1 yoffset=5 xadvance=4 page=0 chnl=0 +char id=169 x=148 y=30 width=8 height=8 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=170 x=416 y=30 width=5 height=4 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=0 +char id=171 x=352 y=30 width=6 height=5 xoffset=0 yoffset=9 xadvance=7 page=0 chnl=0 +char id=172 x=440 y=30 width=7 height=3 xoffset=-1 yoffset=10 xadvance=8 page=0 chnl=0 +char id=174 x=138 y=30 width=8 height=8 xoffset=0 yoffset=5 xadvance=10 page=0 chnl=0 +char id=175 x=490 y=30 width=5 height=1 xoffset=-2 yoffset=6 xadvance=3 page=0 chnl=0 +char id=176 x=410 y=30 width=4 height=4 xoffset=1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=177 x=324 y=30 width=7 height=6 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=178 x=405 y=30 width=3 height=4 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=179 x=399 y=30 width=4 height=4 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=180 x=429 y=30 width=4 height=3 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=181 x=121 y=18 width=5 height=10 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=0 +char id=182 x=110 y=18 width=9 height=10 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=0 +char id=183 x=478 y=30 width=1 height=2 xoffset=0 yoffset=10 xadvance=3 page=0 chnl=0 +char id=184 x=394 y=30 width=3 height=4 xoffset=-1 yoffset=14 xadvance=4 page=0 chnl=0 +char id=185 x=389 y=30 width=3 height=4 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 +char id=186 x=383 y=30 width=4 height=4 xoffset=0 yoffset=6 xadvance=6 page=0 chnl=0 +char id=187 x=344 y=30 width=6 height=5 xoffset=0 yoffset=9 xadvance=7 page=0 chnl=0 +char id=188 x=315 y=2 width=8 height=12 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 +char id=189 x=325 y=2 width=7 height=12 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 +char id=190 x=153 y=2 width=8 height=13 xoffset=-1 yoffset=3 xadvance=8 page=0 chnl=0 +char id=191 x=36 y=18 width=6 height=10 xoffset=-1 yoffset=8 xadvance=6 page=0 chnl=0 +char id=192 x=4 y=2 width=8 height=14 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 +char id=193 x=14 y=2 width=8 height=14 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 +char id=194 x=173 y=2 width=8 height=13 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=195 x=183 y=2 width=8 height=13 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 +char id=196 x=334 y=2 width=8 height=12 xoffset=-1 yoffset=3 xadvance=8 page=0 chnl=0 +char id=197 x=344 y=2 width=9 height=12 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=0 +char id=198 x=482 y=18 width=12 height=10 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=0 +char id=199 x=193 y=2 width=6 height=13 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=200 x=24 y=2 width=6 height=14 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 +char id=201 x=32 y=2 width=6 height=14 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 +char id=202 x=209 y=2 width=6 height=13 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 +char id=203 x=355 y=2 width=7 height=12 xoffset=0 yoffset=3 xadvance=8 page=0 chnl=0 +char id=204 x=49 y=2 width=4 height=14 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 +char id=205 x=55 y=2 width=4 height=14 xoffset=-1 yoffset=1 xadvance=3 page=0 chnl=0 +char id=206 x=217 y=2 width=5 height=13 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 +char id=207 x=374 y=2 width=3 height=12 xoffset=-1 yoffset=3 xadvance=3 page=0 chnl=0 +char id=208 x=339 y=18 width=8 height=10 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=0 +char id=209 x=224 y=2 width=7 height=13 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 +char id=210 x=61 y=2 width=8 height=14 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=0 +char id=211 x=71 y=2 width=8 height=14 xoffset=0 yoffset=1 xadvance=10 page=0 chnl=0 +char id=212 x=233 y=2 width=8 height=13 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 +char id=213 x=243 y=2 width=8 height=13 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 +char id=214 x=364 y=2 width=8 height=12 xoffset=0 yoffset=3 xadvance=10 page=0 chnl=0 +char id=215 x=181 y=30 width=6 height=7 xoffset=0 yoffset=8 xadvance=8 page=0 chnl=0 +char id=216 x=81 y=2 width=8 height=14 xoffset=0 yoffset=3 xadvance=10 page=0 chnl=0 +char id=217 x=91 y=2 width=7 height=14 xoffset=0 yoffset=1 xadvance=9 page=0 chnl=0 +char id=218 x=100 y=2 width=7 height=14 xoffset=0 yoffset=1 xadvance=9 page=0 chnl=0 +char id=219 x=253 y=2 width=7 height=13 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 +char id=220 x=306 y=2 width=7 height=12 xoffset=0 yoffset=3 xadvance=9 page=0 chnl=0 +char id=221 x=109 y=2 width=9 height=14 xoffset=-2 yoffset=1 xadvance=7 page=0 chnl=0 +char id=222 x=426 y=18 width=7 height=10 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=0 +char id=223 x=418 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=224 x=423 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=225 x=407 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=226 x=187 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=227 x=443 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=228 x=451 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=229 x=415 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=230 x=169 y=30 width=10 height=7 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=231 x=404 y=18 width=5 height=10 xoffset=0 yoffset=8 xadvance=6 page=0 chnl=0 +char id=232 x=454 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=233 x=470 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=234 x=474 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=235 x=10 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=236 x=499 y=2 width=4 height=11 xoffset=-2 yoffset=4 xadvance=3 page=0 chnl=0 +char id=237 x=493 y=2 width=4 height=11 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 +char id=238 x=44 y=18 width=5 height=10 xoffset=-2 yoffset=5 xadvance=3 page=0 chnl=0 +char id=239 x=255 y=18 width=3 height=10 xoffset=-1 yoffset=5 xadvance=3 page=0 chnl=0 +char id=240 x=478 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=241 x=466 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=242 x=438 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=243 x=399 y=2 width=6 height=11 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 +char id=244 x=435 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=245 x=59 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=246 x=51 y=18 width=6 height=10 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=247 x=336 y=30 width=6 height=5 xoffset=0 yoffset=9 xadvance=8 page=0 chnl=0 +char id=248 x=384 y=2 width=6 height=11 xoffset=0 yoffset=6 xadvance=8 page=0 chnl=0 +char id=249 x=392 y=2 width=5 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=250 x=431 y=2 width=5 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 +char id=251 x=411 y=18 width=5 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=252 x=459 y=18 width=5 height=10 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 +char id=253 x=40 y=2 width=7 height=14 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 +char id=254 x=201 y=2 width=6 height=13 xoffset=0 yoffset=5 xadvance=8 page=0 chnl=0 +char id=255 x=163 y=2 width=8 height=13 xoffset=-2 yoffset=5 xadvance=7 page=0 chnl=0 +char id=8226 x=377 y=30 width=4 height=4 xoffset=1 yoffset=10 xadvance=8 page=0 chnl=0 +char id=8364 x=129 y=30 width=7 height=9 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 +kernings count=0 diff --git a/assets/ui/uiskin.atlas b/assets/ui/uiskin.atlas new file mode 100644 index 0000000..0c6edf5 --- /dev/null +++ b/assets/ui/uiskin.atlas @@ -0,0 +1,380 @@ + +uiskin.png +size: 512,512 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +button-normal + rotate: false + xy: 2, 111 + size: 41, 42 + orig: 41, 42 + offset: 0, 0 + index: -1 +button-normal-over + rotate: false + xy: 102, 263 + size: 41, 42 + orig: 41, 42 + offset: 0, 0 + index: -1 +button-normal-pressed + rotate: false + xy: 2, 67 + size: 41, 42 + orig: 41, 42 + offset: 0, 0 + index: -1 +check + rotate: false + xy: 290, 306 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +check-on + rotate: false + xy: 316, 306 + size: 24, 24 + orig: 24, 24 + offset: 0, 0 + index: -1 +checkbox + rotate: false + xy: 482, 309 + size: 20, 21 + orig: 20, 21 + offset: 0, 0 + index: -1 +checkbox-over + rotate: false + xy: 438, 309 + size: 20, 21 + orig: 20, 21 + offset: 0, 0 + index: -1 +checkbox-selected + rotate: false + xy: 32, 18 + size: 20, 21 + orig: 20, 21 + offset: 0, 0 + index: -1 +checkbox-selected-over + rotate: false + xy: 460, 309 + size: 20, 21 + orig: 20, 21 + offset: 0, 0 + index: -1 +font + rotate: false + xy: 2, 402 + size: 504, 44 + orig: 504, 44 + offset: 0, 0 + index: -1 +font-list + rotate: false + xy: 2, 332 + size: 505, 30 + orig: 505, 30 + offset: 0, 0 + index: -1 +font-subtitle + rotate: false + xy: 2, 364 + size: 505, 36 + orig: 505, 36 + offset: 0, 0 + index: -1 +font-window + rotate: false + xy: 2, 448 + size: 506, 62 + orig: 506, 62 + offset: 0, 0 + index: -1 +knob-h + rotate: false + xy: 188, 268 + size: 24, 1 + orig: 24, 1 + offset: 0, 0 + index: -1 +knob-v + rotate: false + xy: 508, 422 + size: 1, 24 + orig: 1, 24 + offset: 0, 0 + index: -1 +line-h + rotate: false + xy: 102, 260 + size: 24, 1 + orig: 24, 1 + offset: 0, 0 + index: -1 +line-v + rotate: false + xy: 509, 396 + size: 1, 24 + orig: 1, 24 + offset: 0, 0 + index: -1 +list + rotate: false + xy: 188, 271 + size: 43, 34 + orig: 43, 34 + offset: 0, 0 + index: -1 +progress-bar + rotate: false + xy: 2, 307 + size: 252, 5 + orig: 252, 5 + offset: 0, 0 + index: -1 +progress-bar-knob + rotate: false + xy: 2, 314 + size: 252, 5 + orig: 252, 5 + offset: 0, 0 + index: -1 +progress-bar-square + rotate: false + xy: 256, 309 + size: 4, 4 + orig: 4, 4 + offset: 0, 0 + index: -1 +progress-bar-square-knob + rotate: false + xy: 504, 328 + size: 2, 2 + orig: 2, 2 + offset: 0, 0 + index: -1 +radio + rotate: false + xy: 366, 308 + size: 22, 22 + orig: 22, 22 + offset: 0, 0 + index: -1 +radio-over + rotate: false + xy: 390, 308 + size: 22, 22 + orig: 22, 22 + offset: 0, 0 + index: -1 +radio-selected + rotate: false + xy: 342, 308 + size: 22, 22 + orig: 22, 22 + offset: 0, 0 + index: -1 +radio-selected-over + rotate: false + xy: 414, 308 + size: 22, 22 + orig: 22, 22 + offset: 0, 0 + index: -1 +rect + rotate: false + xy: 32, 41 + size: 12, 24 + orig: 12, 24 + offset: 0, 0 + index: -1 +scrollbar + rotate: false + xy: 46, 150 + size: 17, 16 + orig: 17, 16 + offset: 0, 0 + index: -1 +select + rotate: false + xy: 262, 306 + size: 26, 24 + split: 4, 15, 0, 24 + orig: 26, 24 + offset: 0, 0 + index: -1 +select-box + rotate: false + xy: 145, 263 + size: 41, 42 + orig: 41, 42 + offset: 0, 0 + index: -1 +select-box-open + rotate: false + xy: 58, 214 + size: 41, 42 + orig: 41, 42 + offset: 0, 0 + index: -1 +selection + rotate: false + xy: 46, 168 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +slider + rotate: false + xy: 2, 321 + size: 258, 9 + orig: 258, 9 + offset: 0, 0 + index: -1 +slider-knob + rotate: false + xy: 46, 57 + size: 9, 9 + orig: 9, 9 + offset: 0, 0 + index: -1 +slider-knob-over + rotate: false + xy: 46, 46 + size: 9, 9 + orig: 9, 9 + offset: 0, 0 + index: -1 +spinner-down + rotate: false + xy: 45, 100 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +spinner-down-over + rotate: false + xy: 45, 68 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +spinner-down-pressed + rotate: false + xy: 45, 116 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +spinner-textfield + rotate: false + xy: 2, 7 + size: 28, 28 + orig: 28, 28 + offset: 0, 0 + index: -1 +spinner-textfield-selected + rotate: false + xy: 2, 37 + size: 28, 28 + orig: 28, 28 + offset: 0, 0 + index: -1 +spinner-up + rotate: false + xy: 32, 2 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +spinner-up-over + rotate: false + xy: 45, 84 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +spinner-up-pressed + rotate: false + xy: 50, 2 + size: 16, 14 + orig: 16, 14 + offset: 0, 0 + index: -1 +square + rotate: false + xy: 256, 315 + size: 4, 4 + orig: 4, 4 + offset: 0, 0 + index: -1 +textfield + rotate: false + xy: 2, 155 + size: 42, 47 + orig: 42, 47 + offset: 0, 0 + index: -1 +textfield-selected + rotate: false + xy: 58, 258 + size: 42, 47 + orig: 42, 47 + offset: 0, 0 + index: -1 +tree-minus + rotate: false + xy: 46, 186 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +tree-plus + rotate: false + xy: 45, 132 + size: 16, 16 + orig: 16, 16 + offset: 0, 0 + index: -1 +white + rotate: false + xy: 509, 393 + size: 1, 1 + orig: 1, 1 + offset: 0, 0 + index: -1 +dot + rotate: false + xy: 509, 393 + size: 1, 1 + orig: 1, 1 + offset: 0, 0 + index: -1 +window + rotate: false + xy: 2, 204 + size: 54, 101 + orig: 54, 101 + offset: 0, 0 + index: -1 +window-border + rotate: false + xy: 248, 279 + size: 5, 26 + split: 2, 2, 23, 2 + orig: 5, 26 + offset: 0, 0 + index: -1 +window-resize + rotate: false + xy: 233, 271 + size: 13, 34 + split: 2, 10, 23, 10 + orig: 13, 34 + offset: 0, 0 + index: -1 diff --git a/assets/ui/uiskin.json b/assets/ui/uiskin.json new file mode 100644 index 0000000..8658e76 --- /dev/null +++ b/assets/ui/uiskin.json @@ -0,0 +1,438 @@ +{ +com.badlogic.gdx.graphics.g2d.BitmapFont: { + default: { + file: font.fnt + } + font: { + file: font.fnt + } + list: { + file: font-list.fnt + } + subtitle: { + file: font-subtitle.fnt + } + window: { + file: font-window.fnt + } +} +com.badlogic.gdx.graphics.Color: { + black: { + r: 0 + g: 0 + b: 0 + a: 1 + } + disabled: { + r: 0.23137255 + g: 0.24705882 + b: 0.25882354 + a: 1 + } + highlight: { + r: 0.19215687 + g: 0.6627451 + b: 0.95686275 + a: 1 + } + message: { + r: 0.44313726 + g: 0.47843137 + b: 0.5372549 + a: 1 + } + split: { + r: 0.44313726 + g: 0.47843137 + b: 0.5372549 + a: 1 + } + white: { + r: 1 + g: 1 + b: 1 + a: 1 + } +} +com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: { + split: { + name: white + color: split + } + black: { + name: white + color: black + } + highlight: { + name: white + color: highlight + } +} +com.badlogic.gdx.scenes.scene2d.utils.TiledDrawable: { + progress-bar-knob-t: { + region: progress-bar-knob + minWidth: 0 + minHeight: 5 + } +} +com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: { + default: { + up: button-normal + down: button-normal-pressed + over: button-normal-over + focused: button-normal-over + } + spinner-up: { + up: spinner-up + down: spinner-up-pressed + over: spinner-up-over + } + spinner-down: { + up: spinner-down + down: spinner-down-pressed + over: spinner-down-over + } +} +com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: { + default: { + checkboxOn: checkbox-selected + checkboxOff: checkbox + checkboxOnOver: checkbox-selected-over + checkboxOver: checkbox-over + font: font + } + radio: { + checkboxOn: radio-selected + checkboxOff: radio + checkboxOnOver: radio-selected-over + checkboxOver: radio-over + font: font + } +} +com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle: { + default: { + up: button-normal + down: button-normal-pressed + over: button-normal-over + focused: button-normal-over + } +} +com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton$ImageTextButtonStyle: { + default: { + font: font + up: button-normal + down: button-normal-pressed + over: button-normal-over + focused: button-normal-pressed + } +} +com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { + default: { + font: font + } + window: { + font: window + } + list: { + font: list + } + subtitle: { + font: subtitle + } +} +com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: { + default: { + font: list + fontColorSelected: white + fontColorUnselected: white + selection: selection + background: list + } + list-nobg: { + font: list + fontColorSelected: white + fontColorUnselected: white + selection: selection + } +} +com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle: { + default-horizontal: { + background: progress-bar-square + knobBefore: progress-bar-square-knob + } + default-vertical: { + background: progress-bar-square + knobBefore: progress-bar-square-knob + } + curved: { + background: progress-bar + knobBefore: progress-bar-knob-t + } +} +com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: { + default: { + hScrollKnob: scrollbar + vScrollKnob: scrollbar + } + list: { + background: list + hScrollKnob: scrollbar + vScrollKnob: scrollbar + } +} +com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: { + default: { + font: font + fontColor: white + background: select-box + scrollStyle: list + listStyle: list-nobg + backgroundOpen: select-box-open + } +} +com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: { + default-horizontal: { + knobOver: slider-knob-over + knobDown: slider-knob-over + background: progress-bar-square + knob: slider-knob + } + default-vertical: { + knobOver: slider-knob-over + knobDown: slider-knob-over + background: progress-bar-square + knob: slider-knob + } + curved: { + knobOver: slider-knob-over + knobDown: slider-knob-over + background: slider + knob: slider-knob + } +} +com.badlogic.gdx.scenes.scene2d.ui.SplitPane$SplitPaneStyle: { + default-horizontal: { + handle: split + } + default-vertical: { + handle: split + } +} +com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: { + default: { + font: font + up: button-normal + down: button-normal-pressed + over: button-normal-over + focused: button-normal-over + } +} +com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: { + default: { + font: font + fontColor: white + disabledFontColor: disabled + background: textfield + focusedBackground: textfield-selected + cursor: white + selection: highlight + messageFont: font + messageFontColor: message + } + spinner: { + font: font + fontColor: white + disabledFontColor: disabled + background: spinner-textfield + focusedBackground: spinner-textfield-selected + cursor: white + selection: highlight + messageFont: font + messageFontColor: message + } +} +com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: { + default: { + label: default + background: list + } +} +com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: { + default: { + background: list + knob: slider-knob + } +} +com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle: { + default: { + background: window + titleFont: window + } +}, + + com.badlogic.gdx.graphics.Color: { + white: { r: 1, g: 1, b: 1, a: 1 }, + gray: { r: 0.5, g: 0.5, b: 0.5, a: 1 }, + black: { r: 0, g: 0, b: 0, a: 1 }, + + up: { r: 0.1, g: 0.1, b: 0.1, a: 1 }, + over: { r: 0.3, g: 0.3, b: 0.3, a: 1 }, + down: { r: 0.3, g: 0, b: 0, a: 1 }, + checked: { r: 0.3, g: 0, b: 0, a: 1 }, + checkedOver: { r: 0.4, g: 0, b: 0, a: 1 }, + disabled: { r: 0.4, g: 0.4, b: 0.4, a: 1 }, + background: { r: 0.2, g: 0.2, b: 0.2, a: 1 }, + selection: { r: 0.3, g: 0, b: 0, a: 1 }, + semiTransparent: { r: 0, g: 0, b: 0, a: 0.6 }, + + font: white + fontOver: white + fontDown: gray + fontChecked: white + fontCheckedOver: white + fontDisabled: gray + }, + com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: { + buttonUp: { name: rect, color: up }, + buttonOver: { name: rect, color: over }, + buttonDown: { name: rect, color: down }, + buttonDisabled: { name: rect, color: disabled }, + buttonChecked: { name: rect, color: checked }, + buttonCheckedOver: { name: rect, color: checkedOver }, + checkBoxOn: { name: check-on, color: up }, + checkBoxOff: { name: check, color: up }, + checkBoxOver: { name: check, color: over }, + checkBoxOnDisabled: { name: check-on, color: disabled }, + checkBoxOffDisabled: { name: check, color: disabled }, + icon: { name: check-on, color: font }, + selection: { name: dot, color: selection }, + list: { name: rect, color: background }, + progressHorizontal: { name: line-v, color: up }, + progressHorizontalKnob: { name: line-v, color: down }, + progressHorizontalDisabled: { name: line-v, color: disabled }, + progressHorizontalKnobDisabled: { name: line-v, color: disabled }, + progressVertical: { name: line-h, color: up }, + progressVerticalKnob: { name: line-h, color: down }, + progressVerticalDisabled: { name: line-h, color: disabled }, + progressVerticalKnobDisabled: { name: line-h, color: disabled }, + scrollHorizontal: { name: line-v, color: up }, + scrollVertical: { name: line-h, color: up }, + scrollKnob: { name: knob-v, color: down }, + scrollKnobVertical: { name: knob-h, color: down }, + scrollPane: { name: rect, color: background }, + selectBox: { name: select, color: up }, + selectOver: { name: select, color: over }, + selectDown: { name: select, color: over }, + selectDisabled: { name: select, color: disabled }, + selectList: { name: rect, color: over }, + splitPane: { name: square, color: down }, + sliderHorizontal: { name: square, color: up }, + sliderKnob: { name: rect, color: up }, + sliderKnobOver: { name: rect, color: over }, + sliderKnobDown: { name: rect, color: down }, + sliderKnobDisabled: { name: rect, color: disabled }, + sliderVertical: { name: square, color: up }, + sliderVerticalKnob: { name: rect, color: up }, + sliderVerticalKnobOver: { name: rect, color: over }, + sliderVerticalKnobDown: { name: rect, color: down }, + sliderVerticalKnobDisabled: { name: rect, color: disabled }, + textField: { name: rect, color: up }, + textFieldDown: { name: rect, color: over }, + textFieldDisabled: { name: rect, color: disabled }, + textFieldCursor: { name: dot, color: font }, + tooltip: { name: rect, color: up }, + touchpad: { name: rect, color: over }, + touchpadKnob: { name: check-on, color: down }, + tree: { name: rect, color: background }, + treeOver: { name: dot, color: over }, + treeMinus: { name: tree-minus, color: up }, + treePlus: { name: tree-plus, color: up }, + window: { name: rect, color: background }, + windowResize: { name: window-resize, color: background }, + windowBorder: { name: window-border, color: background }, + alpha: { name: dot, color: semiTransparent } + }, + com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: { + default: { up: buttonUp, over: buttonOver, down: buttonDown, disabled: buttonDisabled }, + toggle: { up: buttonUp, over: buttonOver, down: buttonDown, checked: buttonChecked, checkedOver: buttonCheckedOver, disabled: buttonDisabled } + }, + com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: { + default: { checkboxOn: checkBoxOn, checkboxOff: checkBoxOff, checkboxOver: checkBoxOver, checkboxOnDisabled: checkBoxOnDisabled, + checkboxOffDisabled: checkBoxOffDisabled, font: default, fontColor: font, overFontColor: fontOver, downFontColor: fontDown, + checkedFontColor: fontChecked, checkedOverFontColor: fontCheckedOver, disabledFontColor: fontDisabled, pressedOffsetY: -1, pressedOffsetX: 1 } + }, + com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle: { + default: { up: buttonUp, over: buttonOver, down: buttonDown, disabled: buttonDisabled, imageUp: icon } + }, + com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton$ImageTextButtonStyle: { + default: { up: buttonUp, over: buttonOver, down: buttonDown, disabled: buttonDisabled, font: default, fontColor: font, + overFontColor: fontOver, downFontColor: fontDown, disabledFontColor: fontDisabled, pressedOffsetY: -1, pressedOffsetX: 1, imageUp: icon } + }, + com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { + default: { font: default, fontColor: font }, + white: { font: default, fontColor: white } + }, + com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: { + default: { fontColorUnselected: font, selection: selection, fontColorSelected: fontDown, font: default }, + background: { background: list, fontColorUnselected: font, selection: selection, fontColorSelected: fontDown, font: default } + }, + com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle: { + default-horizontal: { background: progressHorizontal, knobBefore: progressHorizontalKnob, + disabledBackground: progressHorizontalDisabled, disabledKnobBefore: progressHorizontalKnobDisabled }, + default-vertical: { background: progressVertical, knobBefore: progressVerticalKnob, + disabledBackground: progressVerticalDisabled, disabledKnobBefore: progressVerticalKnobDisabled } + }, + com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: { + default: { hScrollKnob: scrollKnob, vScrollKnob: scrollKnobVertical, hScroll: scrollHorizontal, vScroll: scrollVertical }, + clean: { hScrollKnob: scrollKnob, vScrollKnob: scrollKnobVertical }, + background: { background: scrollPane, hScrollKnob: scrollKnob, vScrollKnob: scrollKnobVertical, hScroll: scrollHorizontal, vScroll: scrollVertical } + }, + com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: { + default: { font: default, fontColor: font, disabledFontColor: fontDisabled, background: selectBox, backgroundOver: selectOver, + backgroundOpen: selectDown, backgroundDisabled: selectDisabled, scrollStyle: default, listStyle: + { background: selectList, fontColorUnselected: font, selection: selection, fontColorSelected: fontDown, font: default } + } + }, + com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: { + default-horizontal: { background: sliderHorizontal, knob: sliderKnob, knobOver: sliderKnobOver, knobDown: sliderKnobDown, + disabledKnob: sliderKnobDisabled }, + default-vertical: { background: sliderVertical, knob: sliderVerticalKnob, knobOver: sliderVerticalKnobOver, + knobDown: sliderVerticalKnobDown, disabledKnob: sliderVerticalKnobDisabled } + }, + com.badlogic.gdx.scenes.scene2d.ui.SplitPane$SplitPaneStyle: { + default-vertical: { handle: splitPane }, + default-horizontal: { handle: splitPane } + }, + com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: { + default: { up: buttonUp, over: buttonOver, down: buttonDown, disabled: buttonDisabled, font: default, fontColor: font, + overFontColor: fontOver, downFontColor: fontDown, disabledFontColor: fontDisabled, pressedOffsetY: -1, pressedOffsetX: 1 }, + toggle: { up: buttonUp, over: buttonOver, down: buttonDown, checked: buttonChecked, checkedOver: buttonCheckedOver, + disabled: buttonDisabled, font: default, fontColor: font, overFontColor: fontOver, downFontColor: fontDown, disabledFontColor: + fontDisabled, checkedFontColor: fontChecked, checkedOverFontColor: fontCheckedOver, pressedOffsetY: -1, pressedOffsetX: 1 }, + text: { font: default, fontColor: up, overFontColor: over, downFontColor: down, disabledFontColor: disabled, + pressedOffsetY: -1, pressedOffsetX: 1 }, + textToggle: { font: default, fontColor: up, overFontColor: over, downFontColor: down, disabledFontColor: + disabled, checkedFontColor: font, checkedOverFontColor: fontOver, pressedOffsetY: -1, pressedOffsetX: 1 } + }, + com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: { + default: { font: default, messageFont: default, fontColor: font, focusedFontColor: fontOver, disabledFontColor: fontDisabled, + messageFontColor: fontDown, background: textField, focusedBackground: textFieldDown, disabledBackground: textFieldDisabled, + cursor: textFieldCursor, selection: selection } + }, + com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: { + default: { label: default, background: tooltip } + }, + com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: { + default: { background: touchpad, knob: touchpadKnob } + }, + com.badlogic.gdx.scenes.scene2d.ui.Tree$TreeStyle: { + default: { minus: treeMinus, plus: treePlus, selection: selection, over: treeOver }, + background: { background: tree, minus: treeMinus, plus: treePlus, selection: selection, over: treeOver } + }, + com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle: { + default: { titleFont: default, background: window, titleFontColor: fontDisabled }, + resize: { titleFont: default, background: windowResize, titleFontColor: fontDisabled }, + border: { titleFont: default, background: windowBorder, titleFontColor: fontDisabled }, + dialog: { titleFont: default, background: window, titleFontColor: fontDisabled, stageBackground: alpha } + } +} diff --git a/assets/ui/uiskin.png b/assets/ui/uiskin.png new file mode 100644 index 0000000..957c02d Binary files /dev/null and b/assets/ui/uiskin.png differ diff --git a/assets/фон.png b/assets/фон.png new file mode 100644 index 0000000..5396449 Binary files /dev/null and b/assets/фон.png differ diff --git a/assets/фон1.png b/assets/фон1.png new file mode 100644 index 0000000..e185095 Binary files /dev/null and b/assets/фон1.png differ diff --git a/assets/фон2.png b/assets/фон2.png new file mode 100644 index 0000000..ea54c75 Binary files /dev/null and b/assets/фон2.png differ diff --git a/assets/фон3.png b/assets/фон3.png new file mode 100644 index 0000000..f58acaa Binary files /dev/null and b/assets/фон3.png differ diff --git a/assets/фон4.png b/assets/фон4.png new file mode 100644 index 0000000..095bb74 Binary files /dev/null and b/assets/фон4.png differ diff --git a/assets/фон5.png b/assets/фон5.png new file mode 100644 index 0000000..c392ec4 Binary files /dev/null and b/assets/фон5.png differ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..7717722 --- /dev/null +++ b/build.gradle @@ -0,0 +1,69 @@ +buildscript { + repositories { + mavenCentral() + gradlePluginPortal() + mavenLocal() + google() + maven { url = 'https://central.sonatype.com/repository/maven-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' + java.sourceCompatibility = 8 + + // 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 = 'AbsurdCityBuilder1' + repositories { + mavenCentral() + // You may want to remove the following line if you have errors downloading dependencies. + mavenLocal() + maven { url = 'https://central.sonatype.com/repository/maven-snapshots/' } + maven { url = 'https://jitpack.io' } + } +} + +eclipse.project.name = 'AbsurdCityBuilder1' + '-parent' diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000..69a26cb --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,15 @@ +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +eclipse.project.name = appName + '-core' + +dependencies { + api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" + api "com.badlogicgames.gdx:gdx-bullet:$gdxVersion" + api "com.badlogicgames.gdx:gdx:$gdxVersion" + api "com.kotcrab.vis:vis-ui:$visUiVersion" + api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + api "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" + + if(enableGraalNative == 'true') { + implementation "io.github.berstanio:gdx-svmhelper-annotations:$graalHelperVersion" + } +} diff --git a/core/src/main/java/com/mygdx/game/AbsurdCityBuilder1.java b/core/src/main/java/com/mygdx/game/AbsurdCityBuilder1.java new file mode 100644 index 0000000..91f09c5 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/AbsurdCityBuilder1.java @@ -0,0 +1,557 @@ +package com.mygdx.game; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; + +import java.util.Random; + +public class AbsurdCityBuilder1 extends ApplicationAdapter { + // Константы + private static final int WIDTH = 1700; + private static final int HEIGHT = 950; + private static final int UI_INPUT_HEIGHT = 210; + + // Основные объекты + private SpriteBatch batch; + private ShapeRenderer shapeRenderer; + private OrthographicCamera camera; + private Viewport viewport; + private BitmapFont font; + private GlyphLayout glyphLayout; + private Texture whitePixel; + + // Игровые объекты + private Array buildings; + private Building currentBuilding; + private MathProblem currentProblem; + private Random random; + private Array citizens; + private Array jokeBubbles; + + // Переменные игры + private float time = 0; + private boolean showWrongAnswerJoke = false; + private String wrongAnswerJoke = ""; + private float jokeTimer = 0; + + // UI переменные + private int selectedBuildingType = 0; + private StringBuilder inputText = new StringBuilder(); + private boolean isTyping = false; + private String messageText = "Добро пожаловать! Выберите здание и кликните на поле."; + private Color messageColor = Color.WHITE; + private String problemText = "Нажмите ESC для возврата в меню"; + + // Текстуры и рендереры + private Texture backgroundTexture; + private BuildingRenderer buildingRenderer; + private UIRenderer uiRenderer; + private MenuRenderer menuRenderer; + + // Планета + private Planet currentPlanet; + private float planetSwitchTimer = 0; + private boolean isSwitchingPlanets = false; + private Planet targetPlanet; + + // Состояние игры + private GameState gameState = GameState.MAIN_MENU; + private boolean wasJustClicked = false; + + @Override + public void create() { + batch = new SpriteBatch(); + shapeRenderer = new ShapeRenderer(); + + GameAssets.createFonts(); + font = GameAssets.getFont(); + glyphLayout = new GlyphLayout(); + whitePixel = GameAssets.createWhitePixel(); + + camera = new OrthographicCamera(); + viewport = new FitViewport(WIDTH, HEIGHT, camera); + viewport.apply(); + camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0); + + random = new Random(); + buildings = new Array<>(); + citizens = new Array<>(); + jokeBubbles = new Array<>(); + + // Начинаем с Земли + currentPlanet = Planet.EARTH; + + try { + backgroundTexture = new Texture(Gdx.files.internal("фон4.png")); + } catch (Exception e) { + backgroundTexture = null; + } + + buildingRenderer = new BuildingRenderer(shapeRenderer, batch, font, glyphLayout, whitePixel); + uiRenderer = new UIRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT, UI_INPUT_HEIGHT); + menuRenderer = new MenuRenderer(batch, font, glyphLayout, whitePixel, WIDTH, HEIGHT); + + updateUI(); + } + + @Override + public void render() { + handleInput(); + update(); + + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + camera.update(); + batch.setProjectionMatrix(camera.combined); + shapeRenderer.setProjectionMatrix(camera.combined); + + switch (gameState) { + case MAIN_MENU: + renderMainMenu(); + break; + case PLANET_SELECT: + renderPlanetSelect(); + break; + case HELP: + renderHelp(); + break; + case ABOUT: + renderAbout(); + break; + case PLAYING: + renderGame(); + break; + } + } + + private void handleInput() { + // Обработка кликов мыши + boolean isClicked = Gdx.input.justTouched(); + float mouseX = Gdx.input.getX(); + float mouseY = HEIGHT - Gdx.input.getY(); // Инвертируем Y + + // ESC для возврата в меню из игры + if (Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)) { + if (gameState == GameState.PLAYING) { + if (isTyping) { + // Отмена ввода + setTyping(false); + getInputText().setLength(0); + setMessageText("Ввод отменен."); + setMessageColor(Color.YELLOW); + } else { + // Возврат в главное меню + gameState = GameState.MAIN_MENU; + setMessageText("Игра приостановлена. Нажмите ESC для продолжения."); + } + } else if (gameState != GameState.MAIN_MENU) { + // Возврат в главное меню из других состояний + gameState = GameState.MAIN_MENU; + } + } + + // Обработка состояний меню + switch (gameState) { + case MAIN_MENU: + handleMainMenuInput(mouseX, mouseY, isClicked); + break; + case PLANET_SELECT: + handlePlanetSelectInput(mouseX, mouseY, isClicked); + break; + case HELP: + handleHelpInput(mouseX, mouseY, isClicked); + break; + case ABOUT: + handleAboutInput(mouseX, mouseY, isClicked); + break; + case PLAYING: + InputHandler.handleInput(this); + break; + } + + wasJustClicked = isClicked; + } + + private void handleMainMenuInput(float mouseX, float mouseY, boolean isClicked) { + if (isClicked) { + MenuButton clickedButton = menuRenderer.getMainMenuButtonAt(mouseX, mouseY); + if (clickedButton != null) { + String buttonText = clickedButton.getText(); // Используйте геттер + + if (buttonText.contains("НОВАЯ ИГРА")) { + startNewGame(); + } else if (buttonText.contains("ВЫБОР ПЛАНЕТЫ")) { + gameState = GameState.PLANET_SELECT; + } else if (buttonText.contains("ПОМОЩЬ")) { + gameState = GameState.HELP; + } else if (buttonText.contains("ОБ ИГРЕ")) { + gameState = GameState.ABOUT; + } else if (buttonText.contains("ВЫХОД")) { + Gdx.app.exit(); + } + } + } + } + + private void handlePlanetSelectInput(float mouseX, float mouseY, boolean isClicked) { + if (isClicked) { + MenuButton clickedButton = menuRenderer.getPlanetSelectButtonAt(mouseX, mouseY); + if (clickedButton != null) { + String buttonText = clickedButton.getText(); // Используйте геттер + + if (buttonText.contains("ЗЕМЛЯ")) { + startNewGameOnPlanet(Planet.EARTH); + } else if (buttonText.contains("МАРС")) { + startNewGameOnPlanet(Planet.MARS); + } else if (buttonText.contains("ВЕНЕРА")) { + startNewGameOnPlanet(Planet.VENUS); + } else if (buttonText.contains("НАЗАД")) { + gameState = GameState.MAIN_MENU; + } + } + } + } + + private void handleHelpInput(float mouseX, float mouseY, boolean isClicked) { + if (isClicked) { + MenuButton clickedButton = menuRenderer.getHelpButtonAt(mouseX, mouseY); + if (clickedButton != null) { + String buttonText = clickedButton.getText(); // Используйте геттер + + if (buttonText.contains("НАЗАД")) { + gameState = GameState.MAIN_MENU; + } + } + } + } + + private void handleAboutInput(float mouseX, float mouseY, boolean isClicked) { + if (isClicked) { + // Простая проверка на кнопку "Назад" + if (mouseX >= 50 && mouseX <= 250 && mouseY >= 50 && mouseY <= 110) { + gameState = GameState.MAIN_MENU; + } + } + } + + private void startNewGame() { + // Очищаем всё и начинаем новую игру на Земле + buildings.clear(); + citizens.clear(); + jokeBubbles.clear(); + currentBuilding = null; + currentProblem = null; + selectedBuildingType = 0; + inputText.setLength(0); + isTyping = false; + + currentPlanet = Planet.EARTH; + isSwitchingPlanets = false; + + messageText = "Добро пожаловать на Землю! Выберите здание и кликните на поле."; + messageColor = Color.GREEN; + + gameState = GameState.PLAYING; + updateUI(); + } + + private void startNewGameOnPlanet(Planet planet) { + // Очищаем всё и начинаем новую игру на выбранной планете + buildings.clear(); + citizens.clear(); + jokeBubbles.clear(); + currentBuilding = null; + currentProblem = null; + selectedBuildingType = 0; + inputText.setLength(0); + isTyping = false; + + currentPlanet = planet; + isSwitchingPlanets = false; + + messageText = "Добро пожаловать на " + planet.getName() + "! Выберите здание и кликните на поле."; + messageColor = Color.GREEN; + + gameState = GameState.PLAYING; + updateUI(); + } + + private void update() { + float deltaTime = Gdx.graphics.getDeltaTime(); + time += deltaTime; + + // Обновляем меню + menuRenderer.update(deltaTime); + + // Обработка плавной смены планет + if (isSwitchingPlanets) { + planetSwitchTimer += deltaTime; + if (planetSwitchTimer >= 1.0f) { + currentPlanet = targetPlanet; + isSwitchingPlanets = false; + setMessageText("Добро пожаловать на " + currentPlanet.getName() + "! 🌍"); + } + } + + if (gameState == GameState.PLAYING) { + for (Building b : buildings) { + b.update(deltaTime); + } + if (currentBuilding != null) { + currentBuilding.update(deltaTime); + } + + // Обновляем жителей + for (Citizen citizen : citizens) { + citizen.update(deltaTime); + } + + // Обновляем пузыри с шутками + for (int i = jokeBubbles.size - 1; i >= 0; i--) { + JokeBubble bubble = jokeBubbles.get(i); + bubble.update(deltaTime); + if (bubble.isExpired()) { + jokeBubbles.removeIndex(i); + } + } + + // Обновляем таймер шутки + if (showWrongAnswerJoke) { + jokeTimer += deltaTime; + if (jokeTimer > 3.0f) { + showWrongAnswerJoke = false; + } + } + } + } + + public void checkAnswer() { + AnswerChecker.checkAnswer(this); + } + + public void startPlanetSwitch(Planet newPlanet) { + if (currentPlanet == newPlanet || isSwitchingPlanets) return; + + isSwitchingPlanets = true; + targetPlanet = newPlanet; + planetSwitchTimer = 0; + + // Очищаем город при смене планеты + buildings.clear(); + citizens.clear(); + jokeBubbles.clear(); + currentBuilding = null; + currentProblem = null; + selectedBuildingType = 0; + + setMessageText("Запускаем космический корабль на " + newPlanet.getName() + "! 🚀"); + setMessageColor(Color.YELLOW); + updateUI(); + } + + public void updateUI() { + UIUpdater.updateUI(this); + } + + private void renderMainMenu() { + float mouseX = Gdx.input.getX(); + float mouseY = HEIGHT - Gdx.input.getY(); + menuRenderer.renderMainMenu(mouseX, mouseY); + } + + private void renderPlanetSelect() { + float mouseX = Gdx.input.getX(); + float mouseY = HEIGHT - Gdx.input.getY(); + menuRenderer.renderPlanetSelect(mouseX, mouseY); + } + + private void renderHelp() { + float mouseX = Gdx.input.getX(); + float mouseY = HEIGHT - Gdx.input.getY(); + menuRenderer.renderHelp(mouseX, mouseY); + } + + private void renderAbout() { + float mouseX = Gdx.input.getX(); + float mouseY = HEIGHT - Gdx.input.getY(); + menuRenderer.renderAbout(mouseX, mouseY); + } + + private void renderGame() { + renderBackground(); + renderBuildings(); + renderCitizens(); + renderJokeBubbles(); + renderBuildingNames(); + renderPlanetTransition(); + renderUI(); + } + + private void renderBackground() { + batch.begin(); + + Color bgColor; + if (isSwitchingPlanets) { + // Плавный переход между цветами + Color fromColor = currentPlanet.getColor(); + Color toColor = targetPlanet.getColor(); + float progress = Math.min(planetSwitchTimer * 2, 1.0f); + + bgColor = new Color( + fromColor.r + (toColor.r - fromColor.r) * progress, + fromColor.g + (toColor.g - fromColor.g) * progress, + fromColor.b + (toColor.b - fromColor.b) * progress, + 1 + ); + } else { + bgColor = currentPlanet.getColor(); + } + + if (backgroundTexture != null) { + batch.setColor(bgColor); + batch.draw(backgroundTexture, 0, UI_INPUT_HEIGHT, WIDTH, HEIGHT - UI_INPUT_HEIGHT); + batch.setColor(Color.WHITE); + } else { + batch.setColor(bgColor); + batch.draw(whitePixel, 0, UI_INPUT_HEIGHT, WIDTH, HEIGHT - UI_INPUT_HEIGHT); + batch.setColor(Color.WHITE); + } + + batch.end(); + } + + private void renderBuildings() { + buildingRenderer.renderBuildings(buildings, currentBuilding, time, currentPlanet); + } + + private void renderCitizens() { + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + for (Citizen citizen : citizens) { + citizen.draw(shapeRenderer, time); + } + shapeRenderer.end(); + } + + private void renderJokeBubbles() { + for (JokeBubble bubble : jokeBubbles) { + bubble.draw(batch, shapeRenderer, font, glyphLayout, whitePixel); + } + } + + private void renderBuildingNames() { + buildingRenderer.renderBuildingNames(buildings, currentBuilding); + } + + private void renderPlanetTransition() { + if (!isSwitchingPlanets) return; + + batch.begin(); + + // Затемнение экрана + float alpha = Math.min(planetSwitchTimer * 2, 1.0f); + batch.setColor(0, 0, 0, alpha * 0.7f); + batch.draw(whitePixel, 0, 0, WIDTH, HEIGHT); + + // Текст перехода + font.setColor(1, 1, 1, alpha); + font.getData().setScale(1.5f); + + String transitionText; + if (planetSwitchTimer < 0.5f) { + transitionText = "Покидаем " + currentPlanet.getName() + "..."; + } else { + transitionText = "Прибываем на " + targetPlanet.getName() + "!"; + } + + glyphLayout.setText(font, transitionText); + font.draw(batch, transitionText, + WIDTH/2 - glyphLayout.width/2, + HEIGHT/2 + 50); + + font.getData().setScale(1.0f); + batch.end(); + } + + private void renderUI() { + uiRenderer.renderUI(selectedBuildingType, problemText, messageText, messageColor, + isTyping, currentProblem, inputText.toString(), showWrongAnswerJoke, + wrongAnswerJoke, time, currentBuilding, currentPlanet, isSwitchingPlanets); + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height); + } + + @Override + public void dispose() { + batch.dispose(); + shapeRenderer.dispose(); + font.dispose(); + if (backgroundTexture != null) { + backgroundTexture.dispose(); + } + if (whitePixel != null) { + whitePixel.dispose(); + } + menuRenderer.dispose(); + } + + // Геттеры и сеттеры + public int getWIDTH() { return WIDTH; } + public int getHEIGHT() { return HEIGHT; } + public int getUI_INPUT_HEIGHT() { return UI_INPUT_HEIGHT; } + public int getSelectedBuildingType() { return selectedBuildingType; } + public void setSelectedBuildingType(int selectedBuildingType) { this.selectedBuildingType = selectedBuildingType; } + public StringBuilder getInputText() { return inputText; } + public boolean isTyping() { return isTyping; } + public void setTyping(boolean typing) { isTyping = typing; } + public String getMessageText() { return messageText; } + public void setMessageText(String messageText) { this.messageText = messageText; } + public Color getMessageColor() { return messageColor; } + public void setMessageColor(Color messageColor) { this.messageColor = messageColor; } + public String getProblemText() { return problemText; } + public void setProblemText(String problemText) { this.problemText = problemText; } + public Array getBuildings() { return buildings; } + public Building getCurrentBuilding() { return currentBuilding; } + public void setCurrentBuilding(Building currentBuilding) { this.currentBuilding = currentBuilding; } + public MathProblem getCurrentProblem() { return currentProblem; } + public void setCurrentProblem(MathProblem currentProblem) { this.currentProblem = currentProblem; } + public Random getRandom() { return random; } + public Array getCitizens() { return citizens; } + public Array getJokeBubbles() { return jokeBubbles; } + public boolean isShowWrongAnswerJoke() { return showWrongAnswerJoke; } + public void setShowWrongAnswerJoke(boolean showWrongAnswerJoke) { this.showWrongAnswerJoke = showWrongAnswerJoke; } + public String getWrongAnswerJoke() { return wrongAnswerJoke; } + public void setWrongAnswerJoke(String wrongAnswerJoke) { this.wrongAnswerJoke = wrongAnswerJoke; } + public float getJokeTimer() { return jokeTimer; } + public void setJokeTimer(float jokeTimer) { this.jokeTimer = jokeTimer; } + public Texture getWhitePixel() { return whitePixel; } + public BitmapFont getFont() { return font; } + public GlyphLayout getGlyphLayout() { return glyphLayout; } + public ShapeRenderer getShapeRenderer() { return shapeRenderer; } + public SpriteBatch getBatch() { return batch; } + public float getTime() { return time; } + public Planet getCurrentPlanet() { return currentPlanet; } + public void setCurrentPlanet(Planet planet) { this.currentPlanet = planet; } + public boolean isSwitchingPlanets() { return isSwitchingPlanets; } + public Planet getTargetPlanet() { return targetPlanet; } + public float getPlanetSwitchTimer() { return planetSwitchTimer; } + public GameState getGameState() { return gameState; } + public void setGameState(GameState state) { this.gameState = state; } +} diff --git a/core/src/main/java/com/mygdx/game/AnswerChecker.java b/core/src/main/java/com/mygdx/game/AnswerChecker.java new file mode 100644 index 0000000..159a802 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/AnswerChecker.java @@ -0,0 +1,249 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; + +public class AnswerChecker { + private static final String[][] FUNNY_COMMENTS_BY_PLANET = { + // Земля + { + "Вау! Такое здание видел только в мультиках!", + "Архитектор сошел с ума от радости!", + "Город стал похож на мультфильм!", + "Это самое безумное здание в городе!", + "Жители в восторге от этой абсурдности!", + "Эй, это похоже на город из моих снов!", + "Такое здание украсит любой мультфильм!" + }, + // Марс + { + "Отлично! Марсианская колония растёт! 🚀", + "На Марсе теперь есть своё безумие!", + "Эти здания переживут любую пылевую бурю!", + "Марсиане будут в восторге! 👽", + "Похоже, мы колонизируем Марс!", + "Красная планета стала разноцветнее!", + "Это здание выглядит инопланетно круто!" + }, + // Венера + { + "Горячо! Венерианский шедевр готов! 🔥", + "Здание плавится от собственной красоты!", + "Венера стала ещё ярче! 🌟", + "Это здание сияет как сама Венера!", + "Похоже, мы выживаем на Венере!", + "Такая красота плавит сердце!", + "Золотой век венерианской архитектуры!" + } + }; + + private static final String[][] WRONG_ANSWER_JOKES_BY_PLANET = { + // Земля + { + "Твоя математика кривее моих зданий!", + "Даже мультяшный архитектор считает лучше!", + "Ты что, в мультиках учился математике?", + "Ошибка! Попробуй посчитать на пальцах ног!", + "Неправильно! Давай еще разочек, как в мультике!", + "Бывает! Даже мультяшные гении ошибаются!", + "Ой, кажется, ты перепутал с мультипликацией!", + "Неверно! Но зато здание выглядит смешнее!" + }, + // Марс + { + "Неверно! Марсиане считают лучше! 👽", + "Ошибка в расчётах! Пылевая буря съела цифры!", + "Твоя математика не переживёт марсианскую зиму!", + "Неудача! Даже марсоход считает точнее!", + "Неправильно! Попробуй считать в скафандре!", + "Ошибка! Кислородное голодание сказывается?", + "Марсианские калькуляторы не одобряют!", + "Неверно! Может, радиация помешала?" + }, + // Венера + { + "Горячая ошибка! 🔥 Попробуй ещё!", + "Неверно! Даже венерианская жара не оправдывает!", + "Ошибка! Кислотные облака затуманили разум?", + "Неправильно! Слишком жарко для точных расчётов?", + "Провал! Венерианские калькуляторы плавятся!", + "Неудача! Давление в 90 атмосфер давит на мозги?", + "Ошибка! Попробуй считать в теплозащитном костюме!", + "Неверно! Золотое сечение не спасло!" + } + }; + + public static void checkAnswer(AbsurdCityBuilder1 game) { + if (game.getCurrentBuilding() == null || game.getInputText().length() == 0) { + game.setMessageText("Введите ответ!"); + game.setMessageColor(Color.RED); + return; + } + + try { + int userAnswer = Integer.parseInt(game.getInputText().toString()); + Planet currentPlanet = game.getCurrentPlanet(); + int planetIndex = currentPlanet.ordinal(); + + if (userAnswer == game.getCurrentProblem().getAnswer()) { + // Правильный ответ + game.getCurrentBuilding().addBlock(); + + String[] planetComments = FUNNY_COMMENTS_BY_PLANET[planetIndex]; + String successMessage = "Отлично! Блок построен!"; + + if (game.getCurrentBuilding().isComplete()) { + successMessage = "Успех! " + planetComments[game.getRandom().nextInt(planetComments.length)]; + game.getBuildings().add(game.getCurrentBuilding()); + + // Создаем жителей при завершении здания + game.getCurrentBuilding().createCitizensForBuilding(game.getCitizens(), game.getRandom()); + + // Проверяем разблокировку планет + checkPlanetUnlock(game); + + game.setCurrentBuilding(null); + game.setCurrentProblem(null); + game.setTyping(false); + } else { + game.setCurrentProblem(MathProblem.generateProblem(game.getBuildings().size, game.getRandom())); + } + + game.setMessageText(successMessage); + game.setMessageColor(Color.GREEN); + + } else { + // Неправильный ответ + game.getCurrentBuilding().removeBlock(); + + String[] planetJokes = WRONG_ANSWER_JOKES_BY_PLANET[planetIndex]; + String joke = planetJokes[game.getRandom().nextInt(planetJokes.length)]; + game.setWrongAnswerJoke(joke); + game.setShowWrongAnswerJoke(true); + game.setJokeTimer(0); + + // Создаем пузырь с шуткой + if (game.getCitizens().size > 0) { + Citizen randomCitizen = game.getCitizens().get(game.getRandom().nextInt(game.getCitizens().size)); + game.getJokeBubbles().add(new JokeBubble(joke, randomCitizen.x, randomCitizen.y + 60, game.getRandom())); + } + + String message; + if (game.getCurrentBuilding().constructionProgress == 0) { + message = "Здание разрушено до основания! " + joke; + game.setCurrentBuilding(null); + game.setCurrentProblem(null); + game.setTyping(false); + } else { + message = "Неверно! Блок разрушен! " + joke; + game.setCurrentProblem(MathProblem.generateProblem(game.getBuildings().size, game.getRandom())); + } + + game.setMessageText(message); + game.setMessageColor(Color.RED); + } + + game.updateUI(); + game.getInputText().setLength(0); + + } catch (NumberFormatException e) { + // Обработка некорректного ввода + Planet currentPlanet = game.getCurrentPlanet(); + String errorMessage; + + switch (currentPlanet) { + case MARS: + errorMessage = "Марсиане не понимают такие цифры! Введите целое число!"; + break; + case VENUS: + errorMessage = "Слишком жарко для таких символов! Введите целое число!"; + break; + default: + errorMessage = "Введите целое число!"; + } + + game.setMessageText(errorMessage); + game.setMessageColor(Color.RED); + game.getInputText().setLength(0); + } + } + + private static void checkPlanetUnlock(AbsurdCityBuilder1 game) { + Planet currentPlanet = game.getCurrentPlanet(); + int buildingsCount = game.getBuildings().size; + + // Проверяем условия для разблокировки Марса + if (currentPlanet == Planet.EARTH && buildingsCount >= 3) { + // Марс уже разблокирован по умолчанию в нашей реализации + // Но можно добавить специальное сообщение + if (buildingsCount == 3) { + game.setMessageText(game.getMessageText() + " 🚀 Марс доступен! Нажмите ↑ для полёта!"); + game.setMessageColor(Color.CYAN); + } + } + + // Проверяем условия для разблокировки Венеры + if (currentPlanet == Planet.MARS && buildingsCount >= 6) { + // Венера уже разблокирована + if (buildingsCount == 6) { + game.setMessageText(game.getMessageText() + " 🔥 Венера доступна! Нажмите ↑ для полёта!"); + game.setMessageColor(Color.ORANGE); + } + } + + // Бонус за много построек + if (buildingsCount % 5 == 0) { + String bonusMessage = getBonusMessage(currentPlanet, buildingsCount); + game.setMessageText(game.getMessageText() + " " + bonusMessage); + } + } + + private static String getBonusMessage(Planet planet, int buildingsCount) { + switch (planet) { + case EARTH: + return "🎉 Вы построили " + buildingsCount + " зданий на Земле!"; + case MARS: + return "👽 Марсианская колония из " + buildingsCount + " зданий!"; + case VENUS: + return "🌟 Венерианский мегаполис из " + buildingsCount + " зданий!"; + default: + return "🏆 Достижение: " + buildingsCount + " зданий!"; + } + } + + // Метод для получения подсказки (опционально) + public static String getHint(MathProblem problem, Planet planet) { + int answer = problem.getAnswer(); + String question = problem.getQuestion(); + + switch (planet) { + case MARS: + if (question.contains("+")) { + return "Подсказка: складывай как марсиане - от красного к красному!"; + } else if (question.contains("-")) { + return "Подсказка: вычитай как улетающую ракету!"; + } else if (question.contains("×")) { + return "Подсказка: умножай на количество марсоходов!"; + } + break; + case VENUS: + if (question.contains("+")) { + return "Подсказка: складывай жар как на Венере!"; + } else if (question.contains("-")) { + return "Подсказка: вычитай облака кислоты!"; + } else if (question.contains("×")) { + return "Подсказка: умножай как давление на Венере!"; + } + break; + default: + if (question.contains("+")) { + return "Подсказка: представь, что складываешь мультяшных зверюшек!"; + } else if (question.contains("-")) { + return "Подсказка: убери лишние мультяшные детали!"; + } else if (question.contains("×")) { + return "Подсказка: умножай как в мультике - всё становится больше!"; + } + } + + return "Подсказка: внимательно посчитай!"; + } +} diff --git a/core/src/main/java/com/mygdx/game/Building.java b/core/src/main/java/com/mygdx/game/Building.java new file mode 100644 index 0000000..0d8b8bd --- /dev/null +++ b/core/src/main/java/com/mygdx/game/Building.java @@ -0,0 +1,441 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.utils.Array; +import java.util.Random; + +public class Building { + // Названия зданий по планетам + public static final String[][] BUILDING_TYPES_BY_PLANET = { + // Земля (существующие здания) + { + "✨ Уютный Домик ✨", + "🏥 Детская Больница 🏥", + "🎒 Весёлая Школа 🎒", + "🎪 Игровая Площадка 🎪", + "💰 Надёжный Банк 💰", + "💊 Здоровая Аптека 💊", + "🎭 Волшебный Театр 🎭", + "🎬 КиноМир 🎬" + }, + // Марс (красные, технологичные) + { + "🚀 Марсианская База 🚀", + "🔴 Красная Лаборатория 🔴", + "🛰️ Космопорт 🛰️", + "⚡ Энергокупол ⚡", + "💧 Водородный Завод 💧", + "🌌 Обсерватория 🌌", + "🤖 Робо-Фабрика 🤖", + "🧪 Биокупол 🧪" + }, + // Венера (желтые, вулканические) + { + "🌋 Вулканический Дом 🌋", + "🔥 Термальная Станция 🔥", + "🌅 Золотой Дворец 🌅", + "☁️ Облачный Город ☁️", + "💎 Кристальная Шахта 💎", + "🌡️ Теплица 🌡️", + "🌀 Вихревой Генератор 🌀", + "✨ Сияющая Башня ✨" + } + }; + + // Яркие цвета для разных планет + public static final Color[][][] BUILDING_COLOR_THEMES_BY_PLANET = { + // 0. Земля - тёплые цвета + { + // Дома - тёплые цвета + { + new Color(1.0f, 0.85f, 0.7f, 1), // Персиковый + new Color(0.95f, 0.9f, 0.75f, 1), // Светло-бежевый + new Color(0.9f, 0.8f, 0.85f, 1) // Розоватый + }, + // Больницы - чистые светлые цвета + { + new Color(1.0f, 1.0f, 1.0f, 1), // Белоснежный + new Color(0.98f, 0.98f, 1.0f, 1), // Голубоватый + new Color(0.96f, 1.0f, 0.98f, 1) // Мятный + }, + // Школы - яркие весёлые цвета + { + new Color(1.0f, 0.95f, 0.8f, 1), // Лимонный + new Color(0.85f, 0.95f, 1.0f, 1), // Небесно-голубой + new Color(0.95f, 0.85f, 1.0f, 1) // Лавандовый + }, + // Игровые площадки - яркие игровые цвета + { + new Color(1.0f, 0.9f, 0.8f, 1), // Абрикосовый + new Color(0.9f, 1.0f, 0.9f, 1), // Салатовый + new Color(0.9f, 0.9f, 1.0f, 1) // Сиреневый + }, + // Банки - солидные цвета + { + new Color(0.95f, 0.95f, 0.9f, 1), // Слоновая кость + new Color(0.9f, 0.92f, 0.85f, 1), // Бежевый + new Color(0.85f, 0.89f, 0.8f, 1) // Оливковый + }, + // Аптеки - медицинские цвета + { + new Color(1.0f, 1.0f, 1.0f, 1), // Белый + new Color(0.98f, 1.0f, 0.98f, 1), // Светло-зелёный + new Color(0.96f, 0.98f, 1.0f, 1) // Светло-голубой + }, + // Театры - благородные цвета + { + new Color(0.95f, 0.9f, 0.95f, 1), // Сиреневый + new Color(0.9f, 0.95f, 1.0f, 1), // Лазурный + new Color(1.0f, 0.95f, 0.9f, 1) // Кремовый + }, + // Кинотеатры - тёмные с неоном + { + new Color(0.2f, 0.2f, 0.3f, 1), // Тёмно-синий + new Color(0.3f, 0.2f, 0.4f, 1), // Фиолетовый + new Color(0.4f, 0.3f, 0.5f, 1) // Пурпурный + } + }, + // 1. Марс - красные, оранжевые, коричневые + { + // Марсианская База + { + new Color(0.8f, 0.3f, 0.2f, 1), // Красный марсианский + new Color(0.9f, 0.5f, 0.3f, 1), // Оранжевый + new Color(0.7f, 0.4f, 0.3f, 1) // Коричневый + }, + // Красная Лаборатория + { + new Color(0.9f, 0.4f, 0.4f, 1), + new Color(1.0f, 0.6f, 0.5f, 1), + new Color(0.8f, 0.5f, 0.5f, 1) + }, + // Космопорт + { + new Color(0.7f, 0.5f, 0.4f, 1), + new Color(0.8f, 0.6f, 0.5f, 1), + new Color(0.6f, 0.4f, 0.3f, 1) + }, + // Энергокупол + { + new Color(0.9f, 0.6f, 0.3f, 1), + new Color(1.0f, 0.7f, 0.4f, 1), + new Color(0.8f, 0.5f, 0.2f, 1) + }, + // Водородный Завод + { + new Color(0.6f, 0.7f, 0.8f, 1), + new Color(0.7f, 0.8f, 0.9f, 1), + new Color(0.5f, 0.6f, 0.7f, 1) + }, + // Обсерватория + { + new Color(0.3f, 0.4f, 0.6f, 1), + new Color(0.4f, 0.5f, 0.7f, 1), + new Color(0.2f, 0.3f, 0.5f, 1) + }, + // Робо-Фабрика + { + new Color(0.5f, 0.5f, 0.5f, 1), + new Color(0.6f, 0.6f, 0.6f, 1), + new Color(0.4f, 0.4f, 0.4f, 1) + }, + // Биокупол + { + new Color(0.4f, 0.7f, 0.4f, 1), + new Color(0.5f, 0.8f, 0.5f, 1), + new Color(0.3f, 0.6f, 0.3f, 1) + } + }, + // 2. Венера - желтые, золотые, оранжевые + { + // Вулканический Дом + { + new Color(1.0f, 0.7f, 0.3f, 1), // Золотистый + new Color(1.0f, 0.8f, 0.4f, 1), // Желтый + new Color(0.9f, 0.6f, 0.2f, 1) // Оранжевый + }, + // Термальная Станция + { + new Color(1.0f, 0.6f, 0.2f, 1), + new Color(1.0f, 0.7f, 0.3f, 1), + new Color(0.9f, 0.5f, 0.1f, 1) + }, + // Золотой Дворец + { + new Color(1.0f, 0.9f, 0.3f, 1), + new Color(1.0f, 1.0f, 0.5f, 1), + new Color(0.9f, 0.8f, 0.2f, 1) + }, + // Облачный Город + { + new Color(1.0f, 0.95f, 0.8f, 1), + new Color(1.0f, 1.0f, 0.9f, 1), + new Color(0.95f, 0.9f, 0.7f, 1) + }, + // Кристальная Шахта + { + new Color(0.8f, 0.9f, 1.0f, 1), + new Color(0.9f, 1.0f, 1.0f, 1), + new Color(0.7f, 0.8f, 0.9f, 1) + }, + // Теплица + { + new Color(0.7f, 0.9f, 0.6f, 1), + new Color(0.8f, 1.0f, 0.7f, 1), + new Color(0.6f, 0.8f, 0.5f, 1) + }, + // Вихревой Генератор + { + new Color(0.9f, 0.8f, 0.5f, 1), + new Color(1.0f, 0.9f, 0.6f, 1), + new Color(0.8f, 0.7f, 0.4f, 1) + }, + // Сияющая Башня + { + new Color(1.0f, 0.95f, 0.7f, 1), + new Color(1.0f, 1.0f, 0.8f, 1), + new Color(0.95f, 0.9f, 0.6f, 1) + } + } + }; + + // Крыши в мультяшных цветах по планетам + public static final Color[][][] ROOF_COLORS_BY_PLANET = { + // Земля + { + { new Color(0.9f, 0.3f, 0.2f, 1), new Color(0.7f, 0.4f, 0.2f, 1) }, // Дома + { new Color(1.0f, 0.8f, 0.8f, 1), new Color(0.9f, 0.7f, 0.7f, 1) }, // Больницы + { new Color(0.4f, 0.7f, 1.0f, 1), new Color(0.3f, 0.6f, 0.9f, 1) }, // Школы + { new Color(1.0f, 0.8f, 0.4f, 1), new Color(0.9f, 0.5f, 0.9f, 1) }, // Площадки + { new Color(1.0f, 0.9f, 0.3f, 1), new Color(0.9f, 0.8f, 0.2f, 1) }, // Банки + { new Color(0.4f, 0.9f, 0.5f, 1), new Color(0.3f, 0.8f, 0.4f, 1) }, // Аптеки + { new Color(0.8f, 0.4f, 1.0f, 1), new Color(0.7f, 0.3f, 0.9f, 1) }, // Театры + { new Color(0.3f, 0.3f, 0.4f, 1), new Color(0.4f, 0.3f, 0.5f, 1) } // Кинотеатры + }, + // Марс + { + { new Color(0.7f, 0.2f, 0.1f, 1), new Color(0.6f, 0.1f, 0.0f, 1) }, // Марсианская База + { new Color(0.8f, 0.3f, 0.2f, 1), new Color(0.7f, 0.2f, 0.1f, 1) }, // Красная Лаборатория + { new Color(0.5f, 0.4f, 0.3f, 1), new Color(0.4f, 0.3f, 0.2f, 1) }, // Космопорт + { new Color(0.8f, 0.5f, 0.2f, 1), new Color(0.7f, 0.4f, 0.1f, 1) }, // Энергокупол + { new Color(0.4f, 0.5f, 0.7f, 1), new Color(0.3f, 0.4f, 0.6f, 1) }, // Водородный Завод + { new Color(0.2f, 0.3f, 0.5f, 1), new Color(0.1f, 0.2f, 0.4f, 1) }, // Обсерватория + { new Color(0.4f, 0.4f, 0.4f, 1), new Color(0.3f, 0.3f, 0.3f, 1) }, // Робо-Фабрика + { new Color(0.3f, 0.6f, 0.3f, 1), new Color(0.2f, 0.5f, 0.2f, 1) } // Биокупол + }, + // Венера + { + { new Color(0.8f, 0.4f, 0.1f, 1), new Color(0.7f, 0.3f, 0.0f, 1) }, // Вулканический Дом + { new Color(0.9f, 0.5f, 0.1f, 1), new Color(0.8f, 0.4f, 0.0f, 1) }, // Термальная Станция + { new Color(1.0f, 0.8f, 0.1f, 1), new Color(0.9f, 0.7f, 0.0f, 1) }, // Золотой Дворец + { new Color(1.0f, 1.0f, 0.8f, 1), new Color(0.9f, 0.9f, 0.7f, 1) }, // Облачный Город + { new Color(0.7f, 0.8f, 0.9f, 1), new Color(0.6f, 0.7f, 0.8f, 1) }, // Кристальная Шахта + { new Color(0.6f, 0.8f, 0.5f, 1), new Color(0.5f, 0.7f, 0.4f, 1) }, // Теплица + { new Color(0.8f, 0.7f, 0.4f, 1), new Color(0.7f, 0.6f, 0.3f, 1) }, // Вихревой Генератор + { new Color(0.95f, 0.9f, 0.6f, 1), new Color(0.85f, 0.8f, 0.5f, 1) } // Сияющая Башня + } + }; + + // Коэффициенты масштабирования для разных планет + public static final float[][] SIZE_SCALE_FACTORS_BY_PLANET = { + // Земля + {1.0f, 0.75f, 0.8f, 0.85f, 0.7f, 0.65f, 0.8f, 0.85f}, + // Марс (компактнее) + {0.9f, 0.7f, 0.8f, 0.75f, 0.65f, 0.6f, 0.7f, 0.75f}, + // Венера (выше) + {1.1f, 1.0f, 1.05f, 1.0f, 0.9f, 0.85f, 1.0f, 1.05f} + }; + + // Цвета для деталей по планетам + public static final Color[][] DETAIL_COLORS_BY_PLANET = { + // Земля + { + new Color(1.0f, 0.9f, 0.2f, 1), // Золотой + new Color(1.0f, 0.5f, 0.5f, 1), // Коралловый + new Color(0.5f, 0.8f, 1.0f, 1), // Голубой + new Color(0.8f, 1.0f, 0.5f, 1), // Лаймовый + new Color(1.0f, 0.7f, 1.0f, 1) // Розовый + }, + // Марс + { + new Color(1.0f, 0.6f, 0.2f, 1), // Оранжевый + new Color(0.8f, 0.3f, 0.2f, 1), // Красный + new Color(0.9f, 0.8f, 0.4f, 1), // Песочный + new Color(0.7f, 0.8f, 0.9f, 1), // Стальной + new Color(0.4f, 0.7f, 0.4f, 1) // Зеленый марсианский + }, + // Венера + { + new Color(1.0f, 0.9f, 0.3f, 1), // Золотой + new Color(1.0f, 0.7f, 0.2f, 1), // Янтарный + new Color(1.0f, 1.0f, 0.8f, 1), // Светло-желтый + new Color(0.9f, 0.6f, 0.1f, 1), // Темно-оранжевый + new Color(0.8f, 0.9f, 1.0f, 1) // Кристальный + } + }; + + // Цвета для названий по планетам + public static final Color[][] GLOWING_NAME_COLORS_BY_PLANET = { + // Земля + { + new Color(0.3f, 0.7f, 1.0f, 1), // Ярко-синий + new Color(1.0f, 0.4f, 0.4f, 1), // Ярко-красный + new Color(0.3f, 0.9f, 0.3f, 1), // Ярко-зелёный + new Color(1.0f, 0.7f, 0.2f, 1), // Оранжевый + new Color(0.8f, 0.4f, 1.0f, 1) // Фиолетовый + }, + // Марс + { + new Color(1.0f, 0.5f, 0.3f, 1), // Оранжево-красный + new Color(0.8f, 0.3f, 0.2f, 1), // Марсианский красный + new Color(0.9f, 0.7f, 0.4f, 1), // Песочный + new Color(0.6f, 0.8f, 0.9f, 1), // Голубой стальной + new Color(0.4f, 0.6f, 0.3f, 1) // Оливковый + }, + // Венера + { + new Color(1.0f, 0.9f, 0.3f, 1), // Золотой + new Color(1.0f, 0.7f, 0.2f, 1), // Янтарный + new Color(1.0f, 1.0f, 0.6f, 1), // Ярко-желтый + new Color(0.9f, 0.5f, 0.1f, 1), // Теплый оранжевый + new Color(1.0f, 0.95f, 0.8f, 1) // Светло-золотой + } + }; + + String type; + float x; + float y; + float width; + float height; + Color[] colors; + Color roofColor; + Color detailColor; + int constructionProgress; + boolean isOverlapping; + float[] cloudOffsets; + int colorThemeIndex; + boolean showName; + float namePulse; + Color nameColor; + float nameYOffset; + float wobbleOffset; + float wobbleSpeed; + float animationTimer; + float animationSpeed; + int buildingTypeIndex; + float sizeScale; + Random random; + Planet planet; + int planetIndex; + + public Building(String type, float x, float y, float width, float height, Random random, Planet planet) { + this.type = type; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.random = random; + this.planet = planet; + this.planetIndex = planet.ordinal(); + + this.buildingTypeIndex = findBuildingTypeIndex(type, planet); + this.sizeScale = SIZE_SCALE_FACTORS_BY_PLANET[planetIndex][buildingTypeIndex]; + this.colorThemeIndex = random.nextInt(3); + this.colors = BUILDING_COLOR_THEMES_BY_PLANET[planetIndex][buildingTypeIndex]; + this.roofColor = ROOF_COLORS_BY_PLANET[planetIndex][buildingTypeIndex][random.nextInt(2)]; + + Color[] planetDetailColors = DETAIL_COLORS_BY_PLANET[planetIndex]; + this.detailColor = planetDetailColors[random.nextInt(planetDetailColors.length)]; + + Color[] planetNameColors = GLOWING_NAME_COLORS_BY_PLANET[planetIndex]; + this.nameColor = planetNameColors[random.nextInt(planetNameColors.length)]; + + this.constructionProgress = 0; + this.isOverlapping = false; + this.showName = false; + this.namePulse = random.nextFloat() * 100; + this.nameYOffset = 0; + this.wobbleOffset = random.nextFloat() * 100; + this.wobbleSpeed = 0.3f + random.nextFloat() * 0.7f; + this.animationTimer = random.nextFloat() * 100; + this.animationSpeed = 0.5f + random.nextFloat() * 1.0f; + this.cloudOffsets = new float[3]; + for (int i = 0; i < 3; i++) { + cloudOffsets[i] = random.nextFloat() * 100; + } + } + + private int findBuildingTypeIndex(String type, Planet planet) { + String[] planetBuildings = BUILDING_TYPES_BY_PLANET[planet.ordinal()]; + for (int i = 0; i < planetBuildings.length; i++) { + if (planetBuildings[i].equals(type)) { + return i; + } + } + return 0; + } + + public void addBlock() { + if (constructionProgress < 3) constructionProgress++; + if (isComplete()) { + showName = true; + } + } + + public void removeBlock() { + if (constructionProgress > 0) constructionProgress--; + if (!isComplete()) { + showName = false; + } + } + + public boolean isComplete() { return constructionProgress >= 3; } + public float getCurrentHeight() { return (height * constructionProgress) / 3.0f; } + public Rectangle getBounds() { return new Rectangle(x, y, width, getCurrentHeight()); } + public Planet getPlanet() { return planet; } + + public void update(float deltaTime) { + animationTimer += deltaTime * animationSpeed; + + if (showName) { + namePulse += deltaTime * 2; + nameYOffset = (float)Math.sin(namePulse * 0.5f) * 3; + } + + if (isComplete()) { + wobbleOffset += deltaTime * wobbleSpeed; + } + } + + public float getWobbleX() { + if (!isComplete()) return 0; + return (float)Math.sin(wobbleOffset) * 2; + } + + public float getWobbleY() { + if (!isComplete()) return 0; + return (float)Math.cos(wobbleOffset * 1.5f) * 1.5f; + } + + public void createCitizensForBuilding(Array citizens, Random random) { + int citizenCount = 2 + random.nextInt(3); + + for (int i = 0; i < citizenCount; i++) { + float citizenX = x + random.nextFloat() * width; + float citizenY = y - 40; + Color clothesColor = DETAIL_COLORS_BY_PLANET[planetIndex][random.nextInt(DETAIL_COLORS_BY_PLANET[planetIndex].length)]; + + Citizen citizen = new Citizen(citizenX, citizenY, clothesColor, this, random, planet); + citizens.add(citizen); + } + } + + public float getSizeScale() { + return sizeScale; + } + + public Color getDetailColor() { + return detailColor; + } +} diff --git a/core/src/main/java/com/mygdx/game/BuildingPlacer.java b/core/src/main/java/com/mygdx/game/BuildingPlacer.java new file mode 100644 index 0000000..8482088 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/BuildingPlacer.java @@ -0,0 +1,112 @@ +package com.mygdx.game; + +import com.badlogic.gdx.math.Rectangle; + +public class BuildingPlacer { + public static void startNewBuildingAt(AbsurdCityBuilder1 game, float worldX, float worldY) { + Planet planet = game.getCurrentPlanet(); + String[] planetBuildings = Building.BUILDING_TYPES_BY_PLANET[planet.ordinal()]; + String selectedType = planetBuildings[game.getSelectedBuildingType()]; + + float width, height; + + // Разные размеры для разных планет + switch (planet) { + case EARTH: + switch (game.getSelectedBuildingType()) { + case 0: width = 180; height = 200; break; // Уютный Домик + case 1: width = 160; height = 180; break; // Детская Больница + case 2: width = 190; height = 170; break; // Весёлая Школа + case 3: width = 200; height = 160; break; // Игровая Площадка + case 4: width = 140; height = 180; break; // Надёжный Банк + case 5: width = 130; height = 160; break; // Здоровая Аптека + case 6: width = 190; height = 200; break; // Волшебный Театр + case 7: width = 180; height = 170; break; // КиноМир + default: width = 180; height = 200; break; + } + break; + case MARS: + // Марсианские здания (компактнее) + switch (game.getSelectedBuildingType()) { + case 0: width = 150; height = 180; break; // Марсианская База + case 1: width = 140; height = 160; break; // Красная Лаборатория + case 2: width = 170; height = 150; break; // Космопорт + case 3: width = 160; height = 170; break; // Энергокупол + case 4: width = 130; height = 160; break; // Водородный Завод + case 5: width = 120; height = 150; break; // Обсерватория + case 6: width = 140; height = 140; break; // Робо-Фабрика + case 7: width = 150; height = 160; break; // Биокупол + default: width = 150; height = 160; break; + } + break; + case VENUS: + // Венерианские здания (выше) + switch (game.getSelectedBuildingType()) { + case 0: width = 130; height = 200; break; // Вулканический Дом + case 1: width = 160; height = 190; break; // Термальная Станция + case 2: width = 180; height = 210; break; // Золотой Дворец + case 3: width = 170; height = 180; break; // Облачный Город + case 4: width = 140; height = 170; break; // Кристальная Шахта + case 5: width = 120; height = 160; break; // Теплица + case 6: width = 150; height = 190; break; // Вихревой Генератор + case 7: width = 160; height = 210; break; // Сияющая Башня + default: width = 150; height = 190; break; + } + break; + default: + width = 180; height = 200; break; + } + + float x = worldX; + float y = worldY; + + if (x < 10) x = 10; + if (x + width > game.getWIDTH() - 10) x = game.getWIDTH() - width - 10; + if (y + height > game.getHEIGHT()) y = game.getHEIGHT() - height; + if (y < game.getUI_INPUT_HEIGHT() + 10) y = game.getUI_INPUT_HEIGHT() + 10; + + Building tempBuilding = new Building(selectedType, x, y, width, height, game.getRandom(), planet); + tempBuilding.isOverlapping = checkForOverlaps(tempBuilding, game.getBuildings()); + game.setCurrentBuilding(tempBuilding); + game.setCurrentProblem(MathProblem.generateProblem(game.getBuildings().size, game.getRandom())); + + game.updateUI(); + + game.setMessageText(tempBuilding.isOverlapping ? + "🎨 Здание пересекается с существующими! Это добавляет уникальности! 🎨" : + "🌟 Отличное место для строительства! Введите ответ: 🌟"); + game.setMessageColor(tempBuilding.isOverlapping ? com.badlogic.gdx.graphics.Color.ORANGE : com.badlogic.gdx.graphics.Color.GREEN); + + game.setTyping(true); + game.getInputText().setLength(0); + } + + public static void handleBuildingClick(AbsurdCityBuilder1 game, float worldX, float worldY) { + if (game.getCurrentBuilding() != null) { + Rectangle buildingBounds = game.getCurrentBuilding().getBounds(); + if (buildingBounds.contains(worldX, worldY)) { + game.setMessageText("🎯 Кликните вне здания для нового строительства. Ctrl+Z или Delete для удаления. 🎯"); + game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN); + } else { + if (!game.isTyping()) { + startNewBuildingAt(game, worldX, worldY); + } + } + } else { + startNewBuildingAt(game, worldX, worldY); + } + } + + private static boolean checkForOverlaps(Building building, com.badlogic.gdx.utils.Array buildings) { + for (Building existing : buildings) { + if (isOverlapping(building.x, building.width, existing.x, existing.width)) { + return true; + } + } + return false; + } + + private static boolean isOverlapping(float x1, float width1, float x2, float width2) { + return x1 < x2 + width2 && x1 + width1 > x2; + } +} diff --git a/core/src/main/java/com/mygdx/game/BuildingRenderer.java b/core/src/main/java/com/mygdx/game/BuildingRenderer.java new file mode 100644 index 0000000..cb01884 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/BuildingRenderer.java @@ -0,0 +1,1302 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.utils.Array; + +public class BuildingRenderer { + private final ShapeRenderer shapeRenderer; + private final SpriteBatch batch; + private final BitmapFont font; + private final GlyphLayout glyphLayout; + private final Texture whitePixel; + + public BuildingRenderer(ShapeRenderer shapeRenderer, SpriteBatch batch, BitmapFont font, + GlyphLayout glyphLayout, Texture whitePixel) { + this.shapeRenderer = shapeRenderer; + this.batch = batch; + this.font = font; + this.glyphLayout = glyphLayout; + this.whitePixel = whitePixel; + } + + public void renderBuildings(Array buildings, Building currentBuilding, float time, Planet planet) { + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + + for (Building building : buildings) { + renderSingleBuilding(building, time, false, planet); + } + + if (currentBuilding != null) { + renderSingleBuilding(currentBuilding, time, true, planet); + } + + shapeRenderer.end(); + + // Рендерим детали поверх + renderBuildingDetails(buildings, currentBuilding, time); + } + + private void renderSingleBuilding(Building building, float time, boolean isCurrent, Planet planet) { + float x = building.x; + float y = building.y; + float width = building.width; + float height = building.height; + float scale = building.getSizeScale(); + + if (!building.isComplete()) { + renderConstructionPhase(building, x, y, width, height, time, isCurrent, planet); + return; + } + + // Для Земли используем старые методы + if (planet == Planet.EARTH) { + switch (building.buildingTypeIndex) { + case 0: renderCuteHouse(building, x, y, width, height, time, scale); break; + case 1: renderHospital(building, x, y, width, height, time, scale); break; + case 2: renderSchool(building, x, y, width, height, time, scale); break; + case 3: renderPlayground(building, x, y, width, height, time, scale); break; + case 4: renderBank(building, x, y, width, height, time, scale); break; + case 5: renderPharmacy(building, x, y, width, height, time, scale); break; + case 6: renderTheater(building, x, y, width, height, time, scale); break; + case 7: renderCinema(building, x, y, width, height, time, scale); break; + } + } else { + // Для Марса и Венеры используем универсальный рендеринг + renderPlanetBuilding(building, x, y, width, height, time, scale, planet); + } + } + + private void renderConstructionPhase(Building building, float x, float y, float width, float height, + float time, boolean isCurrent, Planet planet) { + float floorHeight = height / 3.0f; + Color buildingColor = building.colors[building.colorThemeIndex]; + float scale = building.getSizeScale(); + + // Фундамент с узором + shapeRenderer.setColor(new Color(0.7f, 0.6f, 0.5f, 1)); + shapeRenderer.rect(x - 10 * scale, y - 20 * scale, width + 20 * scale, 20 * scale); + + // Узор на фундаменте + shapeRenderer.setColor(new Color(0.8f, 0.7f, 0.6f, 1)); + for (int i = 0; i < 5; i++) { + shapeRenderer.rect(x - 8 * scale + i * (width + 16 * scale) / 5, + y - 18 * scale, + (width + 16 * scale) / 5 - 4 * scale, + 16 * scale); + } + + // Построенные этажи + for (int floor = 0; floor < building.constructionProgress; floor++) { + float floorY = y + floor * floorHeight; + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, floorY, width, floorHeight); + + // Окна на этажах + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.8f)); + int windows = 3; + float windowWidth = 25 * scale; + float windowHeight = 35 * scale; + float spacing = (width - windows * windowWidth) / (windows + 1); + + for (int i = 0; i < windows; i++) { + shapeRenderer.rect(x + spacing * (i + 1) + windowWidth * i, + floorY + floorHeight/2 - windowHeight/2, + windowWidth, windowHeight); + } + } + + if (isCurrent && building.isOverlapping) { + shapeRenderer.setColor(new Color(1, 0, 0, 0.3f)); + shapeRenderer.rect(x - 5, y - 5, width + 10, height + 10); + } + } + + // Универсальный рендеринг для зданий Марса и Венеры + private void renderPlanetBuilding(Building building, float x, float y, float width, float height, + float time, float scale, Planet planet) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height); + + // Специальные элементы в зависимости от планеты + switch (planet) { + case MARS: + renderMarsFeatures(building, x, y, width, height, time, scale); + break; + case VENUS: + renderVenusFeatures(building, x, y, width, height, time, scale); + break; + } + + // Крыша + shapeRenderer.setColor(building.roofColor); + shapeRenderer.rect(x - 10 * scale, y + height, width + 20 * scale, 15 * scale); + + // Окна + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.8f)); + int windows = 4; + float windowWidth = 20 * scale; + float windowHeight = 30 * scale; + float spacing = (width - windows * windowWidth) / (windows + 1); + + for (int i = 0; i < windows; i++) { + shapeRenderer.rect(x + spacing * (i + 1) + windowWidth * i, + y + height/2 - windowHeight/2, + windowWidth, windowHeight); + } + + // Детали + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width/2 - 15 * scale, y, 30 * scale, 50 * scale); // Дверь + } + + private void renderMarsFeatures(Building building, float x, float y, float width, float height, + float time, float scale) { + // Антенны для Марса + shapeRenderer.setColor(Color.GRAY); + shapeRenderer.rect(x + width/2 - 2, y + height, 4, 40 * scale); + shapeRenderer.circle(x + width/2, y + height + 40 * scale, 8 * scale); + + // Солнечные панели + shapeRenderer.setColor(new Color(0.2f, 0.3f, 0.4f, 1)); + shapeRenderer.rect(x - 30 * scale, y + height/2, 20 * scale, 40 * scale); + + // Мигающие огни + float flash = (float)Math.sin(time * 8) > 0 ? 1 : 0.3f; + shapeRenderer.setColor(new Color(1, flash, 0, 1)); + shapeRenderer.circle(x + 20 * scale, y + height - 10 * scale, 5 * scale); + shapeRenderer.circle(x + width - 20 * scale, y + height - 10 * scale, 5 * scale); + } + + private void renderVenusFeatures(Building building, float x, float y, float width, float height, + float time, float scale) { + // Кристаллы для Венеры + for (int i = 0; i < 3; i++) { + float crystalX = x + width/4 * (i + 1); + float crystalHeight = 30 * scale + i * 10 * scale; + + shapeRenderer.setColor(new Color(1.0f, 0.9f, 0.6f, 0.8f)); + shapeRenderer.triangle(crystalX - 8 * scale, y + height, + crystalX + 8 * scale, y + height, + crystalX, y + height + crystalHeight); + } + + // Тепловые выбросы + for (int i = 0; i < 2; i++) { + float heatX = x + (i == 0 ? 30 * scale : width - 30 * scale); + float heatY = y + 20 * scale + (float)Math.sin(time * 3 + i) * 5 * scale; + + shapeRenderer.setColor(new Color(1.0f, 0.5f, 0.2f, 0.7f)); + shapeRenderer.circle(heatX, heatY, 10 * scale); + } + } + + // ==================== ✨ УЮТНЫЙ ДОМИК ✨ ==================== + private void renderCuteHouse(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание с закругленными углами + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x + 10, y, width - 20, height * 0.8f); + + // Закругленные углы (круги по углам) + shapeRenderer.circle(x + 10, y + height * 0.8f, 10); + shapeRenderer.circle(x + width - 10, y + height * 0.8f, 10); + shapeRenderer.circle(x + 10, y, 10); + shapeRenderer.circle(x + width - 10, y, 10); + + // Мультяшная крыша + shapeRenderer.setColor(building.roofColor); + shapeRenderer.triangle( + x - 15, y + height * 0.8f, + x + width + 15, y + height * 0.8f, + x + width/2, y + height + 50 + ); + + // Узор на крыше + shapeRenderer.setColor(detailColor); + for (int i = 0; i < 5; i++) { + float tileX = x + i * (width / 5); + shapeRenderer.rect(tileX, y + height * 0.8f + 5, width/5 - 5, 10); + } + + // Дымящаяся труба + shapeRenderer.setColor(new Color(0.6f, 0.5f, 0.4f, 1)); + shapeRenderer.rect(x + width * 0.7f, y + height * 0.7f, 20, 45); + + // Анимированный дым + for (int i = 0; i < 3; i++) { + float smokeSize = 15 + i * 5; + float smokeY = y + height * 0.7f + 50 + i * 20 + (float)Math.sin(time * 2 + i) * 5; + float alpha = 0.7f - i * 0.2f; + shapeRenderer.setColor(new Color(0.95f, 0.95f, 0.95f, alpha)); + shapeRenderer.circle(x + width * 0.7f + 10, smokeY, smokeSize); + } + + // Окна с шторами + renderHouseWindows(building, x, y, width, height, time, scale); + + // Дверь с деталями + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width/2 - 25, y, 50, 70); + + // Дверная ручка + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.circle(x + width/2 + 15, y + 35, 8); + + // Клумба с цветами + shapeRenderer.setColor(new Color(0.3f, 0.7f, 0.3f, 1)); + shapeRenderer.rect(x - 15, y - 25, width + 30, 25); + + // Цветы в клумбе + for (int i = 0; i < 6; i++) { + float flowerX = x + 20 + i * 30; + float flowerY = y - 10 + (float)Math.sin(time * 3 + i) * 5; + + shapeRenderer.setColor(Color.RED); + shapeRenderer.circle(flowerX, flowerY, 8); + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.circle(flowerX, flowerY, 4); + } + } + + private void renderHouseWindows(Building building, float x, float y, float width, float height, float time, float scale) { + Color detailColor = building.getDetailColor(); + + // Левое окно + shapeRenderer.setColor(new Color(0.8f, 0.9f, 1.0f, 0.9f)); + shapeRenderer.rect(x + width * 0.25f - 20, y + height * 0.4f, 40, 50); + + // Рама окна + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width * 0.25f - 20, y + height * 0.4f + 22, 40, 3); + shapeRenderer.rect(x + width * 0.25f, y + height * 0.4f, 3, 50); + + // Шторы + shapeRenderer.setColor(new Color(1.0f, 0.8f, 0.9f, 0.6f)); + shapeRenderer.rect(x + width * 0.25f - 15, y + height * 0.4f + 35, 30, 15); + + // Правое окно + shapeRenderer.setColor(new Color(0.8f, 0.9f, 1.0f, 0.9f)); + shapeRenderer.rect(x + width * 0.75f - 20, y + height * 0.4f, 40, 50); + + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width * 0.75f - 20, y + height * 0.4f + 22, 40, 3); + shapeRenderer.rect(x + width * 0.75f, y + height * 0.4f, 3, 50); + + shapeRenderer.setColor(new Color(0.9f, 0.8f, 1.0f, 0.6f)); + shapeRenderer.rect(x + width * 0.75f - 15, y + height * 0.4f + 35, 30, 15); + + // Подоконник с цветами + for (int i = 0; i < 2; i++) { + float potX = x + width * (i == 0 ? 0.25f : 0.75f) - 5; + shapeRenderer.setColor(new Color(0.8f, 0.6f, 0.4f, 1)); + shapeRenderer.rect(potX, y + height * 0.4f - 10, 10, 10); + + // Цветок + float flowerY = y + height * 0.4f - 5 + (float)Math.sin(time * 4 + i) * 3; + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.circle(potX + 5, flowerY, 6); + } + } + + // ==================== 🏥 ДЕТСКАЯ БОЛЬНИЦА 🏥 ==================== + private void renderHospital(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height); + + // Яркие разноцветные полосы + Color[] stripeColors = { + new Color(1.0f, 0.5f, 0.5f, 1), // Коралловый + new Color(0.5f, 0.8f, 1.0f, 1), // Голубой + new Color(0.8f, 1.0f, 0.5f, 1) // Лаймовый + }; + + for (int i = 0; i < 3; i++) { + shapeRenderer.setColor(stripeColors[i]); + shapeRenderer.rect(x, y + height * (0.2f + i * 0.25f), width, 15 * scale); + } + + // Плоская крыша с ограждением + shapeRenderer.setColor(building.roofColor); + shapeRenderer.rect(x - 15 * scale, y + height, width + 30 * scale, 20 * scale); + + // Ограждение + shapeRenderer.setColor(detailColor); + for (int i = 0; i <= 8; i++) { + float postX = x - 10 * scale + i * ((width + 20 * scale) / 8); + shapeRenderer.rect(postX, y + height + 5 * scale, 6 * scale, 12 * scale); + } + + // Большой красный крест + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x + width/2 - 25 * scale, y + height - 20 * scale, 50 * scale, 10 * scale); + shapeRenderer.rect(x + width/2 - 10 * scale, y + height - 50 * scale, 20 * scale, 40 * scale); + + // Весёлые окна с животными + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.9f)); + int windows = 5; + float windowWidth = 25 * scale; + float windowHeight = 30 * scale; + float spacing = (width - windows * windowWidth) / (windows + 1); + + for (int i = 0; i < windows; i++) { + float windowX = x + spacing * (i + 1) + windowWidth * i; + shapeRenderer.rect(windowX, y + 60 * scale, windowWidth, windowHeight); + + // Наклейки животных в окнах + shapeRenderer.setColor(Color.YELLOW); + if (i % 3 == 0) shapeRenderer.circle(windowX + windowWidth/2, y + 60 * scale + windowHeight/2, 8 * scale); // Солнышко + else if (i % 3 == 1) { + shapeRenderer.triangle(windowX + 5 * scale, y + 60 * scale + 5 * scale, + windowX + windowWidth - 5 * scale, y + 60 * scale + 5 * scale, + windowX + windowWidth/2, y + 60 * scale + windowHeight - 5 * scale); // Сердечко + } else { + shapeRenderer.rect(windowX + 5 * scale, y + 60 * scale + 5 * scale, + windowWidth - 10 * scale, windowHeight - 10 * scale); // Звездочка + } + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.9f)); + } + + // Вход с пандусом + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width/2 - 40 * scale, y, 80 * scale, 50 * scale); + + // Пандус + shapeRenderer.setColor(new Color(0.8f, 0.8f, 0.8f, 1)); + shapeRenderer.rect(x + width/2 - 45 * scale, y - 20 * scale, 90 * scale, 20 * scale); + + // Машинка скорой помощи + renderAmbulance(building, x, y, time, scale); + } + + private void renderAmbulance(Building building, float x, float y, float time, float scale) { + float ambulanceX = x - 70 * scale; + float ambulanceY = y - 30 * scale; + + // Кузов + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(ambulanceX, ambulanceY, 65 * scale, 30 * scale); + + // Красная полоса + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(ambulanceX, ambulanceY + 25 * scale, 65 * scale, 5 * scale); + + // Мигающие фары + float flash = (float)Math.sin(time * 10) > 0 ? 1 : 0.3f; + shapeRenderer.setColor(new Color(1, 1, flash, 1)); + shapeRenderer.circle(ambulanceX + 10 * scale, ambulanceY + 15 * scale, 6 * scale); + shapeRenderer.circle(ambulanceX + 25 * scale, ambulanceY + 15 * scale, 6 * scale); + + // Сирена + shapeRenderer.setColor(new Color(flash, 0, 0, 1)); + shapeRenderer.circle(ambulanceX + 50 * scale, ambulanceY + 15 * scale, 8 * scale); + + // Колеса + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.circle(ambulanceX + 15 * scale, ambulanceY - 5 * scale, 7 * scale); + shapeRenderer.circle(ambulanceX + 45 * scale, ambulanceY - 5 * scale, 7 * scale); + + // Дверь + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(ambulanceX + 30 * scale, ambulanceY + 5 * scale, 20 * scale, 20 * scale); + } + + // ==================== 🎒 ВЕСЁЛАЯ ШКОЛА 🎒 ==================== + private void renderSchool(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height * 0.9f); + + // Кирпичный узор + shapeRenderer.setColor(new Color(0.8f, 0.6f, 0.5f, 0.3f)); + int bricksX = 8; + int bricksY = 4; + float brickWidth = width / bricksX; + float brickHeight = (height * 0.9f) / bricksY; + + for (int i = 0; i < bricksX; i++) { + for (int j = 0; j < bricksY; j++) { + if ((i + j) % 2 == 0) { + shapeRenderer.rect(x + i * brickWidth + 2, + y + j * brickHeight + 2, + brickWidth - 4, + brickHeight - 4); + } + } + } + + // Яркая крыша + shapeRenderer.setColor(building.roofColor); + shapeRenderer.rect(x - 20 * scale, y + height * 0.9f, width + 40 * scale, 30 * scale); + + // Флагшток с анимированным флагом + shapeRenderer.setColor(new Color(0.5f, 0.4f, 0.3f, 1)); + shapeRenderer.rect(x + width * 0.85f, y + height * 0.9f, 8 * scale, 60 * scale); + + float flagWave = (float)Math.sin(time * 3) * 20; + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(x + width * 0.85f + 8 * scale, + y + height * 0.9f + 40 * scale + flagWave, + 35 * scale, 20 * scale); + shapeRenderer.setColor(new Color(0.3f, 0.6f, 1.0f, 1)); + shapeRenderer.rect(x + width * 0.85f + 8 * scale, + y + height * 0.9f + 40 * scale + flagWave, + 35 * scale, 10 * scale); + + // Большие школьные окна + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.9f)); + int windowRows = 3; + int windowCols = 4; + float windowWidth = 35 * scale; + float windowHeight = 45 * scale; + float hSpacing = (width - windowCols * windowWidth) / (windowCols + 1); + float vSpacing = (height * 0.7f - windowRows * windowHeight) / (windowRows + 1); + + for (int row = 0; row < windowRows; row++) { + for (int col = 0; col < windowCols; col++) { + float windowX = x + hSpacing * (col + 1) + windowWidth * col; + float windowY = y + vSpacing * (row + 1) + windowHeight * row + height * 0.1f; + shapeRenderer.rect(windowX, windowY, windowWidth, windowHeight); + + // Переплеты окон + shapeRenderer.setColor(new Color(0.4f, 0.3f, 0.2f, 1)); + shapeRenderer.rect(windowX, windowY + windowHeight/2 - 2, windowWidth, 4); + shapeRenderer.rect(windowX + windowWidth/2 - 2, windowY, 4, windowHeight); + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.9f)); + } + } + + // Вход с колоннами + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width/2 - 40 * scale, y, 80 * scale, 70 * scale); + + // Колонны + shapeRenderer.setColor(new Color(0.7f, 0.6f, 0.5f, 1)); + shapeRenderer.rect(x + width/2 - 35 * scale, y, 12 * scale, 70 * scale); + shapeRenderer.rect(x + width/2 + 23 * scale, y, 12 * scale, 70 * scale); + + // Доска объявлений + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(x + width + 20 * scale, y + 40 * scale, 50 * scale, 70 * scale); + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rect(x + width + 22 * scale, y + 42 * scale, 46 * scale, 66 * scale); + + // Надпись на доске + shapeRenderer.setColor(Color.YELLOW); + for (int i = 0; i < 3; i++) { + shapeRenderer.rect(x + width + 30 * scale, + y + 50 * scale + i * 15 * scale, + 30 * scale, 5 * scale); + } + + // Игровая площадка рядом + renderSchoolPlayground(building, x, y, width, height, time, scale); + } + + private void renderSchoolPlayground(Building building, float x, float y, float width, float height, float time, float scale) { + float playgroundX = x + width + 10 * scale; + float playgroundY = y; + + // Площадка + shapeRenderer.setColor(new Color(0.6f, 0.8f, 0.4f, 1)); + shapeRenderer.rect(playgroundX, playgroundY, 60 * scale, 40 * scale); + + // Качели + float swingOffset = (float)Math.sin(time * 4) * 15 * scale; + shapeRenderer.setColor(new Color(0.8f, 0.5f, 0.2f, 1)); + shapeRenderer.rect(playgroundX + 20 * scale, playgroundY, 5 * scale, 25 * scale); + shapeRenderer.rect(playgroundX + 10 * scale, playgroundY + 25 * scale, 25 * scale, 5 * scale); + + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.rect(playgroundX + 18 * scale, playgroundY + swingOffset, 10 * scale, 5 * scale); + + // Баскетбольное кольцо + shapeRenderer.setColor(Color.ORANGE); + shapeRenderer.rect(playgroundX + 45 * scale, playgroundY + 30 * scale, 4 * scale, 15 * scale); + shapeRenderer.circle(playgroundX + 47 * scale, playgroundY + 45 * scale, 12 * scale); + } + + // ==================== 🎪 ИГРОВАЯ ПЛОЩАДКА 🎪 ==================== + private void renderPlayground(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Трава + shapeRenderer.setColor(new Color(0.4f, 0.8f, 0.4f, 1)); + shapeRenderer.rect(x, y, width, height * 0.6f); + + // Песочница + shapeRenderer.setColor(new Color(0.95f, 0.85f, 0.6f, 1)); + shapeRenderer.rect(x + 30 * scale, y + 20 * scale, 60 * scale, 50 * scale); + + // Бортик песочницы + shapeRenderer.setColor(new Color(0.8f, 0.6f, 0.4f, 1)); + shapeRenderer.rect(x + 28 * scale, y + 18 * scale, 64 * scale, 4 * scale); + shapeRenderer.rect(x + 28 * scale, y + 70 * scale, 64 * scale, 4 * scale); + shapeRenderer.rect(x + 28 * scale, y + 18 * scale, 4 * scale, 56 * scale); + shapeRenderer.rect(x + 88 * scale, y + 18 * scale, 4 * scale, 56 * scale); + + // Замок из песка + shapeRenderer.setColor(new Color(0.9f, 0.8f, 0.7f, 1)); + shapeRenderer.rect(x + 50 * scale, y + 40 * scale, 20 * scale, 15 * scale); + shapeRenderer.triangle(x + 50 * scale, y + 55 * scale, + x + 70 * scale, y + 55 * scale, + x + 60 * scale, y + 65 * scale); + + // Качели + float swingOffset = (float)Math.sin(time * 3) * 20 * scale; + shapeRenderer.setColor(new Color(0.8f, 0.5f, 0.2f, 1)); + // Стойки + shapeRenderer.rect(x + width - 50 * scale, y + 10 * scale, 6 * scale, 30 * scale); + shapeRenderer.rect(x + width - 80 * scale, y + 10 * scale, 6 * scale, 30 * scale); + // Перекладина + shapeRenderer.rect(x + width - 82 * scale, y + 40 * scale, 40 * scale, 6 * scale); + // Сиденье + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x + width - 65 * scale, y + 10 * scale + swingOffset, 20 * scale, 5 * scale); + // Цепи + shapeRenderer.setColor(Color.GRAY); + shapeRenderer.rectLine(x + width - 75 * scale, y + 40 * scale, + x + width - 60 * scale, y + 15 * scale + swingOffset, + 3 * scale); + shapeRenderer.rectLine(x + width - 55 * scale, y + 40 * scale, + x + width - 50 * scale, y + 15 * scale + swingOffset, + 3 * scale); + + // Горка + shapeRenderer.setColor(new Color(1.0f, 0.7f, 0.3f, 1)); + shapeRenderer.triangle(x + 10 * scale, y + 10 * scale, + x + 50 * scale, y + 60 * scale, + x + 90 * scale, y + 10 * scale); + + // Ступеньки горки + shapeRenderer.setColor(new Color(0.7f, 0.5f, 0.3f, 1)); + for (int i = 0; i < 5; i++) { + shapeRenderer.rect(x + 15 * scale + i * 7 * scale, + y + 10 * scale + i * 5 * scale, + 5 * scale, 3 * scale); + } + + // Карусель + float carouselAngle = time * 50; + shapeRenderer.setColor(Color.RED); + shapeRenderer.circle(x + width/2, y + 40 * scale, 25 * scale); + + shapeRenderer.setColor(Color.YELLOW); + for (int i = 0; i < 4; i++) { + float angle = carouselAngle + i * 90; + float seatX = x + width/2 + (float)Math.cos(Math.toRadians(angle)) * 18 * scale; + float seatY = y + 40 * scale + (float)Math.sin(Math.toRadians(angle)) * 18 * scale; + shapeRenderer.circle(seatX, seatY, 8 * scale); + } + + // Деревья + for (int i = 0; i < 2; i++) { + float treeX = x + (i == 0 ? 10 * scale : width - 30 * scale); + shapeRenderer.setColor(new Color(0.5f, 0.3f, 0.2f, 1)); + shapeRenderer.rect(treeX, y - 25 * scale, 8 * scale, 25 * scale); + shapeRenderer.setColor(new Color(0.3f, 0.7f, 0.3f, 1)); + shapeRenderer.circle(treeX + 4 * scale, y, 15 * scale); + shapeRenderer.circle(treeX - 6 * scale, y - 5 * scale, 12 * scale); + shapeRenderer.circle(treeX + 14 * scale, y - 5 * scale, 12 * scale); + } + + // Воздушные шарики + Color[] balloonColors = {Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN, Color.PINK}; + for (int i = 0; i < 5; i++) { + float balloonX = x + 20 * scale + i * 25 * scale; + float balloonY = y + height * 0.6f + 30 * scale + (float)Math.sin(time * 2 + i) * 10 * scale; + + shapeRenderer.setColor(balloonColors[i]); + shapeRenderer.circle(balloonX, balloonY, 12 * scale); + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rectLine(balloonX, balloonY - 12 * scale, + balloonX, balloonY - 25 * scale, + 2 * scale); + } + } + + // ==================== 💰 НАДЁЖНЫЙ БАНК 💰 ==================== + private void renderBank(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height); + + // Колонны + shapeRenderer.setColor(new Color(0.9f, 0.85f, 0.75f, 1)); + int columns = 6; + float columnWidth = 10 * scale; + float spacing = (width - columns * columnWidth) / (columns + 1); + + for (int i = 0; i < columns; i++) { + float colX = x + spacing * (i + 1) + columnWidth * i; + shapeRenderer.rect(colX, y, columnWidth, height * 0.8f); + + // Капители колонн + shapeRenderer.setColor(new Color(1.0f, 0.9f, 0.5f, 1)); + shapeRenderer.rect(colX - 2 * scale, y + height * 0.8f, columnWidth + 4 * scale, 8 * scale); + shapeRenderer.setColor(new Color(0.9f, 0.85f, 0.75f, 1)); + } + + // Крыша с фронтоном + shapeRenderer.setColor(building.roofColor); + shapeRenderer.triangle( + x - 25 * scale, y + height * 0.8f, + x + width + 25 * scale, y + height * 0.8f, + x + width/2, y + height + 60 * scale + ); + + // Золотая надпись "БАНК" + shapeRenderer.setColor(Color.GOLD); + for (int i = 0; i < 4; i++) { + shapeRenderer.rect(x + width/2 - 60 * scale + i * 40 * scale, + y + height * 0.85f, + 30 * scale, 8 * scale); + } + + // Большие часы на фасаде + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.circle(x + width/2, y + height * 0.5f, 40 * scale); + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.circle(x + width/2, y + height * 0.5f, 38 * scale); + + // Стрелки часов + float hourAngle = time * 30; + float minuteAngle = time * 360; + + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rectLine(x + width/2, y + height * 0.5f, + x + width/2 + (float)Math.cos(Math.toRadians(hourAngle - 90)) * 20 * scale, + y + height * 0.5f + (float)Math.sin(Math.toRadians(hourAngle - 90)) * 20 * scale, + 4 * scale); + shapeRenderer.rectLine(x + width/2, y + height * 0.5f, + x + width/2 + (float)Math.cos(Math.toRadians(minuteAngle - 90)) * 30 * scale, + y + height * 0.5f + (float)Math.sin(Math.toRadians(minuteAngle - 90)) * 30 * scale, + 2 * scale); + + // Массивная дверь + shapeRenderer.setColor(new Color(0.5f, 0.4f, 0.3f, 1)); + float doorWidth = width * 0.3f; + shapeRenderer.rect(x + width/2 - doorWidth/2, y, doorWidth, 80 * scale); + + // Золотые детали двери + shapeRenderer.setColor(Color.GOLD); + // Ручки + shapeRenderer.circle(x + width/2 - doorWidth/4, y + 40 * scale, 10 * scale); + shapeRenderer.circle(x + width/2 + doorWidth/4, y + 40 * scale, 10 * scale); + // Замок + shapeRenderer.rect(x + width/2 - 5 * scale, y + 20 * scale, 10 * scale, 15 * scale); + + // Охранник + renderBankSecurity(building, x, y, width, height, time, scale); + + // Банкомат + shapeRenderer.setColor(Color.GRAY); + shapeRenderer.rect(x + width + 20 * scale, y + 30 * scale, 40 * scale, 60 * scale); + shapeRenderer.setColor(Color.BLUE); + shapeRenderer.rect(x + width + 25 * scale, y + 40 * scale, 30 * scale, 20 * scale); + shapeRenderer.setColor(Color.GREEN); + shapeRenderer.circle(x + width + 40 * scale, y + 70 * scale, 8 * scale); + } + + private void renderBankSecurity(Building building, float x, float y, float width, float height, float time, float scale) { + float guardX = x - 50 * scale; + float guardY = y + 20 * scale; + + // Тело + shapeRenderer.setColor(Color.DARK_GRAY); + shapeRenderer.rect(guardX - 10 * scale, guardY, 20 * scale, 45 * scale); + + // Голова + shapeRenderer.setColor(new Color(0.95f, 0.8f, 0.6f, 1)); + shapeRenderer.circle(guardX, guardY + 50 * scale, 15 * scale); + + // Форма + shapeRenderer.setColor(Color.NAVY); + shapeRenderer.rect(guardX - 8 * scale, guardY + 15 * scale, 16 * scale, 25 * scale); + + // Шлем + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rect(guardX - 12 * scale, guardY + 45 * scale, 24 * scale, 8 * scale); + + // Рация + shapeRenderer.setColor(Color.GRAY); + shapeRenderer.rect(guardX + 12 * scale, guardY + 25 * scale, 10 * scale, 20 * scale); + + // Собака охраны + float dogX = guardX + 30 * scale; + float dogY = guardY; + + shapeRenderer.setColor(new Color(0.4f, 0.3f, 0.2f, 1)); + // Тело + shapeRenderer.rect(dogX - 8 * scale, dogY, 16 * scale, 12 * scale); + // Голова + shapeRenderer.circle(dogX, dogY + 15 * scale, 8 * scale); + // Уши + shapeRenderer.triangle(dogX - 5 * scale, dogY + 20 * scale, + dogX - 10 * scale, dogY + 30 * scale, + dogX, dogY + 20 * scale); + shapeRenderer.triangle(dogX + 5 * scale, dogY + 20 * scale, + dogX + 10 * scale, dogY + 30 * scale, + dogX, dogY + 20 * scale); + // Хвост + shapeRenderer.rectLine(dogX + 8 * scale, dogY + 6 * scale, + dogX + 20 * scale, dogY + (float)Math.sin(time * 5) * 10 * scale, + 3 * scale); + } + + // ==================== 💊 ЗДОРОВАЯ АПТЕКА 💊 ==================== + private void renderPharmacy(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height * 0.9f); + + // Зелёная крыша + shapeRenderer.setColor(building.roofColor); + shapeRenderer.rect(x - 10 * scale, y + height * 0.9f, width + 20 * scale, 20 * scale); + + // Большой зелёный крест + shapeRenderer.setColor(new Color(0.2f, 0.8f, 0.2f, 1)); + shapeRenderer.rect(x + width/2 - 30 * scale, y + height * 0.7f, 60 * scale, 12 * scale); + shapeRenderer.rect(x + width/2 - 12 * scale, y + height * 0.6f, 24 * scale, 40 * scale); + + // Неоновая вывеска + float neon = 0.5f + 0.5f * (float)Math.sin(time * 8); + shapeRenderer.setColor(new Color(0, neon, 0, 1)); + shapeRenderer.rect(x + width/2 - 40 * scale, y + height * 0.85f, 80 * scale, 8 * scale); + + // Большая витрина + shapeRenderer.setColor(new Color(0.95f, 0.98f, 1.0f, 0.9f)); + shapeRenderer.rect(x + 20 * scale, y + 30 * scale, width - 40 * scale, 60 * scale); + + // Полки с лекарствами + shapeRenderer.setColor(new Color(0.8f, 0.7f, 0.6f, 1)); + for (int i = 0; i < 4; i++) { + shapeRenderer.rect(x + 25 * scale, y + 35 * scale + i * 15 * scale, width - 50 * scale, 5 * scale); + } + + // Лекарства на полках + renderMedicines(building, x, y, width, height, time, scale); + + // Вход + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(x + width/2 - 25 * scale, y, 50 * scale, 50 * scale); + + // Автоматические двери + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.7f)); + float doorOpen = (float)Math.sin(time * 5) * 0.5f + 0.5f; + shapeRenderer.rect(x + width/2 - 22 * scale, y, 20 * scale * doorOpen, 45 * scale); + shapeRenderer.rect(x + width/2 + 2 * scale, y, 20 * scale * doorOpen, 45 * scale); + + // Витрина с витаминами + shapeRenderer.setColor(new Color(1.0f, 0.95f, 0.9f, 1)); + shapeRenderer.rect(x - 60 * scale, y + 40 * scale, 50 * scale, 70 * scale); + + // Витамины + Color[] vitaminColors = {Color.ORANGE, Color.YELLOW, Color.RED, Color.GREEN, Color.PURPLE}; + for (int i = 0; i < 5; i++) { + shapeRenderer.setColor(vitaminColors[i]); + shapeRenderer.circle(x - 40 * scale + i % 3 * 15 * scale, + y + 60 * scale + (i / 3) * 20 * scale, + 8 * scale); + } + + // Гирлянда + for (int i = 0; i < 8; i++) { + float lightX = x + i * (width / 7); + float brightness = 0.5f + 0.5f * (float)Math.sin(time * 4 + i); + shapeRenderer.setColor(new Color(brightness, 1, brightness, 1)); + shapeRenderer.circle(lightX, y + height * 0.95f, 6 * scale); + } + } + + private void renderMedicines(Building building, float x, float y, float width, float height, float time, float scale) { + // Разноцветные лекарства + Color[] medicineColors = { + Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, + new Color(1, 0.5f, 0, 1), new Color(0.5f, 0, 1, 1) + }; + + // Бутылочки + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 5; col++) { + float medX = x + 30 * scale + col * 25 * scale; + float medY = y + 40 * scale + row * 20 * scale; + int colorIndex = (row * 5 + col) % medicineColors.length; + + shapeRenderer.setColor(medicineColors[colorIndex]); + // Бутылочка + shapeRenderer.rect(medX, medY, 15 * scale, 25 * scale); + // Горлышко + shapeRenderer.rect(medX + 5 * scale, medY + 25 * scale, 5 * scale, 5 * scale); + // Крышечка + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(medX + 5 * scale, medY + 30 * scale, 5 * scale, 3 * scale); + } + } + + // Таблетки + for (int i = 0; i < 10; i++) { + float pillX = x + 35 * scale + (i % 5) * 30 * scale; + float pillY = y + 110 * scale + (i / 5) * 15 * scale; + + if (i % 2 == 0) { + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.circle(pillX, pillY, 6 * scale); + shapeRenderer.setColor(Color.RED); + shapeRenderer.circle(pillX, pillY, 4 * scale); + } else { + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(pillX - 8 * scale, pillY - 4 * scale, 16 * scale, 8 * scale); + shapeRenderer.setColor(Color.BLUE); + shapeRenderer.rect(pillX - 6 * scale, pillY - 3 * scale, 12 * scale, 6 * scale); + } + } + } + + // ==================== 🎭 ВОЛШЕБНЫЙ ТЕАТР 🎭 ==================== + private void renderTheater(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height * 0.8f); + + // Величественный портик с колоннами + shapeRenderer.setColor(new Color(0.95f, 0.9f, 0.8f, 1)); + shapeRenderer.rect(x - 30 * scale, y, width + 60 * scale, 100 * scale); + + // Большие колонны + shapeRenderer.setColor(new Color(0.9f, 0.85f, 0.75f, 1)); + int columns = 8; + float columnWidth = 12 * scale; + float columnSpacing = (width + 60 * scale - columns * columnWidth) / (columns + 1); + + for (int i = 0; i < columns; i++) { + float colX = x - 30 * scale + columnSpacing * (i + 1) + columnWidth * i; + shapeRenderer.rect(colX, y, columnWidth, 90 * scale); + + // Капители + shapeRenderer.setColor(new Color(1.0f, 0.9f, 0.7f, 1)); + shapeRenderer.rect(colX - 3 * scale, y + 90 * scale, columnWidth + 6 * scale, 10 * scale); + shapeRenderer.setColor(new Color(0.9f, 0.85f, 0.75f, 1)); + } + + // Фронтон + shapeRenderer.setColor(building.roofColor); + shapeRenderer.triangle( + x - 40 * scale, y + 100 * scale, + x + width + 40 * scale, y + 100 * scale, + x + width/2, y + 150 * scale + ); + + // Театральные маски на фронтоне + shapeRenderer.setColor(Color.GOLD); + // Комедия + float smileMaskX = x + width/2 - 40 * scale; + shapeRenderer.circle(smileMaskX, y + 120 * scale, 25 * scale); + shapeRenderer.setColor(Color.BLACK); + // Глаза + shapeRenderer.circle(smileMaskX - 10 * scale, y + 125 * scale, 6 * scale); + shapeRenderer.circle(smileMaskX + 10 * scale, y + 125 * scale, 6 * scale); + // Улыбка + shapeRenderer.arc(smileMaskX, y + 115 * scale, 15 * scale, 0, 180, 20); + + // Трагедия + float sadMaskX = x + width/2 + 40 * scale; + shapeRenderer.setColor(Color.GOLD); + shapeRenderer.circle(sadMaskX, y + 120 * scale, 25 * scale); + shapeRenderer.setColor(Color.BLACK); + // Глазы + shapeRenderer.circle(sadMaskX - 10 * scale, y + 125 * scale, 6 * scale); + shapeRenderer.circle(sadMaskX + 10 * scale, y + 125 * scale, 6 * scale); + // Грустный рот + shapeRenderer.arc(sadMaskX, y + 135 * scale, 15 * scale, 180, 180, 20); + + // Красная ковровая дорожка + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x + width/2 - 50 * scale, y - 30 * scale, 100 * scale, 30 * scale); + + // Золотые звёзды на дорожке + shapeRenderer.setColor(Color.GOLD); + for (int i = 0; i < 5; i++) { + float starX = x + width/2 - 40 * scale + i * 20 * scale; + shapeRenderer.circle(starX, y - 15 * scale, 8 * scale); + } + + // Билборд с афишей + shapeRenderer.setColor(new Color(0.2f, 0.1f, 0.3f, 1)); + shapeRenderer.rect(x - 100 * scale, y + 50 * scale, 80 * scale, 120 * scale); + + // Афиша + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.rect(x - 96 * scale, y + 54 * scale, 72 * scale, 112 * scale); + + // Изображение на афише + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x - 90 * scale, y + 60 * scale, 60 * scale, 40 * scale); // Занавес + shapeRenderer.setColor(Color.GOLD); + shapeRenderer.circle(x - 60 * scale, y + 120 * scale, 15 * scale); // Маска + shapeRenderer.setColor(new Color(0.3f, 0.2f, 0.1f, 1)); + for (int i = 0; i < 3; i++) { + shapeRenderer.rect(x - 85 * scale, y + 110 * scale + i * 15 * scale, 50 * scale, 5 * scale); // Текст + } + + // Освещение + for (int i = 0; i < 4; i++) { + float spotX = x + i * (width / 3); + float spotBrightness = 0.7f + 0.3f * (float)Math.sin(time * 3 + i); + shapeRenderer.setColor(new Color(1, 1, spotBrightness, 0.8f)); + shapeRenderer.triangle(spotX - 15 * scale, y + 100 * scale, + spotX + 15 * scale, y + 100 * scale, + spotX, y + 130 * scale); + } + + // Входные двери + shapeRenderer.setColor(new Color(0.6f, 0.5f, 0.4f, 1)); + shapeRenderer.rect(x + width/2 - 40 * scale, y, 35 * scale, 70 * scale); + shapeRenderer.rect(x + width/2 + 5 * scale, y, 35 * scale, 70 * scale); + + // Золотые ручки + shapeRenderer.setColor(Color.GOLD); + shapeRenderer.circle(x + width/2 - 25 * scale, y + 35 * scale, 8 * scale); + shapeRenderer.circle(x + width/2 + 25 * scale, y + 35 * scale, 8 * scale); + + // Очередь (анимированная) + for (int i = 0; i < 5; i++) { + float personX = x + width + 20 * scale + i * 20 * scale; + float personY = y + 20 * scale + (float)Math.sin(time * 2 + i) * 5 * scale; + + shapeRenderer.setColor(detailColor); + shapeRenderer.rect(personX - 5 * scale, personY, 10 * scale, 20 * scale); + shapeRenderer.setColor(new Color(0.95f, 0.8f, 0.6f, 1)); + shapeRenderer.circle(personX, personY + 25 * scale, 8 * scale); + } + } + + // ==================== 🎬 КИНОМИР 🎬 ==================== + private void renderCinema(Building building, float x, float y, float width, float height, float time, float scale) { + Color buildingColor = building.colors[building.colorThemeIndex]; + Color detailColor = building.getDetailColor(); + + // Основное здание + shapeRenderer.setColor(buildingColor); + shapeRenderer.rect(x, y, width, height * 0.7f); + + // Гигантский экран + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rect(x + 20 * scale, y + height * 0.7f - 100 * scale, width - 40 * scale, 80 * scale); + + // Анимированное кино на экране + float movieTime = time * 5; + Color[] movieColors = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.MAGENTA}; + + for (int i = 0; i < 6; i++) { + for (int j = 0; j < 4; j++) { + float cellX = x + 30 * scale + i * 30 * scale; + float cellY = y + height * 0.7f - 90 * scale + j * 20 * scale; + int colorIndex = ((int)(movieTime) + i + j) % movieColors.length; + float brightness = 0.3f + 0.7f * (float)Math.abs(Math.sin(movieTime + i * 0.3f + j * 0.2f)); + + Color cellColor = movieColors[colorIndex]; + shapeRenderer.setColor(new Color( + cellColor.r * brightness, + cellColor.g * brightness, + cellColor.b * brightness, + 1 + )); + shapeRenderer.rect(cellX, cellY, 25 * scale, 15 * scale); + } + } + + // Неоновая вывеска "КИНО" + shapeRenderer.setColor(building.roofColor); + shapeRenderer.rect(x - 20 * scale, y + height * 0.7f, width + 40 * scale, 35 * scale); + + // Мигающие неоновые буквы + for (int i = 0; i < 4; i++) { + float letterX = x + 40 * scale + i * 60 * scale; + float neonFlash = (float)Math.sin(time * 8 + i * 2) > 0 ? 1 : 0.3f; + + shapeRenderer.setColor(new Color(1, neonFlash, neonFlash, 1)); + shapeRenderer.rect(letterX, y + height * 0.7f + 10 * scale, 40 * scale, 20 * scale); + } + + // Билборд с новинками + shapeRenderer.setColor(new Color(0.4f, 0.2f, 0.6f, 1)); + shapeRenderer.rect(x - 120 * scale, y + 60 * scale, 100 * scale, 150 * scale); + + // Постеры на билборде + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x - 115 * scale, y + 65 * scale, 90 * scale, 60 * scale); + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.rect(x - 115 * scale, y + 130 * scale, 90 * scale, 60 * scale); + + // Звёзды на постерах + shapeRenderer.setColor(Color.WHITE); + for (int i = 0; i < 5; i++) { + float starX = x - 100 * scale + i * 20 * scale; + shapeRenderer.circle(starX, y + 75 * scale, 4 * scale); + shapeRenderer.circle(starX, y + 145 * scale, 4 * scale); + } + + // Входная группа с билетными кассами + shapeRenderer.setColor(new Color(0.3f, 0.3f, 0.4f, 1)); + shapeRenderer.rect(x + width/2 - 60 * scale, y, 120 * scale, 60 * scale); + + // Окошки касс + shapeRenderer.setColor(new Color(0.9f, 0.95f, 1.0f, 0.9f)); + shapeRenderer.rect(x + width/2 - 50 * scale, y + 10 * scale, 40 * scale, 25 * scale); + shapeRenderer.rect(x + width/2 + 10 * scale, y + 10 * scale, 40 * scale, 25 * scale); + + // Попкорн-машина + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x - 80 * scale, y, 60 * scale, 80 * scale); + shapeRenderer.setColor(Color.YELLOW); + // Попкорн + for (int i = 0; i < 20; i++) { + float popcornX = x - 60 * scale + (building.random.nextFloat() - 0.5f) * 40 * scale; + float popcornY = y + 30 * scale + (building.random.nextFloat() - 0.5f) * 40 * scale; + float popcornSize = 3 * scale + building.random.nextFloat() * 4 * scale; + + shapeRenderer.setColor(new Color(1, 1, building.random.nextFloat() * 0.3f, 1)); + shapeRenderer.circle(popcornX, popcornY, popcornSize); + } + + // Стаканчик с попкорном + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(x - 65 * scale, y + 85 * scale, 30 * scale, 40 * scale); + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.rect(x - 62 * scale, y + 88 * scale, 24 * scale, 34 * scale); + + // Напитки + shapeRenderer.setColor(new Color(0, 0.5f, 1, 1)); + shapeRenderer.rect(x - 40 * scale, y, 25 * scale, 60 * scale); + shapeRenderer.setColor(new Color(1, 0.5f, 0, 1)); + shapeRenderer.rect(x - 10 * scale, y, 25 * scale, 60 * scale); + + // Очередь в кино + renderCinemaQueue(building, x, y, width, height, time, scale); + + // Проекционные лучи + shapeRenderer.setColor(new Color(1, 1, 1, 0.3f)); + shapeRenderer.rectLine(x + width/2, y + height * 0.7f + 35 * scale, + x + width/2, y + height * 0.7f - 20 * scale, + 10 * scale); + } + + private void renderCinemaQueue(Building building, float x, float y, float width, float height, float time, float scale) { + // Люди в очереди + Color[] peopleColors = { + new Color(1, 0.6f, 0.6f, 1), // Розовый + new Color(0.6f, 0.8f, 1, 1), // Голубой + new Color(0.8f, 1, 0.6f, 1), // Лаймовый + new Color(1, 1, 0.6f, 1), // Жёлтый + new Color(1, 0.8f, 1, 1) // Сиреневый + }; + + for (int i = 0; i < 6; i++) { + float personX = x + width + 20 * scale + i * 18 * scale; + float personY = y + 30 * scale + (float)Math.sin(time * 2 + i) * 8 * scale; + + // Тело + shapeRenderer.setColor(peopleColors[i % peopleColors.length]); + shapeRenderer.rect(personX - 6 * scale, personY, 12 * scale, 25 * scale); + + // Голова + shapeRenderer.setColor(new Color(0.95f, 0.8f, 0.6f, 1)); + shapeRenderer.circle(personX, personY + 30 * scale, 10 * scale); + + // Глазы + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.circle(personX - 4 * scale, personY + 32 * scale, 2 * scale); + shapeRenderer.circle(personX + 4 * scale, personY + 32 * scale, 2 * scale); + + // Рот + shapeRenderer.rect(personX - 3 * scale, personY + 28 * scale, 6 * scale, 1 * scale); + + // Попкорн в руках (у каждого второго) + if (i % 2 == 0) { + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.circle(personX + 8 * scale, personY + 20 * scale, 8 * scale); + } + } + } + + private void renderBuildingDetails(Array buildings, Building currentBuilding, float time) { + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + + // Добавляем детали ко всем зданиям + for (Building building : buildings) { + if (building.isComplete()) { + addSparkles(building, time); + } + } + + if (currentBuilding != null && currentBuilding.isComplete()) { + addSparkles(currentBuilding, time); + } + + shapeRenderer.end(); + } + + private void addSparkles(Building building, float time) { + float x = building.x; + float y = building.y; + float width = building.width; + float height = building.height; + float scale = building.getSizeScale(); + + // Блестки вокруг здания + shapeRenderer.setColor(Color.YELLOW); + for (int i = 0; i < 5; i++) { + float sparkleX = x + (float)Math.sin(time * 3 + i) * width * 0.5f + width * 0.5f; + float sparkleY = y + height + 20 + (float)Math.cos(time * 2 + i) * 10; + float sparkleSize = 3 + (float)Math.sin(time * 4 + i) * 2; + + shapeRenderer.circle(sparkleX, sparkleY, sparkleSize); + } + + // Сияние вокруг названия (если показывается) + if (building.showName) { + float nameX = building.x + building.width/2; + float nameY = building.y + building.getCurrentHeight() + 80; + float glowSize = 60 * scale + (float)Math.sin(time * 3) * 10; + + shapeRenderer.setColor(new Color(1, 1, 0.5f, 0.3f)); + shapeRenderer.circle(nameX, nameY, glowSize); + } + } + + public void renderBuildingNames(Array buildings, Building currentBuilding) { + batch.begin(); + font.getData().setScale(1.0f); + + for (Building building : buildings) { + if (building.showName && building.isComplete()) { + drawBuildingName(building); + } else if (building.constructionProgress > 0) { + drawBuildingProgress(building); + } + } + + if (currentBuilding != null) { + drawCurrentBuildingName(currentBuilding); + } + + batch.end(); + } + + private void drawBuildingName(Building building) { + float x = building.x + building.width/2 + building.getWobbleX(); + float y = building.y + building.getCurrentHeight() + 70 * building.getSizeScale() + building.nameYOffset + building.getWobbleY(); + + float pulse = 0.8f + 0.2f * (float)Math.sin(building.namePulse * 2); + Color pulseColor = new Color( + building.nameColor.r * pulse, + building.nameColor.g * pulse, + building.nameColor.b * pulse, + 1 + ); + + font.setColor(pulseColor); + font.getData().setScale(1.1f * building.getSizeScale()); + + glyphLayout.setText(font, building.type); + float textWidth = glyphLayout.width; + + // Фон с закругленными краями + batch.setColor(new Color(0, 0, 0, 0.6f)); + batch.draw(whitePixel, x - textWidth/2 - 15, y - 25, textWidth + 30, 40); + + // Блестящая рамка + batch.setColor(building.getDetailColor()); + batch.draw(whitePixel, x - textWidth/2 - 15, y - 25, 5, 40); // Левая + batch.draw(whitePixel, x + textWidth/2 + 10, y - 25, 5, 40); // Правая + batch.draw(whitePixel, x - textWidth/2 - 15, y - 25, textWidth + 30, 5); // Верх + batch.draw(whitePixel, x - textWidth/2 - 15, y + 10, textWidth + 30, 5); // Низ + + batch.setColor(Color.WHITE); + font.draw(batch, building.type, x - textWidth/2, y); + font.getData().setScale(1.0f); + } + + private void drawBuildingProgress(Building building) { + float x = building.x + building.width/2; + float y = building.y + building.getCurrentHeight() + 50; + + font.setColor(Color.YELLOW); + font.getData().setScale(0.9f * building.getSizeScale()); + + String cleanType = building.type.replace("✨", "").replace("🏥", "").replace("🎒", "") + .replace("🎪", "").replace("💰", "").replace("💊", "") + .replace("🎭", "").replace("🎬", "").trim(); + String progressText = cleanType + " (" + building.constructionProgress + "/3)"; + glyphLayout.setText(font, progressText); + float textWidth = glyphLayout.width; + + batch.setColor(0, 0, 0, 0.3f); + batch.draw(whitePixel, x - textWidth/2 - 5, y - 15, textWidth + 10, 30); + batch.setColor(Color.WHITE); + + font.draw(batch, progressText, x - textWidth/2, y); + font.getData().setScale(1.0f); + } + + private void drawCurrentBuildingName(Building building) { + float x = building.x + building.width/2; + float y = building.y + building.height + 50; + + font.setColor(Color.YELLOW); + font.getData().setScale(1.0f * building.getSizeScale()); + + String cleanType = building.type.replace("✨", "").replace("🏥", "").replace("🎒", "") + .replace("🎪", "").replace("💰", "").replace("💊", "") + .replace("🎭", "").replace("🎬", "").trim(); + String prefix = building.constructionProgress == 0 ? "Место для: " : "Строится: "; + String progressText = prefix + cleanType + " (" + building.constructionProgress + "/3)"; + glyphLayout.setText(font, progressText); + float textWidth = glyphLayout.width; + + batch.setColor(0, 0, 0, 0.3f); + batch.draw(whitePixel, x - textWidth/2 - 5, y - 15, textWidth + 10, 30); + batch.setColor(Color.WHITE); + + font.draw(batch, progressText, x - textWidth/2, y); + + if (building.isOverlapping) { + font.setColor(Color.RED); + font.getData().setScale(0.8f * building.getSizeScale()); + String warning = "⚠ Пересечение! ⚠"; + glyphLayout.setText(font, warning); + font.draw(batch, warning, x - glyphLayout.width/2, y - 25); + font.getData().setScale(1.0f); + } + + font.getData().setScale(1.0f); + } +} diff --git a/core/src/main/java/com/mygdx/game/Citizen.java b/core/src/main/java/com/mygdx/game/Citizen.java new file mode 100644 index 0000000..6f35cce --- /dev/null +++ b/core/src/main/java/com/mygdx/game/Citizen.java @@ -0,0 +1,203 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import java.util.Random; + +public class Citizen { + float x, y; + float targetX; + float speed; + Color clothesColor; + float walkTimer; + Building homeBuilding; + float bobOffset; + float bobSpeed; + boolean isMoving; + float size; + float emotionTimer; + boolean isHappy; + Random random; + float headSize; + Planet planet; + + public Citizen(float x, float y, Color clothesColor, Building homeBuilding, Random random, Planet planet) { + this.x = x; + this.y = y; + this.targetX = x + (random.nextFloat() - 0.5f) * 300; + this.speed = 40 + random.nextFloat() * 60; + this.clothesColor = clothesColor; + this.walkTimer = random.nextFloat() * 100; + this.homeBuilding = homeBuilding; + this.bobOffset = random.nextFloat() * 100; + this.bobSpeed = 1 + random.nextFloat() * 2; + this.isMoving = random.nextBoolean(); + this.size = 0.9f + random.nextFloat() * 0.3f; + this.headSize = 12 * size; + this.emotionTimer = random.nextFloat() * 5; + this.isHappy = random.nextBoolean(); + this.random = random; + this.planet = planet; + } + + public void update(float deltaTime) { + walkTimer += deltaTime; + bobOffset += deltaTime * bobSpeed; + emotionTimer += deltaTime; + + if (emotionTimer > 3) { + isHappy = !isHappy; + emotionTimer = 0; + } + + if (isMoving) { + float direction = targetX > x ? 1 : -1; + x += direction * speed * deltaTime; + + if (Math.abs(x - targetX) < 10) { + targetX = homeBuilding.x + (random.nextFloat() - 0.5f) * homeBuilding.width; + isMoving = random.nextBoolean(); + } + } + + if (random.nextFloat() < 0.005f) { + isMoving = !isMoving; + if (isMoving) { + targetX = homeBuilding.x + (random.nextFloat() - 0.5f) * homeBuilding.width; + } + } + } + + public void draw(ShapeRenderer shapeRenderer, float time) { + float currentY = y + (float)Math.sin(bobOffset) * 5; + float scale = size; + + // Разный цвет кожи для разных планет + Color skinColor; + switch (planet) { + case EARTH: + skinColor = new Color(1.0f, 0.92f, 0.82f, 1); + break; + case MARS: + skinColor = new Color(0.95f, 0.7f, 0.6f, 1); // Красноватый + break; + case VENUS: + skinColor = new Color(1.0f, 0.85f, 0.7f, 1); // Золотистый + break; + default: + skinColor = new Color(1.0f, 0.92f, 0.82f, 1); + } + + // Голова + shapeRenderer.setColor(skinColor); + shapeRenderer.circle(x, currentY + 25 * scale, headSize); + + // Разные прически для разных планет + shapeRenderer.setColor(getHairColor()); + switch (planet) { + case EARTH: + shapeRenderer.rect(x - headSize * 0.7f, currentY + 25 * scale + headSize * 0.5f, + headSize * 1.4f, headSize * 0.5f); + break; + case MARS: + // Антенны вместо волос + shapeRenderer.setColor(Color.GRAY); + shapeRenderer.rectLine(x, currentY + 25 * scale + headSize, + x, currentY + 25 * scale + headSize + 15 * scale, + 3 * scale); + shapeRenderer.circle(x, currentY + 25 * scale + headSize + 15 * scale, 5 * scale); + break; + case VENUS: + // Кристаллическая "прическа" + shapeRenderer.setColor(new Color(1.0f, 0.9f, 0.3f, 1)); + for (int i = 0; i < 3; i++) { + float crystalX = x - headSize * 0.5f + i * headSize * 0.5f; + shapeRenderer.triangle(crystalX - 3 * scale, currentY + 25 * scale + headSize * 0.5f, + crystalX + 3 * scale, currentY + 25 * scale + headSize * 0.5f, + crystalX, currentY + 25 * scale + headSize * 0.5f + 10 * scale); + } + break; + } + + // Тело + shapeRenderer.setColor(clothesColor); + shapeRenderer.rect(x - 10 * scale, currentY, 20 * scale, 25 * scale); + + // Глаза + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.circle(x - headSize * 0.3f, currentY + 25 * scale + headSize * 0.2f, headSize * 0.25f); + shapeRenderer.circle(x + headSize * 0.3f, currentY + 25 * scale + headSize * 0.2f, headSize * 0.25f); + + // Зрачки + shapeRenderer.setColor(getEyeColor()); + shapeRenderer.circle(x - headSize * 0.3f, currentY + 25 * scale + headSize * 0.2f, headSize * 0.1f); + shapeRenderer.circle(x + headSize * 0.3f, currentY + 25 * scale + headSize * 0.2f, headSize * 0.1f); + + // Блеск в глазах + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.circle(x - headSize * 0.35f, currentY + 25 * scale + headSize * 0.25f, headSize * 0.05f); + shapeRenderer.circle(x + headSize * 0.25f, currentY + 25 * scale + headSize * 0.25f, headSize * 0.05f); + + // Рот + shapeRenderer.setColor(new Color(0.8f, 0.3f, 0.4f, 1)); + if (isHappy) { + shapeRenderer.arc(x, currentY + 25 * scale, headSize * 0.4f, 180, 180, 20); + } else { + shapeRenderer.rectLine(x - headSize * 0.4f, currentY + 25 * scale, + x + headSize * 0.4f, currentY + 25 * scale, + headSize * 0.08f); + } + + // Руки + shapeRenderer.setColor(skinColor); + float armOffset = isMoving ? (float)Math.sin(walkTimer * 10) * 10 * scale : 0; + shapeRenderer.rectLine(x - 10 * scale, currentY + 15 * scale, + x - 20 * scale, currentY + 5 * scale - armOffset, + headSize * 0.2f); + shapeRenderer.rectLine(x + 10 * scale, currentY + 15 * scale, + x + 20 * scale, currentY + 5 * scale + armOffset, + headSize * 0.2f); + + // Ноги + shapeRenderer.setColor(new Color(0.3f, 0.2f, 0.1f, 1)); + float legOffset = isMoving ? (float)Math.sin(walkTimer * 10 + 3.14f) * 8 * scale : 0; + shapeRenderer.rectLine(x - 5 * scale, currentY, + x - 10 * scale, currentY - 15 * scale + legOffset, + headSize * 0.25f); + shapeRenderer.rectLine(x + 5 * scale, currentY, + x + 10 * scale, currentY - 15 * scale - legOffset, + headSize * 0.25f); + + // Обувь + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rect(x - 12 * scale, currentY - 18 * scale + legOffset, + headSize * 0.4f, headSize * 0.2f); + shapeRenderer.rect(x + 8 * scale, currentY - 18 * scale - legOffset, + headSize * 0.4f, headSize * 0.2f); + + // Щёки + if (isHappy) { + shapeRenderer.setColor(new Color(1.0f, 0.7f, 0.7f, 0.5f)); + shapeRenderer.circle(x - headSize * 0.5f, currentY + 25 * scale, headSize * 0.15f); + shapeRenderer.circle(x + headSize * 0.5f, currentY + 25 * scale, headSize * 0.15f); + } + } + + private Color getHairColor() { + switch (planet) { + case EARTH: return new Color(0.2f, 0.15f, 0.1f, 1); + case MARS: return new Color(0.7f, 0.3f, 0.2f, 1); + case VENUS: return new Color(1.0f, 0.8f, 0.3f, 1); + default: return new Color(0.2f, 0.15f, 0.1f, 1); + } + } + + private Color getEyeColor() { + switch (planet) { + case EARTH: return new Color(0.1f, 0.1f, 0.3f, 1); + case MARS: return new Color(0.3f, 0.1f, 0.1f, 1); + case VENUS: return new Color(0.3f, 0.2f, 0.1f, 1); + default: return new Color(0.1f, 0.1f, 0.3f, 1); + } + } +} diff --git a/core/src/main/java/com/mygdx/game/GameAssets.java b/core/src/main/java/com/mygdx/game/GameAssets.java new file mode 100644 index 0000000..26389a0 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/GameAssets.java @@ -0,0 +1,40 @@ +package com.mygdx.game; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; + +public class GameAssets { + private static BitmapFont font; + + public static void createFonts() { + try { + FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("DejaVuSans.ttf")); + FreeTypeFontParameter parameter = new FreeTypeFontParameter(); + parameter.size = 18; + parameter.characters = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?\"'()[]{}<>:;@#$%^&*+-=×–÷/_\\|~`✦✧★☆"; + font = generator.generateFont(parameter); + generator.dispose(); + } catch (Exception e) { + font = new BitmapFont(); + font.getData().setScale(1.1f); + } + } + + public static BitmapFont getFont() { + return font; + } + + public static Texture createWhitePixel() { + Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); + pixmap.setColor(Color.WHITE); + pixmap.fill(); + Texture whitePixel = new Texture(pixmap); + pixmap.dispose(); + return whitePixel; + } +} diff --git a/core/src/main/java/com/mygdx/game/GameState.java b/core/src/main/java/com/mygdx/game/GameState.java new file mode 100644 index 0000000..e232ea0 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/GameState.java @@ -0,0 +1,9 @@ +package com.mygdx.game; + +public enum GameState { + MAIN_MENU, // Главное меню + PLAYING, // Игровой процесс + PLANET_SELECT, // Выбор планеты + HELP, // Помощь/инструкции + ABOUT // Об игре +} diff --git a/core/src/main/java/com/mygdx/game/InputHandler.java b/core/src/main/java/com/mygdx/game/InputHandler.java new file mode 100644 index 0000000..dbe43f9 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/InputHandler.java @@ -0,0 +1,152 @@ +package com.mygdx.game; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; + +public class InputHandler { + public static void handleInput(AbsurdCityBuilder1 game) { + // Проверяем, что мы в игровом режиме + if (game.getGameState() != GameState.PLAYING) { + return; + } + + // Смена типа здания + if (Gdx.input.isKeyJustPressed(Input.Keys.LEFT)) { + if (!game.isTyping() && !game.isSwitchingPlanets()) { + int buildingCount = Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()].length; + int newType = (game.getSelectedBuildingType() - 1 + buildingCount) % buildingCount; + game.setSelectedBuildingType(newType); + game.updateUI(); + + game.setMessageText("Выбран: " + + Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()][newType]); + game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN); + } + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.RIGHT)) { + if (!game.isTyping() && !game.isSwitchingPlanets()) { + int buildingCount = Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()].length; + int newType = (game.getSelectedBuildingType() + 1) % buildingCount; + game.setSelectedBuildingType(newType); + game.updateUI(); + + game.setMessageText("Выбран: " + + Building.BUILDING_TYPES_BY_PLANET[game.getCurrentPlanet().ordinal()][newType]); + game.setMessageColor(com.badlogic.gdx.graphics.Color.CYAN); + } + } + + // Смена планеты + if (!game.isTyping() && !game.isSwitchingPlanets()) { + if (Gdx.input.isKeyJustPressed(Input.Keys.UP)) { + Planet nextPlanet = game.getCurrentPlanet().next(); + game.startPlanetSwitch(nextPlanet); + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.DOWN)) { + Planet prevPlanet = game.getCurrentPlanet().previous(); + game.startPlanetSwitch(prevPlanet); + } + + // Быстрые клавиши для планет + if (Gdx.input.isKeyJustPressed(Input.Keys.NUM_1)) { + game.startPlanetSwitch(Planet.EARTH); + } + if (Gdx.input.isKeyJustPressed(Input.Keys.NUM_2)) { + game.startPlanetSwitch(Planet.MARS); + } + if (Gdx.input.isKeyJustPressed(Input.Keys.NUM_3)) { + game.startPlanetSwitch(Planet.VENUS); + } + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.FORWARD_DEL) || + Gdx.input.isKeyJustPressed(Input.Keys.DEL) || + (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) && Gdx.input.isKeyJustPressed(Input.Keys.Z)) || + (Gdx.input.isKeyPressed(Input.Keys.CONTROL_RIGHT) && Gdx.input.isKeyJustPressed(Input.Keys.Z))) { + + if (!game.isTyping() && !game.isSwitchingPlanets()) { + if (game.getCurrentBuilding() != null) { + game.setCurrentBuilding(null); + game.setCurrentProblem(null); + game.setTyping(false); + game.getInputText().setLength(0); + game.setMessageText("Строительство отменено. Выберите новое место."); + game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW); + game.updateUI(); + } else if (game.getBuildings().size > 0) { + game.getBuildings().removeIndex(game.getBuildings().size - 1); + game.setMessageText("Последнее здание удалено."); + game.setMessageColor(com.badlogic.gdx.graphics.Color.ORANGE); + } else { + game.setMessageText("Нет зданий для удаления."); + game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW); + } + } + } + + if (Gdx.input.justTouched()) { + if (!game.isSwitchingPlanets()) { + float touchX = Gdx.input.getX(); + float touchY = Gdx.input.getY(); + + float worldX = touchX * (game.getWIDTH() / (float)Gdx.graphics.getWidth()); + float worldY = game.getHEIGHT() - touchY * (game.getHEIGHT() / (float)Gdx.graphics.getHeight()); + + if (worldY > game.getUI_INPUT_HEIGHT()) { + BuildingPlacer.handleBuildingClick(game, worldX, worldY); + } + } + } + + if (game.isTyping() && game.getCurrentBuilding() != null && !game.isSwitchingPlanets()) { + for (int key = Input.Keys.NUM_0; key <= Input.Keys.NUM_9; key++) { + if (Gdx.input.isKeyJustPressed(key)) { + game.getInputText().append(Input.Keys.toString(key).charAt(Input.Keys.toString(key).length() - 1)); + } + } + + for (int key = Input.Keys.NUMPAD_0; key <= Input.Keys.NUMPAD_9; key++) { + if (Gdx.input.isKeyJustPressed(key)) { + char numChar = (char)('0' + (key - Input.Keys.NUMPAD_0)); + game.getInputText().append(numChar); + } + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.MINUS) || Gdx.input.isKeyJustPressed(Input.Keys.NUMPAD_SUBTRACT)) { + if (game.getInputText().length() == 0) { + game.getInputText().append('-'); + } + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.BACKSPACE)) { + if (!Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) && + !Gdx.input.isKeyPressed(Input.Keys.CONTROL_RIGHT)) { + + if (game.isTyping() && game.getInputText().length() > 0) { + game.getInputText().deleteCharAt(game.getInputText().length() - 1); + } else if (!game.isTyping() && game.getCurrentBuilding() != null && game.getCurrentBuilding().constructionProgress > 0) { + game.getCurrentBuilding().removeBlock(); + game.setMessageText("Блок удален! Текущий прогресс: " + game.getCurrentBuilding().constructionProgress + "/3"); + game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW); + game.updateUI(); + } + } + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.ENTER)) { + game.checkAnswer(); + } + + if (Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)) { + if (game.isTyping()) { + game.setTyping(false); + game.getInputText().setLength(0); + game.setMessageText("Ввод отменен. Можно продолжить строительство."); + game.setMessageColor(com.badlogic.gdx.graphics.Color.YELLOW); + } + } + } + } +} diff --git a/core/src/main/java/com/mygdx/game/JokeBubble.java b/core/src/main/java/com/mygdx/game/JokeBubble.java new file mode 100644 index 0000000..747245e --- /dev/null +++ b/core/src/main/java/com/mygdx/game/JokeBubble.java @@ -0,0 +1,87 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import java.util.Random; + +public class JokeBubble { + String text; + float x, y; + float timer; + Color bubbleColor; + float floatOffset; + float scale; + Random random; + + public JokeBubble(String text, float x, float y, Random random) { + this.text = text; + this.x = x; + this.y = y; + this.timer = 0; + this.random = random; + this.bubbleColor = new Color( + random.nextFloat() * 0.3f + 0.7f, + random.nextFloat() * 0.3f + 0.7f, + random.nextFloat() * 0.3f + 0.7f, + 0.9f + ); + this.floatOffset = random.nextFloat() * 100; + this.scale = 0.9f + random.nextFloat() * 0.2f; + } + + public void update(float deltaTime) { + timer += deltaTime; + floatOffset += deltaTime * 2; + } + + public boolean isExpired() { + return timer > 3.0f; + } + + public void draw(SpriteBatch batch, ShapeRenderer shapeRenderer, BitmapFont font, + GlyphLayout glyphLayout, Texture whitePixel) { + batch.begin(); + + float currentY = y + (float)Math.sin(floatOffset) * 8; + + // Пузырь + font.getData().setScale(0.8f * scale); + glyphLayout.setText(font, text); + float bubbleWidth = glyphLayout.width + 25; + float bubbleHeight = glyphLayout.height + 20; + + // Рисуем пузырь с закругленными краями + batch.setColor(bubbleColor); + + // Основная часть пузыря + batch.draw(whitePixel, x - bubbleWidth/2, currentY, bubbleWidth, bubbleHeight); + + // Закругленные углы (эмулируем кругами) + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + shapeRenderer.setColor(bubbleColor); + shapeRenderer.circle(x - bubbleWidth/2, currentY + bubbleHeight/2, bubbleHeight/2); + shapeRenderer.circle(x + bubbleWidth/2, currentY + bubbleHeight/2, bubbleHeight/2); + shapeRenderer.end(); + + // Текст + font.setColor(Color.BLACK); + font.draw(batch, text, x - glyphLayout.width/2, currentY + bubbleHeight/2 + glyphLayout.height/2); + + // Хвостик пузыря + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + shapeRenderer.setColor(bubbleColor); + shapeRenderer.triangle( + x - 8, currentY, + x + 8, currentY, + x, currentY - 15 + ); + shapeRenderer.end(); + + font.getData().setScale(1.0f); + batch.end(); + } +} diff --git a/core/src/main/java/com/mygdx/game/MathProblem.java b/core/src/main/java/com/mygdx/game/MathProblem.java new file mode 100644 index 0000000..6bad06d --- /dev/null +++ b/core/src/main/java/com/mygdx/game/MathProblem.java @@ -0,0 +1,59 @@ +package com.mygdx.game; + +import java.util.Random; + +public class MathProblem { + String question; + int answer; + + public MathProblem(String question, int answer) { + this.question = question; + this.answer = answer; + } + + public static MathProblem generateProblem(int difficulty, Random random) { + int a, b, c; + String question; + int answer; + + if (difficulty < 2) { + a = 1 + random.nextInt(20); + b = 1 + random.nextInt(20); + if (random.nextBoolean()) { + question = a + " + " + b + " = ?"; + answer = a + b; + } else { + if (a < b) { + int temp = a; + a = b; + b = temp; + } + question = a + " - " + b + " = ?"; + answer = a - b; + } + } else if (difficulty < 4) { + a = 2 + random.nextInt(9); + b = 2 + random.nextInt(9); + question = a + " × " + b + " = ?"; + answer = a * b; + } else if (difficulty < 6) { + a = 1 + random.nextInt(10); + b = 1 + random.nextInt(10); + c = 2 + random.nextInt(8); + question = "(" + a + " + " + b + ") × " + c + " = ?"; + answer = (a + b) * c; + } else { + b = 2 + random.nextInt(4); + c = 2 + random.nextInt(4); + int multiplication = b * c; + a = multiplication + random.nextInt(10) + 5; + question = a + " - " + b + " × " + c + " = ?"; + answer = a - multiplication; + } + + return new MathProblem(question, answer); + } + + public String getQuestion() { return question; } + public int getAnswer() { return answer; } +} diff --git a/core/src/main/java/com/mygdx/game/MenuButton.java b/core/src/main/java/com/mygdx/game/MenuButton.java new file mode 100644 index 0000000..edf0036 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/MenuButton.java @@ -0,0 +1,87 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.Texture; + +public class MenuButton { + private float x, y, width, height; + private String text; + private Color normalColor; + private Color hoverColor; + private Color textColor; + private boolean isHovered; + private Runnable action; + private String icon; + + public MenuButton(float x, float y, float width, float height, String text, + Color normalColor, Color hoverColor, Runnable action) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.text = text; + this.normalColor = normalColor; + this.hoverColor = hoverColor; + this.textColor = Color.WHITE; + this.isHovered = false; + this.action = action; + this.icon = ""; + } + + public MenuButton withIcon(String icon) { + this.icon = icon; + return this; + } + public String getText() { + return text; + } + + public MenuButton withTextColor(Color color) { + this.textColor = color; + return this; + } + + public void update(float mouseX, float mouseY, boolean isClicked) { + isHovered = mouseX >= x && mouseX <= x + width && + mouseY >= y && mouseY <= y + height; + + if (isHovered && isClicked && action != null) { + action.run(); + } + } + + public void render(SpriteBatch batch, BitmapFont font, GlyphLayout layout, Texture whitePixel) { + // Рисуем кнопку + batch.setColor(isHovered ? hoverColor : normalColor); + batch.draw(whitePixel, x, y, width, height); + + // Рамка + batch.setColor(new Color(1, 1, 1, 0.3f)); + batch.draw(whitePixel, x, y, width, 2); // Верх + batch.draw(whitePixel, x, y + height - 2, width, 2); // Низ + batch.draw(whitePixel, x, y, 2, height); // Левая + batch.draw(whitePixel, x + width - 2, y, 2, height); // Правая + + // Текст + font.setColor(textColor); + if (!icon.isEmpty()) { + font.draw(batch, icon + " " + text, x + 20, y + height/2 + 10); + } else { + layout.setText(font, text); + font.draw(batch, text, x + width/2 - layout.width/2, y + height/2 + 10); + } + + // Эффект при наведении + if (isHovered) { + batch.setColor(new Color(1, 1, 1, 0.1f)); + batch.draw(whitePixel, x, y, width, height); + } + } + + public boolean contains(float px, float py) { + return px >= x && px <= x + width && py >= y && py <= y + height; + } +} diff --git a/core/src/main/java/com/mygdx/game/MenuRenderer.java b/core/src/main/java/com/mygdx/game/MenuRenderer.java new file mode 100644 index 0000000..f43af24 --- /dev/null +++ b/core/src/main/java/com/mygdx/game/MenuRenderer.java @@ -0,0 +1,447 @@ +package com.mygdx.game; + + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import java.util.ArrayList; +import java.util.List; + +public class MenuRenderer { + private final SpriteBatch batch; + private BitmapFont titleFont; + private BitmapFont font; + private GlyphLayout layout; + private Texture whitePixel; + private int width, height; + + private List mainMenuButtons; + private List planetSelectButtons; + private List helpButtons; + + private float titlePulse = 0; + private float starTimer = 0; + + public MenuRenderer(SpriteBatch batch, BitmapFont font, GlyphLayout layout, + Texture whitePixel, int width, int height) { + this.batch = batch; + this.font = font; + this.layout = layout; + this.whitePixel = whitePixel; + this.width = width; + this.height = height; + + // Создаем увеличенный шрифт для заголовка + this.titleFont = new BitmapFont(); + this.titleFont.getData().setScale(2.5f); + + createMainMenuButtons(); + createPlanetSelectButtons(); + createHelpButtons(); + } + + private void createMainMenuButtons() { + mainMenuButtons = new ArrayList<>(); + float buttonWidth = 400; + float buttonHeight = 70; + float startY = height/2 - 50; + float spacing = 85; + + // Кнопка "Новая игра" + mainMenuButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY, buttonWidth, buttonHeight, + "🚀 НОВАЯ ИГРА", + new Color(0.2f, 0.5f, 0.8f, 0.9f), + new Color(0.3f, 0.6f, 0.9f, 1f), + () -> {} + ).withTextColor(Color.YELLOW)); + + // Кнопка "Выбор планеты" + mainMenuButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY - spacing, buttonWidth, buttonHeight, + "🪐 ВЫБОР ПЛАНЕТЫ", + new Color(0.8f, 0.4f, 0.2f, 0.9f), + new Color(0.9f, 0.5f, 0.3f, 1f), + () -> {} + )); + + // Кнопка "Помощь" + mainMenuButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY - spacing * 2, buttonWidth, buttonHeight, + "❓ ПОМОЩЬ", + new Color(0.2f, 0.7f, 0.3f, 0.9f), + new Color(0.3f, 0.8f, 0.4f, 1f), + () -> {} + )); + + // Кнопка "Об игре" + mainMenuButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY - spacing * 3, buttonWidth, buttonHeight, + "ℹ️ ОБ ИГРЕ", + new Color(0.7f, 0.2f, 0.7f, 0.9f), + new Color(0.8f, 0.3f, 0.8f, 1f), + () -> {} + )); + + // Кнопка "Выход" + mainMenuButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY - spacing * 4, buttonWidth, buttonHeight, + "🚪 ВЫХОД", + new Color(0.8f, 0.2f, 0.2f, 0.9f), + new Color(0.9f, 0.3f, 0.3f, 1f), + () -> System.exit(0) + )); + } + + private void createPlanetSelectButtons() { + planetSelectButtons = new ArrayList<>(); + float buttonWidth = 350; + float buttonHeight = 100; + float startY = height/2 + 50; + float spacing = 120; + + // Земля + planetSelectButtons.add(new MenuButton( + width/2 - buttonWidth - 20, startY, buttonWidth, buttonHeight, + "🌍 ЗЕМЛЯ", + new Color(0.3f, 0.6f, 0.9f, 0.9f), + new Color(0.4f, 0.7f, 1.0f, 1f), + () -> {} + ).withTextColor(Color.WHITE)); + + // Марс + planetSelectButtons.add(new MenuButton( + width/2 + 20, startY, buttonWidth, buttonHeight, + "♂️ МАРС", + new Color(0.8f, 0.3f, 0.2f, 0.9f), + new Color(0.9f, 0.4f, 0.3f, 1f), + () -> {} + )); + + // Венера + planetSelectButtons.add(new MenuButton( + width/2 - buttonWidth/2, startY - spacing, buttonWidth, buttonHeight, + "♀️ ВЕНЕРА", + new Color(1.0f, 0.7f, 0.2f, 0.9f), + new Color(1.0f, 0.8f, 0.3f, 1f), + () -> {} + )); + + // Кнопка "Назад" + planetSelectButtons.add(new MenuButton( + 50, 50, 200, 60, + "⬅️ НАЗАД", + new Color(0.4f, 0.4f, 0.4f, 0.9f), + new Color(0.5f, 0.5f, 0.5f, 1f), + () -> {} + )); + } + + private void createHelpButtons() { + helpButtons = new ArrayList<>(); + + // Кнопка "Назад" + helpButtons.add(new MenuButton( + 50, 50, 200, 60, + "⬅️ НАЗАД", + new Color(0.4f, 0.4f, 0.4f, 0.9f), + new Color(0.5f, 0.5f, 0.5f, 1f), + () -> {} + )); + } + + public void update(float deltaTime) { + titlePulse += deltaTime * 2; + starTimer += deltaTime; + } + + public void renderMainMenu(float mouseX, float mouseY) { + batch.begin(); + + // Космический фон + renderSpaceBackground(); + + // Заголовок + renderTitle(); + + // Подзаголовок + font.setColor(new Color(0.8f, 0.9f, 1.0f, 0.8f)); + font.getData().setScale(1.2f); + String subtitle = "Строй абсурдные города на разных планетах!"; + layout.setText(font, subtitle); + font.draw(batch, subtitle, width/2 - layout.width/2, height - 150); + font.getData().setScale(1.0f); + + // Кнопки + for (MenuButton button : mainMenuButtons) { + button.render(batch, font, layout, whitePixel); + } + + // Автор + font.setColor(new Color(1, 1, 1, 0.5f)); + font.getData().setScale(0.8f); + font.draw(batch, "© 2024 Absurd City Builder", width - 250, 30); + font.getData().setScale(1.0f); + + batch.end(); + } + + public void renderPlanetSelect(float mouseX, float mouseY) { + batch.begin(); + + // Космический фон + renderSpaceBackground(); + + // Заголовок + titleFont.setColor(new Color(1, 1, 1, 0.9f)); + String title = "🪐 ВЫБОР ПЛАНЕТЫ"; + layout.setText(titleFont, title); + titleFont.draw(batch, title, width/2 - layout.width/2, height - 100); + + // Описание + font.setColor(new Color(0.8f, 0.9f, 1.0f, 0.8f)); + font.getData().setScale(1.1f); + String desc = "Выберите планету для строительства:"; + layout.setText(font, desc); + font.draw(batch, desc, width/2 - layout.width/2, height - 170); + font.getData().setScale(1.0f); + + // Описания планет + font.setColor(Color.LIGHT_GRAY); + font.getData().setScale(0.9f); + + // Земля + String earthText = "Мультяшные здания\nЯркие цвета\nМилые жители"; + layout.setText(font, earthText); + font.draw(batch, earthText, width/2 - 380, height/2 - 50); + +// Марс + String marsText = "Технологичные постройки\nКрасный пейзаж\nМарсианские роботы"; + layout.setText(font, marsText); + font.draw(batch, marsText, width/2 + 30, height/2 - 50); + +// Венера + String venusText = "Вулканические здания\nРаскаленная атмосфера\nКристаллические формы"; + layout.setText(font, venusText); + font.draw(batch, venusText, width/2 - 175, height/2 - 200); + font.getData().setScale(1.0f); + + // Кнопки + for (MenuButton button : planetSelectButtons) { + button.render(batch, font, layout, whitePixel); + } + + batch.end(); + } + + public void renderHelp(float mouseX, float mouseY) { + batch.begin(); + + // Фон + batch.setColor(new Color(0.1f, 0.1f, 0.2f, 0.95f)); + batch.draw(whitePixel, 0, 0, width, height); + batch.setColor(Color.WHITE); + + // Заголовок + titleFont.setColor(Color.YELLOW); + String title = "❓ ПОМОЩЬ И УПРАВЛЕНИЕ"; + layout.setText(titleFont, title); + titleFont.draw(batch, title, width/2 - layout.width/2, height - 100); + + // Инструкции + font.setColor(Color.WHITE); + font.getData().setScale(1.1f); + + float textY = height - 200; + float lineHeight = 35; + + String[] instructions = { + "🎮 ОСНОВНОЕ УПРАВЛЕНИЕ:", + "• ЛКМ - кликнуть на поле для строительства", + "• ←/→ - выбрать тип здания", + "• Enter - отправить ответ на задачу", + "• Backspace - удалить блок/символ", + "• Delete/Ctrl+Z - удалить здание", + "• ESC - отмена ввода", + "", + "🪐 УПРАВЛЕНИЕ ПЛАНЕТАМИ:", + "• ↑/↓ - переключить планету", + "• 1 - Земля, 2 - Марс, 3 - Венера", + "", + "🎯 КАК ИГРАТЬ:", + "1. Выберите тип здания", + "2. Кликните на игровом поле", + "3. Решите математическую задачу", + "4. Постройте 3 блока для завершения", + "5. Стройте разные здания на разных планетах!" + }; + + for (String line : instructions) { + if (line.startsWith("🎮") || line.startsWith("🪐") || line.startsWith("🎯")) { + font.setColor(Color.CYAN); + } else if (line.startsWith("•")) { + font.setColor(Color.LIGHT_GRAY); + } else { + font.setColor(Color.WHITE); + } + font.draw(batch, line, 100, textY); + textY -= lineHeight; + } + + font.getData().setScale(1.0f); + + // Кнопки + for (MenuButton button : helpButtons) { + button.render(batch, font, layout, whitePixel); + } + + batch.end(); + } + + public void renderAbout(float mouseX, float mouseY) { + batch.begin(); + + // Галактический фон + batch.setColor(new Color(0.05f, 0.05f, 0.1f, 1)); + batch.draw(whitePixel, 0, 0, width, height); + + // Звезды + batch.setColor(Color.WHITE); + for (int i = 0; i < 50; i++) { + float starX = (float)Math.sin(starTimer + i) * width + width/2; + float starY = (float)Math.cos(starTimer * 0.5f + i) * height/2 + height/2; + float size = 1 + (float)Math.sin(starTimer * 2 + i) * 2; + batch.draw(whitePixel, starX, starY, size, size); + } + + batch.setColor(Color.WHITE); + + // Заголовок + titleFont.setColor(new Color(0.8f, 0.4f, 1.0f, 1)); + String title = "✨ ОБ ИГРЕ"; + layout.setText(titleFont, title); + titleFont.draw(batch, title, width/2 - layout.width/2, height - 100); + + // Описание игры + font.setColor(new Color(0.9f, 0.9f, 1.0f, 0.9f)); + font.getData().setScale(1.2f); + + String[] aboutText = { + "Absurd City Builder - это уникальная игра,", + "где вы строите безумные города на разных планетах!", + "", + "Особенности игры:", + "• 3 уникальные планеты с разными зданиями", + "• Забавные математические задачи", + "• Мультяшная графика и анимации", + "• Динамичные жители и шутки", + "• Бесконечные возможности для творчества!", + "", + "Разработано с ❤️ для любителей абсурда и математики.", + "", + "Версия 1.0" + }; + + float textY = height - 200; + for (String line : aboutText) { + layout.setText(font, line); + font.draw(batch, line, width/2 - layout.width/2, textY); + textY -= 40; + } + + font.getData().setScale(1.0f); + + // Кнопка "Назад" + MenuButton backButton = new MenuButton( + 50, 50, 200, 60, + "⬅️ НАЗАД", + new Color(0.4f, 0.4f, 0.4f, 0.9f), + new Color(0.5f, 0.5f, 0.5f, 1f), + () -> {} + ); + backButton.render(batch, font, layout, whitePixel); + + batch.end(); + } + + private void renderSpaceBackground() { + // Темный космический фон + batch.setColor(new Color(0.05f, 0.05f, 0.1f, 1)); + batch.draw(whitePixel, 0, 0, width, height); + + // Звезды + batch.setColor(Color.WHITE); + for (int i = 0; i < 100; i++) { + float starX = (i * 37.3f) % width; + float starY = (i * 23.7f) % height; + float twinkle = 0.5f + 0.5f * (float)Math.sin(starTimer * 3 + i); + batch.setColor(new Color(1, 1, 1, twinkle)); + float size = 1 + (i % 3); + batch.draw(whitePixel, starX, starY, size, size); + } + batch.setColor(Color.WHITE); + + // Планеты на заднем фоне + batch.setColor(new Color(0.3f, 0.6f, 0.9f, 0.3f)); + batch.draw(whitePixel, width - 200, 100, 150, 150); + + batch.setColor(new Color(0.8f, 0.3f, 0.2f, 0.3f)); + batch.draw(whitePixel, 100, height - 200, 120, 120); + + batch.setColor(new Color(1.0f, 0.7f, 0.2f, 0.3f)); + batch.draw(whitePixel, width - 150, height - 150, 100, 100); + } + + private void renderTitle() { + // Пульсирующий заголовок + float pulse = 0.8f + 0.2f * (float)Math.sin(titlePulse); + titleFont.setColor(new Color(1, pulse, 0.5f, 1)); + + String title = "✨ ABSURD CITY BUILDER ✨"; + layout.setText(titleFont, title); + titleFont.draw(batch, title, width/2 - layout.width/2, height - 100); + + // Блестки вокруг заголовка + batch.setColor(new Color(1, 1, 0.5f, 0.3f)); + for (int i = 0; i < 8; i++) { + float angle = titlePulse + i * 0.785f; + float sparkleX = width/2 + (float)Math.cos(angle) * 200; + float sparkleY = height - 100 + (float)Math.sin(angle) * 50; + float size = 5 + (float)Math.sin(titlePulse * 2 + i) * 3; + batch.draw(whitePixel, sparkleX, sparkleY, size, size); + } + } + + public MenuButton getMainMenuButtonAt(float x, float y) { + for (MenuButton button : mainMenuButtons) { + if (button.contains(x, y)) { + return button; + } + } + return null; + } + + public MenuButton getPlanetSelectButtonAt(float x, float y) { + for (MenuButton button : planetSelectButtons) { + if (button.contains(x, y)) { + return button; + } + } + return null; + } + + public MenuButton getHelpButtonAt(float x, float y) { + for (MenuButton button : helpButtons) { + if (button.contains(x, y)) { + return button; + } + } + return null; + } + + public void dispose() { + titleFont.dispose(); + } +} diff --git a/core/src/main/java/com/mygdx/game/Planet.java b/core/src/main/java/com/mygdx/game/Planet.java new file mode 100644 index 0000000..94a7bbe --- /dev/null +++ b/core/src/main/java/com/mygdx/game/Planet.java @@ -0,0 +1,42 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; + +public enum Planet { + EARTH("Земля", 0.68f, 0.85f, 0.9f, 1.0f), + MARS("Марс", 0.8f, 0.4f, 0.3f, 0.9f), + VENUS("Венера", 1.0f, 0.7f, 0.4f, 1.0f); + + private final String name; + private final float r, g, b, a; + + Planet(String name, float r, float g, float b, float a) { + this.name = name; + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + public String getName() { return name; } + public float getR() { return r; } + public float getG() { return g; } + public float getB() { return b; } + public float getA() { return a; } + + public Color getColor() { + return new Color(r, g, b, a); + } + + public Planet next() { + Planet[] planets = values(); + int nextIndex = (this.ordinal() + 1) % planets.length; + return planets[nextIndex]; + } + + public Planet previous() { + Planet[] planets = values(); + int prevIndex = (this.ordinal() - 1 + planets.length) % planets.length; + return planets[prevIndex]; + } +} diff --git a/core/src/main/java/com/mygdx/game/UIRenderer.java b/core/src/main/java/com/mygdx/game/UIRenderer.java new file mode 100644 index 0000000..c86d67b --- /dev/null +++ b/core/src/main/java/com/mygdx/game/UIRenderer.java @@ -0,0 +1,254 @@ +package com.mygdx.game; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +public class UIRenderer { + private SpriteBatch batch; + private BitmapFont font; + private GlyphLayout glyphLayout; + private Texture whitePixel; + private int WIDTH; + private int HEIGHT; + private int UI_INPUT_HEIGHT; + + public UIRenderer(SpriteBatch batch, BitmapFont font, GlyphLayout glyphLayout, + Texture whitePixel, int width, int height, int uiInputHeight) { + this.batch = batch; + this.font = font; + this.glyphLayout = glyphLayout; + this.whitePixel = whitePixel; + this.WIDTH = width; + this.HEIGHT = height; + this.UI_INPUT_HEIGHT = uiInputHeight; + } + + public void renderUI(int selectedBuildingType, String problemText, String messageText, Color messageColor, + boolean isTyping, MathProblem currentProblem, String inputText, + boolean showWrongAnswerJoke, String wrongAnswerJoke, float time, + Building currentBuilding, Planet currentPlanet, boolean isSwitchingPlanets) { + batch.begin(); + + batch.setColor(0.2f, 0.3f, 0.4f, 0.95f); + batch.draw(whitePixel, 0, 0, WIDTH, UI_INPUT_HEIGHT); + batch.setColor(Color.WHITE); + + batch.setColor(0.4f, 0.6f, 0.8f, 1); + batch.draw(whitePixel, 0, UI_INPUT_HEIGHT, WIDTH, 3); + batch.setColor(Color.WHITE); + + font.setColor(Color.WHITE); + + int lineHeight = 28; + int currentY = UI_INPUT_HEIGHT - 30; + + // ==================== ЛЕВАЯ КОЛОНКА ==================== + // Отображение текущей планеты + String planetDisplay = "🌍 Планета: " + currentPlanet.getName(); + if (isSwitchingPlanets) { + planetDisplay += " (Перелет...)"; + } + font.draw(batch, planetDisplay, 20, currentY); + currentY -= lineHeight; + + // Управление планетой + font.setColor(Color.YELLOW); + font.draw(batch, "↑/↓ - сменить планету", 20, currentY); + currentY -= lineHeight; + font.setColor(Color.LIGHT_GRAY); + font.draw(batch, "1-Земля, 2-Марс, 3-Венера", 20, currentY); + currentY -= lineHeight; + + font.setColor(Color.WHITE); + font.draw(batch, "───────────────", 20, currentY); + currentY -= lineHeight; + + // Тип здания + String[] planetBuildings = Building.BUILDING_TYPES_BY_PLANET[currentPlanet.ordinal()]; + font.draw(batch, "🏗️ Тип здания: " + planetBuildings[selectedBuildingType], 20, currentY); + currentY -= lineHeight; + + // Управление зданиями + font.setColor(Color.CYAN); + font.draw(batch, "←/→ - выбрать тип здания", 20, currentY); + currentY -= lineHeight; + + font.setColor(Color.WHITE); + font.draw(batch, "───────────────", 20, currentY); + currentY -= lineHeight; + + // Отображение задачи + String displayText = problemText; + if (problemText.length() > 40) { + int splitIndex = problemText.lastIndexOf(" ", 40); + if (splitIndex > 0) { + String line1 = problemText.substring(0, splitIndex); + String line2 = problemText.substring(splitIndex + 1); + font.draw(batch, line1, 20, currentY); + currentY -= lineHeight; + font.draw(batch, line2, 20, currentY); + } else { + font.draw(batch, displayText, 20, currentY); + } + } else { + font.draw(batch, displayText, 20, currentY); + } + currentY -= lineHeight; + + // Прогресс строительства + if (currentBuilding != null) { + font.draw(batch, "📊 Прогресс: " + currentBuilding.constructionProgress + "/3 блоков", + 20, currentY); + } else { + font.draw(batch, "📊 Прогресс: 0/3 блоков", 20, currentY); + } + currentY -= lineHeight; + + // ==================== ПРАВАЯ КОЛОНКА ==================== + // Сообщения игры + font.setColor(messageColor); + float messageX = WIDTH - 500; + drawWrappedText(messageText, messageX, UI_INPUT_HEIGHT - 40, 480); + + // ==================== ЦЕНТРАЛЬНАЯ ЧАСТЬ ==================== + if (isTyping && currentProblem != null) { + renderInputSection(currentProblem, inputText, time); + } + + // Шутка при неправильном ответе + if (showWrongAnswerJoke) { + renderWrongAnswerJoke(wrongAnswerJoke); + } + + // ==================== НИЖНЯЯ ПАНЕЛЬ ==================== + renderBottomPanel(currentPlanet, isSwitchingPlanets); + + batch.end(); + } + + private void renderInputSection(MathProblem currentProblem, String inputText, float time) { + // Фон для ввода + batch.setColor(0.3f, 0.4f, 0.5f, 0.8f); + batch.draw(whitePixel, WIDTH/2 - 250, UI_INPUT_HEIGHT - 150, 500, 130); + batch.setColor(Color.WHITE); + + // Задача + font.setColor(Color.YELLOW); + String mathProblem = "🧮 Задача: " + currentProblem.getQuestion(); + glyphLayout.setText(font, mathProblem); + font.draw(batch, mathProblem, + WIDTH/2 - glyphLayout.width/2, + UI_INPUT_HEIGHT - 60); + + // Поле ввода + font.setColor(Color.WHITE); + font.draw(batch, "✏️ Введите ответ:", WIDTH/2 - 230, UI_INPUT_HEIGHT - 95); + + // Введенный текст + String inputStr = inputText.isEmpty() ? "_" : inputText; + font.draw(batch, inputStr, WIDTH/2 - 230, UI_INPUT_HEIGHT - 130); + + // Мигающий курсор + if ((int)(time * 2) % 2 == 0 && inputText.isEmpty()) { + font.setColor(Color.YELLOW); + font.draw(batch, "_", WIDTH/2 - 230, UI_INPUT_HEIGHT - 130); + font.setColor(Color.WHITE); + } + + // Подсказки + font.setColor(Color.LIGHT_GRAY); + font.getData().setScale(0.7f); + font.draw(batch, "⏎ Enter - отправить ответ", WIDTH/2 - 230, UI_INPUT_HEIGHT - 160); + font.draw(batch, "⎋ ESC - отмена ввода", WIDTH/2 - 230, UI_INPUT_HEIGHT - 180); + font.draw(batch, "⌫ Backspace - удалить символ", WIDTH/2 - 230, UI_INPUT_HEIGHT - 200); + font.getData().setScale(1.0f); + } + + private void renderWrongAnswerJoke(String wrongAnswerJoke) { + // Фон для шутки + batch.setColor(1, 0.2f, 0.2f, 0.3f); + batch.draw(whitePixel, WIDTH/2 - 300, HEIGHT/2 - 50, 600, 100); + batch.setColor(Color.WHITE); + + // Шутка + font.setColor(Color.RED); + font.getData().setScale(1.3f); + glyphLayout.setText(font, wrongAnswerJoke); + font.draw(batch, wrongAnswerJoke, + WIDTH/2 - glyphLayout.width/2, + HEIGHT/2 + 10); + font.getData().setScale(1.0f); + } + + // ВОТ ТОТ САМЫЙ МЕТОД, КОТОРЫЙ ВЫ СПРАШИВАЛИ: + private void renderBottomPanel(Planet planet, boolean isSwitchingPlanets) { + font.setColor(Color.LIGHT_GRAY); + font.getData().setScale(0.6f); + + // Основные инструкции + String instruction = "🖱️ Кликните на поле для строительства"; + glyphLayout.setText(font, instruction); + font.draw(batch, instruction, WIDTH/2 - glyphLayout.width/2, 30); + + // Управление + String controls = "🗑️ Delete/Ctrl+Z - удалить здание | ⌫ Backspace - удалить блок | ⎋ ESC - меню"; + glyphLayout.setText(font, controls); + font.draw(batch, controls, WIDTH/2 - glyphLayout.width/2, 15); + + // Индикатор планеты + font.setColor(getPlanetColor(planet)); + font.getData().setScale(0.8f); + String planetInfo = getPlanetEmoji(planet) + " " + planet.getName(); + if (isSwitchingPlanets) { + planetInfo += " 🚀"; + } + font.draw(batch, planetInfo, WIDTH - 150, 25); + + font.getData().setScale(1.0f); + } + + // Вспомогательные методы для работы с планетами: + private Color getPlanetColor(Planet planet) { + switch (planet) { + case EARTH: return new Color(0.3f, 0.7f, 1.0f, 1); + case MARS: return new Color(1.0f, 0.4f, 0.3f, 1); + case VENUS: return new Color(1.0f, 0.8f, 0.3f, 1); + default: return Color.WHITE; + } + } + + private String getPlanetEmoji(Planet planet) { + switch (planet) { + case EARTH: return "🌍"; + case MARS: return "♂️"; + case VENUS: return "♀️"; + default: return "🪐"; + } + } + + private void drawWrappedText(String text, float x, float y, float maxWidth) { + String[] words = text.split(" "); + StringBuilder line = new StringBuilder(); + float currentY = y; + + for (String word : words) { + String testLine = line.length() > 0 ? line.toString() + " " + word : word; + glyphLayout.setText(font, testLine); + + if (glyphLayout.width > maxWidth && line.length() > 0) { + font.draw(batch, line.toString(), x, currentY); + line = new StringBuilder(word); + currentY -= 25; + } else { + line = new StringBuilder(testLine); + } + } + + if (line.length() > 0) { + font.draw(batch, line.toString(), x, currentY); + } + } +} diff --git a/core/src/main/java/com/mygdx/game/UIUpdater.java b/core/src/main/java/com/mygdx/game/UIUpdater.java new file mode 100644 index 0000000..3b9f80d --- /dev/null +++ b/core/src/main/java/com/mygdx/game/UIUpdater.java @@ -0,0 +1,33 @@ +package com.mygdx.game; + +public class UIUpdater { + public static void updateUI(AbsurdCityBuilder1 game) { + if (game.getGameState() != GameState.PLAYING) { + return; + } + + Planet planet = game.getCurrentPlanet(); + String[] planetBuildings = Building.BUILDING_TYPES_BY_PLANET[planet.ordinal()]; + + if (game.getCurrentBuilding() != null && game.getCurrentProblem() != null) { + String overlapText = game.getCurrentBuilding().isOverlapping ? " (пересекается!)" : ""; + String colorInfo = ""; + if (game.getCurrentBuilding().isComplete()) { + colorInfo = String.format(" [Цвет: Тема %d]", game.getCurrentBuilding().colorThemeIndex + 1); + } + String fullText = "Строим " + game.getCurrentBuilding().type + + " (" + game.getCurrentBuilding().constructionProgress + "/3)" + colorInfo + + ": " + game.getCurrentProblem().getQuestion() + overlapText; + game.setProblemText(fullText); + } else { + String planetText = game.isSwitchingPlanets() ? + "Перелет на " + game.getTargetPlanet().getName() + "..." : + "Планета: " + planet.getName(); + + game.setProblemText(planetText + + " | Тип здания: " + planetBuildings[game.getSelectedBuildingType()] + + " (←/→ для выбора, кликните на поле для строительства)" + + " | ESC - меню"); + } + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..8dca129 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# This doesn't need to be false, and some projects may be able to take advantage of setting daemon to true. +# We set it to false by default in order to avoid too many daemons from being created and persisting; each needs RAM. +org.gradle.daemon=false +# Sets starting memory usage to 512MB, maximum memory usage to 1GB, and tries to set as much to use Unicode as we can. +org.gradle.jvmargs=-Xms512M -Xmx1G -Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8 +# "Configure on-demand" must be false because it breaks projects that have Android modules. The default is also false. +org.gradle.configureondemand=false +# The logging level determines which messages get shown about how Gradle itself is working, such as if build.gradle +# files are fully future-proof (which they never are, because Gradle constantly deprecates working APIs). +# You can change 'quiet' below to 'lifecycle' to use Gradle's default behavior, which shows some confusing messages. +# You could instead change 'quiet' below to 'info' to see info that's important mainly while debugging build files. +# Note that if you want to use Gradle Build Scans, you should set the below logging level to 'lifecycle', otherwise +# the link to the scan won't get shown at all. +# Documented at: https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging +org.gradle.logging.level=quiet +visUiVersion=1.5.7 +enableGraalNative=false +graalHelperVersion=2.0.1 +gdxVersion=1.14.0 +projectVersion=1.0.0 diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties new file mode 100644 index 0000000..67ed422 --- /dev/null +++ b/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,12 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73c462e34475aeb6509ab7ba3eda218f/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/54001d0b636ad500b432d20ef3d580d0/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73c462e34475aeb6509ab7ba3eda218f/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/54001d0b636ad500b432d20ef3d580d0/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29c55e6bad8a0049163f0184625cecd9/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/3ac7a5361c25c0b23d933f44bdb0abd9/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73c462e34475aeb6509ab7ba3eda218f/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/54001d0b636ad500b432d20ef3d580d0/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/28937bb8a7f83f57de92429a9a11c04e/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/52fa104f4f641439587f75dd68b31bc2/redirect +toolchainVersion=17 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..23449a2 --- /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-9.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..adff685 --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 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 + + + +# 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" ) + + 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, 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" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# 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 100644 index 0000000..c4bdd3a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@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 + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +: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/lwjgl2/build.gradle b/lwjgl2/build.gradle new file mode 100644 index 0000000..dc444d8 --- /dev/null +++ b/lwjgl2/build.gradle @@ -0,0 +1,50 @@ +apply plugin: 'application' + + +sourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ] +application.mainClass = 'com.mygdx.game.lwjgl2.Lwjgl2Launcher' +eclipse.project.name = appName + '-lwjgl2' +java.sourceCompatibility = 8 +java.targetCompatibility = 8 +if (JavaVersion.current().isJava9Compatible()) { + compileJava.options.release.set(8) +} + +dependencies { + implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" + implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + implementation project(':core') +} + +jar { + archiveBaseName.set(appName) +// 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. +// enabling native access helps avoid a warning when Java 24 or later runs the JAR. + manifest { + attributes 'Main-Class': application.mainClass, 'Enable-Native-Access': 'ALL-UNNAMED' + } +// this last step may help on some OSes that need extra instruction to make runnable JARs. + doLast { + file(archiveFile).setExecutable(true, false) + } +} + +// Equivalent to the jar task; here for compatibility with gdx-setup. +tasks.register('dist') { + dependsOn 'jar' +} + +run { + ignoreExitValue = true +} diff --git a/lwjgl2/src/main/java/com/mygdx/game/lwjgl2/Lwjgl2Launcher.java b/lwjgl2/src/main/java/com/mygdx/game/lwjgl2/Lwjgl2Launcher.java new file mode 100644 index 0000000..9606311 --- /dev/null +++ b/lwjgl2/src/main/java/com/mygdx/game/lwjgl2/Lwjgl2Launcher.java @@ -0,0 +1,30 @@ +package com.mygdx.game.lwjgl2; + +import com.badlogic.gdx.Files.FileType; +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; + +/** Launches the desktop (LWJGL2) application. */ +public class Lwjgl2Launcher { + public static void main(String[] args) { + createApplication(); + } + + private static LwjglApplication createApplication() { + return new LwjglApplication(new AbsurdCityBuilder1(), getDefaultConfiguration()); + } + + private static LwjglApplicationConfiguration getDefaultConfiguration() { + LwjglApplicationConfiguration configuration = new LwjglApplicationConfiguration(); + configuration.title = "AbsurdCityBuilder1"; + configuration.width = 640; + configuration.height = 480; + //// This prevents a confusing error that would appear after exiting normally. + configuration.forceExit = false; + + for (int size : new int[] { 128, 64, 32, 16 }) { + configuration.addIcon("libgdx" + size + ".png", FileType.Internal); + } + return configuration; + } +} diff --git a/lwjgl2/src/main/resources/libgdx128.png b/lwjgl2/src/main/resources/libgdx128.png new file mode 100644 index 0000000..f810616 Binary files /dev/null and b/lwjgl2/src/main/resources/libgdx128.png differ diff --git a/lwjgl2/src/main/resources/libgdx16.png b/lwjgl2/src/main/resources/libgdx16.png new file mode 100644 index 0000000..a6b1327 Binary files /dev/null and b/lwjgl2/src/main/resources/libgdx16.png differ diff --git a/lwjgl2/src/main/resources/libgdx32.png b/lwjgl2/src/main/resources/libgdx32.png new file mode 100644 index 0000000..9447b39 Binary files /dev/null and b/lwjgl2/src/main/resources/libgdx32.png differ diff --git a/lwjgl2/src/main/resources/libgdx64.png b/lwjgl2/src/main/resources/libgdx64.png new file mode 100644 index 0000000..7513f3b Binary files /dev/null and b/lwjgl2/src/main/resources/libgdx64.png differ diff --git a/lwjgl3/build.gradle b/lwjgl3/build.gradle new file mode 100644 index 0000000..aad865d --- /dev/null +++ b/lwjgl3/build.gradle @@ -0,0 +1,184 @@ + +buildscript { + repositories { + gradlePluginPortal() + } + dependencies { + classpath "io.github.fourlastor:construo:2.1.0" + 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 ] +application.mainClass = 'com.mygdx.game.lwjgl3.Lwjgl3Launcher' +eclipse.project.name = appName + '-lwjgl3' +java.sourceCompatibility = 8 +java.targetCompatibility = 8 +if (JavaVersion.current().isJava9Compatible()) { + compileJava.options.release.set(8) +} + +dependencies { + implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" + implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-lwjgl3-angle:$gdxVersion" + 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-bullet:$graalHelperVersion" + + } +} + +def os = System.properties['os.name'].toLowerCase(Locale.ROOT) + +run { + workingDir = rootProject.file('assets').path +// You can uncomment the next line if your IDE claims a build failure even when the app closed properly. + //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. +// enabling native access helps avoid a warning when Java 24 or later runs the JAR. + manifest { + attributes 'Main-Class': application.mainClass, 'Enable-Native-Access': 'ALL-UNNAMED' + } +// this last step may help on some OSes that need extra instruction to make runnable JARs. + doLast { + file(archiveFile).setExecutable(true, false) + } +} + +// Builds a JAR that only includes the files needed to run on macOS, not Windows or Linux. +// The file size for a Mac-only JAR is about 7MB smaller than a cross-platform JAR. +tasks.register("jarMac") { + dependsOn("jar") + group("build") + jar.archiveFileName.set("${appName}-${projectVersion}-mac.jar") + jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dll", "**/*.so", + 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') + dependencies { + jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", + 'META-INF/INDEX.LIST', 'META-INF/maven/**') + } +} + +// Builds a JAR that only includes the files needed to run on Linux, not Windows or macOS. +// The file size for a Linux-only JAR is about 5MB smaller than a cross-platform JAR. +tasks.register("jarLinux") { + dependsOn("jar") + group("build") + jar.archiveFileName.set("${appName}-${projectVersion}-linux.jar") + jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**", "**/*.dll", "**/*.dylib", + 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') + dependencies { + jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**", + 'META-INF/INDEX.LIST', 'META-INF/maven/**') + } +} + +// Builds a JAR that only includes the files needed to run on Windows, not Linux or macOS. +// The file size for a Windows-only JAR is about 6MB smaller than a cross-platform JAR. +tasks.register("jarWin") { + dependsOn("jar") + group("build") + jar.archiveFileName.set("${appName}-${projectVersion}-win.jar") + jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dylib", "**/*.so", + 'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA') + dependencies { + jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", + 'META-INF/INDEX.LIST', 'META-INF/maven/**') + } +} + +construo { + // name of the executable + name.set(appName) + // human-readable name, used for example in the `.app` name for macOS + humanName.set(appName) + + targets.configure { + register("linuxX64", Target.Linux) { + architecture.set(Target.Architecture.X86_64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_x64_linux_hotspot_17.0.15_6.tar.gz") + // Linux does not currently have a way to set the icon on the executable + } + register("macM1", Target.MacOs) { + architecture.set(Target.Architecture.AARCH64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_aarch64_mac_hotspot_17.0.15_6.tar.gz") + // macOS needs an identifier + identifier.set("com.mygdx.game." + appName) + // Optional: icon for macOS, as an ICNS file + macIcon.set(project.file("icons/logo.icns")) + } + register("macX64", Target.MacOs) { + architecture.set(Target.Architecture.X86_64) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_x64_mac_hotspot_17.0.15_6.tar.gz") + // macOS needs an identifier + identifier.set("com.mygdx.game." + appName) + // Optional: icon for macOS, as an ICNS file + macIcon.set(project.file("icons/logo.icns")) + } + register("winX64", Target.Windows) { + architecture.set(Target.Architecture.X86_64) + // Optional: icon for Windows, as a PNG + icon.set(project.file("icons/logo.png")) + jdkUrl.set("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.15%2B6/OpenJDK17U-jdk_x64_windows_hotspot_17.0.15_6.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 0000000..5e41ad7 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 0000000..c4f2d5e 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 0000000..f810616 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 0000000..bee3fd2 --- /dev/null +++ b/lwjgl3/nativeimage.gradle @@ -0,0 +1,54 @@ + +project(":lwjgl3") { + apply plugin: "org.graalvm.buildtools.native" + + graalvmNative { + binaries { + main { + imageName = appName + mainClass = application.mainClass + 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/com/mygdx/game/lwjgl3/Lwjgl3Launcher.java b/lwjgl3/src/main/java/com/mygdx/game/lwjgl3/Lwjgl3Launcher.java new file mode 100644 index 0000000..f2217a1 --- /dev/null +++ b/lwjgl3/src/main/java/com/mygdx/game/lwjgl3/Lwjgl3Launcher.java @@ -0,0 +1,19 @@ +package com.mygdx.game.lwjgl3; + +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; +import com.mygdx.game.AbsurdCityBuilder1; + +public class Lwjgl3Launcher { + public static void main(String[] args) { + Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); + + config.setTitle("Волшебный Строитель Города - LibGDX"); + config.setWindowedMode(1700, 950); + config.setResizable(false); + config.useVsync(true); + config.setForegroundFPS(60); + + new Lwjgl3Application(new AbsurdCityBuilder1(), config); + } +} diff --git a/lwjgl3/src/main/java/com/mygdx/game/lwjgl3/StartupHelper.java b/lwjgl3/src/main/java/com/mygdx/game/lwjgl3/StartupHelper.java new file mode 100644 index 0000000..5b8278f --- /dev/null +++ b/lwjgl3/src/main/java/com/mygdx/game/lwjgl3/StartupHelper.java @@ -0,0 +1,204 @@ +/* + * 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 com.mygdx.game.lwjgl3; + +import com.badlogic.gdx.Version; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3NativesLoader; +import org.lwjgl.system.macosx.LibC; +import org.lwjgl.system.macosx.ObjCRuntime; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; + +import static org.lwjgl.system.JNI.invokePPP; +import static org.lwjgl.system.JNI.invokePPZ; +import static org.lwjgl.system.macosx.ObjCRuntime.objc_getClass; +import static org.lwjgl.system.macosx.ObjCRuntime.sel_getUid; + +/** + * 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. + *
+ * Based on this java-gaming.org post by kappa + * @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. + *

+ * Usage: + * + *


+     * 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
+     * }
+     * 
+ * + * @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(java.util.Locale.ROOT); + 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. +// We also temporarily change the "user.name" property to one without any chars that would be invalid. +// We revert our changes immediately after loading LWJGL3 natives. + String programData = System.getenv("ProgramData"); + if(programData == null) programData = "C:\\Temp\\"; // if ProgramData isn't set, try some fallback. + String prevTmpDir = System.getProperty("java.io.tmpdir", programData); + String prevUser = System.getProperty("user.name", "libGDX_User"); + System.setProperty("java.io.tmpdir", programData + "/libGDX-temp"); + System.setProperty("user.name", ("User_" + prevUser.hashCode() + "_GDX" + Version.VERSION).replace('.', '_')); + Lwjgl3NativesLoader.load(); + System.setProperty("java.io.tmpdir", prevTmpDir); + System.setProperty("user.name", prevUser); + } + return false; + } + + // There is no need for -XstartOnFirstThread on Graal native image + if (!System.getProperty("org.graalvm.nativeimage.imagecode", "").isEmpty()) { + return false; + } + + // Checks if we are already on the main thread, such as from running via Construo. + long objc_msgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend"); + long NSThread = objc_getClass("NSThread"); + long currentThread = invokePPP(NSThread, sel_getUid("currentThread"), objc_msgSend); + boolean isMainThread = invokePPZ(currentThread, sel_getUid("isMainThread"), objc_msgSend); + if(isMainThread) 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 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. + *

+ * Usage: + * + *

+     * public static void main(String... args) {
+     * 	if (StartupHelper.startNewJvmIfRequired()) return; // This handles macOS support and helps on Windows.
+     * 	// the actual main method code
+     * }
+     * 
+ * + * @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 0000000..f810616 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 0000000..a6b1327 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 0000000..9447b39 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 0000000..7513f3b 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 0000000..e27fb9a --- /dev/null +++ b/settings.gradle @@ -0,0 +1,8 @@ +plugins { + // Applies the foojay-resolver plugin to allow automatic download of JDKs. + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" +} +// 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 'core', 'lwjgl3', 'lwjgl2'