728x90
반응형
private:
	list<CObj*>*	m_pBullet;

총알을 저장할 리스트를 포인터형으로 만들어주고, 

CObj * CPlayer::Create_Bullet(int _iA)		// 매개변수는 정해진 키 값을 전해주기위해 설정하였다.
{
	CBullet*	pBullet = new CBullet;			// 동적할당
	pBullet->Initialize();				// 총알에 대한 기본 위치, 이동할 속도에 대한 정보
	pBullet->Set_Pos(m_tInfo.fX, m_tInfo.fY, _iA);	// 메인스테이지와 연결해준다.

	return pBullet;
}

여기는 리스트에 넣어줄 정보를 담은 함수이다.

	if (GetAsyncKeyState(0x41) & 0x8000)		// A
		m_pBullet->emplace_back(Create_Bullet(0x41));	// 해당 키 값을 Bullet클래스로 전달
	if (GetAsyncKeyState(0x44) & 0x8000)		// D
		m_pBullet->emplace_back(Create_Bullet(0x44));
	if (GetAsyncKeyState(0x57) & 0x8000)		// W
		m_pBullet->emplace_back(Create_Bullet(0x57));
	if (GetAsyncKeyState(0x53) & 0x8000)		// S
		m_pBullet->emplace_back(Create_Bullet(0x53));

키를 눌렀을 때 총알이 생성되도록 해당 키일때 emplace_back으로 원소 삽입 해준다.

	if (m_iCheck == 0x41)			// 받아 온 키 값을 조건식으로 사용함.
		m_tInfo.fX -= m_fSpeed;		// m_fSpeed(10.f)만큼 이동.
	if (m_iCheck == 0x44)
		m_tInfo.fX += m_fSpeed;
	if (m_iCheck == 0x57)
		m_tInfo.fY -= m_fSpeed;
	if (m_iCheck == 0x53)
		m_tInfo.fY += m_fSpeed;

 

메인함수를 보면 UpDate 함수와 Render함수에서 계속 0.01초마다 새로고침이 진행되고 있다. 그렇기 때문에 좌표값을 조절해주면 이동하는 것처럼 보이는 것이다.

 << main 함수 >>
 while (WM_QUIT != msg.message)		// msg 안에 메세지가 WM_QUIT 아닐경우 수행한다.
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))	//PeekMessage -> 메세지가 있으면 가공해서 전해줘라
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

		if (dwTime + 10 < GetTickCount())	// 만약 0.01초가 지나면 수행해라
		{
			mainGame.UpDate();	// 이 if문을 걸어주지 않으면 한 번 움직일 때 많은 반복을 하기 때문에 조건을 걸어줘야함!
			mainGame.Render();

			dwTime = GetTickCount();	// 다시 값을 넣어준다.
		}
		
    }

총알을 담은 리스트를 화면에 출력해주어야하는데 리스트를 출력할 위치는 UpDate나 Render함수에 해야한다!

void CMainGame::Render()
{

	RECT rc = { 100, 100, 700, 500 };
	Rectangle(m_hDC, 0, 0, WINCX, WINCY);		// 빈 공간을 넣어줌으로써 잔상이 남지 않는다.
	Rectangle(m_hDC, rc.left, rc.top, rc.right, rc.bottom);		// 큰 사각형을 하나 만들었다.
	list<CObj*>::iterator    iter = m_listBullet.begin();

	for (auto& pBullet : m_listBullet)	// 총알 출력
	{
		pBullet->Render(m_hDC);
	}

	for (; iter != m_listBullet.end();)		// 큰 사각형의 밖으로 총알이 나가면 총알이 삭제되도록..
	{		//Get_fX() : X좌표, Get_fY(): Y좌표							
		if ((*iter)->Get_fX() <= rc.left || (*iter)->Get_fX() >= rc.right || (*iter)->Get_fY() <= rc.top || (*iter)->Get_fY() >= rc.bottom)
		{
			delete (*iter);
			iter = m_listBullet.erase(iter);
		}
		else
			++iter;										// 조건에 만족하지 않으면 다음을 가리켜라
	}
	m_pPlayer->Render(m_hDC);		// 총알이 나올 플레이어


}

Render함수는 화면이 계속 새로고침되기 때문에 그냥 도형만 출력하면 잔상이 남는 것처럼 보이므로 제일 처음에 화면을 벗어나는 크기의 사각형을 만들어 빈 공간을 넣어준다. -> 잔상이 남지 않음

사각형 밖으로 총알이 나가지 않도록 조건을 주고 사각형 밖이면 삭제해주는데 삭제할 때 동적할당한 공간을 먼저 지워주고 삭제하였다. 이 부분에서 반복자를 주의해야한다!

iter = m_listBullet.erase(iter); 이렇게 했을 때 iter은 다음을 가르키고 있기 때문에 후에 추가로 ++iter를 하면 오류가 날 수 있으니 주의하자!

저 조건을 만족하지 않으면 ++iter로 다음 iter를 가르키게 해줘야함!  

프로그램을 실행하고 키를 누르면 총알이 발사된다.

현재 리스트의 원소는 동적할당이 되어있기 때문에 동적할당 해주는 것 잊지 않아야 한다!

for_each(m_listBullet.begin(), m_listBullet.end(), Safe_Delete<CObj*>);
	m_listBullet.clear();

for_each알고리즘을 이용하여 동적할당 해제를 먼저 진행한 후 원소를 삭제하였다.

728x90
반응형

'API > API' 카테고리의 다른 글

API - 충돌 (IntersectRect 함수)  (0) 2021.06.01
API - 움직이는 객체 맞추기  (0) 2021.05.30
GetAsyncKeyState 함수  (0) 2021.05.29
API - 도형 (총알 발사)  (0) 2021.05.29
API - 도형만들기  (0) 2021.05.26

+ Recent posts