⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapedit.cpp

📁 用vc++写的迷宫基于图形的算法,可以自己编辑地图,并具有保存地图的功能
💻 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 + -