타일 변경,맵 저장,불러오기

맵툴

맵툴에서 타일을 출력하고 선택해서 이미지를 출력해보겠습니다.

리스트박스의 속성에서 Horizontal Scroll을 true로 체크해 가로 스크롤을 활성화해줍니다.
(추가로 함수를 호출해주어야만 가로 스크롤을 쓸수있습니다)

void CMapTool::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	int iCount = DragQueryFile(hDropInfo, 0xffffffff, nullptr, 0);
	TCHAR szBuf[MAX_PATH] = L""; 
	for (int i = 0 ; i < iCount; ++i )
	{
		DragQueryFile(hDropInfo, i, szBuf, MAX_PATH); 
		CString wstrRelativePath = CFileInfo::ConvertRelativePath(szBuf); 
        //절대경로를 상대경로로 변경하기위해 구현한 함수
		CString wstrFileNameAndEx  =  PathFindFileName(szBuf);  
        // 파일명만 추출하는 함수
		TCHAR szFileName[MAX_PATH]{}; 
		lstrcpy(szFileName, wstrFileNameAndEx.GetString()); 
		PathRemoveExtension(szFileName);
        //확장자를 제거해주는 함수
		m_ListBox.AddString(szFileName);
        //리스트박스에 추가
	}

	m_ListBox.SetHorizontalExtent(800); 
    //세로 스크롤을기본적으로 제공하지만 가로 스크롤은 사용자가 지정해주어야함
    
	UpdateData(FALSE); 
	CDialog::OnDropFiles(hDropInfo);
}
CString CFileInfo::ConvertRelativePath(const CString & wstrAbsolutePath)
{
	TCHAR szCurrentDir[MAX_PATH]{}; 

	GetCurrentDirectory(MAX_PATH, szCurrentDir);
    //현재 절대 경로로 구함
	TCHAR szRelativePath[MAX_PATH]{}; 
	// 주의 사항 - C:: -> C:: 가능. 
	//			다른 드라이브 :: -> 다른드라이브 X 
	//			C:: -> D:: X
	//			D:: -> C:: X
	//			E:: -> C:: X
	//			슈발 슈발 슈발 n개 불가. 

	PathRelativePathTo(szRelativePath,
		szCurrentDir, FILE_ATTRIBUTE_DIRECTORY,
		wstrAbsolutePath.GetString(), FILE_ATTRIBUTE_DIRECTORY);
	// 절대경로를 상대경로로 변경해주는 함수
    
	return CString(szRelativePath);// 없으요 
}

파일 드롭다운시 파일명으로 리스트박스에 등록이 된다.

리스트박스 선택시 이미지 출력

void CMapTool::OnLbnSelchangeList1()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	int iIndex = m_ListBox.GetCurSel();
	CString wstrFindName; 
	m_ListBox.GetText(iIndex, wstrFindName); 
    //현재 선택된 파일명을 가져와줍니다 여기서 숫자만 추출을 해야합니다
	int i = 0;
	//Tile0;
	for (; i < wstrFindName.GetLength(); ++i)
	{
		// 0~ 9까지의 숫자인지 아닌지를 판단해주는 함수. 
		if (isdigit(wstrFindName[i]))
			break; 
        //숫자가 나올때까지 인덱스를 증가시켜줍니다
	}
	wstrFindName.Delete(0, i); 
    //앞에서부터 숫자가 나오기 전까지의 글자를 제거해줍니다
	m_iDrawID = _ttoi(wstrFindName.GetString()); 
	//TChar를 int형으로 변환 
	const TEXINFO* pTexInfo = CTexture_Manager::Get_Instance()->Get_TexInfo_Manager(L"Terrain", L"Tile", m_iDrawID); 
    //선택한 DrawID에 해당하는 타일 불러오기
	if (nullptr == pTexInfo)
		return; 
	D3DXMATRIX matScale, matTrans, matWorld; 
	float fRatioX = WINCX / TILECX; 
	float fRatioY = WINCY / TILECY;
	D3DXMatrixScaling(&matScale, fRatioX, fRatioY, 0.f);
    //화면에 꽉차는 비율로 확대
	D3DXMatrixTranslation(&matTrans, 400.f,300.f, 0.f); 
    //정중앙에 배치
	matWorld = matScale * matTrans; 

	float fCenterX = pTexInfo->tTexInfo.Width >> 1; 
	float fCenterY = pTexInfo->tTexInfo.Height >> 1; 
    
    //센터값 잡아줌
	CGraphic_Device::Get_Instance()->Render_Begin(); 
	CGraphic_Device::Get_Instance()->Get_Sprite()->SetTransform(&matWorld); 
	CGraphic_Device::Get_Instance()->Get_Sprite()->Draw(pTexInfo->pTexture, nullptr, &D3DXVECTOR3(fCenterX, fCenterY, 0.f), nullptr, D3DCOLOR_ARGB(255, 255, 255, 255));
    //
	CGraphic_Device::Get_Instance()->Render_End(m_Picture.m_hWnd);
    //맵툴의 픽쳐 부분에 그려줌
	UpdateData(FALSE); 
}

타일 선택시 이미지가 출력되는것을 확인가능

