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

📄 cbmouse.cpp

📁 网页游戏赤壁
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////
//	CBDraw.cpp		:	v0021
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.2 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996-1997 WayAhead Corporation
//	v0021			:	Jan.22.1997, devided from CBDraw.cpp
//  v0022			:	Sep.11.1997, HitTestU() parameters changed
/////////////////////
#include "stdafx.h"
#include <stdio.h>
#include "CBMouse.h"

#include "Assert.h"
#include "DDCompo.h"
#include "CBMap.h"
#include "CBGame.h"
#include "CBDraw.h"
#include "CBCtrl.h"
#include "CBEyes.h"
#include "CBMini.h"
#include "CBShadow.h"

#include "Marco.h"

/////////////////////
// external globals
// declared in CBDraw.cpp
extern RECT DRAW_rcScreen;
extern RECT DRAW_rcClient;
extern POINT DRAW_ptScreenOffset;
extern POINT DRAW_ptCovering[2][9];
/////////////////////

// private globals,for mouse control
/////////////////////
// array used for detecting if mouse hit the region
// 探测鼠标点击
int nByConts[MAP_ITEM_WIDTH][MAP_ITEM_HEIGHT];
/////////////////////

/////////////////////
// state of the cursor, 但是不一定与pCursor的状态一样
int MOUSE_nState = MOUSE_STATE_NONE;
/////////////////////

/////////////////////
// local functions
BOOL MOUSE_bEnableTest=TRUE;
void MOUSE_testState( int nPosX, int nPosY );
/////////////////////

/////////////////////
// 初始化探测用数据
extern CDDPalette palMain;
void MOUSE_InitByConts()
{
//为数组nByConts[MAP_ITEM_WIDTH][MAP_ITEM_HEIGHT]赋值
	memset( nByConts, 0, MAP_ITEM_WIDTH*MAP_ITEM_HEIGHT );
	int halfwidth = MAP_ITEM_WIDTH>>1;
	int jj;
	for(int j=0; j<(MAP_ITEM_HEIGHT>>1); j++ ) 
	{
		jj = (j+1)<<1;
		for(int i=halfwidth-jj; i<halfwidth+jj; i++ )
		{
			nByConts[i][j]=1;
			nByConts[i][MAP_ITEM_HEIGHT-j-2]=1;
		}
	}
}
/////////////////////

/////////////////////
// 检验鼠标点击的效果
// pt		:	鼠标点击的坐标,直接从GetCursorPos()中的得到的,以点为单位。
// 返回格子(行、列)
inline POINT MOUSE_hitTestPoint( POINT pt )
{
	POINT ptReturn;
	POINT ptGrid[3], ptOff[3];
	SIZE szItem;

	// initialize
	szItem.cx = MAP_Lib.szItem.cx, szItem.cy = MAP_Lib.szItem.cy;
	ptReturn.x = ptReturn.y = -1;

//	OutputString( pt.x, "," );
//	OutputString( pt.y, "\n" );

	// get grids position
	int halfy = szItem.cy>>1;
	int halfx = szItem.cx>>1;
	ptGrid[0].y = pt.y/(halfy);
	ptGrid[1].y = ptGrid[0].y-1;
	ptGrid[2].y = ptGrid[0].y-1;
	ptOff[0].y = pt.y - ptGrid[0].y*(halfy);
	ptOff[1].y = ptOff[0].y + halfy;
	ptOff[2].y = ptOff[0].y + halfy;
	int bOdd = ptGrid[0].y&1;
	int bEven = 1 - bOdd;
	ptGrid[0].x = (pt.x - halfx*bOdd) / szItem.cx;
	ptGrid[1].x = ptGrid[0].x + bOdd - 1; 
	ptGrid[2].x = ptGrid[0].x + bOdd;
	ptOff[0].x = pt.x - ptGrid[0].x*szItem.cx - halfx*bOdd;
	ptOff[1].x = pt.x - ptGrid[1].x*szItem.cx - halfx*bEven;
	ptOff[2].x = pt.x - ptGrid[2].x*szItem.cx - halfx*bEven;

	// check
	for( int i=0; i<3; i++ )
	{
		if( ptOff[i].x >= 0 && ptOff[i].y >= 0 &&
			ptOff[i].x < szItem.cx && ptOff[i].y < szItem.cy )
		{
			// test if in the points
			if( nByConts[ptOff[i].x][ptOff[i].y] == 1 )
			{
				// global position
//				ptReturn.x = DRAW_rcScreen.left + ptGrid[i].x + DRAW_SCREEN_ADJUST;
//				ptReturn.y = DRAW_rcScreen.top + ptGrid[i].y;
				ptReturn.x = ptGrid[i].x;// + DRAW_SCREEN_ADJUST;
				ptReturn.y = ptGrid[i].y;
				return ptReturn;
			}
		}
	}

	// set coords
	return ptReturn;
}

