diff --git a/1mGame.vcxproj b/1mGame.vcxproj
index 30df8b9..9aed699 100644
--- a/1mGame.vcxproj
+++ b/1mGame.vcxproj
@@ -56,6 +56,7 @@
WIN32_LEAN_AND_MEAN;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpp20
+ stdc17
Console
@@ -72,6 +73,7 @@
WIN32_LEAN_AND_MEAN;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpp20
+ stdc17
Windows
@@ -85,13 +87,19 @@
+
+
+
+
+
+
diff --git a/1mGame.vcxproj.filters b/1mGame.vcxproj.filters
index 2c7b4ff..46ee765 100644
--- a/1mGame.vcxproj.filters
+++ b/1mGame.vcxproj.filters
@@ -42,5 +42,19 @@
源文件
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+
+
+ 资源文件
+
\ No newline at end of file
diff --git a/BackGround.ixx b/BackGround.ixx
new file mode 100644
index 0000000..b2d7da7
--- /dev/null
+++ b/BackGround.ixx
@@ -0,0 +1,69 @@
+module;
+
+
+export module BackGround;
+import GameObject;
+import Graphics;
+
+export struct BackGround : GameObject
+{
+ static constexpr Rect GroundRect{ 2,104,2402,130 };
+ static constexpr Rect CloudRect{ 166,2,258,29 };
+ float speed = -500.f;
+ Vector2 CloudPosi;
+ virtual void OnStartUp()
+ {
+ imge.rect = GroundRect;
+ Posi = { 0,50 };
+ CloudPosi = { 1050,200 };
+ Size = imge.rect.size();
+ }
+ virtual void OnCleanUp()
+ {
+
+ }
+ virtual void OnUpdate(float delta)
+ {
+ Posi.x += speed * delta;
+ CloudPosi.x += speed * delta * 0.5f;
+ }
+ virtual void OnLaterUpdate(float delta)
+ {
+ if (Posi.x <= -Size.x)
+ {
+ Posi.x += Size.x;
+ }
+ if (CloudPosi.x <= 0 - CloudRect.size().x)
+ {
+ CloudPosi.x = 1050;
+ }
+ }
+ virtual void OnReset() override
+ {
+ Posi.x = 0;
+ }
+ virtual void OnRender() override
+ {
+ Rect dst =
+ {
+ Posi.x - Size.x * Anch.x,
+ Posi.y + Size.y * (1.f - Anch.y),
+ Posi.x + Size.x * (1.f - Anch.x),
+ Posi.y - Size.y * Anch.y,
+ };
+ Graphics::DrawBitMap(imge.bitmap, dst, imge.rect);
+ dst.left += Size.x;
+ dst.right += Size.x;
+ Graphics::DrawBitMap(imge.bitmap, dst, imge.rect);
+
+ auto cloud_size = CloudRect.size();
+ Rect cloud_dst =
+ {
+ CloudPosi.x,
+ CloudPosi.y + cloud_size.y,
+ CloudPosi.x + cloud_size.x,
+ CloudPosi.y,
+ };
+ Graphics::DrawBitMap(imge.bitmap, dst, CloudRect);
+ }
+};
\ No newline at end of file
diff --git a/GameObject.ixx b/GameObject.ixx
index 7d697e4..680a0e9 100644
--- a/GameObject.ixx
+++ b/GameObject.ixx
@@ -36,12 +36,34 @@ public:
Vector2 Anch;
Vector2 Size;
+ Rect getRect() const
+ {
+ return
+ {
+ Posi.x - Size.x * Anch.x,
+ Posi.y - Size.y * Anch.y,
+ Posi.x + Size.x * (1.f - Anch.x),
+ Posi.y + Size.y * (1.f - Anch.y),
+ };
+ }
+
+ bool isPaused = false;
+ void Pause()
+ {
+ isPaused = true;
+ }
+ void Resume()
+ {
+ isPaused = false;
+ }
+
GameObject() {}
virtual void OnStartUp() = 0;
virtual void OnCleanUp() = 0;
virtual void OnUpdate(float delta) = 0;
virtual void OnLaterUpdate(float delta) = 0;
+ virtual void OnReset() {}
virtual void OnRender()
{
diff --git a/Graphics.cpp b/Graphics.cpp
index 504667d..a4d0ca3 100644
--- a/Graphics.cpp
+++ b/Graphics.cpp
@@ -9,8 +9,6 @@ module Graphics;
using namespace D2D1;
using namespace ::Microsoft::WRL;
-constexpr D2D1_RECT_F SteveRect{ 1678,2,1766,96 };
-
ComPtr Graphics::RT = nullptr;
ComPtr Graphics::wic_factory = nullptr;
Vector2 Graphics::RtSize{};
diff --git a/Input.ixx b/Input.ixx
index 1b3fc98..29d2898 100644
--- a/Input.ixx
+++ b/Input.ixx
@@ -1,20 +1,35 @@
module;
+#include
export module Input;
export class KeyBoard
{
- static bool KeyStatus[256];
+ static bool LastKeyStatus[256];
+ static bool CurrKeyStatus[256];
public:
- static void Update(char keycode, bool status)
+ static void OnKeyMsg(char keycode, bool status)
{
- KeyStatus[keycode] = status;
+ CurrKeyStatus[keycode] = status;
}
static bool GetKey(char keycode)
{
- return KeyStatus[keycode];
+ return CurrKeyStatus[keycode];
+ }
+ static bool GetKeyUp(char keycode)
+ {
+ return LastKeyStatus[keycode] && !CurrKeyStatus[keycode];
+ }
+ static bool GetKeyDown(char keycode)
+ {
+ return !LastKeyStatus[keycode] && CurrKeyStatus[keycode];
+ }
+ static void Flush()
+ {
+ memcpy(LastKeyStatus, CurrKeyStatus, sizeof(CurrKeyStatus));
}
};
-bool KeyBoard::KeyStatus[256]{};
\ No newline at end of file
+bool KeyBoard::LastKeyStatus[256]{};
+bool KeyBoard::CurrKeyStatus[256]{};
\ No newline at end of file
diff --git a/Math.ixx b/Math.ixx
index 9b4227e..c8381e3 100644
--- a/Math.ixx
+++ b/Math.ixx
@@ -1,5 +1,6 @@
module;
#include
+#include
export module Math;
@@ -16,4 +17,19 @@ export
return { right - left, bottom - top };
}
};
+
+ inline bool isIntersection(const Rect& lhs, const Rect& rhs)
+ {
+ auto ox1 = (lhs.left + lhs.right) * 0.5f;
+ auto oy1 = (lhs.top + lhs.bottom) * 0.5f;
+ auto ox2 = (rhs.left + rhs.right) * 0.5f;
+ auto oy2 = (rhs.top + rhs.bottom) * 0.5f;
+
+ auto rx1 = abs(lhs.right - lhs.left) * 0.5f;
+ auto ry1 = abs(lhs.top - lhs.bottom) * 0.5f;
+ auto rx2 = abs(rhs.right - rhs.left) * 0.5f;
+ auto ry2 = abs(rhs.top - rhs.bottom) * 0.5f;
+
+ return ((abs(ox1 - ox2) - (rx1 + rx2)) < -20.f) && ((abs(oy1 - oy2) - (ry1 + ry2)) < -20.f);
+ }
}
\ No newline at end of file
diff --git a/MegaEngine.cpp b/MegaEngine.cpp
index f5ef46e..f99f70a 100644
--- a/MegaEngine.cpp
+++ b/MegaEngine.cpp
@@ -4,7 +4,6 @@ module;
#include
#include
#include
-#include
module MegaEngine;
@@ -34,16 +33,61 @@ void Game::StartUp()
CreateWnd();
Graphics::Init(hwnd);
+ status = Begin;
+
+ image = Texture::LoadFromFile(L"Steve.png");
+
+ steve.imge = image;
+ obs.imge = image;
+ score.imge = image;
+ background.imge = image;
+
steve.OnStartUp();
-
+ obs.OnStartUp();
+ score.OnStartUp();
+ background.OnStartUp();
}
-
+bool vk_space_down = false;
void Game::Update()
{
auto now = steady_clock::now();
delta = duration_cast>(now - last).count();
last = now;
- steve.OnUpdate(delta);
+ switch (status)
+ {
+ case Game::Begin:
+ if (KeyBoard::GetKey(VK_SPACE))
+ status = Running;
+ break;
+ case Game::Running:
+ steve.OnUpdate(delta);
+ obs.OnUpdate(delta);
+ background.OnUpdate(delta);
+ score += obs.speed * delta;
+ score.OnUpdate(delta);
+ if (isIntersection(steve.getRect(), obs.getRect()))
+ {
+ status = End;
+ steve.status = Steve::Dead;
+ steve.imge.rect = Steve::DeadRect;
+ steve.Size = steve.imge.rect.size();
+ }
+ break;
+ case Game::End:
+ if (KeyBoard::GetKeyDown(VK_SPACE)) vk_space_down = true;
+ if (vk_space_down && KeyBoard::GetKeyUp(VK_SPACE))
+ {
+ vk_space_down = false;
+ steve.OnReset();
+ obs.OnReset();
+ score.OnReset();
+ background.OnReset();
+ status = Begin;
+ }
+ break;
+ default:
+ break;
+ }
}
void Game::Render()
@@ -51,20 +95,41 @@ void Game::Render()
Graphics::BeginDraw();
Graphics::Clear();
+ background.OnRender();
+ obs.OnRender();
steve.OnRender();
-
+ score.OnRender();
+
+ if (status == End)
+ {
+ Rect gameover_rect = { 1294,29,1675,50 };
+ auto size = gameover_rect.size();
+ size.x /= 2; size.y /= 2;
+ Graphics::DrawBitMap(image.bitmap, { 525 - size.x,250 - size.y,525 + size.x,250+size.y }, gameover_rect);
+ }
+
Graphics::Present();
}
void Game::LaterUpdate()
{
- steve.OnLaterUpdate(delta);
+ if (status == Running)
+ {
+ steve.OnLaterUpdate(delta);
+ obs.OnLaterUpdate(delta);
+ background.speed = obs.speed;
+ background.OnLaterUpdate(delta);
+ score.OnLaterUpdate(delta);
+ }
+ KeyBoard::Flush();
}
void Game::CleanUp()
{
steve.OnCleanUp();
-
+ obs.OnCleanUp();
+ score.OnCleanUp();
+ background.OnCleanUp();
Graphics::Finalize();
if (hwnd) DestroyWindow(hwnd);
@@ -163,10 +228,10 @@ LRESULT Game::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch (msg)
{
case WM_KEYDOWN:
- KeyBoard::Update((char)wParam, true);
+ KeyBoard::OnKeyMsg((char)wParam, true);
break;
case WM_KEYUP:
- KeyBoard::Update((char)wParam, false);
+ KeyBoard::OnKeyMsg((char)wParam, false);
break;
case WM_CLOSE:
done = true;
diff --git a/MegaEngine.ixx b/MegaEngine.ixx
index 56608b1..74ed1c9 100644
--- a/MegaEngine.ixx
+++ b/MegaEngine.ixx
@@ -10,6 +10,9 @@ import Input;
import Graphics;
import GameObject;
import Steve;
+import Obstacle;
+import ScoreBoard;
+import BackGround;
using namespace std;
using namespace std::chrono;
@@ -25,10 +28,16 @@ public:
void Run();
private:
+ Texture image;
Steve steve;
+ Obstacle obs;
+ ScoreBoard score;
+ BackGround background;
steady_clock::time_point last;
float delta;
+ enum Status { Begin, Running, End } status;
+
HWND hwnd = nullptr;
bool done = false;
@@ -44,6 +53,9 @@ private:
bool PeekMsg();
bool Done();
+ void GameOver();
+ void ReStart();
+
static LRESULT CALLBACK WndProcSetUp(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WndProcThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
diff --git a/Obstacle.ixx b/Obstacle.ixx
new file mode 100644
index 0000000..d658c8d
--- /dev/null
+++ b/Obstacle.ixx
@@ -0,0 +1,93 @@
+module;
+
+#include
+
+export module Obstacle;
+
+import GameObject;
+
+export struct Obstacle : GameObject
+{
+ static constexpr Rect ObstacleRectList[]
+ {
+ //Small Cactus
+ { 446,2,480,72 },
+ { 480,2,514,72 },
+ { 514,2,548,72 },
+ { 548,2,582,72 },
+ { 582,2,616,72 },
+ { 616,2,650,72 },
+ //Giant Cactus
+ { 652,2,702,102 },
+ { 702,2,750,102 },
+ { 752,2,802,102 },
+ { 802,2,850,102 },
+ //Double Giant Cactus
+ { 652,2,750,102 },
+ { 752,2,850,102 },
+ //Tirple Giant Cactus
+ { 850,2,952,102 },
+ //Qradro Giant Cactus
+ { 802,2,952,102 },
+ //
+ { 260,2,352,82 },
+ { 352,2,444,82 },
+ };
+
+ float speed = -500.f;
+ float time = 0.f;
+ bool isCactus = true;
+ virtual void OnStartUp() override
+ {
+ imge.rect = ObstacleRectList[0];
+ Size = imge.rect.size();
+ Posi = { 1200, 50 };
+ Anch = { 0.5f,0 };
+ Reset();
+ }
+ virtual void OnCleanUp() override
+ {
+
+ }
+ virtual void OnUpdate(float delta) override
+ {
+ time += delta;
+ Posi.x += speed * delta;
+ imge.rect = (int)(time / 0.3) % 2 ? ObstacleRectList[14] : ObstacleRectList[15];
+ }
+ virtual void OnLaterUpdate(float delta) override
+ {
+ if (Posi.x <= -100.f) Reset();
+ }
+ void Start()
+ {
+
+ }
+ std::mt19937 random{std::random_device()()};
+ void Reset()
+ {
+ int index = 14;// random() % 15;
+ if (index == 14)
+ {
+ isCactus = false;
+ Posi.y = 125;
+ }
+ else
+ {
+ isCactus = true;
+ Posi.y = 50;
+ }
+ imge.rect = ObstacleRectList[index];
+ Size = imge.rect.size();
+ speed += -1.f;
+ Posi.x = 1200.f;
+ }
+ virtual void OnReset() override
+ {
+ imge.rect = ObstacleRectList[0];
+ Size = imge.rect.size();
+ Posi = { 1200, 50 };
+ Anch = { 0.5f,0 };
+ Reset();
+ }
+};
\ No newline at end of file
diff --git a/ScoreBoard.ixx b/ScoreBoard.ixx
new file mode 100644
index 0000000..71f430b
--- /dev/null
+++ b/ScoreBoard.ixx
@@ -0,0 +1,100 @@
+module;
+
+#include
+#include
+
+export module ScoreBoard;
+
+import GameObject;
+import Math;
+
+struct Digit : GameObject
+{
+ static constexpr Rect DigitsRectList[]
+ {
+ { 1294,2,1314,23 },
+ { 1314,2,1334,23 },
+ { 1334,2,1354,23 },
+ { 1354,2,1374,23 },
+ { 1374,2,1394,23 },
+ { 1394,2,1414,23 },
+ { 1414,2,1434,23 },
+ { 1434,2,1454,23 },
+ { 1454,2,1474,23 },
+ { 1474,2,1494,23 },
+ };
+
+ char value;
+
+ virtual void OnStartUp()
+ {
+
+ }
+ virtual void OnCleanUp()
+ {
+
+ }
+ virtual void OnUpdate(float delta)
+ {
+
+ }
+ virtual void OnLaterUpdate(float delta)
+ {
+
+ }
+};
+
+export struct ScoreBoard : GameObject
+{
+ float score = 0;
+ std::vector digits;
+ virtual void OnStartUp()
+ {
+ Posi = { 900,400 };
+ }
+ virtual void OnCleanUp()
+ {
+
+ }
+ virtual void OnUpdate(float delta)
+ {
+ auto str = std::to_string(static_cast(score/100.f));
+ digits.resize(str.size());
+ for (size_t i = 0; i < digits.size(); i++)
+ {
+ auto& digit = digits[i];
+ digit.value = str[i] - '0';
+ digit.imge = imge;
+ digit.imge.rect = Digit::DigitsRectList[digit.value];
+ digit.Size = digit.imge.rect.size();
+ digit.Posi = { Posi.x + i * digit.Size.x, Posi.y };
+ }
+ }
+ virtual void OnLaterUpdate(float delta)
+ {
+
+ }
+ virtual void OnRender() override
+ {
+ for (auto& digit : digits)
+ {
+ digit.OnRender();
+ }
+ }
+ virtual void OnReset() override
+ {
+ score = 0;
+ digits.resize(1);
+
+ auto& digit = digits[0];
+ digit.value = 0;
+ digit.imge = imge;
+ digit.imge.rect = Digit::DigitsRectList[digit.value];
+ digit.Size = digit.imge.rect.size();
+ digit.Posi = Posi;
+ }
+ void operator+=(float value)
+ {
+ score += value;
+ }
+};
\ No newline at end of file
diff --git a/Steve.ixx b/Steve.ixx
index bf421b8..3314db6 100644
--- a/Steve.ixx
+++ b/Steve.ixx
@@ -9,31 +9,30 @@ import Input;
export struct Steve : GameObject
{
static constexpr const float ground_height = 50;
- static constexpr const float y_pos = 100;
+ static constexpr const float x_pos = 100;
float a, v, h;
bool jumping = false;
float time = 0.0f;
- Rect IdleRect = { 76, 2, 164, 96 };
- Rect NormalRect = { 1678, 2, 1766, 96 };
- Rect CloseEyeRect = { 1766, 2, 1854, 96 };
- Rect RightRect = { 1854, 2, 1942, 96 };
- Rect LeftRect = { 1942, 2, 2030, 96 };
- Rect BigEyeRect = { 2030, 2, 2118, 96 };
- Rect DeadRect = { 2122, 2, 2202, 96 };
- Rect CrawlingRightRect = { 2203, 2, 2321, 96 };
- Rect CrawlingLeftRect = { 2321, 2, 2439, 96 };
+ static constexpr Rect IdleRect = { 76, 2, 164, 96 };
+ static constexpr Rect NormalRect = { 1678, 2, 1766, 96 };
+ static constexpr Rect CloseEyeRect = { 1766, 2, 1854, 96 };
+ static constexpr Rect RightRect = { 1854, 2, 1942, 96 };
+ static constexpr Rect LeftRect = { 1942, 2, 2030, 96 };
+ static constexpr Rect BigEyeRect = { 2030, 2, 2118, 96 };
+ static constexpr Rect DeadRect = { 2122, 2, 2202, 96 };
+ static constexpr Rect CrawlingRightRect = { 2203, 2, 2321, 96 };
+ static constexpr Rect CrawlingLeftRect = { 2321, 2, 2439, 96 };
enum Status { Idle, Running, Jumping, Freefall, Crawling, Dead } status;
virtual void OnStartUp() override
{
- imge = Texture::LoadFromFile(L"steve.png");
imge.rect = IdleRect;
- Posi = { y_pos, ground_height };
Anch = { 0.5f,0 };
- Size = { 88, 94 };
+ Posi = { x_pos, ground_height };
+ Size = imge.rect.size();
a = v = h = 0.0f;
}
@@ -43,12 +42,14 @@ export struct Steve : GameObject
}
virtual void OnUpdate(float delta) override
{
+ if (isPaused) return;
time += delta;
switch (status)
{
case Steve::Idle:
if (KeyBoard::GetKey(VK_SPACE)) status = Running;
imge.rect = IdleRect;
+ Size = imge.rect.size();
break;
case Steve::Running:
if (KeyBoard::GetKey(VK_SPACE))
@@ -56,10 +57,17 @@ export struct Steve : GameObject
status = Jumping;
break;
}
+ if (KeyBoard::GetKey(VK_DOWN))
+ {
+ status = Crawling;
+ break;
+ }
imge.rect = (int)(time / 0.1) % 2 ? LeftRect : RightRect;
+ Size = imge.rect.size();
break;
case Steve::Jumping:
imge.rect = NormalRect;
+ Size = imge.rect.size();
if ((h < 75 || KeyBoard::GetKey(VK_SPACE)) && h < 150.f)
{
v = 1000.f;
@@ -84,8 +92,15 @@ export struct Steve : GameObject
}
break;
case Steve::Crawling:
- break;
- case Steve::Dead:
+ if (KeyBoard::GetKey(VK_DOWN))
+ {
+ imge.rect = (int)(time / 0.1) % 2 ? CrawlingLeftRect : CrawlingRightRect;
+ Size = imge.rect.size();
+ }
+ else
+ {
+ status = Running;
+ }
break;
default:
break;
@@ -93,5 +108,17 @@ export struct Steve : GameObject
}
virtual void OnLaterUpdate(float delta) override
{
+ if (isPaused) return;
+ }
+ virtual void OnReset() override
+ {
+ imge.rect = IdleRect;
+ status = Idle;
+
+ Anch = { 0.5f,0 };
+ Posi = { x_pos, ground_height };
+ Size = imge.rect.size();
+
+ a = v = h = 0.0f;
}
};
\ No newline at end of file