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

📄 dlgmain.cpp

📁 A*算法
💻 CPP
字号:
#include <windows.h>
#include <winuser.h>
#include "main.h"
#include "resource.h"
#include "WayPoint.h"
#include "AStar.h"
#include <math.h>
#include "MyDialog.h"

char FileName[512]={0};
HWND _hWnd; 
CWayPoint WayPoint;
CAStar AStar;
HHOOK hMsgHook=NULL;
bool bControlIsDown=false;
HDC hdc;
float Scale=1.0f;//比例
int DrawLeft=0;//显示区域的左上角
int DrawTop=0;//显示区域的左上角
HBRUSH BackColorHbr;
RECT CanvasRect;
int OldMousePosX,OldMousePosY;
int SelectedIndex=-1;
int SelectedIndexTo=-1;
POINT tempLineF,tempLineT;

//创建内存兼容DC
HDC DestHdc;//目标DC
HDC CompDC;//内存兼容dc
HBITMAP CompBMP;//内存兼容bmp
HGDIOBJ oldOBJBMP;//

struct SSMallTestMan
{
	int x;
	int y;
	int endNode;
	int nextNode;
}smallTestMan;

void DrawCircle(int x,int y,int r,int color)
{
	HPEN hPen=CreatePen(PS_SOLID,1,color);
	HGDIOBJ oldObj=SelectObject(CompDC,hPen);
	int tempx=(x)*Scale-DrawLeft;
	int tempy=(y)*Scale-DrawTop;
	Ellipse(CompDC,tempx-r/2,tempy-r/2,tempx+r/2,tempy+r/2);
	SelectObject(CompDC,oldObj);
	DeleteObject(hPen);
}
void DrawLine(int fx,int fy,int tx,int ty,int color)
{
	int tempx=(fx)*Scale-DrawLeft;
	int tempy=(fy)*Scale-DrawTop;
	MoveToEx(CompDC,tempx,tempy,NULL);
	tempx=(tx)*Scale-DrawLeft;
	tempy=(ty)*Scale-DrawTop;
	LineTo(CompDC,tempx,tempy);
}

void ShowAllPoint()
{

	FillRect(CompDC,&CanvasRect,BackColorHbr);//填充背景色
	int NCount=WayPoint.GetNodeCount();
	for(int i=0;i<NCount;i++)
	{
		SWPNode *tempNode=WayPoint.GetWPNode(i);
		DrawCircle(tempNode->x,tempNode->y,6,0);
		if(i==SelectedIndex)
			DrawCircle(tempNode->x,tempNode->y,8,RGB(0,0,0xff));
		if(i==SelectedIndexTo)
			DrawCircle(tempNode->x,tempNode->y,8,RGB(0,0xff,0));
		for(int j=0;j<tempNode->NeighborCount;j++)
		{
			SWPNode *NbNode=WayPoint.GetWPNodeByID(tempNode->Neighbor[j]);
			DrawLine(tempNode->x,tempNode->y,NbNode->x,NbNode->y,0);
		}
	}
	if(SelectedIndex!=-1&&bControlIsDown)
	{
		//DrawLine(tempLineF.x,tempLineF.y,tempLineT.x,tempLineT.y,0);
		MoveToEx(CompDC,tempLineF.x,tempLineF.y,NULL);
		LineTo(CompDC,tempLineT.x,tempLineT.y);
	}
	DrawCircle(smallTestMan.x,smallTestMan.y,9,RGB(0xff,0,0));
	BitBlt(hdc,0,0,CanvasRect.right,CanvasRect.bottom,CompDC,0,0,SRCCOPY);
}

void Open_OnClick()
{
	CMyDialog mydlg(_hWnd,_hInstance);
	mydlg.SetFilter("*.txt");
	mydlg.SetFileName("*.txt");
	if(mydlg.ShowOpen())
	{
		mydlg.GetFile(FileName);
		if(FileName[0]!='\0')
		{
			SetWindowText(_hWnd,FileName);
			WayPoint.ReadWayPointFile(FileName);
			SelectedIndex=-1;
			int NCount=WayPoint.GetNodeCount();
			ShowAllPoint();
		}
	}
}