// 检测单元
// pt			:	鼠标点击的坐标,直接从GetCursorPos()中的得到的,以点为单位。
// pHitResult	:	检测的结果
// bEnemy		:	只选择敌人时为真
// 返回FALSE时pHitResult无效
BOOL MOUSE_HitTestU( POINT pt, struct MOUSE_HITRESULT_STRUCT *pHitResult, BOOL bEnemy/*=0*/ )
{
	POINT point, ptGrid;

	ptGrid.x = -1, ptGrid.y = -1;
	pHitResult->nType = MOUSE_HITRESULT_NONE;	// initialize

	pt.x += DRAW_ptScreenOffset.x, pt.y += DRAW_ptScreenOffset.y;
	ptGrid = MOUSE_hitTestPoint( pt );
	if( ptGrid.x == -1 || ptGrid.y == -1 )	return FALSE;
	Assert( ptGrid.x != -1 && ptGrid.y != -1 );
	pt.x -= DRAW_ptScreenOffset.x, pt.y -= DRAW_ptScreenOffset.y;

	// get display data
	point.x = ptGrid.x, point.y = ptGrid.y;
	WORD codeUEx = MAP_GetUnitDataEx( point.x, point.y );
	if( codeUEx != MAP_DATA_NONE )
	{
		struct UNIT_STRUCT * pUnit = MAP_GetUnit( codeUEx );
		// reset position
		point.x = pUnit->Draw.nX, point.y = pUnit->Draw.nY;

		// Please note:
		RECT rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pUnit->Draw );
		if( rect.left < pt.x && rect.right >= pt.x &&
			rect.top < pt.y && rect.bottom >= pt.y )
		{
			// 如果该单元已经死亡,则不算
			// 如果该单元不是敌人,而且bEnemy是TRUE,则不算, Sep.11.1997
			struct UNIT_STRUCT *pUnit = MAP_GetUnit( codeUEx );
			Assert( pUnit );
			if( !EYE_IfUnitIsDead( pUnit ) 
				&& !( bEnemy == TRUE && pUnit->Draw.nPlayer == GAME.nMe ) )
			{
				BOOL bSet = TRUE;
				if( SHADOW_IfEnabled() )
				{
					WORD codeR = MAP_GetRegionData( point.x, point.y );
					struct MAP_REGION_CODE_STRUCT stctR;
					MAP_RegionDeCode( codeR, &stctR );
					if( stctR.nShadow == MAP_SHADOW_NONE || stctR.nShadowEx == 1 )
					{// 有任何形式的阴影,不响应
						bSet = FALSE;
					}
					if( pUnit->Draw.nPlayer == 0 )
					{// 是资源,可以响应
						bSet = TRUE;
					}
				}
				if( bSet == TRUE )
				{
					pHitResult->nType = MOUSE_HITRESULT_UNIT;	
					pHitResult->nLayer = pUnit->Draw.nLayer;
					Assert( pHitResult->nLayer < 3 );
					pHitResult->wCode = codeUEx;
					pHitResult->ptHit.x = point.x;
					pHitResult->ptHit.y = point.y;
					return TRUE;
				}
			}
		}
	}

	for( int y=4; y>=0; y-- )
	for( int x=0; x<9; x++ )
	{
		// calc next position
		int bOdd = pt.y&1;
		point.x = ptGrid.x+DRAW_ptCovering[bOdd][x].x;
		point.y = ptGrid.y+DRAW_ptCovering[bOdd][x].y+y*2;
		if( EYE_IfOutOfRange( point.x, point.y ) )
			continue;

		// get display data
		WORD codeUEx = MAP_GetUnitDataEx( point.x, point.y );
		if( codeUEx != MAP_DATA_NONE )
		{
			struct UNIT_STRUCT * pUnit = MAP_GetUnit( codeUEx );
			// reset position
			point.x = pUnit->Draw.nX, point.y = pUnit->Draw.nY;
			RECT rect = MAP_GetUnitRect( DRAW_ptScreenOffset, &pUnit->Draw );
			if( rect.left < pt.x && rect.right >= pt.x &&
				rect.top < pt.y && rect.bottom >= pt.y )
			{
				// 如果该单元已经死亡,则不算
				// 如果该单元不是敌人,而且bEnemy是TRUE,则不算, Sep.11.1997
				struct UNIT_STRUCT *pUnit = MAP_GetUnit( codeUEx );
				Assert( pUnit );
				if( !EYE_IfUnitIsDead( pUnit ) 
					&& !( bEnemy == TRUE && pUnit->Draw.nPlayer == GAME.nMe ) )
				{
					BOOL bSet = TRUE;

					if( SHADOW_IfEnabled() )
					{
						WORD codeR = MAP_GetRegionData( point.x, point.y );
						struct MAP_REGION_CODE_STRUCT stctR;
						MAP_RegionDeCode( codeR, &stctR );
						if( stctR.nShadow == MAP_SHADOW_NONE || stctR.nShadowEx == 1 )
						{
							bSet = FALSE;
						}
					}
					if( bSet == TRUE )
					{
						pHitResult->nType = MOUSE_HITRESULT_UNIT;
						pHitResult->nLayer = pUnit->Draw.nLayer;
						pHitResult->wCode = codeUEx;
						pHitResult->ptHit.x = point.x;
						pHitResult->ptHit.y = point.y;

						return TRUE;
					}
				}
			}
		}
	}

	// else return false
