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

📄 mainfrm.cpp

📁 2D Collsion Detection in Real-time Demonstration This is the sample application that accompanies G
💻 CPP
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
// MainFrm.cpp : implementation of the CMainFrame class
//
// Purpose:	Implementation of 2D Collision System
//
// Created:
//		JL 11/1/98		
//
// Notes:  THIS CONTAINS SOME USEFUL COMPUTATIONAL GEOMETRY ROUTINES AT THE
//	END OF THIS FILE.
//
///////////////////////////////////////////////////////////////////////////////
//
//	Copyright 1998 Jeff Lander, All Rights Reserved.
//  For educational purposes only.
//  Please do not republish in electronic or print form without permission
//  Thanks - jeffl@darwin3d.com
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <math.h>
#include <mmsystem.h>
#include <Direct.h>
#include "Fate.h"

#include "MainFrm.h"

//IGNORE THE DOUBLE TO FLOAT CONVERSION WARNING
#pragma warning ( disable : 4244 )

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(ID_OPTIONS_GRID_DOWN, OnOptionsGridDown)
	ON_COMMAND(ID_OPTIONS_GRIDUP, OnOptionsGridup)
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_OPTIONS_ZOOMIN, OnOptionsZoomin)
	ON_COMMAND(ID_OPTIONS_ZOOMOUT, OnOptionsZoomout)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONUP()
	ON_WM_PAINT()
	ON_COMMAND(ID_FILE_NEW, OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	//}}AFX_MSG_MAP
	// Global help commands
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,				// status line indicator
	ID_INDICATOR_INFO,          // status line INFO
	ID_INDICATOR_SNAP,          // status line SNAP
	ID_INDICATOR_GRID,          // status line GRIDSIZE
	ID_INDICATOR_SC2,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	m_offX = 0;
	m_offY = 0;
	m_scale = 0.4;
	m_gridsize = 64;
	m_snap = TRUE;
	m_point = NULL;
	// SET UP THE WORLD VARIABLES
	m_cursector = NULL;
	m_curedge = NULL;
	m_firstedge = NULL;		// FIRST EDGE IN A SECTOR
	m_edgecnt = 0;
	m_sectorcnt = 0;
	m_nearest_edge = -1;
	m_nearest_pnt.x = 0;
	m_nearest_pnt.y = 0;
	m_old_pnt.x = -2;
	m_old_pnt.y = -2;

	m_cam_pos.x = 0;
	m_cam_pos.y = 0;
	m_cam_pos.z = 0;
	m_cam_yaw = 0;
	m_cam_pitch = 0;
	m_cam_sector = -1;

	InitTrig();
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	char str[80];

	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	GetWindowRect(&m_window_rect);

	sprintf(str,"Zoom = %2.1f",m_scale);
	SetStatusText(4,str);
	sprintf(str,"Grid = %3d",m_gridsize);
	SetStatusText(3,str);
	SetStatusText(2,"Snap On");
	sprintf(str,"Sectors = %3d  Edges = %3d",m_sectorcnt,m_edgecnt);
	SetStatusText(1,str);

	return 0;
}

void CMainFrame::SetStatusText(short id,char *string )
{
	m_wndStatusBar.SetPaneText(id,string);
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFrameWnd::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// Scale the Grid Size Up
void CMainFrame::OnOptionsGridup() 
{
	char str[80];
	if (m_gridsize <= 1024) m_gridsize *= 2;
	sprintf(str,"Grid = %4d",m_gridsize);
	SetStatusText(3,str);
	Invalidate (TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// Scale the Grid Size Down
void CMainFrame::OnOptionsGridDown() 
{
	char str[80];
	if (m_gridsize > 2) 
	{
		m_gridsize /= 2;
		sprintf(str,"Grid = %4d",m_gridsize);
	}
	else
	{
		m_gridsize = 1;
		sprintf(str,"Grid OFF");
	}
	SetStatusText(3,str);
	Invalidate (TRUE);
}

void CMainFrame::OnOptionsZoomin() 
{
	char str[80];
	if (m_scale <= 10.0) m_scale += .1;
	sprintf(str,"Zoom = %2.1f",m_scale);
	SetStatusText(4,str);
	Invalidate (TRUE);
}

void CMainFrame::OnOptionsZoomout() 
{
	char str[80];
	if (m_scale > 0.2)
	{
		m_scale -= 0.1;
	}
	sprintf(str,"Zoom = %2.1f",m_scale);
	SetStatusText(4,str);
	Invalidate (TRUE);
}

void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	tPoint3D	temp;
	tPoint2D	temp2D;
	int cx, cy;
	CRect rect;
	cx = (GetSystemMetrics(SM_CXFULLSCREEN) - (640 + 8)) / 2;
	cy = (GetSystemMetrics(SM_CYFULLSCREEN) - (480 + 94)) / 2;
	
	switch (nChar)
	{
		case VK_INSERT:
			InsertPoint();
			Invalidate(TRUE);
			break;
		case VK_DELETE:		
			DeleteSector();
			Invalidate(TRUE);
			break;
		case VK_RETURN:		
			CloseSector();
			Invalidate(TRUE);
			break;
		case VK_ADD:
			OnOptionsGridup();
			break;
		case VK_SUBTRACT:
			OnOptionsGridDown();
			break;
		case 'A':
			OnOptionsZoomin();
			break;
		case 'M':
			break;
		case 'Z':
			OnOptionsZoomout();
			break;
		case 'S':
			m_snap = TRUE - m_snap;
			if (m_snap)
				SetStatusText(2,"Snap On");
			else
				SetStatusText(2,"Snap Off");
			break;
		case VK_UP:
			temp.x = m_cam_pos.x + (m_sin[m_cam_yaw]>>13);
			temp.z = m_cam_pos.z + (m_cos[m_cam_yaw]>>13);
			if (m_cam_sector == -1)
			{
				m_cam_pos.x = temp.x;
				m_cam_pos.z = temp.z;
				temp2D.x = temp.x;
				temp2D.y = temp.z;
				m_cam_sector = InsideSector(&temp2D);
			}
			else
			{
				if (CheckCollision(m_cam_sector,&temp))
				{
					m_cam_pos.x = temp.x;
					m_cam_pos.z = temp.z;
				}
			}
			Invalidate(TRUE);
			break;
		case VK_DOWN:
			temp.x = m_cam_pos.x - (m_sin[m_cam_yaw]>>13);
			temp.z = m_cam_pos.z - (m_cos[m_cam_yaw]>>13);
			if (m_cam_sector == -1)
			{
				m_cam_pos.x = temp.x;
				m_cam_pos.z = temp.z;
				temp2D.x = temp.x;
				temp2D.y = temp.z;
				m_cam_sector = InsideSector(&temp2D);
			}
			else
			{
				if (CheckCollision(m_cam_sector,&temp))
				{
					m_cam_pos.x = temp.x;
					m_cam_pos.z = temp.z;
				}
			}
			Invalidate(TRUE);
			break;
		case VK_LEFT:
			m_cam_yaw += (4096 - 128);
			m_cam_yaw %= 4096;
			Invalidate(TRUE);
			break;
		case VK_RIGHT:
			m_cam_yaw += 128;
			m_cam_yaw %= 4096;
			Invalidate(TRUE);
			break;
	}
	
	CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

//////////////////////////////////////////////////////////////////
// Procedure:	OnRButtonUp
// Purpose:		Right Mouse Button Handler
//////////////////////////////////////////////////////////////////
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) 
{
	tPoint2D temp;
	// MOVE THE CAMERA POSITION TO WHERE THE USER CLICKS
	m_cam_pos.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale);
	m_cam_pos.z = -(long)((point.y + m_offY - (m_sizeY / 2)) / m_scale);
	temp.x = m_cam_pos.x;
	temp.y = m_cam_pos.z;
	m_cam_sector = InsideSector(&temp);
	Invalidate(TRUE);
	CFrameWnd::OnRButtonUp(nFlags, point);
}

#define VERTEX_SNAP_PROXIMITY		100

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) 
{
	short loop,t_sector,t_edge;	
	tPoint2D temp;
	long dist;
	char message[80];

	temp.x = (long)((point.x + m_offX - (m_sizeX / 2)) / m_scale);
	temp.y = (long)-((point.y + m_offY - (m_sizeY / 2)) / m_scale);
	if ((nFlags & MK_CONTROL) > 0)
	{
		t_sector = -1;
		for (loop = 0; loop < m_edgecnt; loop++)
		{
			dist = (temp.x - m_edgelist[loop].pos.x) * 		// SQUARED DISTANCE
					(temp.x - m_edgelist[loop].pos.x) +
					(temp.y - m_edgelist[loop].pos.y) * 
					(temp.y - m_edgelist[loop].pos.y); 
			if (dist < VERTEX_SNAP_PROXIMITY)
			{
				temp.x = m_edgelist[loop].pos.x;
				temp.y = m_edgelist[loop].pos.y;
				t_sector = m_edgelist[loop].sector;
				t_edge = loop;
			}
		}
		if (t_sector == -1)	// IF I DIDN'T CLICK ON AN EXISTING POINT, SNAP IT
		{
			SnapPoint(&temp);
			// CHECK ALL POINTS AGAIN ONCE I HAVE SNAPPED
			for (loop = 0; loop < m_edgecnt; loop++)
			{
				dist = (temp.x - m_edgelist[loop].pos.x) *		// SQUARED DISTANCE
						(temp.x - m_edgelist[loop].pos.x) +
						(temp.y - m_edgelist[loop].pos.y) * 
						(temp.y - m_edgelist[loop].pos.y); 
				if (dist < VERTEX_SNAP_PROXIMITY)
				{
					temp.x = m_edgelist[loop].pos.x;
					temp.y = m_edgelist[loop].pos.y;
					t_sector = m_edgelist[loop].sector;
					t_edge = loop;
				}
			}
		}
		if (m_cursector == NULL)	// haven't created a sector
		{
			m_cursector = &m_sectorlist[m_sectorcnt];
			m_cursector->edge = m_edgecnt;
			m_cursector->edgecnt = 1;
			m_cursector->flags = 0;
			m_curedge = &m_edgelist[m_edgecnt];
			m_curedge->pos.x = temp.x;
			m_curedge->pos.y = temp.y;
			m_curedge->sector = m_sectorcnt;
			m_curedge->backsector = -1;
			m_curedge->backedge = -1;
			m_curedge->nextedge = -1;
			m_curedge->prevedge = -1;
			m_firstedge = m_curedge;
			m_sectorcnt++;
			m_edgecnt++;
			Invalidate(TRUE);
		}
		else
		{
			if (&m_sectorlist[t_sector] == m_cursector)
			{
				if (t_edge == m_cursector->edge)	// CLOSED THE SECTOR
				{
					m_curedge->nextedge = m_cursector->edge;
					m_firstedge->prevedge = m_edgecnt - 1;	// LINK BACK THE START TO THE END
					m_cursector->flags = SECTOR_FLAGS_CLOSED;
					m_cursector->ceil_tex = 0;
					m_cursector->floor_tex = 0;
					m_cursector->floor_height = 0;
					m_cursector->ceil_height = 2048;
					m_cursector = NULL;
					CheckDoubleSided();
				}
			}
			else
			{
				m_curedge->nextedge = m_edgecnt;
				m_cursector->edgecnt++;
				m_curedge = &m_edgelist[m_edgecnt];
				m_curedge->pos.x = temp.x;
				m_curedge->pos.y = temp.y;
				m_curedge->sector = m_sectorcnt - 1;
				m_curedge->backsector = -1;
				m_curedge->backedge = -1;
				m_curedge->nextedge = -1;
				m_curedge->prevedge = m_edgecnt - 1;
				m_edgecnt++;
			}
			Invalidate(TRUE);
		}
		m_point = NULL;
		sprintf(message,"Sectors = %d  Edges = %d",m_sectorcnt,m_edgecnt);
		SetStatusText(1,message);
	}
	else if ((nFlags & MK_SHIFT) > 0)
	{
		m_clickpoint = point;
	}
	else	// MOVE A SET POINT
	{
		m_point = NULL;
		for (loop = 0; loop < m_edgecnt; loop++)
		{
			dist = (temp.x - m_edgelist[loop].pos.x) * 

⌨️ 快捷键说明

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