Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 2870번
- 백준 2870번
- 백준 1103번 c++
- c++
- 백준 c++ 2870번
- Beakjoon
- dfs
- Algorithm
- Lv.3
- 백준 1103번 게임
- 오브젝트 풀링
- Unity
- 백준 17070번 c++
- 백준
- 코딩테스트
- 유니티
- 17070번
- 2870번 수학숙제
- 백준 1103번
- 2468 c++
- 코테
- Lv2
- 2870번 c++
- 플레이어 이동
- C#
- 수학숙제
- 프로그래머스
- 백준 17070번
- 백준 c++ 2468번
- 2870번 수학숙제 c++
Archives
- Today
- Total
주녘공부일지
[C++] 벽돌깨기 게임 ( WinAPI ) 본문
1. 벽돌깨기 게임 ( WinAPI )
- 알카노이드를 레퍼런스로 하여 제작한 게임
https://github.com/godgjwnsgur7/WinAPI_BrickBreaking/tree/main/BrickBreaking
WinAPI_BrickBreaking/BrickBreaking at main · godgjwnsgur7/WinAPI_BrickBreaking
Contribute to godgjwnsgur7/WinAPI_BrickBreaking development by creating an account on GitHub.
github.com
2. 게임 핵심 구현 요소
1) Vector2
- 위치 벡터, 방향 벡터 등 범용적으로 사용하기 편리하도록 Vector2 구조체를 구현하여 사용함
struct Vector2
{
float x, y;
Vector2();
Vector2(float x, float y);
Vector2 operator-(const Vector2& other) const;
Vector2 operator+(const Vector2& other) const;
Vector2 operator*(float scalar) const;
float Dot(const Vector2& other) const;
Vector2 Normalize() const;
};
2) 일정 주기로 호출 ( Update )
- deltaTime 개념을 넣어 일정 주기로 Update 메서드를 호출
- Update에서 각 객체들의 상태를 업데이트하고, 갱신된 내용을 그려줌
int APIENTRY wWinMain( ... )
{
...
while (1)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { ... }
else
{
DWORD currentTime = GetTickCount64();
deltaTime += (currentTime - previousTime);
previousTime = currentTime;
if (deltaTime > 10)
{
Update();
deltaTime = 0;
InvalidateRect(winhWnd, NULL, FALSE);
}
}
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND: { ... }
break;
case WM_CREATE:
Start();
break;
case WM_MOUSEMOVE:
OnMouseMoveEvent(lParam);
break;
case WM_PAINT:
Draw(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
3) 더블 버퍼링, 메모리 풀
- 더블 버퍼링 : 메모리 DC를 생성해 미리 그림을 그린 후 실제 출력할 화면 DC에 고속 복사
- 메모리 풀 : 많이 사용될 수 있는 객체에 대하여 일정 메모리 크기만큼 미리 점유시켜놓고 사용
void Draw(HWND& hWnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
SelectObject(memDC, memBitmap);
FillRect(memDC, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
// 아이템
for (Item& item : items)
if (item.isUsing)
item.Draw(memDC);
// 블럭
for (std::vector<Brick>& brick : bricks)
{
for (Brick& b : brick)
{
if (b.GetCount() > 0)
b.Draw(memDC);
else
b = NULL;
}
}
// 공
for (Ball& ball : balls)
if (ball.isUsing)
ball.Draw(memDC);
// 바
bar.Draw(memDC);
BitBlt(hdc, 0, 0, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, memDC, 0, 0, SRCCOPY);
DeleteObject(memBitmap);
DeleteDC(memDC);
EndPaint(hWnd, &ps);
}
4) 원과 직사각형의 충돌 판단 ( Ball <-> Bar, Brick )
- 직사각형의 모서리 영역 중에 원의 원점과 가장 가까운 위치 좌표를 가져와 거리를 측정
- 거리가 원의 반지름보다 적다면 충돌이 일어났다고 판단
bool Ball::CheckCollisionBar(Bar& bar)
{
int closestX = std::max((float)(bar.GetRect().left), std::min(pos.x, (float)(bar.GetRect().right)));
int closestY = std::max((float)(bar.GetRect().top), std::min(pos.y, (float)(bar.GetRect().bottom)));
int distanceX = pos.x - closestX;
int distanceY = pos.y - closestY;
if ((distanceX * distanceX + distanceY * distanceY) <= (radius * radius))
{
float diffX = pos.x - bar.GetPos().x;
float barHalfLength = bar.GetLength() / 2;
float velocityX = diffX / barHalfLength;
velocity = { velocityX * 2.0f , -1 };
if (pos.y >= bar.GetPos().y - 10 - radius)
pos.y = bar.GetPos().y - 10 - radius;
return true;
}
return false;
}
3. 플레이 영상
'GameDevelopment > [C++] Project' 카테고리의 다른 글
[C++] 종스크롤 슈팅 게임 ( WinAPI ) (1) | 2024.10.30 |
---|---|
[C언어] 콘솔 비행기 게임 (1) | 2024.09.11 |