//	OutputDebugString( "HitTestU: Not Detected!\n" );
	return FALSE;
}

// 检测地形
// pt			:	鼠标点击的坐标,直接从GetCursorPos()中的得到的,以点为单位。
// pHitResult	:	检测的结果
// nLayer		:	检测的层数,缺省值为2,所有三层的地形都要检测
// 返回FALSE时pHitResult无效
BOOL MOUSE_HitTestG( POINT pt, struct MOUSE_HITRESULT_STRUCT *pHitResult, int nLayer/* = 2*/ )
{
	POINT ptGrid;
	POINT point;
	WORD codeG;

	// initialize
	ptGrid.x = -1, ptGrid.y = -1;
	pHitResult->nType = MOUSE_HITRESULT_NONE;

	pt.x += DRAW_ptScreenOffset.x, pt.y += DRAW_ptScreenOffset.y;
	point.x = pt.x;
	for( int i=nLayer; i>=0 ; i-- )
	{
		point.y = pt.y+MAP_Lib.nHeight[i+1];
		ptGrid = MOUSE_hitTestPoint( point );
		// hit point test
		if( ptGrid.x == -1 || ptGrid.y == -1 )	return FALSE;	// not hit any point

		codeG = MAP_GetGroundData( i, ptGrid.x, ptGrid.y );
		if( codeG != MAP_DATA_NONE )
		{
			pHitResult->nType = MOUSE_HITRESULT_GROUND;	
			pHitResult->nLayer = i;
			Assert( i < 3 );
			pHitResult->wCode = codeG;
			pHitResult->ptHit.x = ptGrid.x;
			pHitResult->ptHit.y = ptGrid.y;
			return TRUE;
		}
	}
	// else return false
//	OutputDebugString( "HitTestG: Not Detected!\n" );
	return FALSE;
}

// 先检测地形后检测单元
// pt			:	鼠标点击的坐标,直接从GetCursorPos()中的得到的,以点为单位。
// pHitResult	:	检测的结果
// 返回FALSE时pHitResult无效
BOOL MOUSE_HitTestGU( POINT pt, struct MOUSE_HITRESULT_STRUCT *pHitResult )
{
	if( !MOUSE_HitTestG( pt, pHitResult ) )
	{
		return MOUSE_HitTestU( pt, pHitResult );
	}
	return TRUE;
}

// 先检测单元后检测地形
// pt			:	鼠标点击的坐标,直接从GetCursorPos()中的得到的,以点为单位。
// pHitResult	:	检测的结果
// bEnemy		:	只选择敌人时为真
// 返回FALSE时pHitResult无效
BOOL MOUSE_HitTestUG( POINT pt, struct MOUSE_HITRESULT_STRUCT *pHitResult, BOOL bEnemy /*=0*/ )
{
	if( !MOUSE_HitTestU( pt, pHitResult, bEnemy ) )
	{
		return MOUSE_HitTestG( pt, pHitResult );
	}
	return TRUE;
}
/////////////////////

/////////////////////
// test mouse dragging

// globals
// synchronization for drag and draw
BOOL MOUSE_bSemaphore = FALSE;

// if left mouse button is down
BOOL MOUSE_bLeftDown = FALSE;
BOOL MOUSE_bLeftDownLast = FALSE;

/*
// if right mouse button is down
BOOL MOUSE_bRightDown = FALSE;
BOOL MOUSE_bRightDownLast = FALSE;
*/

// dragging rectangle, and the old one
RECT MOUSE_rcDrag, MOUSE_rcDragLast;

// the first point mouse button down
POINT MOUSE_ptFirst;

// save the origional mouse moving range
RECT rcOldRange;

// if mouse left button down, set down flag, begin dragging process
// nPosX, nPosY	:	mouse cursor position
void MOUSE_LeftDown( int nPosX, int nPosY )
{
	// clear semaphore flag
	MOUSE_bSemaphore = FALSE;

	// set the flag
	if( MOUSE_bLeftDown == TRUE )
		return;
	MOUSE_bLeftDown = TRUE;
	MOUSE_bLeftDownLast = TRUE;

	// set value to MOUSE_rcDrag
	SetRect( &MOUSE_rcDrag, nPosX, nPosY, nPosX, nPosY );
	SetRect( &MOUSE_rcDragLast, nPosX, nPosY, nPosX, nPosY );
	MOUSE_ptFirst.x = nPosX, MOUSE_ptFirst.y = nPosY;

	// set mouse cursor new range
	class CDDCursor *pCursor;
	pCursor = CURSOR_Get();
	Assert( pCursor!= NULL );
	rcOldRange = pCursor->SetRange( &DRAW_rcClient );
	Assert( rcOldRange.left == 0 && rcOldRange.top == 0 );

	// change cursor state
	MOUSE_testState( nPosX, nPosY );
}

// if mouse left button up, clear down flag, end dragging process
// nPosX, nPosY	:	mouse cursor position
// return		:	dragging rectangle

⌨️ 快捷键说明

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