📄 mapedit.cpp
字号:
// MapEdit.cpp: implementation of the CMapEdit class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "MapEdit.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAZEGROUND 0
#define MAZEWALL 1
#define MAZEBALL 2
#define MAZEEXIT 3
#define MAZENULL -1
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMapEdit::CMapEdit()
{
CClientDC dc(AfxGetMainWnd());
m_pbmp=new CBitmap[4];
m_tmpDC=new CDC;
m_pFirstStep=new StepPoint;
m_pCurStep=new StepPoint;
m_pPreStep=new StepPoint;
Init();
maze=NULL;
m_pbmp[MAZEWALL].m_hObject=(HBITMAP)::LoadImage(NULL,"res/wall.bmp",IMAGE_BITMAP,40,40,LR_LOADFROMFILE);
m_pbmp[MAZEBALL].m_hObject=(HBITMAP)::LoadImage(NULL,"res/ball.bmp",IMAGE_BITMAP,40,40,LR_LOADFROMFILE);
m_pbmp[MAZEEXIT].m_hObject=(HBITMAP)::LoadImage(NULL,"res/exit.bmp",IMAGE_BITMAP,40,40,LR_LOADFROMFILE);
m_pbmp[MAZEGROUND].m_hObject=(HBITMAP)::LoadImage(NULL,"res/ground.bmp",IMAGE_BITMAP,40,40,LR_LOADFROMFILE);
m_tmpDC->CreateCompatibleDC(&dc);
m_BallNum=m_ExitNum=0;
m_MazeStart=m_MazeExit=(0,0);
m_CurPos=0;
m_NextPos=0;
IsEnableOut=false;
}
CMapEdit::~CMapEdit()
{
delete []m_pbmp;
delete m_tmpDC;
delete maze;
while (m_pFirstStep!=NULL)
{
delete m_pFirstStep;
m_pFirstStep=m_pCurStep->next;
}
delete m_pFirstStep;
delete m_pPreStep;
}
BOOL CMapEdit::DrawMap(CDC *pDC)
{
int x=0,y=0;
for(int i=0;i<m_MazeHigh;i++)
for(int j=0;j<m_MazeWidth;j++)
{
x=j*40;
y=i*40;
char tmp=maze[j+i*m_MazeWidth];
m_tmpDC->SelectObject(&m_pbmp[tmp]);
pDC->BitBlt(x,y,40,40,m_tmpDC,0,0,SRCCOPY);
}
return true;
}
void CMapEdit::ClearMap()
{
if (!maze)
{
maze=new char[400];
IsPass=new BOOL[400];
}
for (int i=0;i<400;i++)
{
maze[i]=MAZEGROUND; //初始化
IsPass[i]=false;
}
}
void CMapEdit::LoadMap()
{
ClearMap();
CFile mfile;
BOOL Btmp=mfile.Open("maze.dat",CFile::modeReadWrite);
if (!Btmp)
{
char str[255];
for(int i=0;i<255;i++)str[i]=0;
AfxMessageBox("读取文件失败!"); //文件不存在
mfile.Open("maze.dat",CFile::modeCreate|CFile::modeWrite);
m_MazeHigh=6;
m_MazeWidth=7;
mfile.Write(&m_MazeWidth,1);
mfile.Write(&m_MazeHigh,1);
mfile.Write(str,m_MazeWidth*m_MazeHigh);
mfile.Write(&m_BallNum,1);
mfile.Write(&m_ExitNum,1);
mfile.SetLength(m_MazeWidth*m_MazeHigh+4);
ClearMap();
}
else
{
if(mfile.GetLength()>0)//文件存在
{
BYTE fileHight,fileWidth;
mfile.Read(&fileWidth,1);
mfile.Read(&fileHight,1);
m_MazeHigh=fileHight;
m_MazeWidth=fileWidth;
if (fileHight!=m_MazeHigh||fileWidth!=m_MazeWidth) //地图长宽不正确
{
AfxMessageBox("地图信息错误!");
mfile.SeekToBegin();
mfile.Write(&m_MazeWidth,1);
mfile.Write(&m_MazeHigh,1);
mfile.Read(maze,m_MazeWidth*m_MazeHigh);
mfile.Read(&m_BallNum,1);
mfile.Read(&m_ExitNum,1);
mfile.SetLength(m_MazeWidth*m_MazeHigh+4);
LoadPoint();
}
else //地图正确
{
mfile.Read(maze,m_MazeWidth*m_MazeHigh);
mfile.Read(&m_BallNum,1);
mfile.Read(&m_ExitNum,1);
LoadPoint();
}
}
}
m_pFirstStep->m_StepPoint=m_MazeStart;
m_pFirstStep->direct=0;
m_pFirstStep->next=m_pCurStep;
m_pFirstStep->pre=NULL;
mfile.Close();
}
void CMapEdit::SaveMap()
{
CFile file("maze.dat",CFile::modeReadWrite);
file.Write(&m_MazeWidth,1);
file.Write(&m_MazeHigh,1);
file.Write(maze,m_MazeWidth*m_MazeHigh);
file.Write(&m_BallNum,1);
file.Write(&m_ExitNum,1);
file.Close();
AfxMessageBox("保存文件成功!");
}
void CMapEdit::DrawMouseCursor(CPoint point,char CurrSel,CDC *pDC)
{
if(CurrSel!=MAZENULL)
{
m_tmpDC->SelectObject(&m_pbmp[CurrSel]);
pDC->BitBlt(point.x-20,point.y-20,40,40,m_tmpDC,0,0,SRCCOPY);
}
}
void CMapEdit::ChangMap(CPoint point, char CurSel)
{
char x,y;
x=point.x/40;
y=point.y/40;
if (CurSel==MAZEBALL|| CurSel==MAZEEXIT)
{
if (CurSel==MAZEBALL && m_BallNum==0)
{
m_BallNum++;
m_MazeStart.x=x;
m_MazeStart.y=y;
maze[y*m_MazeWidth+x]=CurSel;
}
if (CurSel==MAZEEXIT && m_ExitNum==0)
{
m_ExitNum++;
m_MazeExit.x=x;
m_MazeExit.y=y;
maze[y*m_MazeWidth+x]=CurSel;
}
}
else
{
CPoint tpoint;
tpoint.x=x;
tpoint.y=y;
maze[y*m_MazeWidth+x]=CurSel;
if (tpoint==m_MazeStart)
{
m_BallNum--;
if (m_BallNum<0)
m_BallNum=0;
}
if (tpoint==m_MazeExit)
{
m_ExitNum--;
if (m_ExitNum<0)
m_ExitNum=0;
}
}
}
BOOL CMapEdit::CheckMaze()
{
if (m_BallNum!=1 )
{
AfxMessageBox("请放置入口");
return false;
}
if ( m_ExitNum!=1)
{
AfxMessageBox("请放置出口");
return false;
}
return true;
}
BOOL CMapEdit::GoMaze(UINT keyNum)
{
if (CheckMaze())
{
char x,y;
x=(char)m_MazeStart.x;
y=(char)m_MazeStart.y;
CPoint tmp;
tmp=m_MazeStart;
if (keyNum == 38 && maze[(y-1)*m_MazeWidth+x]!=MAZEWALL &&(y-1>=0) && !IsPass[m_NextPos]) //上
{
m_MazeStart.y--;
maze[y*m_MazeWidth+x]=MAZEGROUND;
maze[(y-1)*m_MazeWidth+x]=MAZEBALL;
}
if (keyNum == 40 && maze[(y+1)*m_MazeWidth+x]!=MAZEWALL&&(y+1<m_MazeHigh)&& !IsPass[m_NextPos]) //下
{
m_MazeStart.y++;
maze[y*m_MazeWidth+x]=MAZEGROUND;
maze[(y+1)*m_MazeWidth+x]=MAZEBALL;
}
if (keyNum == 37 && maze[y*m_MazeWidth+x-1]!=MAZEWALL&&(x-1>=0)&& !IsPass[m_NextPos]) //左
{
m_MazeStart.x--;
maze[y*m_MazeWidth+x]=MAZEGROUND;
maze[y*m_MazeWidth+x-1]=MAZEBALL;
}
if (keyNum == 39 && maze[y*m_MazeWidth+x+1]!=MAZEWALL&&(x+1<m_MazeWidth)&& !IsPass[m_NextPos]) //右
{
m_MazeStart.x++;
maze[y*m_MazeWidth+x]=MAZEGROUND;
maze[y*m_MazeWidth+x+1]=MAZEBALL;
}
if (m_MazeStart == m_MazeExit)
{
m_ExitNum=0;
}
m_pCurStep->direct++;
if (tmp!=m_MazeStart)
return true;
else return false;
}
return false;
}
void CMapEdit::LoadPoint()
{
for (int i=0;i<(m_MazeHigh*m_MazeWidth);i++)
{
if (maze[i]==MAZEBALL)
{
m_MazeStart.x=i%m_MazeWidth;
m_MazeStart.y=i/m_MazeWidth;
m_pFirstStep->m_StepPoint=m_MazeStart;
m_pFirstStep->direct=0;
m_pFirstStep->next=m_pCurStep;
m_pFirstStep->pre=NULL;
}
if (maze[i]==MAZEEXIT)
{
m_MazeExit.x=i%m_MazeWidth;
m_MazeExit.y=i/m_MazeWidth;
}
}
}
BOOL CMapEdit::SearchMaze()
{
m_CurPos=m_MazeStart.y*m_MazeWidth+m_MazeStart.x;
m_pCurStep->m_StepPoint=m_MazeStart;
if(m_MazeStart==m_MazeExit)
{
IsEnableOut=true;
return true;//true 结束探索
}
if (Pass(m_CurPos))
{
IsPass[m_CurPos]=true;
NextPos(m_pCurStep->direct);
if (GoMaze(m_pCurStep->direct+37))
{
StepPoint *nextStep; //周围能够通过
nextStep=new StepPoint;
nextStep->m_StepPoint=m_MazeStart;
nextStep->direct=0;
nextStep->next=NULL;
nextStep->pre=m_pCurStep;
m_pCurStep->next=nextStep;
m_pCurStep=nextStep;
m_pPreStep=m_pCurStep->pre;
m_CurPos=m_MazeStart.y*m_MazeWidth+m_MazeStart.x;
}
}
else
{
if (m_pCurStep!=m_pFirstStep->next)
{
if (m_pCurStep->direct==4 && m_pCurStep!=NULL)
{
UpdateMap(m_pCurStep->m_StepPoint,MAZEGROUND); //贴回地板
StepPoint *tmpStep;
tmpStep=m_pCurStep;
ASSERT(m_pPreStep->next);
m_pPreStep=m_pPreStep->pre;
m_pCurStep=m_pCurStep->pre;
m_MazeStart=m_pCurStep->m_StepPoint;
delete tmpStep;
UpdateMap(m_pCurStep->m_StepPoint,MAZEBALL);
}
}
else
return true;
}
return false;
}
BOOL CMapEdit::Pass(char direct)
{
if (IsPass[m_CurPos] && m_pCurStep->direct>3)
return false;
else
return true;
}
void CMapEdit::NextPos(char direct)
{
switch(direct)
{
case 0:
m_NextPos=m_CurPos-1;
break;
case 1:
m_NextPos=(m_MazeStart.y-1)*m_MazeWidth+m_MazeStart.x;
break;
case 2:
m_NextPos=m_CurPos+1;
break;
case 3:
m_NextPos=(m_MazeStart.y+1)*m_MazeWidth+m_MazeStart.x;
break;
}
}
void CMapEdit::UpdateMap(CPoint point, char CurSel)
{
int x,y;
x=point.x;
y=point.y;
maze[y*m_MazeWidth+x]=CurSel;
}
void CMapEdit::ShowShort(CDC *pDC)
{
StepPoint *tmp;
m_tmpDC->SelectObject(&m_pbmp[MAZEBALL]);
int x,y;
tmp=m_pFirstStep;
while (tmp!=NULL)
{
x=tmp->m_StepPoint.x*40;
y=tmp->m_StepPoint.y*40;
pDC->BitBlt(x,y,40,40,m_tmpDC,0,0,SRCCOPY);
tmp=tmp->next;
}
x=m_pPreStep->pre->m_StepPoint.x*40;
y=m_pPreStep->pre->m_StepPoint.y*40;
pDC->BitBlt(x,y,40,40,m_tmpDC,0,0,SRCCOPY);
}
void CMapEdit::InitPointer()
{
m_pFirstStep=new StepPoint;
m_pCurStep=new StepPoint;
m_pPreStep=new StepPoint;
m_pFirstStep->m_StepPoint=m_MazeStart;
m_pFirstStep->direct=0;
m_pFirstStep->next=m_pCurStep;
m_pPreStep=m_pCurStep;
m_pFirstStep->pre=NULL;
m_pCurStep->direct=0;
IsEnableOut=false;
for (int i=0;i<400;i++)
IsPass[i]=false;
}
void CMapEdit::Init()
{
m_pFirstStep->direct=0;
m_pFirstStep->next=NULL;
m_pFirstStep->pre=NULL;
m_pCurStep->direct=0;
m_pCurStep->next=NULL;
m_pCurStep->pre=NULL;
m_pPreStep->direct=0;
m_pPreStep->next=NULL;
m_pPreStep->pre=NULL;
m_pCurStep->pre=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -