반응형
경일게임아카데미 프로그래밍반 28기 16일차 수업 (2021. 04. 29)
WIN32 API 백버퍼 (댕글링포인터)
image.h 파일 소스코드
#pragma once
class image
{
public:
typedef struct tagImageInfo
{
HDC hMemDC;
HBITMAP hBit;
HBITMAP hOBit;
int width;
int height;
tagImageInfo()
{
hMemDC = NULL;
hBit = NULL;
hOBit = NULL;
width = 0;
height = 0;
}
}IMAGE_INFO, *LPIMAGE_INFO;
private:
LPIMAGE_INFO _backBuffer;
public:
image();
~image();
HRESULT init(int width, int height);
void release();
void render(HDC hdc, int destX, int destY);
//백버퍼에 대한 접근자
inline HDC getMemDC() { return _backBuffer->hMemDC; }
};
구조체 앞에 typedef를 붙여주면 뒤에 선언된 IMAGE_INFO, *LPIMAGE_INFO 두 이름으로 이름을 명칭해서 쓸 수 있다. 예를들어
private:
LPIMAGE_INFO _backBuffer;
는 *LPIMAGE_INFO로 사용해도 상관이 없다.
gameNode.h 파일 소스코드
#pragma once
#include "image.h"
class gameNode
{
private:
image* _backBuffer; //빈 DC공간과 빈 bitmap공간
void setBackBuffer();
public:
gameNode();
virtual ~gameNode();
//HRESULT 마소 전용 반환형식인데
//S_OK, E_FAIL, SUCCEDED
virtual HRESULT init(); //초기화 함수
virtual void release(); //메모리 해제 함수
virtual void update(); //연산 함수
virtual void render(HDC hdc); //그리기 함수
//백버퍼 접근자!
image* getBackBuffer() { return _backBuffer; }
LRESULT MainProc(HWND, UINT, WPARAM, LPARAM);
};
댕글링 포인터를 설명해줄 당시 선생님께서는 널값을 통한 공갈벽돌을 이용해 배열이 터지는 것을 방지한다. 라고 설명해주셨다. 하지만 이해가 되지 않아 구글에 검색해서 찾아보니 무슨 역할을 하는지 대략적으로 이해할 수 있었다. 내가 참고한 사이트는 https://thinkpro.tistory.com/67 이다.
조커 카드 찾기
#include "stdafx.h"
#include "playGround.h"
playGround::playGround()
{
}
playGround::~playGround()
{
}
//초기화는 여기다 하세요 제발
HRESULT playGround::init()
{
gameNode::init();
for (int i = 0; i < 5; i++)
{
_box[i].rc = RectMakeCenter(100 + i * 200, 200, 100, 100);
_box[i].isCheck = false;
_box[i].isJoker = false;
}
_box[RND->getInt(5)].isJoker = true;
return S_OK;
}
//메모리 해제는 여기다 하세요 제발
void playGround::release()
{
gameNode::release();
}
//여기에다 연산하세요 제에발
void playGround::update()
{
gameNode::update();
//왼쪽클릭하면
if (KEYMANAGER->isOnceKeyDown(VK_LBUTTON))
{
for (int i = 0; i < 5; i++)
{
if (PtInRect(&_box[i].rc, _ptMouse))
{
_box[i].isCheck = true;
}
}
}
for (int i = 0; i < 5; i++)
{
if (_box[i].isCheck && _box[i].isJoker)
{
_box[i].rc.top += 5;
_box[i].rc.bottom += 5;
if (_box[i].rc.top > WINSIZEY) this->init();
}
}
}
//여기에다 그려라 좀! 쫌!
void playGround::render(HDC hdc)
{
HDC backDC = this->getBackBuffer()->getMemDC();
PatBlt(backDC, 0, 0, WINSIZEX, WINSIZEY, WHITENESS);
// 위에 건들지마라
//================제발 이 사이에 좀 그립시다==========================
for (int i = 0; i < 5; i++)
{
if (_box[i].isCheck && !_box[i].isJoker)
{
HBRUSH brush = CreateSolidBrush(RGB(0, 0, 255));
HBRUSH oldBrush = (HBRUSH)SelectObject(backDC, brush);
Rectangle(backDC, _box[i].rc);
SelectObject(backDC, oldBrush);
DeleteObject(brush);
}
else if (_box[i].isCheck && _box[i].isJoker)
{
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
Rectangle(backDC, _box[i].rc);
FillRect(backDC, &_box[i].rc, brush);
DeleteObject(brush);
}
else Rectangle(backDC, _box[i].rc);
}
//==================================================
//여기도 건들지마라
this->getBackBuffer()->render(hdc, 0, 0);
}
주어진 게임은 5개의 카드에서 조커를 찾는 게임이다.
이를 바탕으로 악어게임을 제작해보자!
악어 게임이란?
위와 같이 생긴 악어가 있을 떄 손가락으로 악어 이빨을 눌렀을 떄 입이 닫히는 버튼이 랜덤으로 있다.
닫히는 버튼을 눌렀을때 악어가 입을 닫게 된다. 입이 닫히는 버튼은 랜덤으로 생성해야 한다.
이를 통해 총 20개의 선택지를 만들어 1개의 조커를 뽑을 경우 게임이 끝나고 다시 시작하는 것을 만들어보자!
반응형
'학원 > 경일게임아카데미' 카테고리의 다른 글
27. 열여섯번째 수업과제 [악어 게임] (0) | 2022.12.29 |
---|---|
26. 열여섯번째 수업과제 [러닝 게임] (0) | 2022.12.29 |
24. 열다섯번째 수업과제 (0) | 2022.12.26 |
23. 열다섯번째 수업 (0) | 2022.12.26 |
22. 열네번째 수업과제 [윈도우 탐색기 구현] (1) | 2022.12.23 |