MegaSteve/MegaEngine.cpp

248 lines
5.4 KiB
C++

module;
#include <Windows.h>
#include <windowsx.h>
#include <wincodec.h>
#include <iostream>
#include <chrono>
module MegaEngine;
import Input;
using namespace std;
using namespace std::chrono;
void Game::Run()
{
StartUp();
while (PeekMsg() && !Done())
{
Update();
Render();
LaterUpdate();
}
CleanUp();
}
void Game::StartUp()
{
last = steady_clock::now();
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<duration<float>>(now - last).count();
last = now;
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()
{
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()
{
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);
auto hInst = GetModuleHandleW(nullptr);
UnregisterClassW(L"1mGameWnd", hInst);
}
void Game::CreateWnd()
{
auto hInst = GetModuleHandleW(nullptr);
WNDCLASSEXW wc =
{
sizeof(WNDCLASSEXW),
CS_CLASSDC,
WndProcSetUp,
0,
0,
hInst,
LoadIconW(nullptr, IDI_APPLICATION),
LoadCursorW(nullptr, IDC_ARROW),
CreateSolidBrush(0x808080),
nullptr,
wndClassName,
nullptr
};
wc.lpszClassName = L"1mGameWnd";
RegisterClassExW(&wc);
auto wnd_style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;//WS_CAPTION | WS_SYSMENU;
RECT client_rect{ 0, 0, wndWidth, wndHeight };
AdjustWindowRectEx(&client_rect, wnd_style, FALSE, 0u);
hwnd = CreateWindowExW
(
0L,
L"1mGameWnd",
L"1mGame",
wnd_style,
CW_USEDEFAULT,
CW_USEDEFAULT,
client_rect.right - client_rect.left,
client_rect.bottom - client_rect.top,
nullptr, nullptr, hInst, (LPVOID)this
);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
}
bool Game::PeekMsg()
{
MSG msg;
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) return false;
DispatchMessageW(&msg);
}
return true;
}
bool Game::Done()
{
return done;
}
LRESULT CALLBACK Game::WndProcSetUp(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_NCCREATE)
{
ImmDisableIME(GetCurrentThreadId());
auto CreateData = reinterpret_cast<CREATESTRUCTW*>(lParam);
auto wnd_ptr = reinterpret_cast<Game*>(CreateData->lpCreateParams);
SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Game::WndProcThunk));
SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(wnd_ptr));
return wnd_ptr->WndProc(hWnd, msg, wParam, lParam);
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
LRESULT CALLBACK Game::WndProcThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
auto wnd_ptr = reinterpret_cast<Game*>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
return wnd_ptr->WndProc(hWnd, msg, wParam, lParam);
}
LRESULT Game::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
KeyBoard::OnKeyMsg((char)wParam, true);
break;
case WM_KEYUP:
KeyBoard::OnKeyMsg((char)wParam, false);
break;
case WM_CLOSE:
done = true;
DestroyWindow(hwnd);
hwnd = nullptr;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
return 0;
}