Compare commits

...

114 Commits

Author SHA1 Message Date
Vladislav Khorev
5e7c050c68 Merge branch 'spark' 2026-03-10 11:39:02 +03:00
Vladislav Khorev
c88784a669 Added inverse, fixing server bug 2026-03-10 11:38:16 +03:00
Vlad
181132e092 merge 2026-03-10 14:36:35 +06:00
Vlad
6fe10eacfc Merge remote-tracking branch 'origin/main' into spark 2026-03-10 14:26:51 +06:00
Vlad
9e692c9ec3 added enter nicknamw 2026-03-10 14:25:00 +06:00
Vladislav Khorev
785b96ce82 Working on list of players 2026-03-09 23:04:48 +03:00
Vladislav Khorev
a8ded217df Fixing ui bugs 2026-03-09 20:52:16 +03:00
Vladislav Khorev
3e8dba36a4 fixing minor bugs, fixing velocity not changed after death, fixing server crash 2026-03-09 19:27:20 +03:00
Vladislav Khorev
84a5e888a0 Added pickup boxes 2026-03-09 18:36:04 +03:00
Vladislav Khorev
86a9f38c3b Some UI changes 2026-03-09 13:50:59 +03:00
Vladislav Khorev
24aa7007bb Added trails to other ships toos 2026-03-08 21:27:45 +03:00
Vladislav Khorev
59b5bea540 Fixing particles 2026-03-08 19:07:02 +03:00
Vladislav Khorev
9da3cc4401 Fixing bug in particle emitter 2026-03-08 00:22:13 +03:00
Vladislav Khorev
4a542fd6c8 Added multi-touch, added on press down 2026-03-07 22:41:25 +03:00
Vladislav Khorev
a06cb77a66 Fixing minor stuff, refactoring 2026-03-07 20:51:34 +03:00
Vladislav Khorev
3c2c06ca40 Working on refactoring 2026-03-07 20:03:16 +03:00
Vladislav Khorev
928600acd4 Refactoring 2026-03-07 19:41:15 +03:00
Vladislav Khorev
7ccda081b0 Fixing bugs 2026-03-06 23:15:56 +03:00
Vladislav Khorev
41f370f2ee Minor fixing 2026-03-06 22:34:03 +03:00
Vladislav Khorev
4af20c65e6 Make menu to state machine 2026-03-06 21:52:00 +03:00
Vladislav Khorev
ac551122d9 Added force disconnect from server 2026-03-06 20:05:55 +03:00
Vladislav Khorev
8528b4dc90 Clean up server 2026-03-06 19:08:55 +03:00
Vladislav Khorev
c35e093cc5 Working on encoding 2026-03-06 17:51:46 +03:00
Vladislav Khorev
a8c76dee3c Working on fixing minor bugs 2026-03-05 23:58:35 +03:00
Vladislav Khorev
e84a094ad9 Merge branch 'spark' 2026-03-05 19:54:24 +03:00
Vladislav Khorev
b0b7391939 Fixed low quality 2026-03-05 19:53:27 +03:00
Vlad
3e2632c5b5 added textures 2026-03-05 20:14:02 +06:00
Vladislav Khorev
70ef730e86 Merge branch 'main' into ShipSpawn 2026-03-05 10:24:17 +03:00
Vladislav Khorev
92b288d978 fixing bugs 2026-03-05 10:15:55 +03:00
Vladislav Khorev
cca1d0ece2 Merge branch 'spark' 2026-03-05 09:10:38 +03:00
Vladislav Khorev
8effdd5dfa Merge branch 'sergey' 2026-03-05 09:10:00 +03:00
Vladislav Khorev
e78429b600 Working on running the game even in Telegram 2026-03-04 21:41:51 +03:00
05a13a40e7 fixed: Box destroition 2026-03-04 16:37:00 +06:00
ef7617701e fix server collision radius mismatch 2026-03-04 03:37:58 +06:00
2f50dc1522 fix Lead Indicator rendering when target off-screen 2026-03-04 01:42:57 +06:00
9eafcd27fb Fix lead indicator prediction & align projectile lifetime (client/server) 2026-03-03 19:42:08 +06:00
Vlad
3879eb1d75 fixed web ship types boxes / local boxes collision and projectiles 2026-03-03 19:17:07 +06:00
78046e5e2d Merge remote-tracking branch 'origin/main' into ShipSpawn 2026-03-02 17:49:09 +06:00
26233f934f fixed: spawning ships 2026-03-02 17:47:46 +06:00
Vlad
167c04b107 install 2026-03-02 14:05:23 +06:00
Vladislav Khorev
5fcb1d1234 server changes 2026-03-01 22:35:17 +03:00
Vladislav Khorev
70a617b688 More changes 2026-03-01 22:34:12 +03:00
Vladislav Khorev
bb0f584bf6 Working on UI and web game 2026-03-01 21:22:57 +03:00
Vladislav Khorev
6b4b549b3c Working on UI for web 2026-02-28 23:01:26 +03:00
Vladislav Khorev
ffbecbbcde Working on ui 2026-02-28 22:21:08 +03:00
Vladislav Khorev
2728ca9646 Adapting web version 2026-02-28 20:37:47 +03:00
Vladislav Khorev
7e5aa22fee merge 2026-02-28 13:33:33 +03:00
Vlad
c20e82634a fix game over 2026-02-28 12:07:40 +06:00
Vladislav Khorev
9f82e7a2e6 Adapt for web 2026-02-27 22:31:07 +03:00
Vlad
7418bbbe27 fix spaceship rotation fix sync boxes 2026-02-27 17:37:00 +06:00
Vladislav Khorev
be2aa76f8b Working on server optimization 2026-02-26 22:26:43 +03:00
Vladislav Khorev
e8f1786a2a merge 2026-02-26 21:22:38 +03:00
Vladislav Khorev
e30f8a4c70 merge 2026-02-26 21:10:27 +03:00
Vladislav Khorev
f8642efa23 merge 2026-02-26 21:02:16 +03:00
5da5a754fe add configurable HUD crosshair 2026-02-26 01:49:49 +06:00
fb1b0a1c2e Lead Indicator fix 2026-02-25 22:18:47 +06:00
Vlad
74c2f786a1 added choising spaceship type for multiplayer and some fix in respawn 2026-02-25 19:17:42 +06:00
Vlad
5216965496 added choosing spaceship in singleplay 2026-02-24 20:34:01 +06:00
Vlad
ad7294ceea added random spaceship type 2026-02-24 19:51:33 +06:00
Vlad
3893038d9a Merge remote-tracking branch 'origin/main' into spark 2026-02-23 15:30:01 +06:00
Vlad
cb2e8318e7 added multi_menu 2026-02-23 15:29:05 +06:00
Vladislav Khorev
5cca2413fe changes 2026-02-23 11:46:57 +03:00
Vladislav Khorev
db4254e205 working on web 2026-02-23 11:45:55 +03:00
fa3a4c66c9 add lead indicator 2026-02-23 14:43:23 +06:00
Vladislav Khorev
84006380db Added loading screen 2026-02-23 09:55:01 +03:00
Vladislav Khorev
f6cc30a30c Try out Cursor 2026-02-22 21:20:39 +03:00
Vladislav Khorev
d883b58260 Adapt for web 2026-02-22 20:04:18 +03:00
Vladislav Khorev
b59a10b7e6 Major refactoring for game menu 2026-02-22 19:50:13 +03:00
Vladislav Khorev
5b57696acf Refactoring major 2026-02-22 19:15:25 +03:00
Vladislav Khorev
1265d87bc5 Updated UI 2026-02-22 18:23:27 +03:00
Vladislav Khorev
46d7a2a25d Merge branch 'spark' 2026-02-22 17:02:40 +03:00
Vlad
0babfff28b added multiplayer menu 2026-02-22 19:21:12 +06:00
Vladislav Khorev
ed6e1bacc7 merge 2026-02-22 16:03:11 +03:00
Vladislav Khorev
9c39782729 Fixing bug with collisions 2026-02-22 15:53:04 +03:00
Vladislav Khorev
efad2dde3e Restore as it was before 2026-02-22 14:08:12 +03:00
Vladislav Khorev
84d8ee7eee Merge branch 'spark' 2026-02-22 13:30:33 +03:00
Vladislav Khorev
7693237aa5 Added websocket 2026-02-22 13:29:06 +03:00
528c94e921 Add enemy target brackets + off-screen arrows 2026-02-19 01:13:08 +06:00
Vlad
a8700af1d0 added npc destroy 2026-02-13 15:40:40 +06:00
Vlad
9793c5bf06 fix npc 2026-02-12 18:13:19 +06:00
b56fafa0e0 Add mesh caching for unchanging text labels 2026-02-12 13:23:16 +06:00
Vladislav Khorev
22ee99418d Working on web version 2026-02-11 21:48:25 +03:00
4eda57b4e4 single texture atlas for all font glyphs in TextRenderer 2026-02-12 00:08:52 +06:00
Vladislav Khorev
2ffd8124f2 Change the way fire happens 2026-02-11 20:02:15 +03:00
Vladislav Khorev
210c191d41 Added different hash func 2026-02-10 21:06:21 +03:00
Vladislav Khorev
251a59ddbe added hash 2026-02-10 11:42:23 +03:00
Vlad
5df2216da6 added npc 2026-02-10 12:42:19 +06:00
Vladislav Khorev
2c1c077611 Added time offset sync, added web version multiplayer 2026-02-09 22:56:48 +03:00
Vlad
629c9ba7b1 add local server 2026-02-09 18:42:07 +06:00
Vladislav Khorev
a59bcc0c4b Adapting for web 2026-02-08 22:38:24 +03:00
Vladislav Khorev
cf1ec1e76f merge 2026-02-08 15:53:55 +03:00
Vladislav Khorev
8a374a4231 Merge with main 2026-02-08 15:31:25 +03:00
Vlad
da2b6e5577 some fix/added sync boxes 2026-02-06 19:16:17 +06:00
aa9590e2f4 Add velocity HUD display (Velocity: 0) in top-left corner 2026-02-06 18:04:33 +06:00
a1d54b01b0 Add TextView UI component 2026-02-06 15:11:27 +06:00
Vlad
65a2066727 size 2026-02-05 14:00:20 +06:00
Vladislav Khorev
c49c4626d0 merge 2026-02-05 10:43:24 +03:00
Vlad
ec156bd679 add sync projectiles 2026-02-05 13:29:21 +06:00
Vladislav Khorev
7b1d9363a0 Fixing lag compensation and make more smooth 2026-02-05 09:00:54 +03:00
Vladislav Khorev
82ca994fac merge 2026-02-05 07:33:13 +03:00
Vladislav Khorev
0d2f705d42 merge 2026-02-05 07:30:12 +03:00
e799b4ec79 conflict resolution 2026-02-05 01:43:45 +06:00
c8076b6018 adjust label scale: constant far, smooth growth near 2026-02-05 01:34:14 +06:00
Vlad
88f68b20ea some fix 2026-02-02 14:45:36 +06:00
d249f17d22 everything uselles 2026-02-02 13:50:43 +06:00
bee3545196 change to permanent visibility of ship labels 2026-02-02 13:48:28 +06:00
e050d7d0ec Improve ship nickname rendering 2026-02-02 04:44:18 +06:00
e18484ea62 add player ID labels for ships 2026-02-01 23:34:21 +06:00
Vlad
204b79bf06 add main menu 2026-01-31 19:25:40 +06:00
Vlad
50232c0816 fix shooting 2026-01-31 16:44:00 +06:00
Vlad
e8fb14b809 added sync projectiles/boxes 2026-01-27 19:38:18 +06:00
Vladislav Khorev
d425167dce Added planet physics and simple base 2026-01-25 20:55:36 +03:00
f41228acf8 add freetype-based text rendering and box labels 2026-01-22 15:54:21 +06:00
Vlad
cacc18dc7e added boxes from server 2026-01-19 22:04:33 +06:00
165 changed files with 22659 additions and 2375 deletions