void Save_OnClick()
{
	if(FileName[0]=='\0')
	{
		CMyDialog mydlg(_hWnd,_hInstance);
		mydlg.SetFilter("*.txt");
		mydlg.SetFileName("*.txt");
		mydlg.ShowSave();
		mydlg.GetFile(FileName);
	}
	if(FileName[0]!='\0')
	{
		WayPoint.SaveWayPointToFile(FileName);
		SetWindowText(_hWnd,FileName);
	}
}

void New_OnClick()
{
	WayPoint.ClearNode();
	FileName[0]='\0';
	SelectedIndex=-1;
	SetWindowText(_hWnd,"新建");
	ShowAllPoint();
}

void Form_OnLoad()
{
	BackColorHbr=CreateSolidBrush(0xaaaaaa);
	GetClientRect(GetDlgItem(_hWnd,IDC_PICMAIN),&CanvasRect);
	hdc=GetDC(GetDlgItem(_hWnd,IDC_PICMAIN));
	Scale=1;
	DrawLeft=0;
	RegisterHotKey(_hWnd,GlobalAddAtom("ctrl+a"),MOD_CONTROL,'P');
	/***********************/
	GetClientRect(_hWnd,&CanvasRect);
	//创建内存兼容DC
	DestHdc=GetDC(_hWnd);	
	CompDC=CreateCompatibleDC(NULL);
	CompBMP=CreateCompatibleBitmap(DestHdc,CanvasRect.right,CanvasRect.bottom);
	oldOBJBMP=SelectObject(CompDC,CompBMP);
}

void Form_OnClose()
{
	ReleaseDC(GetDlgItem(_hWnd,IDC_PICMAIN),hdc);
}

void Form_OnKeyDown(WPARAM wParam)
{
	switch(wParam)
	{
	case VK_CONTROL:
		bControlIsDown=true;
		SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(32649)));
		break;
	case VK_SHIFT:
		SetCursor(LoadCursor(NULL,IDC_CROSS));
		break;
	case VK_DELETE:
		if(SelectedIndex!=-1)
		{
			WayPoint.RemoveNode(SelectedIndex);
			SelectedIndex=-1;
			ShowAllPoint();
		}
	}
}

void Form_OnKeyUp(WPARAM wParam)
{
	switch(wParam)
	{
	case VK_CONTROL:case VK_SHIFT:
		bControlIsDown=false;
		SelectedIndexTo=-1;
		ShowAllPoint();
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		break;
	}
}

void Form_OnMouseWheel(int fwKeys,int zDelta,int xPos,int yPos )
{
	float cx,cy;//实际的位置
	cx=(CanvasRect.right/2+DrawLeft)/Scale;
	cy=(CanvasRect.bottom/2+DrawTop)/Scale;
	if(zDelta>0)
	{
		Scale=Scale*1.2;		
		DrawLeft=(cx)*Scale-CanvasRect.right/2;
		DrawTop=cy*Scale-CanvasRect.bottom/2;
	}
	else
	{
		Scale=Scale/1.2;
		DrawLeft=(cx)*Scale-CanvasRect.right/2;
		DrawTop=cy*Scale-CanvasRect.bottom/2;
	}
	ShowAllPoint();
}

int GetPointNearMouse(int xPos,int yPos)
{
	int TempIndex=-1;
	int NCount=WayPoint.GetNodeCount();
	for(int i=0;i<NCount;i++)
	{
		SWPNode *tempNode=WayPoint.GetWPNode(i);
		int dx=(xPos+DrawLeft)-tempNode->x*Scale;
		int dy=(yPos+DrawTop)-tempNode->y*Scale;
		if(dx*dx+dy*dy<36)
		{
			TempIndex=i;
			break;
		}
	}
	return TempIndex;
}

