├── .gitignore
├── .gitmodules
├── 3rdparty
└── CMakeLists.txt
├── CMakeLists.txt
├── README.md
├── doc
├── Android.md
├── Emscripten.md
├── Linux.md
├── Mac.md
└── Windows.md
└── sdlms
├── CMakeLists.txt
├── Components
├── AnimatedSprite.cpp
├── AnimatedSprite.h
├── Avatar.cpp
├── Avatar.h
├── Camera.cpp
├── Camera.h
├── Component.cpp
├── Component.h
├── DistanceSprite.cpp
├── DistanceSprite.h
├── HVMove.cpp
├── HVMove.h
├── HVTile.cpp
├── HVTile.h
├── LimitTransform.cpp
├── LimitTransform.h
├── Line.cpp
├── Line.h
├── Physic
│ ├── Normal.cpp
│ └── Normal.h
├── Player.cpp
├── Player.h
├── RandomInput.cpp
├── RandomInput.h
├── RelativeTransform.cpp
├── RelativeTransform.h
├── Sound.cpp
├── Sound.h
├── Sprite.cpp
├── Sprite.h
├── Transform.cpp
├── Transform.h
├── Video.cpp
└── Video.h
├── Core
├── ECSSystem.h
├── File.cpp
├── File.h
├── FreeType.cpp
├── FreeType.h
├── Input.cpp
├── Input.h
├── Map.cpp
├── Map.h
├── MathHelper.h
├── Window.cpp
├── Window.h
├── World.cpp
└── World.h
├── Entities
├── BackGround.cpp
├── BackGround.h
├── Border.cpp
├── Border.h
├── Character.cpp
├── Character.h
├── ChatBalloon.cpp
├── ChatBalloon.h
├── Entity.cpp
├── Entity.h
├── FootHold.cpp
├── FootHold.h
├── LadderRope.cpp
├── LadderRope.h
├── Mob.cpp
├── Mob.h
├── NameTag.cpp
├── NameTag.h
├── Npc.cpp
├── Npc.h
├── Obj.cpp
├── Obj.h
├── Portal.cpp
├── Portal.h
├── String.cpp
├── String.h
├── Tile.cpp
├── Tile.h
├── Timer.cpp
└── Timer.h
├── Resource
├── Resource.h
├── Wz.cpp
└── Wz.h
├── Systems
├── CameraSystem.cpp
├── CameraSystem.h
├── DeltaTimeSystem.cpp
├── DeltaTimeSystem.h
├── InputSystem.cpp
├── InputSystem.h
├── PhysicSystem.cpp
├── PhysicSystem.h
├── RenderSystem.cpp
├── RenderSystem.h
├── SoundSystem.cpp
├── SoundSystem.h
├── SpriteSystem.cpp
├── SpriteSystem.h
├── System.h
├── TransformSystem.cpp
├── TransformSystem.h
├── VideoSystem.cpp
└── VideoSystem.h
└── main.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | data
3 | .vscode
4 | font
5 | ffmpeg
6 | .vs
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "wzlibcpp"]
2 | path = 3rdparty/wzlibcpp
3 | url = https://github.com/PShocker/wzlibcpp.git
4 | [submodule "freetype"]
5 | path = 3rdparty/freetype
6 | url = https://github.com/freetype/freetype.git
7 | [submodule "SDL"]
8 | path = 3rdparty/SDL
9 | url = https://github.com/libsdl-org/SDL.git
10 | branch = release-2.30.x
11 |
--------------------------------------------------------------------------------
/3rdparty/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(freetype)
2 | add_subdirectory(SDL)
3 | add_subdirectory(wzlibcpp)
4 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.19.2)
2 | project(sdlMS)
3 |
4 | set(CMAKE_CXX_STANDARD 20)
5 |
6 | # Add compile information for LSP
7 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
8 |
9 | if(CMAKE_BUILD_TYPE STREQUAL "Release")
10 | if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
11 | # 启用lto -flto=auto
12 | # 把 MINGW-根目录\libexec\gcc\x86_64-w64-mingw32\13.2.0 下的 liblto_plugin.dll,复制到 MINGW-根目录\lib\bfd-plugins
13 | # 去掉调试符号
14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s")
15 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
16 | # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto=auto")
17 |
18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s")
19 | # 对本机cpu生成特定优化代码,可能存在兼容性问题
20 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
21 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto")
22 | endif()
23 | endif()
24 |
25 | add_subdirectory(3rdparty)
26 |
27 | add_subdirectory(sdlms)
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **实验版本已发布,采用SDL3,ENTT,请切换到new分支查看**
2 |
3 | 试玩地址:https://pshocker.github.io/sdlMS_online/sdlMS.html
4 |
5 | 用SDL2复刻冒险岛,使用[cmake(MinGW)](https://github.com/niXman/mingw-builds-binaries/releases/tag/13.2.0-rt_v11-rev0)构建.
6 |
7 | 资源文件进QQ群760717877下载
8 |
9 | 快速拉取本项目
10 | ```
11 | git clone --recurse-submodules https://github.com/PShocker/sdlMS.git --depth 1
12 | ```
13 |
14 | **[Windows编译](doc/Windows.md)**
15 |
16 | **[Linux编译](doc/Linux.md)**
17 |
18 | **[Emscripten编译(WEB)](doc/Emscripten.md)**
19 |
20 | **[Android编译(Android Studio)](doc/Android.md)**
21 |
22 | **[Mac编译](doc/Mac.md)**
23 |
--------------------------------------------------------------------------------
/doc/Android.md:
--------------------------------------------------------------------------------
1 | **Android编译(Android Studio Iguana | 2023.2.1 Patch 1)**
2 |
3 | 把根目录SDL文件夹的```android-project```提取出来,然后把项目放到```android-project\app\jni```
4 |
5 | ```
6 | └── android-project
7 | ├── app
8 | │ ├── jni
9 | │ │ ├── freetype
10 | │ │ ├── SDL
11 | │ │ ├── sdlms
12 | │ │ ├── wzlibcpp
13 | │ │ └── CMakeLists.txt(替换)
14 | ```
15 |
16 | 修改```android-project\app\build.gradle```去掉mk编译,使用cmake编译,并且使用```c++_shared```
17 | ```
18 | externalNativeBuild {
19 | // ndkBuild {
20 | // arguments "APP_PLATFORM=android-21"
21 | // abiFilters 'arm64-v8a'
22 | // }
23 | cmake {
24 | arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_shared"
25 | // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
26 | abiFilters 'arm64-v8a'
27 | }
28 | }
29 | ```
30 | ```
31 | externalNativeBuild {
32 | // ndkBuild {
33 | // path 'jni/Android.mk'
34 | // }
35 | cmake {
36 | path 'jni/CMakeLists.txt'
37 | }
38 | }
39 | ```
40 | 修改```android-project\app\build.gradle```指定ndk版本
41 | ```
42 | android {
43 | ndkVersion "26.3.11579264" // e.g., ndkVersion "21.3.6528147"
44 | }
45 | ```
46 |
47 | AndroidManifest.xml配置读取sdcard权限
48 | ```
49 |
50 |
51 | ```
52 |
53 | 修改```android-project\app\src\main\java\org\libsdl\app\SDLActivity.java```申请读取文件权限(安卓11以上)
54 | ```java
55 | private void requestManageExternalStoragePermission() {
56 | Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
57 | intent.setData(Uri.parse("package:" + getPackageName()));
58 | startActivityForResult(intent, 0);
59 | }
60 | // Setup
61 | @Override
62 | protected void onCreate(Bundle savedInstanceState) {
63 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
64 | if (!Environment.isExternalStorageManager()) {
65 | requestManageExternalStoragePermission();
66 | }
67 | }
68 | ......
69 | }
70 | ```
71 |
72 | **资源文件放进/sdcard/Data/**
73 |
--------------------------------------------------------------------------------
/doc/Emscripten.md:
--------------------------------------------------------------------------------
1 | **emscripten编译**
2 |
3 | 配置emscripten环境
4 | https://emscripten.org/docs/getting_started/downloads.html
5 |
6 | ```
7 | cd build
8 | emcmake cmake ..
9 | emmake make -j8
10 | python -m http.server 8500
11 | ```
12 | emscripten编译zlib可能会有问题,如果出现打不开的情况需要重新编译一次
13 |
--------------------------------------------------------------------------------
/doc/Linux.md:
--------------------------------------------------------------------------------
1 | **DeepinV23/Debian/Ubuntu编译**
2 | ```bash
3 | sudo apt-get install libsdl2-dev libfreetype-dev
4 | # 安装ffmpeg相关库
5 | sudo apt-get install libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev
6 | cd build
7 | cmake -DLINUX=1 ..
8 | make -j8
9 | ```
--------------------------------------------------------------------------------
/doc/Mac.md:
--------------------------------------------------------------------------------
1 | **Mac编译**
2 |
3 | **确保你的clang支持c++20**
4 |
5 | 一、安装FFMPEG
6 | 访问[FFMPEG官方网站](https://ffmpeg.org/download.html),下载xz源码包,或者进群下载.
7 | 或者使用brew安装
8 | ```
9 | brew install ffmpeg
10 | ```
11 | 1.解压
12 | ```bash
13 | tar xvf ffmpeg-7.0.tar.xz
14 | cd ffmpeg-7.0
15 | ```
16 | 2.配置FFMPEG编译选项
17 | ```
18 | ./configure --enable-static --disable-shared --disable-ffmpeg --disable-ffplay --disable-debug --disable-doc --disable-asm --prefix=/usr/local
19 | ```
20 | 3.编译和安装
21 | ```
22 | make
23 | make install
24 | ```
25 |
26 | 二、编译sdlMS
27 | ```
28 | cd build
29 | cmake ..
30 | make -j8
31 | ```
32 | 编译后的文件在
33 | ```
34 | build/bin
35 | ```
36 |
--------------------------------------------------------------------------------
/doc/Windows.md:
--------------------------------------------------------------------------------
1 | **MinGW编译**
2 | ```
3 | cd build
4 | cmake ..
5 | make -j8
6 | ```
7 | MinGW的make默认是```mingw32-make.exe```,需要改名为```make.exe```
8 |
9 | **VS编译**
10 |
11 | VS2022打开项目,编译
--------------------------------------------------------------------------------
/sdlms/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
2 | set(FFMPEG_INCLUDE "E:\\mygame\\Maple\\sdlMS2\\FFMPEG\\include")
3 | set(FFMPEG_LIB "E:\\mygame\\Maple\\sdlMS2\\FFMPEG\\lib")
4 |
5 | include_directories(
6 | ${CMAKE_CURRENT_SOURCE_DIR}
7 | )
8 |
9 | include_directories(
10 | ${FFMPEG_INCLUDE}
11 | )
12 |
13 | set(wzlibcpp ${PROJECT_SOURCE_DIR}/3rdparty/wzlibcpp)
14 | include_directories(
15 | ${wzlibcpp}
16 | ${wzlibcpp}/include
17 | ${wzlibcpp}/mio/include
18 | )
19 |
20 | link_directories(
21 | ${FFMPEG_LIB}
22 | )
23 |
24 | file(GLOB SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/**/*.cpp)
25 |
26 | if(WIN32)
27 | add_executable(sdlMS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${SOURCE_FILES})
28 | # 将 SDL2 库链接到可执行文件中
29 | target_link_libraries(sdlMS PRIVATE SDL2-static SDL2main)
30 | # 链接 wzlib 库
31 | target_link_libraries(sdlMS PRIVATE wzlib)
32 | # 链接 FFMPEG库
33 | target_link_libraries(sdlMS PRIVATE avformat avdevice avcodec avutil swscale avfilter swresample)
34 | # freetype
35 | target_link_libraries(sdlMS PRIVATE freetype)
36 | # 链接 Windows平台库(FFMPEG)
37 | target_link_libraries(sdlMS PRIVATE bcrypt ws2_32 Secur32 Strmiids)
38 | # 链接 FFMPEG依赖库,wzlib里面已经包含了zlib库
39 | if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
40 | # 使用微软编译器
41 | add_definitions(-DNOMINMAX)
42 | else()
43 | # 使用 Mingw 编译器
44 | target_link_libraries(sdlMS PRIVATE bz2-1 iconv-2 lzma-5)
45 | endif()
46 |
47 | set_target_properties(sdlMS PROPERTIES
48 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
49 | )
50 | endif()
51 |
52 | if(LINUX)
53 | add_executable(sdlMS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${SOURCE_FILES})
54 | # 将 SDL2 库链接到可执行文件中
55 | target_link_libraries(sdlMS PRIVATE SDL2-static SDL2main)
56 | # 链接 wzlib 库
57 | target_link_libraries(sdlMS PRIVATE wzlib)
58 | # 链接 FFMPEG库
59 | target_link_libraries(sdlMS PRIVATE avformat avdevice avcodec avutil swscale avfilter swresample)
60 | # freetype
61 | target_link_libraries(sdlMS PRIVATE freetype)
62 | set_target_properties(sdlMS PROPERTIES
63 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
64 | )
65 | endif()
66 |
67 | # 设置 Emscripten 编译选项
68 | if(EMSCRIPTEN)
69 | add_executable(sdlMS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${SOURCE_FILES})
70 | # 将 SDL2 库链接到可执行文件中
71 | target_link_libraries(sdlMS PRIVATE SDL2-static SDL2main)
72 | # 链接 wzlib 库
73 | target_link_libraries(sdlMS PRIVATE wzlib)
74 | # 链接 FFMPEG库
75 | target_link_libraries(sdlMS PRIVATE avformat avdevice avcodec avutil swscale avfilter swresample)
76 | # freetype
77 | target_link_libraries(sdlMS PRIVATE freetype)
78 |
79 | set(CMAKE_EXECUTABLE_SUFFIX ".html")
80 | set_target_properties(sdlMS PROPERTIES LINK_FLAGS
81 | "--preload-file ${CMAKE_SOURCE_DIR}/build/Data/@Data/"
82 | # 可以添加其他Emscripten链接器选项
83 | )
84 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -sALLOW_MEMORY_GROWTH -g -sUSE_ZLIB")
85 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sALLOW_MEMORY_GROWTH -g -sUSE_ZLIB")
86 | set_target_properties(sdlMS PROPERTIES
87 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
88 | )
89 | endif()
90 |
91 | if(ANDROID)
92 | add_library(main SHARED)
93 | target_sources(main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${SOURCE_FILES})
94 | find_library(SDL2 SDL2)
95 | target_link_libraries(main SDL2 android)
96 | # 链接 wzlib 库
97 | target_link_libraries(main wzlib)
98 | # 链接 FFMPEG 库
99 | target_link_libraries(main avformat avdevice avcodec avutil swscale avfilter swresample -Wl,-Bsymbolic)
100 | # freetype
101 | target_link_libraries(main freetype)
102 | endif()
103 |
104 | if (APPLE)
105 | # Find packages
106 | find_library(COREMEDIA_FRAMEWORK CoreMedia)
107 | find_library(VIDEOTOOLBOX_FRAMEWORK VideoToolbox)
108 | find_library(SECURITY_FRAMEWORK Security)
109 |
110 | add_executable(sdlMS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${SOURCE_FILES})
111 |
112 | # 将 SDL2 库链接到可执行文件中
113 | target_link_libraries(sdlMS PRIVATE SDL2-static SDL2main)
114 |
115 | # 链接 wzlib 库
116 | target_link_libraries(sdlMS PRIVATE wzlib)
117 | # 链接 FFMPEG库
118 | target_link_libraries(sdlMS PRIVATE avformat avdevice avcodec avutil swscale avfilter swresample)
119 | # freetype
120 | target_link_libraries(sdlMS PRIVATE freetype)
121 |
122 | # Link frameworks
123 | target_link_libraries(
124 | sdlMS
125 | PRIVATE
126 | ${COREMEDIA_FRAMEWORK}
127 | ${VIDEOTOOLBOX_FRAMEWORK}
128 | ${SECURITY_FRAMEWORK}
129 | )
130 |
131 | set_target_properties(sdlMS PROPERTIES
132 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
133 | )
134 | endif()
135 |
--------------------------------------------------------------------------------
/sdlms/Components/AnimatedSprite.cpp:
--------------------------------------------------------------------------------
1 | #include "AnimatedSprite.h"
2 |
3 | AnimatedSprite::AnimatedSprite(wz::Node *node, int alpha)
4 | {
5 | // 从第0帧顺序读
6 | for (int i = 0; i < node->children_count(); i++)
7 | {
8 | auto it = node->get_child(std::to_string(i));
9 | if (it == nullptr)
10 | {
11 | // 如果发现没读取到,说明已经读完,则退出读取
12 | break;
13 | }
14 | wz::Property *canvas;
15 | if (it->type == wz::Type::UOL)
16 | {
17 | auto uol = dynamic_cast *>(it);
18 | canvas = dynamic_cast *>(uol->get_uol());
19 | }
20 | else if (it->type == wz::Type::Canvas)
21 | {
22 | canvas = dynamic_cast *>(it);
23 | }
24 | else
25 | {
26 | continue;
27 | }
28 |
29 | Sprite *sprite = new Sprite(canvas, alpha);
30 |
31 | sprites.push_back(sprite);
32 | }
33 | if (node->get_child(u"zigzag") != nullptr)
34 | {
35 | // 如果存在zigzag属性,则认为属于zigzag动画
36 | z = true;
37 | }
38 |
39 | anim_size = sprites.size();
40 | anim_index = 0;
41 | anim_time = 0;
42 | }
43 |
44 | AnimatedSprite::~AnimatedSprite()
45 | {
46 | for (auto &spr : sprites)
47 | {
48 | delete spr;
49 | }
50 | }
--------------------------------------------------------------------------------
/sdlms/Components/AnimatedSprite.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "Sprite.h"
8 | #include "wz/Property.hpp"
9 |
10 | class AnimatedSprite : public Component
11 | {
12 | private:
13 | std::vector sprites;
14 | int anim_index;
15 | int anim_time;
16 | int anim_size;
17 | bool animate = true; // 是否播放动画,特殊情况,冰冻状态下会暂停动画
18 | bool z = false; // ziazag
19 |
20 | public:
21 | AnimatedSprite(wz::Node *node, int alpha = 255);
22 | ~AnimatedSprite();
23 | void add_anim_time(const int val) { anim_time += val; }
24 |
25 | auto get_anim_time() { return anim_time; }
26 | auto get_anim_index() { return anim_index; }
27 | auto get_anim_size() { return anim_size; }
28 | auto get_zigzag() { return z; }
29 | auto get_animate() { return animate; }
30 | auto get_current_sprite() { return sprites[anim_index]; }
31 | auto get_anim_delay() { return sprites[anim_index]->delay; }
32 | auto get_anim_width() { return sprites[anim_index]->get_width(); }
33 | auto get_anim_height() { return sprites[anim_index]->get_height(); }
34 | auto &get_sprites() { return sprites; }
35 |
36 | void set_anim_index(const int val) { anim_index = val; }
37 | void set_anim_time(const int val) { anim_time = val; }
38 | void set_animate(const bool val) { animate = val; }
39 | };
--------------------------------------------------------------------------------
/sdlms/Components/Avatar.cpp:
--------------------------------------------------------------------------------
1 | #include "Avatar.h"
2 | #include "Resource/Wz.h"
3 | #include
4 |
5 | Avatar *Avatar::load()
6 | {
7 | [[unlikely]]
8 | if (!inited)
9 | {
10 | inited = true;
11 | init();
12 | }
13 | return new Avatar();
14 | }
15 |
16 | void Avatar::init()
17 | {
18 | character_node = World::get_world()->get_resource().Character->get_root();
19 | {
20 | auto body_node = character_node->find_from_path(u"00002000.img");
21 | auto head_node = character_node->find_from_path(u"00012000.img");
22 | for (auto stance_node : body_node->get_children())
23 | {
24 | auto ststr = stance_node.first;
25 |
26 | uint16_t attackdelay = 0;
27 |
28 | for (uint8_t frame = 0; auto frame_node = stance_node.second[0]->get_child(std::to_string(frame)); ++frame)
29 | {
30 | if (frame_node->get_child(u"action") != nullptr)
31 | {
32 | /* code */
33 | }
34 | else
35 | {
36 | auto type = type_map.at(ststr);
37 | auto delay_node = frame_node->get_child(u"delay");
38 | auto delay = 100;
39 | if (delay_node != nullptr)
40 | {
41 | delay = dynamic_cast *>(delay_node)->get();
42 | }
43 | stance_delays[type][frame] = delay;
44 |
45 | auto face_node = frame_node->get_child(u"face");
46 | auto face = true;
47 | if (face_node != nullptr)
48 | {
49 | face = dynamic_cast *>(face_node)->get();
50 | }
51 | show_face[type][frame] = face;
52 |
53 | std::unordered_map> body_shift_map;
54 |
55 | for (auto part_node : frame_node->get_children())
56 | {
57 | auto part_name = part_node.first;
58 |
59 | if (part_name != u"delay" && part_name != u"face")
60 | {
61 | auto part = part_node.second[0];
62 | if (part->type == wz::Type::UOL)
63 | {
64 | part = dynamic_cast *>(part)->get_uol();
65 | }
66 |
67 | auto zstr = dynamic_cast *>(part->get_child(u"z"))->get();
68 | auto z = layer_map.at(zstr);
69 |
70 | for (auto map_node : part->get_child(u"map")->get_children())
71 | {
72 | auto v = dynamic_cast *>(map_node.second[0])->get();
73 |
74 | body_shift_map[z].emplace(map_node.first, SDL_FPoint{(float)v.x, (float)v.y});
75 | }
76 | }
77 | }
78 | std::string frame_str = std::to_string(frame);
79 | auto h = head_node->find_from_path(ststr + u"/" + std::u16string{frame_str.begin(), frame_str.end()} + u"/" + u"head");
80 | if (h != nullptr)
81 | {
82 | if (h->type == wz::Type::UOL)
83 | {
84 | h = dynamic_cast *>(h)->get_uol();
85 | }
86 | for (auto map_node : h->get_child(u"map")->get_children())
87 | {
88 | auto v = dynamic_cast *>(map_node.second[0])->get();
89 |
90 | body_shift_map[Layer::HEAD].emplace(map_node.first, SDL_FPoint{(float)v.x, (float)v.y});
91 | }
92 | }
93 |
94 | body_positions[type][frame] = body_shift_map[Layer::BODY][u"navel"];
95 |
96 | arm_positions[type][frame] = body_shift_map.count(Layer::ARM) ? (body_shift_map[Layer::ARM][u"hand"] - body_shift_map[Layer::ARM][u"navel"] + body_shift_map[Layer::BODY][u"navel"])
97 | : (body_shift_map[Layer::ARM_OVER_HAIR][u"hand"] - body_shift_map[Layer::ARM_OVER_HAIR][u"navel"] + body_shift_map[Layer::BODY][u"navel"]);
98 | hand_positions[type][frame] = body_shift_map[Layer::HAND_BELOW_WEAPON][u"handMove"];
99 | head_positions[type][frame] = body_shift_map[Layer::BODY][u"neck"] - body_shift_map[Layer::HEAD][u"neck"];
100 | face_positions[type][frame] = body_shift_map[Layer::BODY][u"neck"] - body_shift_map[Layer::HEAD][u"neck"] + body_shift_map[Layer::HEAD][u"brow"];
101 | hair_positions[type][frame] = body_shift_map[Layer::HEAD][u"brow"] - body_shift_map[Layer::HEAD][u"neck"] + body_shift_map[Layer::BODY][u"neck"];
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
108 | void Avatar::add_body(const std::u16string &val)
109 | {
110 | auto body_node = character_node->find_from_path(val + u".img");
111 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
112 | {
113 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
114 | {
115 | auto no_str = std::to_string(no);
116 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
117 | {
118 | Sprite *sprite = new Sprite(body_node->find_from_path(type + u"/body"));
119 | Transform *f = new Transform();
120 | auto z = std::any_cast(sprite->get_z());
121 | auto part = *zmap[z];
122 | part[i][no] = {f, sprite};
123 | }
124 | {
125 | if (body_node->find_from_path(type + u"/arm") != nullptr)
126 | {
127 | auto arm_pos = dynamic_cast *>(body_node->find_from_path(type + u"/arm/map/hand"))->get();
128 | Sprite *sprite = new Sprite(body_node->find_from_path(type + u"/arm"));
129 | Transform *f = new Transform(arm_positions[i][no] - SDL_FPoint{(float)arm_pos.x, (float)arm_pos.y});
130 | auto z = std::any_cast(sprite->get_z());
131 | auto part = *zmap[z];
132 | part[i][no] = {f, sprite};
133 | }
134 | }
135 | {
136 | if (body_node->find_from_path(type + u"/hand") != nullptr)
137 | {
138 | auto hand = body_node->find_from_path(type + u"/hand");
139 | if (body_node->find_from_path(type + u"/hand/map/navel") != nullptr)
140 | {
141 | auto hand_pos = dynamic_cast *>(hand->find_from_path(u"map/navel"))->get();
142 | Sprite *sprite = new Sprite(hand);
143 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)hand_pos.x, (float)hand_pos.y});
144 | auto z = std::any_cast(sprite->get_z());
145 | auto part = *zmap[z];
146 | part[i][no] = {f, sprite};
147 | }
148 | }
149 | }
150 | {
151 | if (body_node->find_from_path(type + u"/lHand") != nullptr)
152 | {
153 | auto lHand = body_node->find_from_path(type + u"/lHand");
154 | if (lHand->find_from_path(u"map/handMove") != nullptr)
155 | {
156 | auto lHand_pos = dynamic_cast *>(lHand->find_from_path(u"map/handMove"))->get();
157 | Sprite *sprite = new Sprite(lHand);
158 | Transform *f = new Transform(hand_positions[i][no] - SDL_FPoint{(float)lHand_pos.x, (float)lHand_pos.y});
159 | auto z = std::any_cast(sprite->get_z());
160 | auto part = *zmap[z];
161 | part[i][no] = {f, sprite};
162 | }
163 | else
164 | {
165 | auto lHand_pos = dynamic_cast *>(lHand->find_from_path(u"map/navel"))->get();
166 | Sprite *sprite = new Sprite(lHand);
167 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)lHand_pos.x, (float)lHand_pos.y});
168 | auto z = std::any_cast(sprite->get_z());
169 | auto part = *zmap[z];
170 | part[i][no] = {f, sprite};
171 | }
172 | }
173 | }
174 | {
175 | if (body_node->find_from_path(type + u"/rHand") != nullptr)
176 | {
177 | auto rHand = body_node->find_from_path(type + u"/rHand");
178 | if (rHand->find_from_path(u"map/navel") != nullptr)
179 | {
180 | auto rHand_pos = dynamic_cast *>(rHand->find_from_path(u"map/navel"))->get();
181 | Sprite *sprite = new Sprite(rHand);
182 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)rHand_pos.x, (float)rHand_pos.y});
183 | auto z = std::any_cast(sprite->get_z());
184 | auto part = *zmap[z];
185 | part[i][no] = {f, sprite};
186 | }
187 | }
188 | }
189 | }
190 | }
191 | }
192 |
193 | void Avatar::add_coat(const std::u16string &val)
194 | {
195 | auto coat_node = character_node->find_from_path(u"Coat/" + val + u".img");
196 | if (coat_node != nullptr)
197 | {
198 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
199 | {
200 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
201 | {
202 | auto no_str = std::to_string(no);
203 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
204 | {
205 | if (coat_node->find_from_path(type + u"/mail") != nullptr)
206 | {
207 | auto coat_pos = dynamic_cast *>(coat_node->find_from_path(type + u"/mail/map/navel"))->get();
208 | Sprite *sprite = new Sprite(coat_node->find_from_path(type + u"/mail"));
209 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)coat_pos.x, (float)coat_pos.y});
210 | auto z = std::any_cast(sprite->get_z());
211 | auto part = *zmap[z];
212 | part[i][no] = {f, sprite};
213 | }
214 | }
215 | {
216 | if (coat_node->find_from_path(type + u"/mailArm") != nullptr)
217 | {
218 | auto mail_arm_pos = dynamic_cast *>(coat_node->find_from_path(type + u"/mailArm/map/navel"))->get();
219 | Sprite *sprite = new Sprite(coat_node->find_from_path(type + u"/mailArm"));
220 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)mail_arm_pos.x, (float)mail_arm_pos.y});
221 | auto z = std::any_cast(sprite->get_z());
222 | auto part = *zmap[z];
223 | part[i][no] = {f, sprite};
224 | }
225 | }
226 | }
227 | }
228 | }
229 | }
230 |
231 | void Avatar::add_cap(const std::u16string &val)
232 | {
233 | auto cap_node = character_node->find_from_path(u"Cap/" + val + u".img");
234 | if (cap_node != nullptr)
235 | {
236 | cap_vslot.clear();
237 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
238 | {
239 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
240 | {
241 | auto no_str = std::to_string(no);
242 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
243 | if (cap_node->find_from_path(type) != nullptr)
244 | {
245 | for (auto it : cap_node->find_from_path(type)->get_children())
246 | {
247 | auto cap = it.second[0];
248 | if (cap->type == wz::Type::UOL)
249 | {
250 | cap = dynamic_cast *>(cap)->get_uol();
251 | }
252 | auto cap_pos = dynamic_cast *>(cap->find_from_path(u"map/brow"))->get();
253 | Sprite *sprite = new Sprite(cap);
254 | Transform *f = new Transform(face_positions[i][no] - SDL_FPoint{(float)cap_pos.x, (float)cap_pos.y});
255 | auto z = std::any_cast(sprite->get_z());
256 | auto part = *zmap[z];
257 | part[i][no] = {f, sprite};
258 | }
259 | }
260 | }
261 | }
262 | auto vslot = dynamic_cast *>(cap_node->find_from_path(u"info/vslot"))->get();
263 | for (size_t i = 0; i < vslot.size(); i += 2)
264 | {
265 | cap_vslot.emplace(vslot.substr(i, 2));
266 | }
267 | }
268 | }
269 |
270 | void Avatar::add_pants(const std::u16string &val)
271 | {
272 | auto pants_node = character_node->find_from_path(u"Pants/" + val + u".img");
273 | if (pants_node != nullptr)
274 | {
275 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
276 | {
277 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
278 | {
279 | auto no_str = std::to_string(no);
280 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
281 | if (pants_node->find_from_path(type + u"/pants") != nullptr)
282 | {
283 | auto pants_pos = dynamic_cast *>(pants_node->find_from_path(type + u"/pants/map/navel"))->get();
284 | Sprite *sprite = new Sprite(pants_node->find_from_path(type + u"/pants"));
285 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)pants_pos.x, (float)pants_pos.y});
286 | auto z = std::any_cast(sprite->get_z());
287 | auto part = *zmap[z];
288 | part[i][no] = {f, sprite};
289 | }
290 | }
291 | }
292 | }
293 | }
294 |
295 | void Avatar::add_head(const std::u16string &val)
296 | {
297 | auto head_node = character_node->find_from_path(val + u".img");
298 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
299 | {
300 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
301 | {
302 | auto no_str = std::to_string(no);
303 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
304 | if (head_node->find_from_path(type + u"/head") != nullptr)
305 | {
306 | Sprite *sprite = new Sprite(head_node->find_from_path(type + u"/head"));
307 | Transform *f = new Transform(head_positions[i][no]);
308 | auto z = std::any_cast(sprite->get_z());
309 | auto part = *zmap[z];
310 | part[i][no] = {f, sprite};
311 | }
312 | }
313 | }
314 | }
315 |
316 | void Avatar::add_face(const std::u16string &val)
317 | {
318 | auto face_node = character_node->find_from_path(u"Face/" + val + u".img/default/face");
319 | if (face_node != nullptr)
320 | {
321 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
322 | {
323 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
324 | {
325 | auto face_pos = dynamic_cast *>(face_node->find_from_path(u"map/brow"))->get();
326 | Sprite *sprite = new Sprite(face_node);
327 | Transform *f = new Transform(face_positions[i][no] - SDL_FPoint{(float)face_pos.x, (float)face_pos.y});
328 | auto z = std::any_cast(sprite->get_z());
329 | auto part = *zmap[z];
330 | part[i][no] = {f, sprite};
331 | }
332 | }
333 | }
334 | }
335 |
336 | void Avatar::add_hairs(const std::u16string &val)
337 | {
338 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
339 | {
340 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
341 | {
342 | auto no_str = std::to_string(no);
343 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
344 | auto hairs_node = character_node->find_from_path(u"Hair/" + val + u".img/" + type);
345 | if (hairs_node != nullptr)
346 | {
347 | for (auto it : hairs_node->get_children())
348 | {
349 | auto hairs = it.second[0];
350 | if (hairs->type == wz::Type::UOL)
351 | {
352 | hairs = dynamic_cast *>(hairs)->get_uol();
353 | }
354 | if (it.first == u"hairShade")
355 | {
356 | hairs = hairs->find_from_path(u"0");
357 | }
358 | auto hair_pos = dynamic_cast *>(hairs->find_from_path(u"map/brow"))->get();
359 | Sprite *sprite = new Sprite(hairs);
360 | Transform *f = new Transform(face_positions[i][no] - SDL_FPoint{(float)hair_pos.x, (float)hair_pos.y});
361 | auto z = std::any_cast(sprite->get_z());
362 | auto part = *zmap[z];
363 | part[i][no] = {f, sprite};
364 | }
365 | }
366 | }
367 | }
368 | }
369 |
370 | void Avatar::add_shoes(const std::u16string &val)
371 | {
372 | auto shoes_node = character_node->find_from_path(u"Shoes/" + val + u".img");
373 | if (shoes_node != nullptr)
374 | {
375 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
376 | {
377 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
378 | {
379 | auto no_str = std::to_string(no);
380 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
381 | if (shoes_node->find_from_path(type + u"/shoes") != nullptr)
382 | {
383 | auto shoes_pos = dynamic_cast *>(shoes_node->find_from_path(type + u"/shoes/map/navel"))->get();
384 | Sprite *sprite = new Sprite(shoes_node->find_from_path(type + u"/shoes"));
385 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)shoes_pos.x, (float)shoes_pos.y});
386 | auto z = std::any_cast(sprite->get_z());
387 | auto part = *zmap[z];
388 | part[i][no] = {f, sprite};
389 | }
390 | }
391 | }
392 | }
393 | }
394 |
395 | void Avatar::add_weapon(const std::u16string &val)
396 | {
397 | auto weapon_node = character_node->find_from_path(u"Weapon/" + val + u".img");
398 | if (weapon_node != nullptr)
399 | {
400 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
401 | {
402 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
403 | {
404 | auto no_str = std::to_string(no);
405 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
406 | if (weapon_node->find_from_path(type + u"/weapon") != nullptr)
407 | {
408 | if (weapon_node->find_from_path(type + u"/weapon/map/hand") != nullptr)
409 | {
410 | auto weapon_pos = dynamic_cast *>(weapon_node->find_from_path(type + u"/weapon/map/hand"))->get();
411 | Sprite *sprite = new Sprite(weapon_node->find_from_path(type + u"/weapon"));
412 | Transform *f = new Transform(arm_positions[i][no] - SDL_FPoint{(float)weapon_pos.x, (float)weapon_pos.y});
413 | auto z = std::any_cast(sprite->get_z());
414 | auto part = *zmap[z];
415 | part[i][no] = {f, sprite};
416 | }
417 | else
418 | {
419 | auto weapon_pos = dynamic_cast *>(weapon_node->find_from_path(type + u"/weapon/map/navel"))->get();
420 | Sprite *sprite = new Sprite(weapon_node->find_from_path(type + u"/weapon"));
421 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)weapon_pos.x, (float)weapon_pos.y});
422 | auto z = std::any_cast(sprite->get_z());
423 | auto part = *zmap[z];
424 | part[i][no] = {f, sprite};
425 | }
426 | }
427 | }
428 | }
429 | }
430 | }
431 |
432 | void Avatar::add_shield(const std::u16string &val)
433 | {
434 | auto shield_node = character_node->find_from_path(u"Shield/" + val + u".img");
435 | if (shield_node != nullptr)
436 | {
437 | for (uint8_t i = 0; i < ACTION::LENGTH; i++)
438 | {
439 | for (uint8_t no = 0; no < body_positions[i].size(); no++)
440 | {
441 | auto no_str = std::to_string(no);
442 | auto type = type_map2.at(i) + u"/" + std::u16string{no_str.begin(), no_str.end()};
443 | if (shield_node->find_from_path(type + u"/shield") != nullptr)
444 | {
445 | auto shield_pos = dynamic_cast *>(shield_node->find_from_path(type + u"/shield/map/navel"))->get();
446 | Sprite *sprite = new Sprite(shield_node->find_from_path(type + u"/shield"));
447 | Transform *f = new Transform(body_positions[i][no] - SDL_FPoint{(float)shield_pos.x, (float)shield_pos.y});
448 | auto z = std::any_cast(sprite->get_z());
449 | auto part = *zmap[z];
450 | part[i][no] = {f, sprite};
451 | }
452 | }
453 | }
454 | }
455 | }
456 |
457 | Avatar::~Avatar()
458 | {
459 | auto del_func = [](std::pair &pai) -> void
460 | {
461 | auto &[tr, spr] = pai;
462 | delete tr;
463 | delete spr;
464 | };
465 | for (auto &it : body)
466 | {
467 | for (auto &[key, val] : it)
468 | {
469 | del_func(val);
470 | }
471 | }
472 | }
--------------------------------------------------------------------------------
/sdlms/Components/Camera.cpp:
--------------------------------------------------------------------------------
1 | #include "Camera.h"
2 |
3 | Camera::Camera(int x, int y, float w, float h) : x(x), y(y), w(w), h(h)
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/sdlms/Components/Camera.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 | #include
4 |
5 | //
6 | class Camera : public Component
7 | {
8 | public:
9 | Camera(int x, int y, float w, float h);
10 | constexpr auto get_x() { return x; }
11 | constexpr auto get_y() { return y; }
12 | constexpr auto get_w() { return w; }
13 | constexpr auto get_h() { return h; }
14 |
15 | void set_x(const int val) { x = val; }
16 | void set_y(const int val) { y = val; }
17 | void set_w(const float val) { w = val; }
18 | void set_h(const float val) { h = val; }
19 |
20 | private:
21 | int x;
22 | int y;
23 | float w;
24 | float h;
25 | };
--------------------------------------------------------------------------------
/sdlms/Components/Component.cpp:
--------------------------------------------------------------------------------
1 | #include "Component.h"
2 |
3 | Component::Component() {}
4 | Component::~Component() {}
--------------------------------------------------------------------------------
/sdlms/Components/Component.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "Core/World.h"
8 |
9 | class Entity;
10 |
11 | class Component
12 | {
13 | public:
14 | Component();
15 | virtual ~Component();
16 | int id = 0;
17 |
18 | protected:
19 | Entity *owner = nullptr;
20 |
21 | public:
22 | int get_id() const
23 | {
24 | return id;
25 | };
26 |
27 | void set_id(int value)
28 | {
29 | id = value;
30 | };
31 |
32 | Entity *get_owner()
33 | {
34 | return owner;
35 | };
36 | void set_owner(Entity *value)
37 | {
38 | owner = value;
39 | };
40 | template
41 | C *get_owner()
42 | {
43 | return dynamic_cast(owner);
44 | }
45 |
46 | template
47 | C *get_owner_component();
48 | };
49 |
50 | #include "Entities/Entity.h"
51 |
52 | template
53 | C *Component::get_owner_component()
54 | {
55 | return static_cast(owner->get_component());
56 | }
57 |
--------------------------------------------------------------------------------
/sdlms/Components/DistanceSprite.cpp:
--------------------------------------------------------------------------------
1 | #include "DistanceSprite.h"
2 |
3 | DistanceSprite::DistanceSprite(){}
4 | DistanceSprite::~DistanceSprite(){}
5 |
6 | void DistanceSprite::add(std::optional h, std::optional v, std::optional> disspr)
7 | {
8 | hs.push_back(h);
9 | vs.push_back(v);
10 | dissprs.push_back(disspr);
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/sdlms/Components/DistanceSprite.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Components/Component.h"
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "Sprite.h"
10 | #include "AnimatedSprite.h"
11 |
12 | class DistanceSprite : public Component
13 | {
14 | private:
15 | std::vector>> dissprs;
16 | std::vector> hs; // 水平范围
17 | std::vector> vs; // 垂直范围
18 |
19 | public:
20 | DistanceSprite();
21 | ~DistanceSprite();
22 | void add(std::optional h, std::optional v, std::optional> disspr);
23 | constexpr auto &get_dissprs() { return dissprs; }
24 | constexpr auto &get_hs() { return hs; }
25 | constexpr auto &get_vs() { return vs; }
26 | };
27 |
--------------------------------------------------------------------------------
/sdlms/Components/HVMove.cpp:
--------------------------------------------------------------------------------
1 | #include "HVMove.h"
2 |
3 | HVMove::HVMove(int rx, int ry, bool hspeed, bool vspeed) : rx(rx), ry(ry), hspeed(hspeed), vspeed(vspeed)
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/sdlms/Components/HVMove.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 |
4 | // 表示左右运动的属性
5 | class HVMove : public Component
6 | {
7 | public:
8 | HVMove(int rx, int ry, bool hspeed, bool vspeed);
9 | constexpr auto get_rx() { return rx; }
10 | constexpr auto get_ry() { return ry; }
11 | constexpr auto get_offset_x() { return offset_x; }
12 | constexpr auto get_offset_y() { return offset_y; }
13 | constexpr auto get_hspeed() { return hspeed; }
14 | constexpr auto get_vspeed() { return vspeed; }
15 | void set_offset_x(const float val) { offset_x = val; }
16 | void set_offset_y(const float val) { offset_y = val; }
17 |
18 | public:
19 | int rx;
20 | int ry;
21 | float offset_x = 0.0f;
22 | float offset_y = 0.0f;
23 | bool hspeed = false;
24 | bool vspeed = false;
25 | };
--------------------------------------------------------------------------------
/sdlms/Components/HVTile.cpp:
--------------------------------------------------------------------------------
1 | #include "HVTile.h"
2 |
3 | HVTile::HVTile(int cx, int cy, bool htile, bool vtile) : cx(cx), cy(cy), htile(htile), vtile(vtile)
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/sdlms/Components/HVTile.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 |
4 | // 平铺属性
5 | class HVTile : public Component
6 | {
7 | public:
8 | HVTile(int cx, int cy, bool htile, bool vtile);
9 | constexpr auto get_cx() { return cx; }
10 | constexpr auto get_cy() { return cy; }
11 |
12 | public:
13 | // 平铺间隔
14 | int cx;
15 | int cy;
16 | // 是否平铺
17 | bool htile = false;
18 | bool vtile = false;
19 | };
--------------------------------------------------------------------------------
/sdlms/Components/LimitTransform.cpp:
--------------------------------------------------------------------------------
1 | #include "LimitTransform.h"
2 |
3 | LimitTransform::LimitTransform(Transform *tr, std::optional h, std::optional v) : tr(tr), h(h), v(v)
4 | {
5 | }
--------------------------------------------------------------------------------
/sdlms/Components/LimitTransform.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 | #include "Transform.h"
4 | #include
5 |
6 | // 限制Transform的移动范围
7 | class LimitTransform : public Component
8 | {
9 | private:
10 | std::optional h = std::nullopt;
11 | std::optional v = std::nullopt;
12 | Transform *tr = nullptr;
13 |
14 | public:
15 | LimitTransform(Transform *tr, std::optional h, std::optional v);
16 | auto &get_h() { return h; }
17 | auto &get_v() { return v; }
18 | auto &get_tr() { return tr; }
19 | };
--------------------------------------------------------------------------------
/sdlms/Components/Line.cpp:
--------------------------------------------------------------------------------
1 | #include "Line.h"
2 | #include
3 |
4 | Line::Line(SDL_FPoint m, SDL_FPoint n) : m(m), n(n)
5 | {
6 | auto [x1, y1] = m;
7 | auto [x2, y2] = n;
8 | if (x1 != x2)
9 | {
10 | // 斜线
11 | k = ((float)y2 - (float)y1) / ((float)x2 - (float)x1);
12 | intercept = y1 - k.value() * x1;
13 | }
14 | }
15 |
16 | std::optional Line::get_y(float x)
17 | {
18 | [[likely]]
19 | if (x >= get_min_x() && x <= get_max_x())
20 | {
21 | [[likely]]
22 | if (k.has_value())
23 | {
24 | return k.value() * x + intercept.value();
25 | }
26 | }
27 | return std::nullopt;
28 | }
29 |
30 | std::optional Line::get_x(float y)
31 | {
32 | [[likely]]
33 | if (y >= get_min_y() && y <= get_max_y())
34 | {
35 | [[likely]]
36 | if (k.has_value())
37 | {
38 | return (y - intercept.value()) / k.value();
39 | }
40 | }
41 | return std::nullopt;
42 | }
43 |
--------------------------------------------------------------------------------
/sdlms/Components/Line.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 | #include
4 | #include
5 | // 线
6 | class Line : public Component
7 | {
8 | public:
9 | Line(SDL_FPoint m, SDL_FPoint n);
10 | constexpr auto get_m() { return m; }
11 | constexpr auto get_n() { return n; }
12 | auto get_min_x() { return std::fmin(m.x, n.x); }
13 | auto get_max_x() { return std::fmax(m.x, n.x); }
14 | auto get_min_y() { return std::fmin(m.y, n.y); }
15 | auto get_max_y() { return std::fmax(m.y, n.y); }
16 | constexpr auto get_k() { return k; }
17 | std::optional get_y(float x);
18 | std::optional get_x(float y);
19 |
20 | private:
21 | SDL_FPoint m;
22 | SDL_FPoint n;
23 |
24 | private:
25 | std::optional k = std::nullopt; // 斜率,若k值不存在,可以判断是否是墙面
26 | std::optional intercept = std::nullopt;
27 | };
28 |
--------------------------------------------------------------------------------
/sdlms/Components/Physic/Normal.cpp:
--------------------------------------------------------------------------------
1 | #include "Normal.h"
2 |
--------------------------------------------------------------------------------
/sdlms/Components/Physic/Normal.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "../Component.h"
3 | #include
4 |
5 | // 正常物理状态,非水下,飞翔
6 | class Normal : public Component
7 | {
8 | public:
9 | Normal(){};
10 |
11 | public:
12 | float hspeed = 0.0;
13 | std::optional hspeed_limit = SDL_FPoint{-125.0f, 125.0f};
14 | float vspeed = 0.0;
15 | std::optional vspeed_limit = SDL_FPoint{-5000.0f, 670.0f};
16 | float hforce = 0.0;
17 | float vforce = 0.0;
18 | float hacc = 0.0;
19 | float vacc = 0.0;
20 | enum : uint8_t
21 | {
22 | Ground,
23 | Air,
24 | Climb,
25 | };
26 | uint8_t type = Air;
27 |
28 | enum : uint8_t
29 | {
30 | None,
31 | Up,
32 | Left,
33 | Down,
34 | Right,
35 | };
36 | uint8_t vkey = None; // 上下按键
37 | uint8_t hkey = None; // 左右按键
38 | bool lalt = false;
39 | bool lctrl = false;
40 | };
--------------------------------------------------------------------------------
/sdlms/Components/Player.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PShocker/sdlMS/ef03334602c93e4d0e63a9ca77cad12e2dedd206/sdlms/Components/Player.cpp
--------------------------------------------------------------------------------
/sdlms/Components/Player.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 |
4 | class Player : public Component
5 | {
6 | public:
7 | Player(){};
8 | };
--------------------------------------------------------------------------------
/sdlms/Components/RandomInput.cpp:
--------------------------------------------------------------------------------
1 | #include "RandomInput.h"
2 |
3 | RandomInput::RandomInput(int val)
4 | {
5 | count = std::rand() % val + 100;
6 | }
--------------------------------------------------------------------------------
/sdlms/Components/RandomInput.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 |
4 | // 随机产生按键输出组件
5 | class RandomInput : public Component
6 | {
7 | private:
8 | unsigned int count = 0;
9 | unsigned int tick = 0;
10 |
11 | public:
12 | RandomInput(int val = 60);
13 | auto get_count() { return count; };
14 | auto get_tick() { return tick; };
15 | void set_count(const unsigned int value) { count = value; };
16 | void set_tick(const unsigned int value) { tick = value; };
17 | };
--------------------------------------------------------------------------------
/sdlms/Components/RelativeTransform.cpp:
--------------------------------------------------------------------------------
1 | #include "RelativeTransform.h"
2 |
3 | RelativeTransform::RelativeTransform(Transform *tr) : tr(tr), position({0.0f, 0.0f}), rotation(0), flip(0) {}
4 | RelativeTransform::RelativeTransform(Transform *tr, SDL_FPoint p, int flip) : tr(tr), position(p), rotation(0), flip(flip) {}
5 | RelativeTransform::RelativeTransform(Transform *tr, float x, float y, int flip) : tr(tr), position({x, y}), rotation(0), flip(flip) {}
6 | RelativeTransform::~RelativeTransform() {}
7 |
8 | float RelativeTransform::get_rotation() const
9 | {
10 | return rotation;
11 | }
12 |
13 | int RelativeTransform::get_flip() const
14 | {
15 | return flip;
16 | }
17 |
18 | void RelativeTransform::set_position(const SDL_FPoint &value)
19 | {
20 | position = value;
21 | }
22 | SDL_FPoint RelativeTransform::get_position() const
23 | {
24 | return position;
25 | }
26 |
27 | void RelativeTransform::set_rotation(const float &value)
28 | {
29 | rotation = value;
30 | }
31 |
32 | void RelativeTransform::set_flip(const int value)
33 | {
34 | flip = value;
35 | }
--------------------------------------------------------------------------------
/sdlms/Components/RelativeTransform.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "Components/Component.h"
4 | #include "Transform.h"
5 |
6 | class RelativeTransform : public Component
7 | {
8 | private:
9 | SDL_FPoint position;
10 | float rotation;
11 | int flip;
12 | Transform *tr = nullptr;
13 |
14 | public:
15 | RelativeTransform(Transform *tr);
16 | RelativeTransform(Transform *tr, SDL_FPoint p, int flip = 0);
17 | RelativeTransform(Transform *tr, float x, float y, int flip = 0);
18 | ~RelativeTransform();
19 |
20 | SDL_FPoint get_position() const;
21 | float get_rotation() const;
22 | int get_flip() const;
23 | auto get_tr() { return tr; };
24 |
25 | void set_position(const SDL_FPoint &value);
26 | void set_rotation(const float &value);
27 | void set_flip(const int value);
28 | void set_x(const float value) { position.x = value; };
29 | void set_y(const float value) { position.y = value; };
30 | };
31 |
--------------------------------------------------------------------------------
/sdlms/Components/Sound.cpp:
--------------------------------------------------------------------------------
1 | #include "Sound.h"
2 |
3 | extern "C"
4 | {
5 | #include
6 | #include
7 | #include
8 | #include
9 | }
10 |
11 | Sound *Sound::load(wz::Node *node)
12 | {
13 | // 从map缓存中获取对象
14 | if (sound_map.contains(node))
15 | {
16 | return sound_map[node];
17 | }
18 | else
19 | {
20 | return new Sound(node);
21 | }
22 | }
23 |
24 | Sound::Sound(wz::Node *node)
25 | {
26 | if (node != nullptr)
27 | {
28 | if (node->type == wz::Type::UOL)
29 | {
30 | node = dynamic_cast *>(node)->get_uol();
31 | }
32 |
33 | auto sound = dynamic_cast *>(node);
34 | auto data = sound->get_raw_data();
35 |
36 | struct buffer_data
37 | {
38 | uint8_t *ptr;
39 | size_t size; ///< size left in the buffer
40 | } bd{data.data(), data.size()};
41 |
42 | auto avio_ctx_buffer = av_malloc(0x1000);
43 | AVIOContext *ioCtx = avio_alloc_context(
44 | (uint8_t *)avio_ctx_buffer, 0x1000,
45 | 0, &bd,
46 | [](void *opaque, uint8_t *buf, int buf_size) -> int
47 | {
48 | struct buffer_data *bd = (struct buffer_data *)opaque;
49 | buf_size = FFMIN(buf_size, bd->size);
50 |
51 | if (!buf_size)
52 | return AVERROR_EOF;
53 |
54 | /* copy internal buffer data to buf */
55 | memcpy(buf, bd->ptr, buf_size);
56 | bd->ptr += buf_size;
57 | bd->size -= buf_size;
58 |
59 | return buf_size;
60 | },
61 | NULL, NULL);
62 |
63 | // 打开输入文件并读取音频流信息
64 | AVFormatContext *formatContext = avformat_alloc_context();
65 | formatContext->pb = ioCtx;
66 |
67 | if (avformat_open_input(&formatContext, nullptr, nullptr, nullptr) != 0)
68 | {
69 | // 处理打开文件失败的情况
70 | return;
71 | }
72 | if (avformat_find_stream_info(formatContext, nullptr) < 0)
73 | {
74 | // 处理找不到音频流信息的情况
75 | return;
76 | }
77 |
78 | const AVCodec *codec;
79 | int audioStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
80 | if (audioStreamIndex == -1 || !codec)
81 | {
82 | // 打开音频解码器并分配解码上下文
83 | // 处理找不到音频流的情况
84 | return;
85 | }
86 | AVCodecParameters *codecParameters = formatContext->streams[audioStreamIndex]->codecpar;
87 |
88 | AVCodecContext *codecContext = avcodec_alloc_context3(codec);
89 | if (!codecContext)
90 | {
91 | // 处理无法分配解码上下文的情况
92 | return;
93 | }
94 | if (avcodec_parameters_to_context(codecContext, codecParameters) < 0)
95 | {
96 | // 处理无法设置解码器参数的情况
97 | return;
98 | }
99 | if (avcodec_open2(codecContext, codec, nullptr) < 0)
100 | {
101 | // 处理无法打开解码器的情况
102 | return;
103 | }
104 |
105 | // 解码并存储PCM数据
106 | std::vector pcmData;
107 | // 解码音频帧
108 | AVPacket *packet = av_packet_alloc();
109 | AVFrame *frame = av_frame_alloc();
110 |
111 | SwrContext *swrContext = swr_alloc();
112 | // 音频格式 输入的采样设置参数
113 | AVSampleFormat inFormat = codecContext->sample_fmt;
114 | // 出入的采样格式
115 | AVSampleFormat outFormat = AV_SAMPLE_FMT_S16;
116 | // 输入采样率
117 | int inSampleRate = codecContext->sample_rate;
118 | // 输出采样率
119 | int outSampleRate = inSampleRate;
120 |
121 | swr_alloc_set_opts2(&swrContext, &codecContext->ch_layout, outFormat, outSampleRate,
122 | &codecContext->ch_layout, inFormat, inSampleRate, 0, NULL);
123 |
124 | if (swr_init(swrContext) < 0)
125 | {
126 | return;
127 | }
128 |
129 | int outChannelCount = codecContext->ch_layout.nb_channels;
130 |
131 | uint8_t *out_buffer = (uint8_t *)av_malloc(2 * outSampleRate);
132 | while (av_read_frame(formatContext, packet) >= 0)
133 | {
134 | if ((avcodec_send_packet(codecContext, packet)) >= 0)
135 | {
136 | auto error = avcodec_receive_frame(codecContext, frame);
137 | if (error == AVERROR(EAGAIN) || error == AVERROR_EOF || error < 0)
138 | {
139 | return;
140 | }
141 | else if (error == 0)
142 | {
143 | swr_convert(swrContext, &out_buffer, outSampleRate * 2,
144 | (const uint8_t **)frame->data,
145 | frame->nb_samples);
146 | int size = av_samples_get_buffer_size(NULL, outChannelCount,
147 | frame->nb_samples,
148 | AV_SAMPLE_FMT_S16, 1);
149 |
150 | std::vector out(out_buffer, out_buffer + size);
151 |
152 | pcmData.insert(pcmData.end(), out.begin(), out.end());
153 |
154 | av_frame_unref(frame);
155 | }
156 | av_packet_unref(packet);
157 | }
158 | }
159 | av_freep(&out_buffer);
160 |
161 | av_frame_free(&frame);
162 | av_packet_free(&packet);
163 |
164 | swr_free(&swrContext);
165 |
166 | avcodec_free_context(&codecContext);
167 | avformat_close_input(&formatContext);
168 |
169 | pcm_data = pcmData;
170 | freq = outSampleRate;
171 | offset = 0;
172 | delay = 0;
173 | sound_map[node] = this;
174 | }
175 | }
--------------------------------------------------------------------------------
/sdlms/Components/Sound.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Component.h"
3 | #include "wz/Property.hpp"
4 |
5 | class Sound : public Component
6 | {
7 | public:
8 | static Sound *load(wz::Node *node);
9 | static inline std::map sound_map;
10 |
11 | private:
12 | Sound(wz::Node *node);
13 | Sound(){};
14 |
15 | public:
16 | constexpr auto get_pcm_data() { return &pcm_data; }
17 | constexpr auto get_freq() { return freq; }
18 | constexpr auto get_offset() { return offset; }
19 | constexpr auto get_delay() { return delay; }
20 | constexpr auto get_play() { return play; }
21 |
22 | void set_offset(unsigned int val) { offset = val; }
23 | void set_play(bool val) { play = val; }
24 |
25 | public:
26 | std::vector pcm_data;
27 | unsigned int freq;
28 | unsigned int offset; // 记录当前播放的位置
29 | unsigned int delay; // 播放声音后下次播放的间隔,若为-1,则表示播放1次
30 | bool play = false; // 当前是否播放
31 | };
32 |
--------------------------------------------------------------------------------
/sdlms/Components/Sprite.cpp:
--------------------------------------------------------------------------------
1 | #include "Sprite.h"
2 | #include "Core/Window.h"
3 |
4 | Sprite::Sprite(wz::Node *node, int alpha)
5 | {
6 | if (node->type == wz::Type::UOL)
7 | {
8 | node = dynamic_cast *>(node)->get_uol();
9 | }
10 |
11 | auto canvas = dynamic_cast *>(node);
12 | height = canvas->get().height;
13 | width = canvas->get().width;
14 |
15 | auto raw_data = canvas->get_raw_data();
16 | auto format = canvas->get().format + canvas->get().format2;
17 |
18 | auto o = dynamic_cast *>(canvas->get_child(u"origin"));
19 |
20 | auto ox = 0;
21 | auto oy = 0;
22 |
23 | if (o != nullptr)
24 | {
25 | ox = o->get().x;
26 | oy = o->get().y;
27 | }
28 | origin = {ox, oy};
29 |
30 | delay = 100;
31 |
32 | if (node->get_child(u"delay") != nullptr)
33 | {
34 | if (node->get_child(u"delay")->type == wz::Type::String)
35 | {
36 | auto delay_str = dynamic_cast *>(node->get_child(u"delay"))->get();
37 | delay = std::stoi(std::string{delay_str.begin(), delay_str.end()});
38 | }
39 | else if (node->get_child(u"delay")->type == wz::Type::Int)
40 | {
41 | delay = dynamic_cast *>(node->get_child(u"delay"))->get();
42 | }
43 | }
44 |
45 | if (canvas->get_child(u"a0") != nullptr && canvas->get_child(u"a1") != nullptr)
46 | {
47 | if (canvas->get_child(u"a0")->type == wz::Type::Int)
48 | {
49 |
50 | a0 = dynamic_cast *>(canvas->get_child(u"a0"))->get();
51 | }
52 | else
53 | {
54 | auto a0_str = dynamic_cast *>(node->get_child(u"a0"))->get();
55 | a0 = std::stoi(std::string{a0_str.begin(), a0_str.end()});
56 | }
57 | if (canvas->get_child(u"a1")->type == wz::Type::Int)
58 | {
59 | a1 = dynamic_cast *>(canvas->get_child(u"a1"))->get();
60 | }
61 | else
62 | {
63 | auto a1_str = dynamic_cast *>(node->get_child(u"a1"))->get();
64 | a1 = std::stoi(std::string{a1_str.begin(), a1_str.end()});
65 | }
66 | }
67 | a0 = a0 * ((float)alpha / 255);
68 | a1 = a1 * ((float)alpha / 255);
69 |
70 | if (canvas->get_child(u"z") != nullptr)
71 | {
72 | if (canvas->get_child(u"z")->type == wz::Type::Int)
73 | {
74 | z = dynamic_cast *>(canvas->get_child(u"z"))->get();
75 | }
76 | else if (canvas->get_child(u"z")->type == wz::Type::String)
77 | {
78 | z = dynamic_cast *>(canvas->get_child(u"z"))->get();
79 | }
80 | }
81 |
82 | // 图片原始数据,部分格式需要转换
83 | std::vector pixel;
84 |
85 | switch (format)
86 | {
87 | case 1:
88 | {
89 | pixel = raw_data;
90 | format = SDL_PIXELFORMAT_ARGB4444;
91 | texture = SDL_CreateTexture(Window::get_renderer(), format, SDL_TEXTUREACCESS_STATIC, width, height);
92 | SDL_UpdateTexture(texture, NULL, pixel.data(), width * sizeof(Uint16));
93 | SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
94 | break;
95 | }
96 | case 2:
97 | {
98 | pixel = raw_data;
99 | format = SDL_PIXELFORMAT_ARGB8888;
100 | texture = SDL_CreateTexture(Window::get_renderer(), format, SDL_TEXTUREACCESS_STATIC, width, height);
101 | SDL_UpdateTexture(texture, NULL, pixel.data(), width * sizeof(Uint32));
102 | SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
103 | break;
104 | }
105 | case 517: // rgb565压缩缩略图
106 | {
107 | pixel.resize(width * height * 2, 0);
108 | int lineIndex = 0;
109 | for (int j0 = 0, j1 = height / 16; j0 < j1; j0++)
110 | {
111 | int dstIndex = lineIndex;
112 | for (int i0 = 0, i1 = width / 16; i0 < i1; i0++)
113 | {
114 | int idx = (i0 + j0 * i1) * 2;
115 | unsigned char b0 = raw_data[idx];
116 | unsigned char b1 = raw_data[idx + 1];
117 | for (int k = 0; k < 16; k++)
118 | {
119 | pixel[dstIndex++] = b0;
120 | pixel[dstIndex++] = b1;
121 | }
122 | }
123 | for (int k = 1; k < 16; k++)
124 | {
125 | for (int m = 0; m < width * 2; m++)
126 | {
127 | pixel[dstIndex + m] = pixel[lineIndex + m];
128 | }
129 | dstIndex += width * 2;
130 | }
131 | lineIndex += width * 32;
132 | }
133 |
134 | format = SDL_PIXELFORMAT_RGB565;
135 | texture = SDL_CreateTexture(Window::get_renderer(), format, SDL_TEXTUREACCESS_STATIC, width, height);
136 | SDL_UpdateTexture(texture, NULL, pixel.data(), width * sizeof(Uint16));
137 | break;
138 | }
139 | default:
140 | {
141 | break;
142 | }
143 | }
144 | }
145 |
146 | Sprite::Sprite(wz::Node *node, int width, int height, uint8_t type)
147 | {
148 | switch (type)
149 | {
150 | case NameTag:
151 | {
152 | auto w = dynamic_cast *>(node->find_from_path(u"w"));
153 | auto e = dynamic_cast *>(node->find_from_path(u"e"));
154 | auto c = dynamic_cast *>(node->find_from_path(u"c"));
155 |
156 | width = width + w->get().width + e->get().width;
157 | height = std::max(height, w->get().height);
158 | texture = SDL_CreateTexture(Window::get_renderer(), SDL_PIXELFORMAT_ARGB4444, SDL_TEXTUREACCESS_STATIC, width, height);
159 |
160 | SDL_Rect rect{0, 0, w->get().width, w->get().height};
161 | SDL_UpdateTexture(texture, &rect, w->get_raw_data().data(), w->get().width * sizeof(Uint16));
162 |
163 | for (int i = 0; i <= (width - w->get().width - e->get().width) / c->get().width; i++)
164 | {
165 | rect = {w->get().width + i * c->get().width, 0, c->get().width, c->get().height};
166 | SDL_UpdateTexture(texture, &rect, c->get_raw_data().data(), c->get().width * sizeof(Uint16));
167 | }
168 | rect = {width - e->get().width, 0, e->get().width, e->get().height};
169 | SDL_UpdateTexture(texture, &rect, e->get_raw_data().data(), e->get().width * sizeof(Uint16));
170 | SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
171 | this->width = width;
172 | this->height = height;
173 | break;
174 | }
175 | case ChatBallon:
176 | {
177 | auto c = dynamic_cast *>(node->find_from_path(u"c"));
178 | auto e = dynamic_cast *>(node->find_from_path(u"e"));
179 | auto ne = dynamic_cast *>(node->find_from_path(u"ne"));
180 | auto n = dynamic_cast *>(node->find_from_path(u"n"));
181 | auto nw = dynamic_cast *>(node->find_from_path(u"nw"));
182 | auto w = dynamic_cast *>(node->find_from_path(u"w"));
183 | auto sw = dynamic_cast *>(node->find_from_path(u"sw"));
184 | auto s = dynamic_cast *>(node->find_from_path(u"s"));
185 | auto se = dynamic_cast *>(node->find_from_path(u"se"));
186 | auto arrow = dynamic_cast *>(node->find_from_path(u"arrow"));
187 |
188 | width += nw->get().width + ne->get().width;
189 |
190 | height += nw->get().height + sw->get().height;
191 | auto line = std::ceil((float)height / (float)c->get().height);
192 | height = line * c->get().height;
193 |
194 | texture = SDL_CreateTexture(Window::get_renderer(), SDL_PIXELFORMAT_ARGB4444, SDL_TEXTUREACCESS_STATIC, width, height + 8);
195 | SDL_Rect rect;
196 |
197 | for (int x = 0; x <= width; x += c->get().width)
198 | {
199 | for (int y = 0; y <= height - c->get().height; y += c->get().height)
200 | {
201 | rect = {x, y, c->get().width, c->get().height};
202 | SDL_UpdateTexture(texture, &rect, c->get_raw_data().data(), c->get().width * sizeof(Uint16));
203 | }
204 | }
205 |
206 | for (int i = nw->get().height; i <= height - w->get().height; i += w->get().height)
207 | {
208 | rect = {0, i, w->get().width, w->get().height};
209 | SDL_UpdateTexture(texture, &rect, w->get_raw_data().data(), w->get().width * sizeof(Uint16));
210 |
211 | rect = {width - e->get().width, i, e->get().width, e->get().height};
212 | SDL_UpdateTexture(texture, &rect, e->get_raw_data().data(), e->get().width * sizeof(Uint16));
213 | }
214 |
215 | for (int i = 0; i <= width; i += n->get().width)
216 | {
217 | rect = {i, 0, n->get().width, n->get().height};
218 | SDL_UpdateTexture(texture, &rect, n->get_raw_data().data(), n->get().width * sizeof(Uint16));
219 |
220 | rect = {i, height - s->get().height, s->get().width, s->get().height};
221 | SDL_UpdateTexture(texture, &rect, s->get_raw_data().data(), s->get().width * sizeof(Uint16));
222 | }
223 |
224 | rect = {0, nw->get().height, w->get().width, w->get().height};
225 | SDL_UpdateTexture(texture, &rect, w->get_raw_data().data(), w->get().width * sizeof(Uint16));
226 |
227 | rect = {0, height - sw->get().height - w->get().height, w->get().width, w->get().height};
228 | SDL_UpdateTexture(texture, &rect, w->get_raw_data().data(), w->get().width * sizeof(Uint16));
229 |
230 | rect = {width - e->get().width, nw->get().height, e->get().width, e->get().height};
231 | SDL_UpdateTexture(texture, &rect, e->get_raw_data().data(), e->get().width * sizeof(Uint16));
232 |
233 | rect = {width - e->get().width, height - sw->get().height - e->get().height, e->get().width, e->get().height};
234 | SDL_UpdateTexture(texture, &rect, e->get_raw_data().data(), e->get().width * sizeof(Uint16));
235 |
236 | rect = {0, 0, nw->get().width, nw->get().height};
237 | SDL_UpdateTexture(texture, &rect, nw->get_raw_data().data(), nw->get().width * sizeof(Uint16));
238 |
239 | rect = {0, height - sw->get().height, sw->get().width, sw->get().height};
240 | SDL_UpdateTexture(texture, &rect, sw->get_raw_data().data(), sw->get().width * sizeof(Uint16));
241 |
242 | rect = {width - ne->get().width, 0, ne->get().width, ne->get().height};
243 | SDL_UpdateTexture(texture, &rect, ne->get_raw_data().data(), ne->get().width * sizeof(Uint16));
244 |
245 | rect = {width - se->get().width, height - se->get().height, se->get().width, se->get().height};
246 | SDL_UpdateTexture(texture, &rect, se->get_raw_data().data(), se->get().width * sizeof(Uint16));
247 |
248 | rect = {width / 2 - arrow->get().width / 2, height - arrow->get().height + 8, arrow->get().width - 1, arrow->get().height};
249 | SDL_UpdateTexture(texture, &rect, arrow->get_raw_data().data() + 2, arrow->get().width * sizeof(Uint16));
250 |
251 | SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
252 | this->width = width;
253 | this->height = height;
254 | break;
255 | }
256 | default:
257 | break;
258 | }
259 | }
260 |
261 | Sprite::Sprite(SDL_Texture *texture, int w, int h) : texture(texture), width(w), height(h)
262 | {
263 | }
264 |
265 | Sprite::~Sprite()
266 | {
267 | SDL_DestroyTexture(texture);
268 | }
269 |
--------------------------------------------------------------------------------
/sdlms/Components/Sprite.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include