View File

@ -397,9 +397,11 @@ endif()
add_library(freetype_external_lib UNKNOWN IMPORTED GLOBAL) add_library(freetype_external_lib UNKNOWN IMPORTED GLOBAL)
set_target_properties(freetype_external_lib PROPERTIES set_target_properties(freetype_external_lib PROPERTIES
IMPORTED_LOCATION_DEBUG "${_ft_debug_lib}" IMPORTED_LOCATION_DEBUG "${_ft_debug_lib}"
IMPORTED_LOCATION_RELEASE "${_ft_release_lib}" IMPORTED_LOCATION_RELEASE "${_ft_release_lib}"
INTERFACE_INCLUDE_DIRECTORIES )
"$<IF:$<CONFIG:Debug>,${FREETYPE_BASE_DIR}-Debug/include,${FREETYPE_BASE_DIR}-Release/include>" target_include_directories(freetype_external_lib INTERFACE
"$<IF:$<CONFIG:Debug>,${FREETYPE_BASE_DIR}-Debug/include/freetype2,${FREETYPE_BASE_DIR}-Release/include/freetype2>"
"$<IF:$<CONFIG:Debug>,${FREETYPE_BASE_DIR}-Debug/include,${FREETYPE_BASE_DIR}-Release/include>"
) )
# =========================================== # ===========================================
@ -453,8 +455,8 @@ if(NOT _have_sdl2ttf)
-DSDL2_LIBRARY=${_SDL2_LIB} -DSDL2_LIBRARY=${_SDL2_LIB}
-DSDL2_INCLUDE_DIR=${SDL2_INSTALL_DIR}/include/SDL2 -DSDL2_INCLUDE_DIR=${SDL2_INSTALL_DIR}/include/SDL2
-DFREETYPE_LIBRARY=${_FT_LIB} -DFREETYPE_LIBRARY=${_FT_LIB}
-DFREETYPE_INCLUDE_DIR=${_FT_PREFIX}/include -DFREETYPE_INCLUDE_DIR=${_FT_PREFIX}/include/freetype2
-DFREETYPE_INCLUDE_DIRS=${_FT_PREFIX}/include -DFREETYPE_INCLUDE_DIRS=${_FT_PREFIX}/include/freetype2
-DSDL2TTF_VENDORED=OFF -DSDL2TTF_VENDORED=OFF
-DSDL2TTF_SAMPLES=OFF -DSDL2TTF_SAMPLES=OFF
RESULT_VARIABLE _ttf_cfg_res RESULT_VARIABLE _ttf_cfg_res

View File