void Form_OnMouseMove(WPARAM fwKeys,int xPos,int yPos)
{
	if(fwKeys&MK_SHIFT)
	{
		SetCursor(LoadCursor(NULL,IDC_CROSS));
	}
	else if(fwKeys&MK_CONTROL)
	{
		SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(32649)));
		if(SelectedIndex!=-1)
		{
			tempLineF.x=WayPoint.GetWPNode(SelectedIndex)->x*Scale-DrawLeft;
			tempLineF.y=WayPoint.GetWPNode(SelectedIndex)->y*Scale-DrawTop;
			tempLineT.x=xPos;
			tempLineT.y=yPos;
		}
		SelectedIndexTo=GetPointNearMouse(xPos,yPos);
		if(SelectedIndexTo!=-1)
		{
			tempLineT.x=WayPoint.GetWPNode(SelectedIndexTo)->x*Scale-DrawLeft;
			tempLineT.y=WayPoint.GetWPNode(SelectedIndexTo)->y*Scale-DrawTop;
		}
		ShowAllPoint();
	}
	else if(fwKeys&MK_LBUTTON)
	{
		SetCursor(LoadCursor(NULL,IDC_SIZEALL));
		DrawLeft=DrawLeft-xPos+OldMousePosX;
		DrawTop=DrawTop-yPos+OldMousePosY;
		OldMousePosX=xPos;
		OldMousePosY=yPos;
		ShowAllPoint();
	}
}

void Form_OnLButtonDown(WPARAM fwKeys,int xPos,int yPos)
{
	if(fwKeys&MK_SHIFT&&GetPointNearMouse(xPos,yPos)==-1)
	{
		WayPoint.AddNode((xPos+DrawLeft)/Scale+0.5,(yPos+DrawTop)/Scale+0.5,WayPoint.GetNewID());
		ShowAllPoint();
	}
	else if(fwKeys&MK_CONTROL)
	{
		if(SelectedIndex!=-1)
		{
			int tempToIndex=GetPointNearMouse(xPos,yPos);
			if(tempToIndex!=-1 && tempToIndex!=SelectedIndex)
			{
				int dx=WayPoint.GetWPNode(SelectedIndex)->x
						-WayPoint.GetWPNode(tempToIndex)->x;
				int dy=WayPoint.GetWPNode(SelectedIndex)->y
						-WayPoint.GetWPNode(tempToIndex)->y;
				WayPoint.AddNeighbor(SelectedIndex,
					WayPoint.GetWPNode(tempToIndex)->ID,sqrt(float(dx*dx+dy*dy)));
				WayPoint.AddNeighbor(tempToIndex,
					WayPoint.GetWPNode(SelectedIndex)->ID,sqrt(float(dx*dx+dy*dy)));
				SelectedIndex=tempToIndex;
			}
		}
		ShowAllPoint();
	}
	else
	{
		if(GetPointNearMouse(xPos,yPos)!=-1)
			SelectedIndex=GetPointNearMouse(xPos,yPos);
		ShowAllPoint();
	}
	OldMousePosX=xPos;
	OldMousePosY=yPos;
	//SetCursor(LoadCursor(NULL,IDC_SIZEALL));
}

void Form_OnRButtonDown(WPARAM fwKeys,int xPos,int yPos)
{
	if(WayPoint.GetNodeCount()>0)
	{
		//右键指定测试小人的目标
		int destX=(xPos+DrawLeft)/Scale;
		int destY=(yPos+DrawTop)/Scale;
		int fromIndex=WayPoint.GetNearestIndex(smallTestMan.x,smallTestMan.y);
		int toIndex=WayPoint.GetNearestIndex(destX,destY);
		AStar.InitNodeByWayPoint(&WayPoint);
		if(AStar.FindPath(fromIndex,toIndex))
		{
			smallTestMan.nextNode=0;
			smallTestMan.endNode=AStar.GetNodeCount()-1;
			SetTimer(_hWnd,0,10,NULL);
		}
		ShowAllPoint();
	}
}

void Form_OnTimer()
{
	//移动测试小人
	int ni=AStar.GetNodeIndex(smallTestMan.nextNode);
	int dx=WayPoint.GetWPNode(ni)->x-smallTestMan.x;
	int dy=WayPoint.GetWPNode(ni)->y-smallTestMan.y;
	int dist=sqrt(float(dx*dx+dy*dy));
	if(dist<=4)
	{
		if(smallTestMan.nextNode==smallTestMan.endNode)
			KillTimer(_hWnd,0);
		else
			smallTestMan.nextNode++;
	}
	int step=dist/3;
	if(step==0)
		step=1;
	int vx=dx/step;
	int vy=dy/step;
	smallTestMan.x+=vx;
	smallTestMan.y+=vy;
	LPPAINTSTRUCT lps=NULL;
	BeginPaint(GetDlgItem(_hWnd,IDC_PICMAIN),lps);
	ShowAllPoint();
	EndPaint(GetDlgItem(_hWnd,IDC_PICMAIN),lps);
}

LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
	MSG *msg;
	if(code==HC_ACTION)
	{
		msg=(MSG *)lParam;
		switch(msg->message)
		{
		case WM_KEYDOWN:
			Form_OnKeyDown(msg->wParam);
			break;
		case WM_KEYUP:
			Form_OnKeyUp(msg->wParam);
			break;
		case WM_HOTKEY:
			MessageBox(_hWnd,"ppppp","",NULL);
			break;
		}
	}
	return CallNextHookEx(hMsgHook,code,wParam,lParam);
}


BOOL CALLBACK DlgMainProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	//RECT rp,rc;
	LPPAINTSTRUCT lps=NULL;
	switch(message)
	{
	case WM_INITDIALOG:
		SetIcon(hWnd,LoadIcon(_hInstance,MAKEINTRESOURCE(IDI_ICON1)),true);
		hMsgHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,_hInstance,GetWindowThreadProcessId(hWnd,NULL));
		_hWnd=hWnd;
		Form_OnLoad();
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDC_OPEN:
			Open_OnClick();
			break;
		case IDC_SAVE:
			Save_OnClick();
			break;
		case IDC_NEW:
			New_OnClick();
			break;
		}
		break;
	case WM_MOUSEMOVE:
		Form_OnMouseMove(wParam, LOWORD(lParam),HIWORD(lParam));
		break;
	case WM_LBUTTONDOWN:
		Form_OnLButtonDown(wParam, LOWORD(lParam),HIWORD(lParam));
		break;
	case WM_RBUTTONDOWN:
		Form_OnRButtonDown(wParam, LOWORD(lParam),HIWORD(lParam));
		break;
	case 0x20A:
		Form_OnMouseWheel(LOWORD(wParam),(short) HIWORD(wParam),
			LOWORD(lParam),HIWORD(lParam));
		break;
	case WM_PAINT:
		BeginPaint(GetDlgItem(_hWnd,IDC_PICMAIN),lps);
		ShowAllPoint();
		EndPaint(GetDlgItem(_hWnd,IDC_PICMAIN),lps);
		break;
	case WM_TIMER:
		Form_OnTimer();
		break;
	case WM_SYSCOMMAND:
		switch(wParam)
		{
		case SC_CLOSE:
			Form_OnClose();
			EndDialog(hWnd,0);
			return TRUE;
		}
		break;
	}
	return FALSE;
}

BOOL ShowDlgMain()
{
	if(-1==DialogBox(_hInstance,"DLGMAIN",NULL,DlgMainProc))
	{
		MessageBox(NULL,"生成窗体失败",appName,MB_DEFBUTTON1);
		return FALSE;
	}
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -