From 1e4fb02160dd71b7fd3c813052b89c0082979265 Mon Sep 17 00:00:00 2001 From: name Date: Thu, 4 Mar 2021 16:19:46 +0300 Subject: [PATCH] hemh, ~~ kawaii - win --- GameMap.cpp | 17 ++++ GameMap.h | 4 + General.h | 4 + Image.cpp | 11 +++ Image.h | 3 + main.cpp | 226 +++++++++++++++++++++++++++------------------- maps/C.txt | 17 ++++ maps/F.txt | 15 +-- maps/M_OF_M.txt | 6 +- maps/W.txt | 23 +++++ resources/win.png | Bin 0 -> 741 bytes 11 files changed, 224 insertions(+), 102 deletions(-) create mode 100644 maps/C.txt create mode 100644 maps/W.txt create mode 100644 resources/win.png diff --git a/GameMap.cpp b/GameMap.cpp index 0760ca6..48874ee 100644 --- a/GameMap.cpp +++ b/GameMap.cpp @@ -55,6 +55,19 @@ bool GameMap::CanThrowItem(Point pos) return E_TileType::Floor == now_room->gri.TileType(pos.x, pos.y); } +bool GameMap::CheckWin() +{ + auto wp = now_room->gri.win_point; + if (wp == GameRoomInfo::NOT_WIN_POINT)return false; + auto cp = Player::Get().GetCenter(); + + if ((cp.x < 0) && ((cp + Point {TILE_SZ, 0}) / TILE_SZ == wp))return true; + if ((cp.y < 0) && ((cp + Point {0, TILE_SZ}) / TILE_SZ == wp))return true; + if ((cp.x / TILE_SZ >= now_room->gri.map_width) && ((cp + Point {-TILE_SZ, 0}) / TILE_SZ == wp))return true; + if ((cp.y / TILE_SZ >= now_room->gri.map_height) && ((cp + Point {0, -TILE_SZ}) / TILE_SZ == wp))return true; + return false; +} + bool GameMap::CheckChangeMap() { auto center_pos = Player::Get().GetCenter(); @@ -226,6 +239,9 @@ GameMap::GameRoomInfo::GameRoomInfo(char room_type) else if (c == 'K') { tt = GameMap::E_TileType::Floor; keys_pos.emplace_back(Point {.x = i, .y = map_height}); + } else if (c == 'W') { + tt = GameMap::E_TileType::Floor; + win_point = {.x = i, .y = map_height}; } else error("unknown type of tile '" + line.substr(0, 1) + "'"); @@ -286,4 +302,5 @@ GameMap::GameRoomInfo::GameRoomInfo(char room_type) for (int i = 0; i < enemies.size(); i++)enemies[i].first.y = map_height - 1 - enemies[i].first.y; for (int i = 0; i < door_pos.size(); i++)door_pos[i].y = map_height - 1 - door_pos[i].y; for (int i = 0; i < point_in.size(); i++)point_in[i].y = map_height - 1 - point_in[i].y; + win_point.y = map_height - 1 - win_point.y; } diff --git a/GameMap.h b/GameMap.h index 238de37..03eb801 100644 --- a/GameMap.h +++ b/GameMap.h @@ -98,7 +98,9 @@ private: static GameMap *cur_map; GameMap(); + bool CheckWin(); bool CheckChangeMap(); + void EnemiesMove(Point player_pos) { now_room->map_objects.EnemiesMove(player_pos); } bool CanStay(E_CanStayType stay_type, Point pos, Size obj_sz, bool empty_can, int enemy_id) @@ -166,12 +168,14 @@ private: static GameMap *cur_map; static constexpr int R = 2; static constexpr int D = 3; static constexpr Point BAD_IN = Point {-1, -1}; + static constexpr Point NOT_WIN_POINT = Point {-32, -128}; GameRoomInfo(char room_type); std::vector> tile_type{}; std::vector> enemies{}; // point - pos, int - type std::vector door_pos{}; // point - pos std::vector< std::pair> items{}; // point - pos, int - rarity std::vector keys_pos{}; // point - pos + Point win_point = NOT_WIN_POINT; int map_width = -1; int map_height = -1; diff --git a/General.h b/General.h index c7dfbf8..3feafdf 100644 --- a/General.h +++ b/General.h @@ -8,6 +8,10 @@ static constexpr int TILE_SZ = 32; static constexpr int W_WIDTH = 1024; static constexpr int W_HEIGHT = 720; +static constexpr int W2_WIDTH = W_WIDTH / 2; +static constexpr int W2_HEIGHT = W_HEIGHT / 2; +static constexpr int W_DIAG = W_WIDTH * W_WIDTH + W_HEIGHT * W_HEIGHT; +static constexpr int W2_DIAG = W2_WIDTH * W2_WIDTH + W2_HEIGHT * W2_HEIGHT; struct Point { diff --git a/Image.cpp b/Image.cpp index e943c58..69a9b60 100644 --- a/Image.cpp +++ b/Image.cpp @@ -171,6 +171,17 @@ void Image::Draw(Image &canvas, std::function PixFunc) const canvas.SetPixel(x, y, PixFunc(GetPixel(x, y))); } +void Image::Draw(Image &canvas, std::function PixFunc) const +{ + int c_w = Width(); + int c_h = Height(); + + #pragma omp parallel for + for (int y = 0; y < c_h; y++) + for (int x = 0; x < c_w; x++) + canvas.SetPixel(x, y, PixFunc(Point {x, y}, GetPixel(x, y))); +} + void Image::FastDraw(Image &canvas, int lines, int from_line) const { std::memcpy(canvas.data + (from_line * canvas.width), data, canvas.width * lines * sizeof(Pixel)); diff --git a/Image.h b/Image.h index c356f89..1d1eb34 100644 --- a/Image.h +++ b/Image.h @@ -46,6 +46,8 @@ inline bool operator< (const Pixel a, const Pixel b) constexpr Pixel backgroundColor{0, 0, 0, 0}; +constexpr Pixel WHITE_COLOR{255, 255, 255, 255}; +constexpr Pixel KW_COLOR{210, 255, 255, 255}; enum class E_ImgRotation { Rot_90 }; @@ -107,6 +109,7 @@ struct Image void FastDraw(Image &canvas, int lines, int from_line = 0) const; void Draw(Image &canvas, std::function PixFunc) const; + void Draw(Image &canvas, std::function PixFunc) const; /// chnage image : image[x,y] = PixFunc(image[x,y]) /// if we know that dif color on that image few then we can hash PixFunc result value diff --git a/main.cpp b/main.cpp index d92b719..1c64ba3 100644 --- a/main.cpp +++ b/main.cpp @@ -153,7 +153,7 @@ int initGL() return 0; } -Pixel lin_interp(Pixel from, Pixel to, double proc) +inline Pixel lin_interp(Pixel from, Pixel to, double proc) { uint8_t r = (uint8_t)(from.r + (to.r - from.r) * proc); uint8_t g = (uint8_t)(from.g + (to.g - from.g) * proc); @@ -171,6 +171,32 @@ Pixel only_r_color(Pixel from, double proc) return Pixel {r,g,b,a}; } +Pixel win_fn_backup(Point p, Pixel from, double proc) +{ + double white_r = (1 - proc) * W2_DIAG; + + int d = 0; + if (p.x < W2_WIDTH) d += (W2_WIDTH - p.x) * (W2_WIDTH - p.x); + if (p.x > W2_WIDTH) d += (p.x - W2_WIDTH) * (p.x - W2_WIDTH); + if (p.y < W2_HEIGHT) d += (W2_HEIGHT - p.y) * (W2_HEIGHT - p.y); + if (p.y > W2_HEIGHT) d += (p.y - W2_HEIGHT) * (p.y - W2_HEIGHT); + if (d > white_r)return KW_COLOR; + return from; +} + +Pixel win_fn(Point p, Pixel from, double proc) +{ + double white_r = proc * W2_DIAG; + + int d = 0; + if (p.x < W2_WIDTH) d += (W2_WIDTH - p.x) * (W2_WIDTH - p.x); + if (p.x > W2_WIDTH) d += (p.x - W2_WIDTH) * (p.x - W2_WIDTH); + if (p.y < W2_HEIGHT) d += (W2_HEIGHT - p.y) * (W2_HEIGHT - p.y); + if (p.y > W2_HEIGHT) d += (p.y - W2_HEIGHT) * (p.y - W2_HEIGHT); + if (d <= white_r)return KW_COLOR; + return lin_interp(from, KW_COLOR, white_r / d); +} + void Image_Draw_SpeedUp_Die(Image& screen_save, Image &canvas, double proc) { int c_w = screen_save.Width(); @@ -188,42 +214,41 @@ void Image_Draw_SpeedUp_Die(Image& screen_save, Image &canvas, double proc) } } -int main(int argc, char** argv) +int main(int argc, char **argv) { if (!glfwInit())return -1; -// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); -// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); -// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "task1 base project", nullptr, nullptr); - if (window == nullptr) - { + GLFWwindow *window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "task1 base project", nullptr, nullptr); + if (window == nullptr) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } - - glfwMakeContextCurrent(window); - glfwSetKeyCallback (window, OnKeyboardPressed); - glfwSetCursorPosCallback (window, OnMouseMove); - glfwSetMouseButtonCallback(window, OnMouseButtonClicked); - glfwSetScrollCallback (window, OnMouseScroll); + glfwMakeContextCurrent(window); + + glfwSetKeyCallback(window, OnKeyboardPressed); + glfwSetCursorPosCallback(window, OnMouseMove); + glfwSetMouseButtonCallback(window, OnMouseButtonClicked); + glfwSetScrollCallback(window, OnMouseScroll); - if(initGL() != 0) + if (initGL() != 0) return -1; - - //Reset any OpenGL errors which could be present for some reason + + //Reset any OpenGL errors which could be present for some reason GLenum gl_error = glGetError(); while (gl_error != GL_NO_ERROR) gl_error = glGetError(); std::srand(std::time(nullptr)); - GameMap gmap{}; - + GameMap gmap {}; + LiveObjSprite player_img {HERO_0, SpritePixSz{16}, 125, 2}; Player player {gmap.GetPos(GameMap::E_MapPos::Center, Size{.w = 30, .h = 32}), player_img}; @@ -239,80 +264,95 @@ int main(int argc, char** argv) glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); GL_CHECK_ERRORS; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL_CHECK_ERRORS; - double sec = GameTime::Now().GetTime(); - int frames = 0; - - bool is_alive = true; - Image for_die = Image::Image(0, 0, 0); - - double die_time = 0; - double die_duration = 3; - Player::E_DieType die_type; - bool last_die_draw = false; - - while (!glfwWindowShouldClose(window)) { - GameTime::Now().SetCur(glfwGetTime()); - - if (GameTime::Now().GetTime() - sec > 1) { - sec = GameTime::Now().GetTime(); - std::cout << "fps : " << frames << std::endl; - frames = 0; - } - frames++; - - glfwPollEvents(); - - - if (is_alive) { - - gmap.CheckChangeMap();//TODO: add if(...) for effect - gmap.EnemiesMove(player.GetCenter()); - - gmap.Draw(screenBuffer); - - processPlayerMovement(player); - is_alive = !player.GetIsDied(); - - if (!is_alive) { // die - for_die = Image {screenBuffer}; - die_time = GameTime::Now().GetTime(); - die_type = player.GetDiedType(); - } - else { - player.Draw(screenBuffer); - player.InventoryDraw(screenBuffer); - } - } - if(!is_alive) { - double proc = GameTime::Now().GetSecAfter(die_time) / die_duration; - if (proc >= 1) { - if (last_die_draw) break; - last_die_draw = true; - } - - if(die_type == Player::E_DieType::Kill) - for_die.Draw(screenBuffer, [&](auto x) {return only_r_color(x, proc); }); - else if (die_type == Player::E_DieType::EmptyStay) - for_die.Draw(screenBuffer, [&](auto x) {return lin_interp(x, Pixel {27, 20, 27, 255}, proc); }); - //Image_Draw_SpeedUp_Die(for_die, screenBuffer, proc); - - player.DieDraw(screenBuffer, proc); - } - SpriteManager::Get().DrawDoor(screenBuffer, {32, 32}, E_Dir::UP); - SpriteManager::Get().DrawDoor(screenBuffer, {32, 64}, E_Dir::DOWN); - SpriteManager::Get().DrawDoor(screenBuffer, {32, 64+32}, E_Dir::LEFT); - SpriteManager::Get().DrawDoor(screenBuffer, {32, 128}, E_Dir::RIGHT); - /*TODO:DEL +++*/ - //auto pos = player.GetPos(); - //screenBuffer.SetPixel(pos.x + 12, pos.y + 1, Pixel {.r = 255, .g = 0, .b = 0, .a = 255,}); - //screenBuffer.SetPixel(pos.x + 19, pos.y + 1, Pixel {.r = 255, .g = 0, .b = 0, .a = 255,}); - /*TODO:DEL ---*/ - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_CHECK_ERRORS; - glDrawPixels(WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, screenBuffer.Data()); GL_CHECK_ERRORS; - - glfwSwapBuffers(window); - } + double sec = GameTime::Now().GetTime(); + int frames = 0; + + bool is_alive = true; + Image for_die = Image::Image(0, 0, 0); + + double die_time = 0; + double die_duration = 3; + Player::E_DieType die_type; + bool last_die_draw = false; + + bool win = false; + double win_time = 0; + const double win_duration = 3; + Image win_img {PATH + "win.png"}; + + while (!glfwWindowShouldClose(window)) { + GameTime::Now().SetCur(glfwGetTime()); + + if (GameTime::Now().GetTime() - sec > 1) { + sec = GameTime::Now().GetTime(); + std::cout << "fps : " << frames << std::endl; + frames = 0; + } + frames++; + + glfwPollEvents(); + + + if (!win) { + win = gmap.CheckWin(); + if (win) { + for_die = Image {screenBuffer}; + win_time = GameTime::Now().GetTime(); + } + } + + if (!win && is_alive) { + gmap.CheckChangeMap();//TODO: add if(...) for effect + gmap.EnemiesMove(player.GetCenter()); + + gmap.Draw(screenBuffer); + + processPlayerMovement(player); + is_alive = !player.GetIsDied(); + + if (!is_alive) { // die + for_die = Image {screenBuffer}; + die_time = GameTime::Now().GetTime(); + die_type = player.GetDiedType(); + } else { + player.Draw(screenBuffer); + player.InventoryDraw(screenBuffer); + } + } + if (!is_alive) { + double proc = GameTime::Now().GetSecAfter(die_time) / die_duration; + if (proc >= 1) { + if (last_die_draw) break; + last_die_draw = true; + } + + if (die_type == Player::E_DieType::Kill) + for_die.Draw(screenBuffer, [&](auto x) {return only_r_color(x, proc); }); + else if (die_type == Player::E_DieType::EmptyStay) + for_die.Draw(screenBuffer, [&](auto x) {return lin_interp(x, Pixel {27, 20, 27, 255}, proc); }); + //Image_Draw_SpeedUp_Die(for_die, screenBuffer, proc); + + player.DieDraw(screenBuffer, proc); + } + + if (win) { + double proc = GameTime::Now().GetSecAfter(win_time) / win_duration; + if (proc >= 1)break; + for_die.Draw(screenBuffer, [&](auto pos, auto pix) {return win_fn(pos, pix, proc); }); + win_img.Draw(screenBuffer, Point {.x = (W_WIDTH - win_img.Width()) / 2, .y = (W_HEIGHT - win_img.Height()) / 2}, true); + + } + /*TODO:DEL +++*/ + //auto pos = player.GetPos(); + //screenBuffer.SetPixel(pos.x + 12, pos.y + 1, Pixel {.r = 255, .g = 0, .b = 0, .a = 255,}); + //screenBuffer.SetPixel(pos.x + 19, pos.y + 1, Pixel {.r = 255, .g = 0, .b = 0, .a = 255,}); + /*TODO:DEL ---*/ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_CHECK_ERRORS; + glDrawPixels(WINDOW_WIDTH, WINDOW_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, screenBuffer.Data()); GL_CHECK_ERRORS; + + glfwSwapBuffers(window); + } glfwTerminate(); return 0; diff --git a/maps/C.txt b/maps/C.txt new file mode 100644 index 0000000..2e73a6a --- /dev/null +++ b/maps/C.txt @@ -0,0 +1,17 @@ +z+ +################################ +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +#..............................# +################################ +z- \ No newline at end of file diff --git a/maps/F.txt b/maps/F.txt index 467a207..0743fc7 100644 --- a/maps/F.txt +++ b/maps/F.txt @@ -1,27 +1,30 @@ z+ -#############.################## +#############W################## #I.E...#.........#.............# #......#.........#........E. ..# #......#.........#.............# #E.E...#.........#.......... ..# ##.######.#####.####.#.........# -#..........#.I.......#.........# +#..........#.........#.........# #... ....#.........#####.##### -# ... .....#..I......#.........# -#..........#..I......#.... ..#.# +# ... .....#.........#.........# +#..........#.........#.... ..#.# O. ..E.....#.........#... ...... ####...###########.####........# #.........#..........#.........# #.........#..........#.........# -#...IIIII........E...#.E.....E.# +#...I.I..........E...#.E.....E.# #.........#..........#.... ....# #.........#..........#....K....# ###########.#################### z- +/ it's comment + /E: 0, 0, 0, 0, 0, 0, 0, 0 E: 1, 0, 1, 1, 1, 0, 0, 0 -I: 2, 1, 2, 3, 0, 0, 0, 1, 1 +///I: 2, 1, 2, 3, 0, 0, 0, 1, 1 +I: 2, 0, 0 /I: - rarity of Items in the same order as they stay on map diff --git a/maps/M_OF_M.txt b/maps/M_OF_M.txt index 8d885bd..29d83e8 100644 --- a/maps/M_OF_M.txt +++ b/maps/M_OF_M.txt @@ -1,6 +1,6 @@ ##### -##### -##FAB -##### +###ACW +##FAB# +###### ##### diff --git a/maps/W.txt b/maps/W.txt new file mode 100644 index 0000000..a2e09df --- /dev/null +++ b/maps/W.txt @@ -0,0 +1,23 @@ +z+ +################################ +#.I .................. .... ...# +#... .........#.. ..E..... . ..W +# . ....####.#..... .. .#...# +#...... ... .... .. ..........# +#. .. ........#... .. ...E...# +#. .... ...#I.... ..... .......# +#. .E......#E ........#.. ....# +.. .....E..####.. .....# ...I..# +#. ........#....... ...#.......# +# ...### #..... . .E.#.......# +#.......#.E...... ........E....# +#...#...#.... . .... ..E.....# +#............ .I ..............# +##############.################# +z- + +E: 1, 0, 1, 0, 1, 1, 0, 0, 0 +I: 3, 0, 1, 2 + + +/W mean win (exit) diff --git a/resources/win.png b/resources/win.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f707e4e535e12ee06c3eb1b8be48cc4c885a17 GIT binary patch literal 741 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0(wbAK~!i%?Uzw* z!!Qg(cY$4IXWChZ-71>`DPSDRmK{0Sf_^--rDalKfdYM7mgQDHzTQ87`Ic99{@0-5 zRX|y)^_=G%F>8inGxNkfIiSomLoRJ)*Fy%9>Z0hOCrl8L0R4vV<8~2Vq7C z0{;K5Ea4!`3KBBCTlX`wkb^KQNC5BCWwm@FGb2!OMi_Wz6?S=90u^TjW_h-J;QW@t z(n7)Wv|r5wa;_^(fZ&t|%<`%MIn%PJC_s4Y+gxGihR&RNh|Zi{mg>#>5vV9=z#%+( zZbau=s81wE{%&o5xfIJkwSz!Kp$OWAz*+UbAk4Wl5x}RXFxw5O?i+!Mh8VK|&~dTD z5~6u$Jw$w9rYuWzW7C*N1S%R3vIT%pRb&fB4r4^FV43Gm^K3V zxL%PN1m=f!qap$U_6_dBi?nQlIHk>tb2ccpKgwP;3KUJ0h zUQHjE4duc7@Qze0X$8Ug9fgInbUx(mLB$dca+lMyQ;P^$J{}qVRO}^V5h2UR1N?`* zso0Ayvck@zsK=DTvb?Ey2U!o~k>yXtJIHzuL0eG*oA;pNQ?Y_ZiZZD9!iS14JeIc~ XF-Bbnl=Cbn00000NkvXXu0mjfR=h@j literal 0 HcmV?d00001