@ -21,23 +21,60 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/FetchDependencies.cmake")
set(SOURCES set(SOURCES
../src/main.cpp ../src/main.cpp
../src/Game.cpp ../src/Game.cpp
../src/Game.h
../src/Environment.cpp ../src/Environment.cpp
../src/BoneAnimatedModel.cpp ../src/Environment.h
../src/TextModel.cpp
../src/Projectile.cpp
../src/SparkEmitter.cpp
../src/UiManager.cpp
../src/render/Renderer.cpp ../src/render/Renderer.cpp
../src/render/Renderer.h
../src/render/ShaderManager.cpp ../src/render/ShaderManager.cpp
../src/render/ShaderManager.h
../src/render/TextureManager.cpp ../src/render/TextureManager.cpp
../src/render/FrameBuffer.cpp ../src/render/TextureManager.h
../src/TextModel.cpp
../src/TextModel.h
../src/AudioPlayerAsync.cpp
../src/AudioPlayerAsync.h
../src/BoneAnimatedModel.cpp
../src/BoneAnimatedModel.h
../src/render/OpenGlExtensions.cpp ../src/render/OpenGlExtensions.cpp
../src/render/OpenGlExtensions.h
../src/utils/Utils.cpp ../src/utils/Utils.cpp
../src/utils/TaskManager.cpp ../src/utils/Utils.h
../src/utils/Perlin.cpp ../src/SparkEmitter.cpp
../src/planet/PlanetData.cpp ../src/SparkEmitter.h
../src/planet/PlanetObject.cpp ../src/planet/PlanetObject.cpp
../src/planet/StoneObject.cpp ../src/planet/PlanetObject.h
../src/planet/PlanetData.cpp
../src/planet/PlanetData.h
../src/utils/Perlin.cpp
../src/utils/Perlin.h
../src/utils/TaskManager.cpp
../src/utils/TaskManager.h
../src/planet/StoneObject.cpp
../src/planet/StoneObject.h
../src/render/FrameBuffer.cpp
../src/render/FrameBuffer.h
../src/UiManager.cpp
../src/UiManager.h
../src/Projectile.h
../src/Projectile.cpp
../src/network/NetworkInterface.h
../src/network/LocalClient.h
../src/network/LocalClient.cpp
../src/network/ClientState.h
../src/network/ClientState.cpp
../src/network/WebSocketClientBase.h
../src/network/WebSocketClientBase.cpp
../src/network/WebSocketClientEmscripten.h
../src/network/WebSocketClientEmscripten.cpp
../src/render/TextRenderer.h
../src/render/TextRenderer.cpp
../src/MenuManager.h
../src/MenuManager.cpp
../src/Space.h
../src/Space.cpp
../src/GameConstants.h
../src/GameConstants.cpp
) )
add_executable(space-game001 ${SOURCES}) add_executable(space-game001 ${SOURCES})
@ -58,30 +95,33 @@ set(ENABLE_COMMONCRYPTO OFF CACHE BOOL "" FORCE)
add_subdirectory("../thirdparty/libzip-1.11.4" libzip-build) add_subdirectory("../thirdparty/libzip-1.11.4" libzip-build)
# Линковка: target_link_libraries(space-game001 PRIVATE zip z websocket.js)
# 'zip' берется из add_subdirectory
# 'z' - это системный zlib Emscripten-а (флаг -sUSE_ZLIB=1 добавим ниже)
target_link_libraries(space-game001 PRIVATE zip z)
# Эмскриптен-флаги # Эмскриптен-флаги
set(EMSCRIPTEN_FLAGS set(EMSCRIPTEN_FLAGS
"-sUSE_SDL=2" "-sUSE_SDL=2"
"-sUSE_SDL_IMAGE=2" "-sUSE_SDL_IMAGE=2"
"-sUSE_LIBPNG=1" "-sUSE_LIBPNG=1"
"-sUSE_ZLIB=1" # Добавили zlib порт "-sUSE_ZLIB=1"
"-pthread" "-sUSE_SDL_TTF=2"
"-sUSE_PTHREADS=1" #"-pthread"
#"-sUSE_PTHREADS=1"
"-fexceptions" "-fexceptions"
"-DNETWORK"
) )
target_compile_options(space-game001 PRIVATE ${EMSCRIPTEN_FLAGS} "-O2") target_compile_options(space-game001 PRIVATE ${EMSCRIPTEN_FLAGS} "-O2")
# Only loading.png and the shaders used before resources.zip is ready are preloaded.
# resources.zip is downloaded asynchronously at runtime and served as a separate file.
set(EMSCRIPTEN_LINK_FLAGS set(EMSCRIPTEN_LINK_FLAGS
${EMSCRIPTEN_FLAGS} ${EMSCRIPTEN_FLAGS}
"-O2" "-O2"
"-sPTHREAD_POOL_SIZE=4" #"-sPTHREAD_POOL_SIZE=4"
"-sALLOW_MEMORY_GROWTH=1" "-sALLOW_MEMORY_GROWTH=1"
"--preload-file resources.zip" "-sFULL_ES3=1"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/loading.png@resources/loading.png"
"--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/../resources/shaders@resources/shaders"
) )
# Применяем настройки линковки # Применяем настройки линковки
@ -131,8 +171,8 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/space-game001plain.html"
DESTINATION . DESTINATION .
) )
# Если вам все еще нужен сам resources.zip отдельно в папке public: # resources.zip is served separately and downloaded asynchronously at runtime
#install(FILES "${RESOURCES_ZIP}" DESTINATION .) install(FILES "${RESOURCES_ZIP}" DESTINATION .)
add_custom_command(TARGET space-game001 POST_BUILD add_custom_command(TARGET space-game001 POST_BUILD
COMMAND ${CMAKE_COMMAND} --install . COMMAND ${CMAKE_COMMAND} --install .

View File

@ -1,7 +1,13 @@
# how to build # how to build
If emsdk is not installed, you need to clone it from here: https://github.com/emscripten-core/emsdk
Activate the environment: and install:
```
C:\Work\Projects\emsdk\emsdk.bat install latest
```
Then activate the environment:
``` ```
C:\Work\Projects\emsdk\emsdk.bat activate latest C:\Work\Projects\emsdk\emsdk.bat activate latest
C:\Work\Projects\emsdk\emsdk_env.bat C:\Work\Projects\emsdk\emsdk_env.bat

View File

@ -0,0 +1,2 @@
<!doctypehtml><html lang=en-us><head><meta charset=utf-8><meta content="text/html; charset=utf-8"http-equiv=Content-Type><title>Emscripten-Generated Code</title><style>body{font-family:arial;margin:0;padding:none}.emscripten{padding-right:0;margin-left:auto;margin-right:auto;display:block}div.emscripten{text-align:center}div.emscripten_border{border:1px solid #000}canvas.emscripten{border:0 none;background-color:#000}#emscripten_logo{display:inline-block;margin:0;padding:6px;width:265px}.spinner{height:30px;width:30px;margin:0;margin-top:20px;margin-left:20px;display:inline-block;vertical-align:top;-webkit-animation:rotation .8s linear infinite;-moz-animation:rotation .8s linear infinite;-o-animation:rotation .8s linear infinite;animation:rotation .8s linear infinite;border-left:5px solid #ebebeb;border-right:5px solid #ebebeb;border-bottom:5px solid #ebebeb;border-top:5px solid #787878;border-radius:100%;background-color:#bdd72e}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0)}to{-moz-transform:rotate(360deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0)}to{-o-transform:rotate(360deg)}}@keyframes rotation{from{transform:rotate(0)}to{transform:rotate(360deg)}}#status{display:inline-block;vertical-align:top;margin-top:30px;margin-left:20px;font-weight:700;color:#787878}#progress{height:20px;width:300px}#controls{display:inline-block;float:right;vertical-align:top;margin-top:30px;margin-right:20px}#output{width:100%;height:200px;margin:0 auto;margin-top:10px;border-left:0;border-right:0px;padding-left:0;padding-right:0;display:block;background-color:#000;color:#fff;font-family:'Lucida Console',Monaco,monospace;outline:0}</style></head><body><script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>eruda.init();</script><a href=http://emscripten.org><img id=emscripten_logo src=""></a><div class=spinner id=spinner></div><div class=emscripten id=status>Downloading...</div><span id=controls><span><input type=checkbox id=resize>Resize canvas</span> <span><input type=checkbox id=pointerLock checked>Lock/hide mouse pointer    </span><span><input type=button onclick='Module.requestFullscreen(document.getElementById("pointerLock").checked,document.getElementById("resize").checked)'value=Fullscreen></span></span><div class=emscripten><progress hidden id=progress max=100 value=0></progress></div><div class=emscripten_border><canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas></div><textarea id=output rows=8></textarea><script>var statusElement=document.getElementById("status"),progressElement=document.getElementById("progress"),spinnerElement=document.getElementById("spinner"),canvasElement=document.getElementById("canvas"),outputElement=document.getElementById("output");outputElement&&(outputElement.value=""),canvasElement.addEventListener("webglcontextlost",(e=>{alert("WebGL context lost. You will need to reload the page."),e.preventDefault()}),!1);var Module={print(...e){if(console.log(...e),outputElement){var t=e.join(" ");outputElement.value+=t+"\n",outputElement.scrollTop=outputElement.scrollHeight}},canvas:canvasElement,setStatus(e){if(Module.setStatus.last||(Module.setStatus.last={time:Date.now(),text:""}),e!==Module.setStatus.last.text){var t=e.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/),n=Date.now();t&&n-Module.setStatus.last.time<30||(Module.setStatus.last.time=n,Module.setStatus.last.text=e,t?(e=t[1],progressElement.value=100*parseInt(t[2]),progressElement.max=100*parseInt(t[4]),progressElement.hidden=!1,spinnerElement.hidden=!1):(progressElement.value=null,progressElement.max=null,progressElement.hidden=!0,e||(spinnerElement.style.display="none")),statusElement.innerHTML=e)}},totalDependencies:0,monitorRunDependencies(e){this.totalDependencies=Math.max(this.totalDependencies,e),Module.setStatus(e?"Preparing... ("+(this.totalDependencies-e)+"/"+this.totalDependencies+")":"All downloads complete.")}};Module.setStatus("Downloading..."),window.onerror=e=>{Module.setStatus("Exception thrown, see JavaScript console"),spinnerElement.style.display="none",Module.setStatus=e=>{e&&console.error("[post-exception status] "+e)}}</script><script async src="space-game001.js" crossorigin="anonymous"></script></body></html>

View File

@ -1,100 +1,216 @@
<!doctypehtml> <!DOCTYPE html>
<html lang=en-us> <html lang="en-us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Space Game</title>
<style>
body, html {
margin: 0; padding: 0; width: 100%; height: 100%;
overflow: hidden; background-color: #000;
position: fixed;
}
#canvas {
display: block;
position: absolute;
top: 0; left: 0;
width: 100vw; height: 100vh;
border: none;
}
<head> #fs-button {
<meta charset=utf-8> position: absolute;
<meta content="text/html; charset=utf-8" http-equiv=Content-Type> top: 10px; right: 10px;
<title>Space Game</title> padding: 10px;
<style> z-index: 10;
body { background: rgba(255,255,255,0.3);
font-family: arial; color: white; border: 1px solid white;
margin: 0; cursor: pointer;
overflow: hidden; font-family: sans-serif;
padding: 0; border-radius: 5px;
min-height: 100vh; }
background-color: #000; #status { color: white; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
/* Nick modal */
#nickOverlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0,0,0,0.85);
z-index: 9999;
}
#nickBox {
background: #111;
border: 1px solid #444;
padding: 24px;
width: 320px;
box-shadow: 0 8px 24px rgba(0,0,0,0.6);
text-align: center;
}
#nickBox h2 { margin: 0 0 12px 0; font-size: 18px; color: #eee; }
#nickBox input[type="text"] {
width: 100%;
padding: 10px;
font-size: 16px;
box-sizing: border-box;
margin-bottom: 12px;
border: 1px solid #333;
background: #000;
color: #fff;
}
#nickBox button {
padding: 10px 16px;
font-size: 16px;
background: #2a9fd6;
border: none;
color: #fff;
cursor: pointer;
}
#nickSkip { margin-left: 8px; background: #666; }
</style>
</head>
<body>
<button id="fs-button">Fullscreen</button>
<div id="status">Downloading...</div>
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex="-1"></canvas>
<!--
<script>
var statusElement = document.getElementById("status");
var canvas = document.getElementById("canvas");
var Module = {
canvas: canvas,
setStatus: function(text) {
statusElement.innerHTML = text;
statusElement.style.display = text ? 'block' : 'none';
}
};
document.getElementById('fs-button').addEventListener('click', function() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen().catch(e => {
console.error(`Error attempting to enable full-screen mode: ${e.message}`);
});
} else {
document.exitFullscreen();
}
});
window.addEventListener("orientationchange", function() {
setTimeout(() => {
window.dispatchEvent(new Event('resize'));
}, 200);
});
</script>
<script async src="space-game001.js"></script>-->
<div id="nickOverlay" style="display:none;">
<div id="nickBox">
<h2>Enter your nickname</h2>
<input id="nickInput" type="text" maxlength="32" placeholder="Player" />
<div>
<button id="nickSubmit">Start</button>
</div>
</div>
</div>
<script>
// Utility: подготовить глобальный Module до загрузки Emscripten-скрипта
function prepareModuleEnvironment() {
window.Module = window.Module || {};
var canvasEl = document.getElementById('canvas');
// Устанавливаем canvas для Emscripten, чтобы createContext не падал
window.Module.canvas = canvasEl;
// Подготовим заглушку setStatus, если ещё нет
window.Module.setStatus = window.Module.setStatus || function (text) {
var statusElement = document.getElementById("status");
statusElement.innerHTML = text;
statusElement.style.display = text ? 'block' : 'none';
};
}
// Show overlay only if no nickname saved.
function loadGameScript() {
var s = document.createElement('script');
s.src = 'space-game001.js';
s.async = true;
document.body.appendChild(s);
}
function showNickOverlay() {
var overlay = document.getElementById('nickOverlay');
overlay.style.display = 'flex';
var input = document.getElementById('nickInput');
input.focus();
}
function hideNickOverlay() {
var overlay = document.getElementById('nickOverlay');
overlay.style.display = 'none';
}
function saveNickAndStart(nick) {
try {
if (!nick || nick.trim() === '') nick = 'Player';
localStorage.setItem('spacegame_nick', nick);
} catch (e) {
console.warn('localStorage not available', e);
}
hideNickOverlay();
// перед загрузкой скрипта гарантируем, что Module.canvas задан
prepareModuleEnvironment();
loadGameScript();
}
document.addEventListener('DOMContentLoaded', function() {
// Готовим Module сразу — даже если откроется модалка, поле canvas будет доступно для скрипта (если он загружается позже)
prepareModuleEnvironment();
var stored = null;
try {
stored = localStorage.getItem('spacegame_nick');
} catch (e) {
console.warn('localStorage not available', e);
} }
.emscripten { if (stored && stored.trim() !== '') {
padding-right: 0; // Nick is present — start immediately
margin-left: auto; loadGameScript();
margin-right: auto; } else {
display: block // Show modal to request nickname before loading WASM
showNickOverlay();
var submit = document.getElementById('nickSubmit');
var skip = document.getElementById('nickSkip');
var input = document.getElementById('nickInput');
submit.addEventListener('click', function() {
saveNickAndStart(input.value);
});
skip.addEventListener('click', function() {
saveNickAndStart('Player');
});
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
saveNickAndStart(input.value);
}
});
} }
});
div.emscripten { window.addEventListener("orientationchange", function() {
text-align: center // Chrome на Android обновляет innerWidth/Height не мгновенно.
} // Ждем завершения анимации поворота.
setTimeout(() => {
// В Emscripten это вызовет ваш onWindowResized в C++
window.dispatchEvent(new Event('resize'));
}, 200);
});
div.emscripten_border { </script>
border: 1px solid #000
}
canvas.emscripten { </body>
border: 0 none; </html>
background-color: #000;
width: 90%;
height: 100vh;
}
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0)
}
to {
-webkit-transform: rotate(360deg)
}
}
@-moz-keyframes rotation {
from {
-moz-transform: rotate(0)
}
to {
-moz-transform: rotate(360deg)
}
}
@-o-keyframes rotation {
from {
-o-transform: rotate(0)
}
to {
-o-transform: rotate(360deg)
}
}
@keyframes rotation {
from {
transform: rotate(0)
}
to {
transform: rotate(360deg)
}
}
#status {
display: none;
}
#progress {
height: 20px;
width: 300px
}
</style>
</head>
<body>
<div class=emscripten id=status></div>
<div class=emscripten><progress hidden id=progress max=100 value=0></progress></div>
<div class=emscripten_border><canvas class=emscripten id=canvas oncontextmenu=event.preventDefault()
tabindex=-1></canvas></div>
<script>var statusElement = document.getElementById("status"), progressElement = document.getElementById("progress"), spinnerElement = document.getElementById("spinner"), Module = { print: function () { var e = document.getElementById("output"); return e && (e.value = ""), function (t) { arguments.length > 1 && (t = Array.prototype.slice.call(arguments).join(" ")), console.log(t), e && (e.value += t + "\n", e.scrollTop = e.scrollHeight) } }(), canvas: (() => { var e = document.getElementById("canvas"); return e.addEventListener("webglcontextlost", (e => { alert("WebGL context lost. You will need to reload the page."), e.preventDefault() }), !1), e })(), setStatus: e => { if (Module.setStatus.last || (Module.setStatus.last = { time: Date.now(), text: "" }), e !== Module.setStatus.last.text) { var t = e.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/), n = Date.now(); t && n - Module.setStatus.last.time < 30 || (Module.setStatus.last.time = n, Module.setStatus.last.text = e, t ? (e = t[1], progressElement.value = 100 * parseInt(t[2]), progressElement.max = 100 * parseInt(t[4]), progressElement.hidden = !1, spinnerElement.hidden = !1) : (progressElement.value = null, progressElement.max = null, progressElement.hidden = !0, e || (spinnerElement.style.display = "none")), statusElement.innerHTML = e) } }, totalDependencies: 0, monitorRunDependencies: e => { this.totalDependencies = Math.max(this.totalDependencies, e), Module.setStatus(e ? "Preparing... (" + (this.totalDependencies - e) + "/" + this.totalDependencies + ")" : "All downloads complete.") } }; Module.setStatus("Downloading..."), window.onerror = e => { Module.setStatus("Exception thrown, see JavaScript console"), spinnerElement.style.display = "none", Module.setStatus = e => { e && console.error("[post-exception status] " + e) } }</script>
<script async src=space-game001.js></script>
</body>
</html>

View File

@ -57,6 +57,18 @@ add_executable(space-game001
../src/network/ClientState.cpp ../src/network/ClientState.cpp
../src/network/WebSocketClient.h ../src/network/WebSocketClient.h
../src/network/WebSocketClient.cpp ../src/network/WebSocketClient.cpp
../src/network/WebSocketClientBase.h
../src/network/WebSocketClientBase.cpp
../src/network/WebSocketClientEmscripten.h
../src/network/WebSocketClientEmscripten.cpp
../src/render/TextRenderer.h
../src/render/TextRenderer.cpp
../src/MenuManager.h
../src/MenuManager.cpp
../src/Space.h
../src/Space.cpp
../src/GameConstants.h
../src/GameConstants.cpp
) )
# Установка проекта по умолчанию для Visual Studio # Установка проекта по умолчанию для Visual Studio
@ -78,7 +90,7 @@ target_compile_definitions(space-game001 PRIVATE
WIN32_LEAN_AND_MEAN WIN32_LEAN_AND_MEAN
PNG_ENABLED PNG_ENABLED
SDL_MAIN_HANDLED SDL_MAIN_HANDLED
# NETWORK NETWORK
# SIMPLIFIED # SIMPLIFIED
) )

BIN
resources/Cargo_Base_color_sRGB.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
resources/black.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/blue_transparent.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_minus.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_minus_disabled.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_minus_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_players.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_plus.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_plus_disabled.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_plus_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_take.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_take_disabled.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/button_take_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

6175
resources/cargoship001.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "StaticImage",
"name": "connecting",
"x" : 0,
"y" : 0,
"width": 488,
"height": 154,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"texture": "resources/connecting.png"
}
]
}
}

View File

@ -0,0 +1,52 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "StaticImage",
"name": "connectionFailed",
"x" : 0,
"y" : 0,
"width": 488,
"height": 308,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"texture": "resources/connection_failed.png"
},
{
"type": "Button",
"name": "connectionFailedReconnectButton",
"width": 382,
"height": 56,
"x" : 0,
"y" : -20,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"textures": {
"normal": "resources/game_over/Filledbuttons.png",
"hover": "resources/game_over/Variant5.png",
"pressed": "resources/game_over/Variant6.png"
}
},
{
"type": "Button",
"name": "connectionFailedGoBack",
"width": 382,
"height": 56,
"x" : 0,
"y" : -86,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"textures": {
"normal": "resources/game_over/Secondarybutton.png",
"hover": "resources/game_over/Secondarybutton.png",
"pressed": "resources/game_over/Secondarybutton.png"
}
}
]
}
}

View File

@ -0,0 +1,52 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "StaticImage",
"name": "connectionLost",
"x" : 0,
"y" : 0,
"width": 488,
"height": 308,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"texture": "resources/connection_lost.png"
},
{
"type": "Button",
"name": "reconnectButton",
"width": 382,
"height": 56,
"x" : 0,
"y" : -20,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"textures": {
"normal": "resources/game_over/Filledbuttons.png",
"hover": "resources/game_over/Variant5.png",
"pressed": "resources/game_over/Variant6.png"
}
},
{
"type": "Button",
"name": "exitServerButton",
"width": 382,
"height": 56,
"x" : 0,
"y" : -86,
"horizontal_gravity": "center",
"vertical_gravity": "center",
"textures": {
"normal": "resources/game_over/Secondarybutton.png",
"hover": "resources/game_over/Secondarybutton.png",
"pressed": "resources/game_over/Secondarybutton.png"
}
}
]
}
}

View File

@ -0,0 +1,21 @@
{
"enabled": true,
"referenceResolution": [1280, 720],
"color": [1.0, 1.0, 1.0],
"cl_crosshairalpha": 1.0,
"cl_crosshairthickness": 2.0,
"centerGapPx": 10.0,
"top": {
"lengthPx": 14.0,
"angleDeg": 90.0
},
"arms": [
{ "lengthPx": 20.0, "angleDeg": 210.0 },
{ "lengthPx": 20.0, "angleDeg": 330.0 }
]
}

View File

@ -5,7 +5,7 @@
"texture": "resources/spark_white.png", "texture": "resources/spark_white.png",
"speedRange": [10.0, 30.0], "speedRange": [10.0, 30.0],
"zSpeedRange": [-1.0, 1.0], "zSpeedRange": [-1.0, 1.0],
"scaleRange": [0.5, 1.0], "scaleRange": [5.0, 10.0],
"lifeTimeRange": [200.0, 800.0], "lifeTimeRange": [200.0, 800.0],
"emissionRate": 50.0, "emissionRate": 50.0,
"maxParticles": 5, "maxParticles": 5,

View File

@ -1,55 +1,85 @@
{ {
"root": { "root": {
"type": "LinearLayout", "type": "LinearLayout",
"orientation": "vertical", "orientation": "vertical",
"align": "center", "vertical_align": "center",
"x": 0, "horizontal_align": "center",
"y": 0, "spacing": 10,
"width": 1920, "x": 0,
"height": 1080, "y": 0,
"background": { "width": "match_parent",
"color": [0, 0, 0, 0.7] "height": "match_parent",
}, "children": [
"children": [ {
{ "type": "Button",
"type": "Button", "name": "gameOverText",
"name": "gameOverText", "width": 327,
"x": 350, "height": 26,
"y": 400, "textures": {
"width": 600, "normal": "resources/game_over/MissionFailed.png",
"height": 150, "hover": "resources/game_over/MissionFailed.png",
"textures": { "pressed": "resources/game_over/MissionFailed.png"
"normal": "resources/gameover.png", }
"hover": "resources/gameover.png", },
"pressed": "resources/gameover.png" {
} "type": "Button",
}, "name": "underlineBtn",
{ "width": 168,
"type": "Button", "height": 44,
"name": "restartButton", "textures": {
"x": 350, "normal": "resources/game_over/Container.png",
"y": 300, "hover": "resources/game_over/Container.png",
"width": 300, "pressed": "resources/game_over/Container.png"
"height": 80, }
"textures": { },
"normal": "resources/shoot_normal.png", {
"hover": "resources/shoot_normal.png", "type": "Button",
"pressed": "resources/shoot_normal.png" "name": "finalscore",
} "width": 87,
}, "height": 9,
{ "textures": {
"type": "Button", "normal": "resources/game_over/FinalScore.png",
"name": "gameOverExitButton", "hover": "resources/game_over/FinalScore.png",
"x": 650, "pressed": "resources/game_over/FinalScore.png"
"y": 300, }
"width": 300, },
"height": 80, {
"textures": { "type": "TextView",
"normal": "resources/sand2.png", "name": "scoreText",
"hover": "resources/sand2.png", "width": 600,
"pressed": "resources/sand2.png" "height": 80,
} "text": "0",
} "fontSize": 36,
] "color": [
} 0,
217,
255,
1
],
"align": "center"
},
{
"type": "Button",
"name": "restartButton",
"width": 382,
"height": 56,
"textures": {
"normal": "resources/game_over/Filledbuttons.png",
"hover": "resources/game_over/Variant5.png",
"pressed": "resources/game_over/Variant6.png"
}
},
{
"type": "Button",
"name": "gameOverExitButton",
"width": 382,
"height": 56,
"textures": {
"normal": "resources/game_over/Secondarybutton.png",
"hover": "resources/game_over/Secondarybutton.png",
"pressed": "resources/game_over/Secondarybutton.png"
}
}
]
}
} }

View File

@ -0,0 +1,93 @@
{
"root": {
"type": "LinearLayout",
"orientation": "vertical",
"align": "center",
"x": 0,
"y": 0,
"width": 1920,
"height": 1080,
"background": {
"color": [0, 0, 0, 0.7]
},
"children": [
{
"type": "Button",
"name": "gameOverText",
"x": 476.5,
"y": 500,
"width": 327,
"height": 26,
"textures": {
"normal": "resources/game_over/MissionFailed.png",
"hover": "resources/game_over/MissionFailed.png",
"pressed": "resources/game_over/MissionFailed.png"
}
},
{
"type": "Button",
"name": "underlineBtn",
"x": 556,
"y": 465,
"width": 168,
"height": 44,
"textures": {
"normal": "resources/game_over/Container.png",
"hover": "resources/game_over/Container.png",
"pressed": "resources/game_over/Container.png"
}
},
{
"type": "Button",
"name": "finalscore",
"x": 596.5,
"y": 436,
"width": 87,
"height": 9,
"textures": {
"normal": "resources/game_over/FinalScore.png",
"hover": "resources/game_over/FinalScore.png",
"pressed": "resources/game_over/FinalScore.png"
}
},
{
"type": "TextView",
"name": "scoreText",
"x": 350,
"y": 356,
"width": 600,
"height": 80,
"text": "0",
"fontSize": 36,
"color": [0, 217, 255, 1],
"align": "center"
},
{
"type": "Button",
"name": "restartButton",
"x": 449,
"y": 308,
"width": 382,
"height": 56,
"textures": {
"normal": "resources/game_over/Filledbuttons.png",
"hover": "resources/game_over/Filledbuttons.png",
"pressed": "resources/game_over/Filledbuttons.png"
}
},
{
"type": "Button",
"name": "gameOverExitButton",
"x": 449,
"y": 240,
"width": 382,
"height": 56,
"textures": {
"normal": "resources/game_over/Secondarybutton.png",
"hover": "resources/game_over/Secondarybutton.png",
"pressed": "resources/game_over/Secondarybutton.png"
}
}
]
}
}

View File

@ -0,0 +1,65 @@
{
"root": {
"type": "LinearLayout",
"orientation": "vertical",
"vertical_align": "center",
"horizontal_align": "center",
"spacing": 10,
"x": 0,
"y": 0,
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "StaticImage",
"name": "titleBtn",
"width": 434,
"height": 35,
"texture": "resources/main_menu/title.png"
},
{
"type": "StaticImage",
"name": "underlineBtn",
"width": 168,
"height": 44,
"texture": "resources/main_menu/line.png"
},
{
"type": "StaticImage",
"name": "subtitleBtn",
"width": 144,
"height": 11,
"texture": "resources/main_menu/subtitle.png"
},
{
"type": "Button",
"name": "singleButton",
"width": 382,
"height": 56,
"textures": {
"normal": "resources/main_menu/single.png",
"hover": "resources/main_menu/Variant5.png",
"pressed": "resources/main_menu/Variant6.png"
}
},
{
"type": "Button",
"name": "multiplayerButton",
"width": 382,
"height": 56,
"textures": {
"normal": "resources/main_menu/multi.png",
"hover": "resources/main_menu/Variant7.png",
"pressed": "resources/main_menu/Variant8.png"
}
},
{
"type": "StaticImage",
"name": "versionLabel",
"width": 81,
"height": 9,
"texture": "resources/main_menu/version.png"
}
]
}
}

View File

@ -0,0 +1,158 @@
{
"root": {
"type": "LinearLayout",
"x": 0,
"y": 0,
"width": 1280,
"height": 720,
"children": [
{
"type": "Button",
"name": "langButton",
"x": 1100,
"y": 580,
"width": 142,
"height": 96,
"textures": {
"normal": "resources/main_menu/lang.png",
"hover": "resources/main_menu/lang.png",
"pressed": "resources/main_menu/lang.png"
}
},
{
"type": "Button",
"name": "titleBtn",
"x": 512,
"y": 500,
"width": 254,
"height": 35,
"textures": {
"normal": "resources/multiplayer_menu/title.png",
"hover": "resources/multiplayer_menu/title.png",
"pressed": "resources/multiplayer_menu/title.png"
}
},
{
"type": "Button",
"name": "subtitle",
"x": 596.5,
"y": 470,
"width": 87,
"height": 11,
"textures": {
"normal": "resources/multiplayer_menu/JoinServer.png",
"hover": "resources/multiplayer_menu/JoinServer.png",
"pressed": "resources/multiplayer_menu/JoinServer.png"
}
},
{
"type": "Button",
"name": "subtitleBtn",
"x": 450,
"y": 445,
"width": 94,
"height": 9,
"textures": {
"normal": "resources/multiplayer_menu/ServerName.png",
"hover": "resources/multiplayer_menu/ServerName.png",
"pressed": "resources/multiplayer_menu/ServerName.png"
}
},
{
"type": "TextField",
"name": "serverInputField",
"x": 449,
"y": 390,
"width": 382,
"height": 56,
"placeholder": "Enter server name or IP",
"fontPath": "resources/fonts/DroidSans.ttf",
"fontSize": 16,
"maxLength": 256,
"color": [122, 156, 198, 1],
"placeholderColor": [122, 156, 198, 1],
"backgroundColor": [15, 29, 51, 1],
"borderColor": [15, 29, 51, 1]
},
{
"type": "Button",
"name": "connectButton",
"x": 449,
"y": 350,
"width": 382,
"height": 56,
"textures": {
"normal": "resources/multiplayer_menu/Filledbuttons.png",
"hover": "resources/multiplayer_menu/Filledbuttons.png",
"pressed": "resources/multiplayer_menu/Filledbuttons.png"
}
},
{
"type": "Button",
"name": "backButton",
"x": 449,
"y": 280,
"width": 382,
"height": 56,
"textures": {
"normal": "resources/multiplayer_menu/Backbutton.png",
"hover": "resources/multiplayer_menu/Backbutton.png",
"pressed": "resources/multiplayer_menu/Backbutton.png"
}
},
{
"type": "Button",
"name": "AvailableServers",
"x": 450,
"y": 240,
"width": 139,
"height": 9,
"textures": {
"normal": "resources/multiplayer_menu/AvailableServers.png",
"hover": "resources/multiplayer_menu/AvailableServers.png",
"pressed": "resources/multiplayer_menu/AvailableServers.png"
}
},
{
"type": "Button",
"name": "SerButton",
"x": 436.5,
"y": 170,
"width": 407,
"height": 62,
"textures": {
"normal": "resources/multiplayer_menu/Button.png",
"hover": "resources/multiplayer_menu/Button.png",
"pressed": "resources/multiplayer_menu/Button.png"
}
},
{
"type": "Button",
"name": "SerButton2",
"x": 436.5,
"y": 88,
"width": 407,
"height": 62,
"textures": {
"normal": "resources/multiplayer_menu/Button2.png",
"hover": "resources/multiplayer_menu/Button2.png",
"pressed": "resources/multiplayer_menu/Button2.png"
}
},
{
"type": "Button",
"name": "SerButton3",
"x": 436.5,
"y": 6,
"width": 407,
"height": 62,
"textures": {
"normal": "resources/multiplayer_menu/Button3.png",
"hover": "resources/multiplayer_menu/Button3.png",
"pressed": "resources/multiplayer_menu/Button3.png"
}
}
]
}
}

View File

@ -0,0 +1,66 @@
{
"root": {
"type": "LinearLayout",
"orientation": "vertical",
"vertical_align": "center",
"horizontal_align": "center",
"spacing": 10,
"x": 0,
"y": 0,
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "StaticImage",
"name": "titleBtn",
"width": 266,
"height": 66,
"texture": "resources/select_your_ship.png"
},
{
"type": "LinearLayout",
"orientation": "horizontal",
"vertical_align": "center",
"horizontal_align": "center",
"spacing": 10,
"width": "match_parent",
"height": 260,
"children": [
{
"type": "Button",
"name": "spaceshipButton",
"width": 256,
"height": 256,
"textures": {
"normal": "resources/multiplayer_menu/ship_fighter.png",
"hover": "resources/multiplayer_menu/ship_fighter_pressed.png",
"pressed": "resources/multiplayer_menu/ship_fighter_pressed.png"
}
},
{
"type": "Button",
"name": "cargoshipButton",
"width": 256,
"height": 256,
"textures": {
"normal": "resources/multiplayer_menu/ship_cargo.png",
"hover": "resources/multiplayer_menu/ship_cargo_pressed.png",
"pressed": "resources/multiplayer_menu/ship_cargo_pressed.png"
}
}
]
},
{
"type": "Button",
"name": "backButton",
"width": 382,
"height": 56,
"textures": {
"normal": "resources/multiplayer_menu/Backbutton.png",
"hover": "resources/multiplayer_menu/Backbutton.png",
"pressed": "resources/multiplayer_menu/Backbutton.png"
}
}
]
}
}

View File

@ -1,22 +1,14 @@
{ {
"emissionRate": 100.0, "emissionRate": 1.2,
"maxParticles": 200, "maxParticles": 400,
"particleSize": 0.3, "particleSize": 0.3,
"biasX": 0.3, "biasX": 0.3,
"emissionPoints": [ "emissionPoints": [
{
"position": [-1.3, 0, 0.0]
},
{
"position": [1.3, 0.0, 0.0]
}
], ],
"speedRange": [0.5, 2.0], "speedRange": [0.5, 2.0],
"zSpeedRange": [1.0, 3.0], "zSpeedRange": [1.0, 3.0],
"scaleRange": [0.8, 1.2], "scaleRange": [0.8, 1.2],
"lifeTimeRange": [600.0, 1400.0], "lifeTimeRange": [300.0, 500.0],
"texture": "resources/spark.png", "texture": "resources/spark.png",
"shaderProgramName": "default", "shaderProgramName": "spark"
"vertexShader": "resources/shaders/spark.vertex",
"fragmentShader": "resources/shaders/spark.fragment"
} }

View File

@ -0,0 +1,20 @@
{
"emissionRate": 1.2,
"maxParticles": 400,
"particleSize": 0.3,
"biasX": 0.3,
"emissionPoints": [
{
"position": [0.0, 2.8, -3.5]
},
{
"position": [0.0, 1.5, -3.5]
}
],
"speedRange": [0.5, 2.0],
"zSpeedRange": [1.0, 3.0],
"scaleRange": [0.8, 1.2],
"lifeTimeRange": [600.0, 1400.0],
"texture": "resources/spark.png",
"shaderProgramName": "spark"
}

View File

@ -2,14 +2,14 @@
"emissionPoints": [ "emissionPoints": [
{ "position": [0.0, 0.0, 0.0] } { "position": [0.0, 0.0, 0.0] }
], ],
"texture": "resources/spark_white.png", "texture": "resources/spark2.png",
"speedRange": [10.0, 30.0], "speedRange": [5.0, 10.0],
"zSpeedRange": [-1.0, 1.0], "zSpeedRange": [-1.0, 1.0],
"scaleRange": [0.5, 1.0], "scaleRange": [0.5, 2.0],
"lifeTimeRange": [200.0, 800.0], "lifeTimeRange": [200.0, 800.0],
"emissionRate": 50.0, "emissionRate": 30.0,
"maxParticles": 10, "maxParticles": 150,
"particleSize": 0.09, "particleSize": 1.0,
"biasX": 0.1, "biasX": 0.1,
"shaderProgramName": "default" "shaderProgramName": "default"
} }

View File

@ -1,169 +1,145 @@
{ {
"root": { "root": {
"type": "FrameLayout", "type": "FrameLayout",
"x": 0, "x": 0,
"y": 0, "y": 0,
"width": 1280, "width": "match_parent",
"height": 720, "height": "match_parent",
"children": [ "children": [
{
"type": "FrameLayout",
"name": "leftPanel",
"x": 100,
"y": 100,
"width": 320,
"height": 400,
"children": [
{ {
"type": "LinearLayout", "type": "TextView",
"name": "mainButtons", "name": "gameScoreText",
"orientation": "vertical", "x": 0,
"spacing": 10, "y": 30,
"x": 0, "width": 200,
"y": 0, "height": 60,
"width": 300, "horizontal_gravity": "left",
"height": 300, "vertical_gravity": "top",
"children": [ "text": "Score: 0",
{ "fontSize": 36,
"type": "Button", "color": [
"name": "playButton", 0,
"x": -1000, 217,
"y": 500, 255,
"width": 200, 1
"height": 50, ],
"animations": { "centered": false
"buttonsExit": { },
"repeat": false, {
"steps": [ "type": "Button",
{ "name": "showPlayersButton",
"type": "move", "x": 0,
"to": [ "y": 100,
-400, "width": 150,
0 "height": 150,
], "horizontal_gravity": "left",
"duration": 1.0, "vertical_gravity": "top",
"easing": "easein" "textures": {
} "normal": "resources/button_players.png",
] "hover": "resources/button_players.png",
} "pressed": "resources/button_players.png",
}, "disabled": "resources/button_players.png"
"textures": { }
"normal": "./resources/sand2.png", },
"hover": "./resources/sand2.png", {
"pressed": "./resources/sand2.png" "type": "Button",
} "name": "inverseMouseButton",
}, "x": 0,
{ "y": 100,
"type": "Button", "width": 150,
"name": "settingsButton", "height": 150,
"x": -1000, "horizontal_gravity": "right",
"y": 400, "vertical_gravity": "top",
"width": 200, "textures": {
"height": 50, "normal": "resources/fire.png",
"animations": { "hover": "resources/fire.png",
"buttonsExit": { "pressed": "resources/fire2.png",
"repeat": false, "disabled": "resources/fire.png"
"steps": [ }
{ },
"type": "wait", {
"duration": 0.5 "type": "Button",
}, "name": "shootButton",
{ "x": 0,
"type": "move", "y": 0,
"to": [ "width": 150,
-400, "height": 150,
0 "horizontal_gravity": "right",
], "vertical_gravity": "bottom",
"duration": 1.0, "textures": {
"easing": "easein" "normal": "resources/fire.png",
} "hover": "resources/fire.png",
] "pressed": "resources/fire2.png",
} "disabled": "resources/fire_disabled.png"
}, }
"textures": { },
"normal": "./resources/sand2.png", {
"hover": "./resources/sand2.png", "type": "Button",
"pressed": "./resources/sand2.png" "name": "shootButton2",
} "x": 0,
}, "y": 0,
{ "width": 150,
"type": "Button", "height": 150,
"name": "exitButton", "horizontal_gravity": "left",
"x": -1000, "vertical_gravity": "bottom",
"y": 300, "textures": {
"width": 200, "normal": "resources/fire.png",
"height": 50, "hover": "resources/fire.png",
"animations": { "pressed": "resources/fire2.png",
"buttonsExit": { "disabled": "resources/fire_disabled.png"
"repeat": false, }
"steps": [ },
{ {
"type": "wait", "type": "Button",
"duration": 1.0 "name": "minusButton",
}, "x": -20,
{ "y": 110,
"type": "move", "width": 150,
"to": [ "height": 150,
-400, "border" : 20,
0 "horizontal_gravity": "right",
], "vertical_gravity": "bottom",
"duration": 1.0, "textures": {
"easing": "easein" "normal": "resources/button_minus.png",
} "hover": "resources/button_minus.png",
] "pressed": "resources/button_minus_pressed.png",
}, "disabled" : "resources/button_minus_disabled.png"
"bgScroll": { }
"repeat": true, },
"steps": [ {
{ "type": "Button",
"type": "move", "name": "plusButton",
"to": [ "x": -20,
1280, "y": 220,
0 "width": 150,
], "height": 150,
"duration": 5.0, "border" : 20,
"easing": "linear" "horizontal_gravity": "right",
} "vertical_gravity": "bottom",
] "textures": {
} "normal": "resources/button_plus.png",
}, "hover": "resources/button_plus.png",
"textures": { "pressed": "resources/button_plus_pressed.png",
"normal": "./resources/sand2.png", "disabled" : "resources/button_plus_disabled.png"
"hover": "./resources/sand2.png", }
"pressed": "./resources/sand2.png" },
} {
"type": "Button",
"name": "takeButton",
"x": -20,
"y": 320,
"width": 150,
"height": 150,
"border" : 20,
"horizontal_gravity": "right",
"vertical_gravity": "bottom",
"textures": {
"normal": "resources/button_take.png",
"hover": "resources/button_take.png",
"pressed": "resources/button_take_pressed.png",
"disabled" : "resources/button_take_disabled.png"
} }
]
} }
] ]
},
{
"type": "Slider",
"name": "velocitySlider",
"x": 1140,
"y": 100,
"width": 50,
"height": 500,
"value": 0.0,
"orientation": "vertical",
"textures": {
"track": "resources/velocitySliderTexture.png",
"knob": "resources/velocitySliderButton.png"
}
},
{
"type": "Button",
"name": "shootButton",
"x": 100,
"y": 100,
"width": 100,
"height": 100,
"textures": {
"normal": "resources/shoot_normal.png",
"hover": "resources/shoot_hover.png",
"pressed": "resources/shoot_pressed.png"
}
}
]
} }
} }

View File

@ -0,0 +1,194 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": 1280,
"height": 720,
"children": [
{
"type": "FrameLayout",
"name": "leftPanel",
"x": 100,
"y": 100,
"width": 320,
"height": 400,
"children": [
{
"type": "LinearLayout",
"name": "mainButtons",
"orientation": "vertical",
"spacing": 10,
"x": 0,
"y": 0,
"width": 300,
"height": 300,
"children": [
{
"type": "Button",
"name": "playButton",
"x": -1000,
"y": 500,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
},
{
"type": "Button",
"name": "settingsButton",
"x": -1000,
"y": 400,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "wait",
"duration": 0.5
},
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
},
{
"type": "Button",
"name": "exitButton",
"x": -1000,
"y": 300,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "wait",
"duration": 1.0
},
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
},
"bgScroll": {
"repeat": true,
"steps": [
{
"type": "move",
"to": [
1280,
0
],
"duration": 5.0,
"easing": "linear"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
}
]
}
]
},
{
"type": "Slider",
"name": "velocitySlider",
"x": 1140,
"y": 300,
"width": 50,
"height": 300,
"value": 0.0,
"orientation": "vertical",
"textures": {
"track": "resources/velocitySliderTexture.png",
"knob": "resources/velocitySliderButton.png"
}
},
{
"type": "Button",
"name": "shootButton",
"x": 100,
"y": 100,
"width": 100,
"height": 100,
"textures": {
"normal": "resources/shoot_normal.png",
"hover": "resources/shoot_hover.png",
"pressed": "resources/shoot_pressed.png"
}
},
{
"type": "Button",
"name": "shootButton2",
"x": 1000,
"y": 100,
"width": 100,
"height": 100,
"textures": {
"normal": "resources/shoot_normal.png",
"hover": "resources/shoot_hover.png",
"pressed": "resources/shoot_pressed.png"
}
},
{
"type": "TextView",
"name": "velocityText",
"x": 10,
"y": 10,
"width": 200,
"height": 40,
"text": "Velocity: 0",
"fontSize": 24,
"color": [1.0, 1.0, 1.0, 1.0],
"centered": false
}
]
}
}

BIN
resources/connecting.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/connection_failed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/connection_lost.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/fire.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/fire2.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/fire_disabled.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
resources/game_over/Container.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/Filledbuttons.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/FinalScore.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/MissionFailed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/Secondarybutton.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/Variant5.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/game_over/Variant6.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/gameover.png (Stored with Git LFS)

Binary file not shown.

BIN
resources/loading.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/Variant5.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/Variant6.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/Variant7.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/Variant8.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/about.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/about_hover.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/about_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/exit.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/lang.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/line.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/multi.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/single.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/subtitle.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/title.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/main_menu/version.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/AvailableServers.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/Backbutton.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/Button.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/Button2.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/Button3.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/Filledbuttons.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/JoinServer.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/ServerName.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/ship_cargo.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/ship_cargo_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/ship_fighter.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/ship_fighter_pressed.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/multiplayer_menu/title.png (Stored with Git LFS) Normal file

Binary file not shown.

6079
resources/platform1.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
resources/platform_base.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/select_your_ship.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,125 @@
//precisionhighp float;
// Фрагментный шейдер:
uniform vec3 uColor;
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
// Константы затухания, определенные прямо в шейдере
const float DIST_FOG_MAX = 2000.0;
const float DIST_FOG_MIN = 1000.0;
varying vec3 vWorldNormal;
varying vec3 vViewNormal;
varying vec3 vViewPosition;
// Добавь эти uniform-ы
//uniform float uTime;
uniform vec3 uLightDirView;
uniform vec3 uPlayerDirWorld;
// Простая функция псевдослучайного шума
float hash(float n) { return fract(sin(n) * 43758.5453123); }
float noise(vec3 x) {
vec3 p = floor(x);
vec3 f = fract(x);
f = f * f * (3.0 - 2.0 * f);
float n = p.x + p.y * 57.0 + 113.0 * p.z;
return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
}
// Fractal Brownian Motion для "кучевости" облаков
float fbm(vec3 p) {
float f = 0.5000 * noise(p); p *= 2.02;
f += 0.2500 * noise(p); p *= 2.03;
f += 0.1250 * noise(p);
return f;
}
void main()
{
//gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
vec3 normal = normalize(vViewNormal);
vec3 viewVector = normalize(-vViewPosition);
float NdotV = dot(normal, viewVector);
// Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
vec3 fragmentDir = normalize(vWorldNormal);
// Вектор направления от центра планеты к игроку (нужно передать как uniform)
// Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
// --- 1. Плавное отсечение за горизонтом (Horizon Mask) ---
// Считаем косинус угла между игроком и точкой атмосферы
float cosAngle = dot(fragmentDir, uPlayerDirWorld);
// Плавно затухаем от 0.0 (горизонт) до 0.2 (над головой)
//float horizonMask = smoothstep(0.0, 0.4, cosAngle);
float horizonMask = smoothstep(0.93, 1.0, cosAngle);
// --- 2. Плавный переход при прохождении сквозь слой (Transition Mask) ---
// Определяем "высоту" игрока относительно слоя (напр. слой на 1.03 * R)
// uDistanceToPlanetSurface уже вычислен в PlanetData
float layerHeight = 600.0; // Примерная толщина слоя атмосферы (3% от 20000)
// Делаем прозрачным при приближении к границе (dist около layerHeight)
// и снова видимым, когда спустились ниже
float distToLayer = abs(uDistanceToPlanetSurface - layerHeight);
float transitionMask = smoothstep(0.0, 200.0, distToLayer);
// --- 3. Освещение и облака ---
float diff = max(dot(normal, uLightDirView), 0.0);
if (uDistanceToPlanetSurface < layerHeight) {
diff = max(dot(-normal, uLightDirView), 0.0); // Инверсия для взгляда снизу
}
float lightIntensity = diff + 0.05;
vec3 cloudCoord = fragmentDir * 6.0;
//cloudCoord.x += uTime * 0.03;
float n = fbm(cloudCoord);
float cloudMask = smoothstep(0.4, 0.65, n);
// --- 4. Финальный расчет альфы ---
float atmosphereDensity = pow(1.0 - abs(NdotV), 5.0);
float distanceFactor = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN), 0.0, 1.0);
// Базовая прозрачность облаков
float cloudAlpha = cloudMask * 0.8;
// Применяем маски:
// В космосе важен distanceFactor, на планете важен horizonMask
float finalCloudAlpha = cloudAlpha * transitionMask;
if (uDistanceToPlanetSurface < layerHeight) {
finalCloudAlpha *= horizonMask; // На планете скрываем то, что под ногами
} else {
finalCloudAlpha *= distanceFactor; // В космосе скрываем по вашей старой логике
if (NdotV <=0.0)
{
//finalCloudAlpha = 0.0;
discard;
}
}
vec3 currentAtmo = mix(vec3(0.01, 0.02, 0.1), uColor, lightIntensity);
vec3 currentCloud = mix(vec3(0.1, 0.1, 0.15), vec3(1.0, 1.0, 1.0), lightIntensity);
vec3 finalRGB = mix(currentAtmo, currentCloud, cloudMask);
//vec3 finalRGB = currentAtmo;
// Для дымки (atmo) оставляем затухание при посадке
float atmoAlpha = atmosphereDensity * distanceFactor;
//float atmoAlpha = distanceFactor;
float finalAtmoAlpha = atmoAlpha;
if (uDistanceToPlanetSurface < layerHeight) {
finalCloudAlpha *= horizonMask;
finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
}
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
}

View File

@ -0,0 +1,9 @@
//precisionmediump float;
varying vec3 color;
void main()
{
//gl_FragColor = vec4(color, 1.0);
gl_FragColor = vec4(1.0, 1.0, 0.5, 1.0);
}

View File

@ -0,0 +1,12 @@
//precisionmediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
//gl_FragColor = vec4(color.rgb*0.1 + vec3(0.9, 0.9, 0.9), 1.0);
gl_FragColor = color;
}

View File

@ -0,0 +1,8 @@
//precisionmediump float;
uniform samplerCube Texture;
varying vec3 dir;
void main(){
gl_FragColor = textureCube(Texture, normalize(dir));
}

View File

@ -0,0 +1,9 @@
//precisionmediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
gl_FragColor = color;
}

View File

@ -0,0 +1,37 @@
//precisionmediump float;
uniform samplerCube Texture;
uniform float skyPercent;
uniform float uPlayerLightFactor; // Глобальный фактор дня/ночи для позиции игрока
uniform vec3 uSkyColor;
varying vec3 vViewDir;
void main() {
vec3 viewDir = normalize(vViewDir);
// 1. Получаем звезды
vec4 starsColor = textureCube(Texture, viewDir);
// 2. Цвета атмосферы
vec3 dayColor = uSkyColor;
vec3 nightColor = vec3(0.01, 0.01, 0.04);
// 3. Теперь всё небо окрашивается одинаково в зависимости от положения игрока
// Мы плавно смешиваем ночной и дневной купол
vec3 atmosphericColor = mix(nightColor, dayColor, uPlayerLightFactor);
// 4. Логика видимости звезд
// Звезды видны в космосе (skyPercent=0)
// И в атмосфере, если сейчас ночь (uPlayerLightFactor -> 0)
float starsVisibility = (1.0 - skyPercent) + (skyPercent * (1.0 - uPlayerLightFactor));
// Делаем звезды чуть ярче на ночном небе
starsVisibility = pow(starsVisibility, 1.5);
// 5. Итоговый цвет
// Добавляем слой атмосферы к звездам
vec3 skyLayer = atmosphericColor * skyPercent;
vec3 finalColor = (starsColor.rgb * starsVisibility) + skyLayer;
gl_FragColor = vec4(finalColor, 1.0);
}

View File