선택된 타일로 이미지 변경

MFCToolView에서 타일 ID를 고정으로 바꾸는것이 아닌 현재 맵툴뷰에서 선택된 타일로 변경하게끔 합니다.

void CMFCToolView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	CMainFrame* pMainFrame = dynamic_cast<CMainFrame*>(::AfxGetApp()->GetMainWnd());
	if (!pMainFrame)
		return;
	CMiniView* pView = dynamic_cast<CMiniView*>(pMainFrame->m_tSecondSplitter.GetPane(0, 0));
	CForm* pForm = dynamic_cast<CForm*>(pMainFrame->m_tSecondSplitter.GetPane(1, 0))
    //맵 툴뷰를 가져옵니다.
	int iDrawID = pForm->m_tMapTool.m_iDrawID; 
    //현재 선택된 아이디를 가져옵니다
	D3DXVECTOR3 vMouse = { float(point.x) + GetScrollPos(SB_HORZ), float(point.y) + GetScrollPos(SB_VERT), 0.f };
	m_pTerrain->Tile_Change(vMouse, iDrawID);
	Invalidate(FALSE); 
	pView->Invalidate(FALSE); 
// 	TCHAR szBuf[MAX_PATH]{}; 
// 	swprintf_s(szBuf, L"X : %d, Y : %d", point.x, point.y); 
// 	ERR_MSG(szBuf); 
	CScrollView::OnLButtonDown(nFlags, point);
}

선택한 타일로 맵이 변경되는것을 확인할수있습니다.

저장과 불러오기

Save와 Load에 맞는 기능을 구현합니다.

//Save
void CMapTool::OnBnClickedButton1()
{
	CFileDialog Dlg(FALSE, L"dat", L"*.dat");
	
	TCHAR szFilePath[MAX_PATH]{};
	GetCurrentDirectory(MAX_PATH, szFilePath);
	PathRemoveFileSpec(szFilePath);
	lstrcat(szFilePath, L"\\Data");
	Dlg.m_ofn.lpstrInitialDir = szFilePath;
	if (IDOK == Dlg.DoModal())
	{
		CString wstrFilePath = Dlg.GetPathName();
		//
		HANDLE hFile = CreateFile(Dlg.GetPathName(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
		if (INVALID_HANDLE_VALUE == hFile)
			return;

		DWORD dwByte = 0;
		CMainFrame* pMain = dynamic_cast<CMainFrame*>(AfxGetApp()->GetMainWnd()); 
		CMFCToolView* pView = dynamic_cast<CMFCToolView*>(pMain->m_tMainSplitter.GetPane(0, 1)); 
		vector<TILE*> vecTile = pView->m_pTerrain->Get_TileVector(); 
        
        //타일 벡터를 가져옵니다. 타일벡터는 포인터나 가상함수를 가지고있지않기때문에 WriteFile로 처리해줄수있습니다,
        
		for (auto& pTile : vecTile)
			WriteFile(hFile, pTile, sizeof(TILE), &dwByte, nullptr); 


		CloseHandle(hFile);
	}

}
//Load
void CMapTool::OnBnClickedButton6()
{
	CFileDialog Dlg(TRUE, L"dat", L"*.dat");

	TCHAR szFilePath[MAX_PATH]{};
	GetCurrentDirectory(MAX_PATH, szFilePath);
	PathRemoveFileSpec(szFilePath);
	lstrcat(szFilePath, L"\\Data");
	Dlg.m_ofn.lpstrInitialDir = szFilePath;
	if (IDOK == Dlg.DoModal())
	{
		CString wstrFilePath = Dlg.GetPathName();
		//
		HANDLE hFile = CreateFile(Dlg.GetPathName(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
		if (INVALID_HANDLE_VALUE == hFile)
			return;


		CMainFrame* pMain = dynamic_cast<CMainFrame*>(AfxGetApp()->GetMainWnd());
		CMFCToolView* pView = dynamic_cast<CMFCToolView*>(pMain->m_tMainSplitter.GetPane(0, 1));
		pView->m_pTerrain->Relese_Terrain(); 

		DWORD dwByte = 0;
		TILE* pTile = nullptr;
		
		// 이렇게 하지 마셈 이왕이면 Set이라던가 아니면 Add라던가 하는 함수를 만들어서 쓰셈. 
		// 이러면 퍼블릭이랑 다를게 일절 없음 
		//그래서 갯함수는 대부분const 붙일수 있는데 다 붙인다. 
		//vector<TILE*>& vectile = pView->m_pTerrain->Get_TileVector(); 


		vector<TILE*> vecTile; 
		vecTile.reserve(TILEX * TILEY);
		while (true)
		{
			pTile = new TILE; 
			ReadFile(hFile, pTile, sizeof(TILE), &dwByte, nullptr);
			if (0 == dwByte)
			{
				SAFE_DELETE(pTile);
				break;
			}
			vecTile.emplace_back(pTile); 
		}
		pView->m_pTerrain->Set_Vector(vecTile); 
		pView->Invalidate(FALSE); 

		CloseHandle(hFile);
	}
}

좋은 웹페이지 즐겨찾기