diff --git a/android-project/app/build.gradle b/android-project/app/build.gradle index 7e2a3fd..05e657e 100644 --- a/android-project/app/build.gradle +++ b/android-project/app/build.gradle @@ -17,8 +17,8 @@ android { } minSdkVersion 24 targetSdkVersion 34 - versionCode 1 - versionName "1.0" + versionCode 3 + versionName "1.3" externalNativeBuild { cmake { arguments "-DANDROID_STL=c++_shared", "-DBUILD_TYPE=Release" diff --git a/imgui.ini b/imgui.ini index 4d2523d..2dca3b8 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,21 +1,21 @@ [Window][Debug##Default] Pos=60,60 -Size=400,400 +Size=411,334 Collapsed=0 [Window][State] Pos=10,10 -Size=150,32 +Size=150,48 Collapsed=0 [Window][Controller] -Pos=20,648 -Size=576,378 +Pos=20,480 +Size=450,280 Collapsed=0 [Window][Rotate] -Pos=1526,10 -Size=384,1026 +Pos=1190,10 +Size=300,760 Collapsed=0 [Window][Menu] diff --git a/res/fonts/default.ttf b/res/fonts/default.ttf new file mode 100644 index 0000000..9a539dd Binary files /dev/null and b/res/fonts/default.ttf differ diff --git a/res/fonts/droid_sans.ttf b/res/fonts/droid_sans.ttf new file mode 100644 index 0000000..767c63a Binary files /dev/null and b/res/fonts/droid_sans.ttf differ diff --git a/src/engine/engine_opengl.cpp b/src/engine/engine_opengl.cpp index d537158..87fb3cf 100644 --- a/src/engine/engine_opengl.cpp +++ b/src/engine/engine_opengl.cpp @@ -232,13 +232,11 @@ void ImGui_ImplSdlGL3_RenderDrawLists(engine* eng, ImDrawData* draw_data) const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawIdx* idx_buffer_offset = nullptr; - auto vertex_data = - reinterpret_cast( - cmd_list->VtxBuffer.Data); + auto vertex_data = reinterpret_cast( + cmd_list->VtxBuffer.Data); auto vert_count = static_cast(cmd_list->VtxBuffer.size()); - auto vertex_buff = - new vertex_buffer(vertex_data, vert_count); + auto vertex_buff = new vertex_buffer(vertex_data, vert_count); const std::uint16_t* indexes = cmd_list->IdxBuffer.Data; auto index_count = static_cast(cmd_list->IdxBuffer.size()); @@ -249,8 +247,7 @@ void ImGui_ImplSdlGL3_RenderDrawLists(engine* eng, ImDrawData* draw_data) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - auto tex = - static_cast(pcmd->TextureId); + auto tex = static_cast(pcmd->TextureId); eng->render_triangles(vertex_buff, index_buff, tex, @@ -321,8 +318,11 @@ int engine_opengl::initialize(config& cfg) cfg.width = display_mode->w; cfg.height = display_mode->h; #endif - window = static_cast(SDL_CreateWindow( - cfg.app_name, static_cast(cfg.width), static_cast(cfg.height), SDL_WINDOW_OPENGL)); + window = static_cast( + SDL_CreateWindow(cfg.app_name, + static_cast(cfg.width), + static_cast(cfg.height), + SDL_WINDOW_OPENGL)); } std::cout << "Window size: (" << cfg.width << " " << cfg.height << ")" << std::endl; @@ -608,8 +608,10 @@ void engine_opengl::render_triangles(vertex_buffer* vertexes, bind_vertexes(); bind_normal(); - glDrawElements( - GL_TRIANGLES, static_cast(num_vertexes), GL_UNSIGNED_SHORT, start_vertex_index); + glDrawElements(GL_TRIANGLES, + static_cast(num_vertexes), + GL_UNSIGNED_SHORT, + start_vertex_index); GL_CHECK_ERRORS() } void engine_opengl::render_triangles(vertex_buffer* vertexes, @@ -626,8 +628,10 @@ void engine_opengl::render_triangles(vertex_buffer* vertexes, bind_normal(); bind_colors(); - glDrawElements( - GL_TRIANGLES, static_cast(num_vertexes), GL_UNSIGNED_SHORT, start_vertex_index); + glDrawElements(GL_TRIANGLES, + static_cast(num_vertexes), + GL_UNSIGNED_SHORT, + start_vertex_index); GL_CHECK_ERRORS() } void engine_opengl::render_triangles(vertex_buffer* vertexes, @@ -646,8 +650,10 @@ void engine_opengl::render_triangles(vertex_buffer* vertexes, bind_normal(); bind_texture_coords(); - glDrawElements( - GL_TRIANGLES, static_cast(num_vertexes), GL_UNSIGNED_SHORT, start_vertex_index); + glDrawElements(GL_TRIANGLES, + static_cast(num_vertexes), + GL_UNSIGNED_SHORT, + start_vertex_index); GL_CHECK_ERRORS() } @@ -667,8 +673,10 @@ void engine_opengl::render_triangles( bind_texture_coords(); bind_colors(); - glDrawElements( - GL_TRIANGLES, static_cast(num_vertexes), GL_UNSIGNED_SHORT, start_vertex_index); + glDrawElements(GL_TRIANGLES, + static_cast(num_vertexes), + GL_UNSIGNED_SHORT, + start_vertex_index); GL_CHECK_ERRORS() } @@ -687,8 +695,10 @@ void engine_opengl::render_triangles( bind_texture_coords(); bind_colors(); - glDrawElements( - GL_TRIANGLES, static_cast(num_vertexes), GL_UNSIGNED_SHORT, start_vertex_index); + glDrawElements(GL_TRIANGLES, + static_cast(num_vertexes), + GL_UNSIGNED_SHORT, + start_vertex_index); GL_CHECK_ERRORS() } @@ -776,7 +786,7 @@ void engine_opengl::audio_callback(void* engine_ptr, std::fill_n(stream, stream_size, '\0'); - auto e = static_cast(engine_ptr); + auto e = static_cast(engine_ptr); for (audio_buffer* buff : e->audio_output) { @@ -947,8 +957,8 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects(config& cfg) void ImGui_ImplSdlGL3_InvalidateDeviceObjects() { - void* ptr = ImGui::GetIO().Fonts->TexID; - auto texture = reinterpret_cast(ptr); + void* ptr = ImGui::GetIO().Fonts->TexID; + auto texture = reinterpret_cast(ptr); delete g_imgui_shader; g_imgui_shader = nullptr; @@ -1037,15 +1047,15 @@ void ImGui_ImplSdlGL3_Shutdown() void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) { ImGuiIO& io = ImGui::GetIO(); - // Setup display size (every frame to accommodate for window resizing) int w, h; int display_w, display_h; SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSizeInPixels(window, &display_w, &display_h); - io.DisplaySize = ImVec2(float(w), float(h)); - io.DisplayFramebufferScale = ImVec2(w > 0 ? static_cast(display_w) / w : 0.f, - h > 0 ? static_cast(display_h) / h : 0.f); + io.DisplaySize = ImVec2(float(w), float(h)); + io.DisplayFramebufferScale = + ImVec2(w > 0 ? static_cast(display_w) / w : 0.f, + h > 0 ? static_cast(display_h) / h : 0.f); // Setup time step Uint32 time = SDL_GetTicks(); diff --git a/src/game.cpp b/src/game.cpp index d47cba4..10d5058 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4,6 +4,7 @@ game_tetris::game_tetris() { state.is_started = 0; + state.is_restart = 0; state.is_quit = 0; state.is_rotated = 0; state.is_moving = 0; @@ -41,7 +42,7 @@ int game_tetris::initialize(config _cfg) my_engine->play_sound(cfg.sound_background_music, true); window_score_width = 0.1f * cfg.width; - window_score_height = 0.03f * cfg.height; + window_score_height = 0.06f * cfg.height; window_score_x = 10.f; window_score_y = 10.f; @@ -85,27 +86,27 @@ bool game_tetris::event_listener(event& e) e.motion.x < window_rotate_x && !e.mouse.left_clicked) #endif { - if (e.motion.x_rel && state.is_rotated) { - + if (e.motion.x_rel && state.is_rotated) + { if (abs(e.motion.x_rel) > cfg.max_camera_speed_swipe) - e.motion.x_rel = std::copysign(cfg.max_camera_speed_swipe, e.motion.x_rel); + e.motion.x_rel = std::copysign( + cfg.max_camera_speed_swipe, e.motion.x_rel); camera_angle += e.motion.x_rel * M_PI / 300; - } - if (e.motion.y_rel && state.is_rotated) { - + if (e.motion.y_rel && state.is_rotated) + { if (abs(e.motion.y_rel) > cfg.max_camera_speed_swipe) - e.motion.y_rel = std::copysign(cfg.max_camera_speed_swipe, e.motion.y_rel); + e.motion.y_rel = std::copysign( + cfg.max_camera_speed_swipe, e.motion.y_rel); view_height += e.motion.y_rel / 50; if (view_height < min_view_height) view_height = min_view_height; if (view_height > max_view_height) view_height = max_view_height; - } } @@ -220,7 +221,9 @@ void game_tetris::update() void game_tetris::render() { + // ImGui::PushFont(font); ImGui::NewFrame(); + if (!state.is_started && !state.is_restart) { draw_menu(); @@ -236,6 +239,7 @@ void game_tetris::render() draw_ui(); } ImGui::Render(); + // ImGui::PopFont(); my_engine->swap_buffers(); }; void game_tetris::add_figure(figure* fig, texture* tex) @@ -249,7 +253,8 @@ void game_tetris::draw_menu() static const int window_height = 0.2 * cfg.height; static const int window_x = (cfg.width - window_width) / 2; static const int window_y = (cfg.height - window_height) / 2; - static ImVec2 button_size = ImVec2(window_width - 15, window_height / 2 - 15); + static ImVec2 button_size = + ImVec2(window_width - 15, window_height / 2 - 15); ImGui::SetNextWindowSize(ImVec2(window_width, window_height)); ImGui::SetNextWindowPos(ImVec2(window_x, window_y)); @@ -258,6 +263,7 @@ void game_tetris::draw_menu() nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar); + ImGui::SetWindowFontScale(4); if (ImGui::Button("Start", button_size)) { @@ -288,10 +294,11 @@ void game_tetris::draw_restart_menu() nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar); + ImGui::SetWindowFontScale(2.1); ImGui::LabelText("", "Score: %d", score); - if (ImGui::Button("Restart", ImVec2(0.1 * cfg.width, 0.05 * cfg.height))) + if (ImGui::Button("Restart", ImVec2(window_width - 15, 0.05 * cfg.height))) { start_game(); } @@ -299,7 +306,7 @@ void game_tetris::draw_restart_menu() // cfg.height))) // { // } - if (ImGui::Button("Quit", ImVec2(0.09 * cfg.width, 0.05 * cfg.height))) + if (ImGui::Button("Quit", ImVec2(window_width - 15, 0.05 * cfg.height))) { state.is_quit = true; } @@ -316,6 +323,7 @@ void game_tetris::draw_ui() nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar); + ImGui::SetWindowFontScale(2); ImGui::Text("Score: %zu", score); @@ -336,7 +344,7 @@ void game_tetris::draw_ui() ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBackground); - + ImGui::SetWindowFontScale(2); ImGui::SetCursorPos(ImVec2(button_control_size.x + 15, 5)); if (ImGui::Button("Forvard", button_control_size)) @@ -369,16 +377,16 @@ void game_tetris::draw_ui() ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBackground); - - if (ImGui::Button("Rotate X axis", button_rotate_size)) + ImGui::SetWindowFontScale(4); + if (ImGui::Button("Rotate X \naxis", button_rotate_size)) { rotate_around(axis::x); } - if (ImGui::Button("Rotate Y axis", button_rotate_size)) + if (ImGui::Button("Rotate Y \naxis", button_rotate_size)) { rotate_around(axis::y); } - if (ImGui::Button("Rotate Z axis", button_rotate_size)) + if (ImGui::Button("Rotate Z \naxis", button_rotate_size)) { rotate_around(axis::z); } @@ -412,6 +420,7 @@ void game_tetris::render_scene() for (cell* c : cells) { + figure_cube->set_scale(8. / cells_max, 8. / cells_max, 8. / cells_max); figure_cube->set_translate( vector3d(-1. / 2. + (c->get_position().x + 0.5) / cells_max, (c->get_position().z + 0.5) / cells_max, @@ -451,10 +460,38 @@ void game_tetris::lose_game() void game_tetris::add_primitive() { - static float x = 0; - static float y = 0; - uint8_t index = rand() % textures_block.size(); - cell* root_cell = new cell( + static const int x = cells_max / 2; + static const int y = cells_max / 2; + std::vector cells_to_add; + + switch (rand() % 3) + { + case 0: + cells_to_add = gen_primitive_1(x, y); + break; + case 1: + cells_to_add = gen_primitive_2(x, y); + break; + case 2: + cells_to_add = gen_primitive_3(x, y); + break; + case 3: + cells_to_add = gen_primitive_4(x, y); + break; + } + + for (cell* c : cells_to_add) + { + cells.push_back(c); + find_near(c); + } + active_primitive = new primitive(cells_to_add[0]); +} + +std::vector game_tetris::gen_primitive_1(int x, int y) +{ + uint8_t index = rand() % textures_block.size(); + cell* root_cell = new cell( cell::position{ static_cast(x), static_cast(y), cells_max_z }, index); cell* cell_1 = new cell(cell::position{ static_cast(x), @@ -465,22 +502,74 @@ void game_tetris::add_primitive() static_cast(y), cells_max_z }, index); - cells.push_back(root_cell); - cells.push_back(cell_1); - cells.push_back(cell_2); - find_near(root_cell); - find_near(cell_1); - find_near(cell_2); - active_primitive = new primitive(root_cell); - - x += 2; - if (x == cells_max) - { - x = 0; - y += 0.5; - if (y == cells_max) - y = 0; - } + cell* cell_3 = new cell(cell::position{ static_cast(x - 1), + static_cast(y), + cells_max_z }, + index); + return std::vector{ root_cell, cell_1, cell_2, cell_3 }; +} + +std::vector game_tetris::gen_primitive_2(int x, int y) +{ + uint8_t index = rand() % textures_block.size(); + cell* root_cell = new cell( + cell::position{ static_cast(x), static_cast(y), cells_max_z }, + index); + cell* cell_1 = new cell(cell::position{ static_cast(x - 1), + static_cast(y), + cells_max_z }, + index); + cell* cell_2 = new cell(cell::position{ static_cast(x + 1), + static_cast(y), + cells_max_z }, + index); + cell* cell_3 = new cell(cell::position{ static_cast(x + 2), + static_cast(y), + cells_max_z }, + index); + return std::vector{ root_cell, cell_1, cell_2, cell_3 }; +} + +std::vector game_tetris::gen_primitive_3(int x, int y) +{ + uint8_t index = rand() % textures_block.size(); + cell* root_cell = new cell( + cell::position{ static_cast(x), static_cast(y), cells_max_z }, + index); + cell* cell_1 = new cell(cell::position{ static_cast(x), + static_cast(y), + cells_max_z - 1 }, + index); + cell* cell_2 = new cell(cell::position{ static_cast(x + 1), + static_cast(y), + cells_max_z }, + index); + cell* cell_3 = new cell(cell::position{ static_cast(x + 2), + static_cast(y), + cells_max_z }, + index); + return std::vector{ root_cell, cell_1, cell_2, cell_3 }; +} + +std::vector game_tetris::gen_primitive_4(int x, int y) +{ + uint8_t index = rand() % textures_block.size(); + cell* root_cell = new cell( + cell::position{ static_cast(x), static_cast(y), cells_max_z }, + index); + cell* cell_1 = new cell(cell::position{ static_cast(x), + static_cast(y), + cells_max_z - 1 }, + index); + cell* cell_2 = new cell(cell::position{ static_cast(x + 1), + static_cast(y), + cells_max_z }, + index); + cell* cell_3 = new cell(cell::position{ static_cast(x + 1), + static_cast(y), + cells_max_z - 1 }, + index); + return std::vector{ root_cell, cell_1, cell_2, cell_3 }; } bool game_tetris::move_active_cells(direction dir) @@ -578,7 +667,7 @@ bool game_tetris::rotate_around(axis ax) new_pos = get_rotate_pos(cur_pos) + center_position; if (new_pos.x < 0 || new_pos.y < 0 || new_pos.z < 0 || - (new_pos.x > cells_max - 1) || (new_pos.y > cells_max - 1)) + (new_pos.x > cells_max - 1) || (new_pos.y > cells_max - 1)) { return false; } @@ -702,6 +791,7 @@ void game_tetris::check_layer() } } -bool game_tetris::get_quit_state() const { +bool game_tetris::get_quit_state() const +{ return state.is_quit; } diff --git a/src/game.h b/src/game.h index 43b382c..29c590a 100644 --- a/src/game.h +++ b/src/game.h @@ -23,8 +23,8 @@ enum class direction enum class axis { - x, - y, + x, + y, z }; @@ -85,11 +85,11 @@ class cell { neighboors[static_cast(dir)] = c; } - uint8_t get_texture_index() { return texture_index; } - bool get_moving() { return is_moving; } - void set_moving(bool state) { is_moving = state; } - position get_position() { return pos; } - void set_position(position _pos) { pos = _pos; } + uint8_t get_texture_index() { return texture_index; } + bool get_moving() { return is_moving; } + void set_moving(bool state) { is_moving = state; } + position get_position() { return pos; } + void set_position(position _pos) { pos = _pos; } private: position pos; @@ -113,7 +113,7 @@ class primitive bool is_active = true; }; -constexpr int cells_max = 8; +constexpr int cells_max = 5; constexpr int cells_max_z = 14; constexpr int cells_z_lose = 10; @@ -151,9 +151,13 @@ class game_tetris : public game void draw_ui(); void render_scene(); - void start_game(); - void lose_game(); - void add_primitive(); + void start_game(); + void lose_game(); + void add_primitive(); + std::vector gen_primitive_1(int x, int y); + std::vector gen_primitive_2(int x, int y); + std::vector gen_primitive_3(int x, int y); + std::vector gen_primitive_4(int x, int y); bool move_active_cells(direction dir); bool rotate_around(axis ax); @@ -178,10 +182,10 @@ class game_tetris : public game texture* texture_board = nullptr; std::vector textures_block; - float camera_angle = -M_PI / 2; - float view_height = 1.; - float min_view_height = 1.; - float max_view_height = 1.6; + float camera_angle = -M_PI / 2.f; + float view_height = 1.f; + float min_view_height = 1.f; + float max_view_height = 1.6f * 8.f / cells_max; struct flags { @@ -205,4 +209,6 @@ class game_tetris : public game float window_rotate_height; float window_rotate_x; float window_rotate_y; + + ImFont* font = nullptr; }; \ No newline at end of file