@ -0,0 +1,14 @@
//precisionmediump float;
varying vec2 TexCoord;
varying float vHeight;
uniform sampler2D Texture;
void main()
{
vec4 stoneColor = texture2D(Texture, TexCoord);
gl_FragColor = vec4(stoneColor.rgb, vHeight);
//gl_FragColor = vec4(vHeight, vHeight, vHeight, vHeight);
//gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}

View File

@ -15,7 +15,7 @@ varying vec3 vWorldNormal;
uniform mat4 ProjectionModelViewMatrix; uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix; uniform mat4 ModelViewMatrix;
uniform highp vec3 uViewPos; uniform vec3 uViewPos;
void main() { void main() {
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0); gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);

View File

@ -0,0 +1,116 @@
//precisionhighp float;
varying vec2 TexCoord;
varying vec3 vViewDirTangent;
varying vec3 Color;
varying vec3 worldPosition;
varying vec3 vWorldNormal;
uniform sampler2D Texture;
uniform sampler2D BakedTexture;
uniform float uHeightScale;
uniform float uDistanceToPlanetSurface;
uniform float uCurrentZFar;
uniform vec3 uViewPos;
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман
uniform vec3 uLightDirWorld; // Направление ЛУЧЕЙ (1, -1, -1)
uniform float uPlayerLightFactor;
uniform vec3 uPlayerDirWorld;
void main() {
// --- 1. Расчет освещения поверхности ---
// Направление НА источник света
vec3 lightToSource = normalize(-uLightDirWorld);
vec3 fragmentDir = normalize(vWorldNormal);
// Используем vNormal (нормаль в мировом пространстве, так как vPosition тоже в мировом)
// Важно: если vNormal не нормализована в вершинном, делаем это здесь
vec3 normal = normalize(fragmentDir); // На планете-сфере нормаль совпадает с направлением от центра
float diff = max(dot(normal, lightToSource), 0.0);
float ambient = 0.3; // Базовая освещенность ночной стороны
float surfaceLightIntensity = diff + ambient;
// --- 2. Динамический цвет тумана ---
// Синхронизируем туман с атмосферой: днем голубой, ночью темно-синий
vec3 dayFog = vec3(0.0, 0.5, 1.0);
vec3 nightFog = vec3(0.01, 0.01, 0.04);
vec3 dynamicFogColor = mix(nightFog, dayFog, uPlayerLightFactor);
// --- 3. Основная логика текстур (твой код) ---
vec3 viewDir = normalize(vViewDirTangent);
float height = texture2D(Texture, TexCoord).a;
vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
vec2 finalTexCoord = TexCoord + p;
float realDist = distance(worldPosition, uViewPos);
float textureMixFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
vec4 bakedTextureColor = texture2D(BakedTexture, finalTexCoord);
vec4 textureColor = texture2D(Texture, TexCoord);
vec4 textureFlavoredColor = vec4(textureColor.rgb * Color, 1.0);
if (bakedTextureColor.x < 0.01 && bakedTextureColor.y < 0.01 && bakedTextureColor.z < 0.01) {
textureMixFactor = 1.0;
}
vec4 finalColor = textureMixFactor * textureFlavoredColor + (1.0 - textureMixFactor) * bakedTextureColor;
// --- 4. ПРИМЕНЕНИЕ ОСВЕЩЕНИЯ ---
// Умножаем результат текстурирования на освещенность
finalColor.rgb *= surfaceLightIntensity;
// --- 5. Расчет тумана (с использованием динамического цвета) ---
float h = uDistanceToPlanetSurface;
float fogStart, fogEnd;
if (h >= 1000.0) {
gl_FragColor = vec4(finalColor.rgb, 1.0);
}
else
{
if (h > 100.0) {
// Нормализуем высоту от 100 до 1000 (t: 0 -> 1)
float t = (h - 100.0) / 900.0;
// На высоте 100 туман начинается со 100.
// К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает.
fogStart = mix(1500.0, 15000.0, t);
// Держим ширину зоны тумана в пределах 400-600 единиц
float fogRange = mix(1000.0, 6000.0, t);
fogEnd = fogStart + fogRange;
}
else if (h > 40.0) {
float t = (h - 40.0) / 60.0;
// На высоте 100 туман начинается со 100.
// К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает.
fogStart = mix(800.0, 1500.0, t);
fogEnd = mix(1000.0, 2500.0, t);
}
else if (h > 20.0) {
float t = (h - 20.0) / 20.0;
fogStart = mix(200.0, 800.0, t);
fogEnd = mix(500.0, 1000.0, t);
}
else {
// Минимумы при h = 0: start 25, end 125
float t = clamp(h / 20.0, 0.0, 1.0);
fogStart = mix(100.0, 200.0, t);
fogEnd = mix(250.0, 500.0, t);
}
float fogRange = max(fogEnd - fogStart, 1.0);
float fogFactor = clamp((realDist - fogStart) / fogRange, 0.0, 1.0);
// Смешиваем с динамическим цветом тумана
vec3 mixedColor = mix(finalColor.rgb, dynamicFogColor, fogFactor);
gl_FragColor = vec4(mixedColor, 1.0);
}
}

View File

@ -11,7 +11,7 @@ uniform float uHeightScale;
uniform float uDistanceToPlanetSurface; uniform float uDistanceToPlanetSurface;
uniform float uCurrentZFar; uniform float uCurrentZFar;
uniform vec3 uViewPos; uniform highp vec3 uViewPos;
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман

View File

@ -14,7 +14,7 @@ varying vec3 vWorldNormal;
uniform mat4 ProjectionModelViewMatrix; uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix; uniform mat4 ModelViewMatrix;
uniform highp vec3 uViewPos; uniform vec3 uViewPos;
void main() { void main() {
vWorldNormal = vNormal; vWorldNormal = vNormal;
@ -23,8 +23,6 @@ void main() {
vec3 viewDirWorld = normalize(uViewPos - vPosition); vec3 viewDirWorld = normalize(uViewPos - vPosition);
// Строим матрицу перехода из атрибутов
// Так как базис ортонормирован, TBN^-1 == TBN_transpose
vViewDirTangent = vec3( vViewDirTangent = vec3(
dot(viewDirWorld, vTangent), dot(viewDirWorld, vTangent),
dot(viewDirWorld, vBinormal), dot(viewDirWorld, vBinormal),

View File

@ -0,0 +1,102 @@
//precisionhighp float;
// planetStone фрагментный шейдер
varying vec2 TexCoord;
varying vec3 worldPosition;
varying vec3 vWorldNormal;
uniform sampler2D Texture;
uniform float uDistanceToPlanetSurface;
uniform vec3 uViewPos;
uniform vec3 uLightDirWorld;
uniform float uPlayerLightFactor;
void main()
{
// --- 1. Подготовка векторов ---
vec3 normal = normalize(vWorldNormal);
vec3 lightToSource = normalize(-uLightDirWorld);
// Вектор от центра планеты к камню (нормаль самой поверхности планеты под камнем)
// Предполагаем, что центр планеты в (0,0,0)
vec3 surfaceNormal = normalize(worldPosition);
// --- 2. Расчет Shadow Mask ---
// Проверяем, освещена ли точка планеты, на которой стоит камень
float shadowMask = clamp(dot(surfaceNormal, lightToSource) * 5.0, 0.0, 1.0);
// Коэффициент 5.0 делает переход на терминаторе более четким
// --- 3. Освещение камня ---
float diff = max(dot(normal, lightToSource), 0.0);
// Применяем shadowMask к диффузной составляющей
// Если точка на планете в тени, то прямой свет (diff) обнуляется
float ambient = 0.3;
float lightIntensity = (diff * shadowMask);
lightIntensity *= mix(0.2, 1.0, shadowMask);
lightIntensity += ambient;
// --- 4. Остальная логика (цвета и туман) ---
vec3 dayFog = vec3(0.0, 0.5, 1.0);
vec3 nightFog = vec3(0.01, 0.01, 0.04);
vec3 dynamicFogColor = mix(nightFog, dayFog, uPlayerLightFactor);
vec4 textureColor = texture2D(Texture, TexCoord);
vec3 litColor = textureColor.rgb * lightIntensity;
float realDist = distance(worldPosition, uViewPos);
float h = uDistanceToPlanetSurface;
float alphaFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
float fogStart, fogEnd;
// --- Логика расчета границ тумана ---
if (h >= 1000.0) {
gl_FragColor = vec4(litColor, alphaFactor);
}
else
{
if (h > 100.0) {
// Нормализуем высоту от 100 до 1000 (t: 0 -> 1)
float t = (h - 100.0) / 900.0;
// На высоте 100 туман начинается со 100.
// К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает.
fogStart = mix(1500.0, 15000.0, t);
// Держим ширину зоны тумана в пределах 400-600 единиц
float fogRange = mix(1000.0, 6000.0, t);
fogEnd = fogStart + fogRange;
}
else if (h > 40.0) {
float t = (h - 40.0) / 60.0;
// На высоте 100 туман начинается со 100.
// К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает.
fogStart = mix(800.0, 1500.0, t);
fogEnd = mix(1000.0, 2500.0, t);
}
else if (h > 20.0) {
float t = (h - 20.0) / 20.0;
fogStart = mix(200.0, 800.0, t);
fogEnd = mix(500.0, 1000.0, t);
}
else {
// Минимумы при h = 0: start 25, end 125
float t = clamp(h / 20.0, 0.0, 1.0);
fogStart = mix(100.0, 200.0, t);
fogEnd = mix(250.0, 500.0, t);
}
// Расчет фактора тумана
float fogRange = max(fogEnd - fogStart, 1.0);
float fogFactor = clamp((realDist - fogStart) / fogRange, 0.0, 1.0);
// Смешивание освещенного камня с динамическим туманом
vec3 mixedColor = mix(litColor, dynamicFogColor, fogFactor);
gl_FragColor = vec4(mixedColor, alphaFactor);
}
}

View File

@ -0,0 +1,9 @@
//precisionmediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
gl_FragColor = color;
}

View File

@ -0,0 +1,11 @@
attribute vec2 vPosition;
attribute vec2 vTexCoord;
varying vec2 TexCoord;
uniform mat4 uProjection;
void main() {
TexCoord = vTexCoord;
gl_Position = uProjection * vec4(vPosition, 0.0, 1.0);
}

View File

@ -0,0 +1,14 @@
#version 330 core
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D uText;
uniform vec4 uColor;
uniform vec4 uOutlineColor;
uniform float uOutlineWidth = 0.7;
void main() {
float dist = texture(uText, TexCoord).r;
float outline = smoothstep(0.5 - uOutlineWidth, 0.5 + uOutlineWidth, dist);
float text = smoothstep(0.5, 0.5 + 0.1, dist);
float glow = exp(-pow(dist - 0.5, 2.0) / 0.02);
FragColor = vec4(uColor.rgb * (text + glow * 0.6), uColor.a * outline);
}

Some files were not shown because too many files have changed in this diff Show More