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

📄 gamelogic.cpp

📁 大型3D游戏设计制作详析及源代码,游戏脚本,设计报告,技术报告,用户手册
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************
	created:	2004/07/02
	created:	2:7:2004   22:40
	filename: 	d:\Works\Gamelib\GameLogic.cpp
	file path:	d:\Works\Gamelib
	file base:	GameLogic
	file ext:	cpp
	author:		lazybug
	
	purpose:	游戏逻辑的总管,对Delphi部分的接口函数全部由此提供,在这里创建ActorManager和
	            EventManager,并处理用户输入,管理菜单等等。
*********************************************************************/


#include "StdAfx.h"
#include <mmsystem.h>
#include <iostream>
#include <cmath>
#include "GameLogic.h"

#pragma comment(lib,"Winmm.lib")

using namespace std ;

const double PI = 3.1415926 ;

CGameLogic::CGameLogic(void)
{
	this->LoadResInfo() ;
	this->LoadLogicalMap(".\\Scenes\\bedroom.map") ;
	this->LoadLogicalMap(".\\Scenes\\garden.map") ;
	this->LoadLogicalMap(".\\Scenes\\客厅.map") ;
	this->LoadLogicalMap(".\\Scenes\\厨房.map") ;
	this->LoadLogicalMap(".\\Scenes\\地道入口.map") ;
	this->LoadLogicalMap(".\\Scenes\\柴房.map") ;
	this->LoadLogicalMap(".\\Scenes\\地下室5.map") ;
	this->LoadLogicalMap(".\\Scenes\\地下室6.map") ;
	this->LoadLogicalMap(".\\Scenes\\地下室7.map") ;
	this->LoadLogicalMap(".\\Scenes\\地下室8.map") ;

	this->UseLogicalMap(0) ;

	m_bAccept_user_inputs = true ;
	m_talking_board.actived = false ;
	m_discovery_board.actived = false ;
	m_is_fighting = false ;
	m_current_menu = -1 ;
	m_walking_speed = FASTMODE ;

	m_is_dead = false ;
	m_is_success = false ;

	m_walking_angel_up = 22.0 ;
	m_walking_angel_left = 31.0 ;

	// 敏感距离和室内外相关
	m_sensitive_length = 25 ;
	//m_walking_state = STOP ;

	m_ActorManager = new CActorManager(this) ;
	m_ActorManager->CreateActors() ;

	m_EventManager = new CEventManager(this) ;
	m_EventManager->LoadScene("scene1.script") ;

	// 初始化随机种子
	srand( timeGetTime() ) ;
}

CGameLogic::~CGameLogic(void)
{
	delete m_ActorManager ;
	delete m_EventManager ;
}

void CGameLogic::enumObj(void* object )
{
	static CBaseStruct emptyObj ;
	emptyObj.ResID = 0 ;
	CPlayer*	myPlayer ;

	if (( myPlayer = m_ActorManager->enumActor() ) != NULL )
	{
		memcpy(object, (CBaseStruct*)myPlayer, sizeof(CBaseStruct) ) ;
	}
	else
	{
		memcpy( object, &emptyObj, sizeof(CBaseStruct) ) ;
	}
}

void CGameLogic::AutoUpdate()
{
	static DWORD last_time = 0 ;

	/*
	 *	执行脚本
	 */
	if ( m_EventManager->Has_something_todo() && !m_EventManager->is_wait_for_enter() && m_GameState != MENUING )
	{
		m_EventManager->Continue_Doing() ;
	}

	if ( timeGetTime() - last_time < 30 ) 
		return;

	last_time = timeGetTime() ;

	/*
	 *	间隔一段时间给npc状态自动更新
	 */
	CPlayer*	myPlayer = m_ActorManager->enumActor() ;
	
	while ( myPlayer != NULL )
	{
		myPlayer->AutoUpdate() ;

		myPlayer = m_ActorManager->enumActor() ;
	}
}

void CGameLogic::UserInput(int keymap )
{
	static DWORD last_time = 0 ;
	static int oldkey = 0 ;
	size_t elpsedtime ;
	int dx1 = (int)( m_walking_speed * cos(m_walking_angel_up / 180 * PI) ) ; /*22, 29.5 */
	int dy1 = (int)( m_walking_speed * sin(m_walking_angel_up / 180 * PI) ) ;

	int dx2 = (int)( m_walking_speed * cos(m_walking_angel_left / 180 * PI) ) ; /*31, 21.0*/
	int dy2 = (int)( m_walking_speed * sin(m_walking_angel_left / 180 * PI) ) ;

	CPlayer& Actor = m_ActorManager->GetActiveActor() ;

	if (m_GameState == MENUING)
	{
		elpsedtime = 0 ;
	}
	else
	{
		elpsedtime = 40 ;
	}
	
	if ( timeGetTime() - last_time < elpsedtime) 
		return ;

	last_time = timeGetTime() ;

	if ( oldkey != keymap && Actor.state != FIGHTING )
	{
		//m_walking_state = STOP ;
		Actor.state = STOP ;
	}

	if ( ( keymap & 1 ) && (m_bAccept_user_inputs) )  /* 上 */
	{
		if ( oldkey == keymap )
		{
			//m_walking_state = WALKING ;
			Actor.state = WALKING ;
		}
		this->ActiveMove(dx2,-dy2) ;
		
		/* 向上移动菜单焦点 */
		if ( m_GameState == MENUING )
		{
			if ( (oldkey ^ keymap) & 1 )
			{
				oldkey = keymap ;
			}
			else
			{
				return ;
			}
			if ( m_focused_menu_item == m_scroll_point )
			{
				if ( Scrolled( UPWARD ) )
				{
					m_focused_menu_item-- ;
				}
			}
			else
			{
				m_focused_menu_item-- ;
			}
		}

		// 返回,不接收同时输入
		oldkey = keymap ;
		return ;
	}
	if ( ( keymap & 2 ) && (m_bAccept_user_inputs) )  /* 下 */
	{
		if ( oldkey == keymap )
		{
			//m_walking_state = WALKING ;
			Actor.state = WALKING ;
		}
		ActiveMove(-dx2, dy2) ;

		/* 移动菜单焦点 */
		if ( m_GameState == MENUING )
		{
			if ( (oldkey ^ keymap) & 2 )	
			{
				oldkey = keymap ;
			}
			else
			{
				return ;
			}

			if ( !is_enum_item_end( m_focused_menu_item ) )
			{
				m_focused_menu_item++ ;
				if ( is_enum_item_end(m_focused_menu_item) )
				{
					m_focused_menu_item-- ;
				}
				if ( m_focused_menu_item - m_scroll_point == MAXSCROLLITEM )
				{
					if (!Scrolled( DOWNWARD ))
					{
						m_focused_menu_item-- ;
					}
				}
			}
			
		}
		// 返回,不接收同时输入
		oldkey = keymap ;
		return ;
	}
	if ( ( keymap & 4 ) && (m_bAccept_user_inputs) )  /* 左 */
	{
		if ( oldkey == keymap )
		{
			//m_walking_state = WALKING ;
			Actor.state = WALKING ;
		}
		ActiveMove(-dx1, -dy1) ;

		// 返回,不接收同时输入
		oldkey = keymap ;
		return ;
	}
	if ( ( keymap & 8 ) && (m_bAccept_user_inputs) )  /* 右 */
	{
		if ( oldkey == keymap )
		{
			//m_walking_state = WALKING ;
			Actor.state = WALKING ;
		}
		ActiveMove(dx1, dy1) ;

		// 返回,不接收同时输入
		oldkey = keymap ;
		return ;
	}
	if ( keymap & 32 )
	{
		if ( (oldkey ^ keymap) & 32 )	
		{
			oldkey = keymap ;
		}
		else
		{
			return ;
		}

		if ( m_EventManager->is_wait_for_enter() )
		{
			m_EventManager->UserPressedEnter() ;
		}
		else
		{
			if ( m_bAccept_user_inputs && !Actor.is_dead )
			{
				if ( m_GameState == MENUING ) 
				{
					SelectItem() ;
				}
				else
				{
					Research() ;
				}
			}
		}
		
	}
	/* 呼出菜单 */
	if ( keymap & 64 )
	{
		// todo: 激活菜单
		BringUpMenu( MENU1 ) ;
	}
	if ( keymap & 128 )
	{
		// todo: 二号菜单
	    BringUpMenu( MENU2 ) ;
	}
	if ( keymap & 256 )
	{
		// todo:三号菜单
		//BringUpMenu( MENU3 ) ;
	}
	if ( keymap & 512 )
	{
		// todo: 四号菜单
		//BringUpMenu( MENU4 ) ;
	}
	/* 关闭菜单 */
	if ( keymap & 1024 )
	{
		m_GameState = NORMAL ;
		m_current_menu = NOMENU ;
	}
	oldkey = keymap ;
}

const STalking_Board* CGameLogic::QueryTalking()
{
	if ( m_talking_board.actived )
	{
		return &m_talking_board ;
	}
	else
	{
		return NULL ;
	}
}

const SDiscovery_Board*	CGameLogic::QueryDiscovery()
{
	if ( m_discovery_board.actived )
	{
		return &m_discovery_board ;
	}
	else
	{
		return NULL ;
	}
}

void CGameLogic::ActiveMove(int dx, int dy )
{
	CPlayer&	Actor = m_ActorManager->GetActiveActor() ;
	int ix = Actor.x + dx ;
	int iy = Actor.y + dy ;
	
	int event_id = this->m_LogicMap[m_current_map][ix/granularity][iy/granularity] ;

	if ( event_id != 0 && this->m_current_menu == NOMENU )
	{
		if ( !Actor.DetectOtherActor(dx, dy) )
		{
			Actor.x = ix ;
			Actor.y = iy ;
		}

		if ( dx > 0 && dy > 0 )
			Actor.facing = 1 ;
		if ( dx < 0 && dy < 0 )
			Actor.facing = 3 ;
		if ( dy < 0 && dx > 0 )
			Actor.facing = 2 ;
		if ( dy > 0 && dx < 0 )
			Actor.facing = 0 ;

		if ( event_id != 1 && event_id != -1 && event_id < 256 )
		{
			m_EventManager->Do_Event(event_id) ;
		}
	}
}

/*
 *	读取地图目标
 */
void CGameLogic::LoadLogicalMap(const std::string& name)
{
	int i, j, map_no ;
	ifstream in ;

	in.open(name.c_str(), ios::in) ;
	if ( in.is_open() )
	{
		in >> map_no ;
		for (i = 0; i < 600 / granularity ; i++)
		{
			for ( j = 0; j < 800 / granularity ; j++)
				in >> m_LogicMap[map_no][j][i] ;
		}
	}
	else
	{
		throw exception("map file not found!") ;
	}
}

/*
 *	读取资源信息
 */
void CGameLogic::LoadResInfo()
{
	ifstream in ;
	GameRes info ;
	string	index ;

	in.open( ".\\Scenes\\GameRes.res" ) ;
	
	if ( in.is_open() )
	{
		while ( !in.eof() )
		{
			in >> index >> info.filename >> info.h_frame >> info.v_frame >> info.color_key ;
			m_game_res.insert( make_pair(index, info) ) ;
		}
	}
	
	else
	{
		throw exception("GameResInfo file not found!") ;
	}
}

/*
 *	从资源库根据名字得到资源描述结构体
 */
GameRes*	CGameLogic::GetRes(const std::string& res_name)
{
	map<string,GameRes>::iterator pos = m_game_res.find(res_name) ;

	if ( pos != m_game_res.end())
	{
		return &(pos->second) ;
	}
	else
	{
		throw exception("try to get an nonexsisted resource!") ;
	}
}

/*
 *	枚举菜单项
 */
void CGameLogic::enumMenuItem(void* pItem )
{
	static		SMenuItem item ;
	static		string temp ;
	stringstream stream ;
	CPlayer&	player = m_ActorManager->GetActiveActor() ;

	if ( !( m_enumPointer == m_scroll_point + MAXSCROLLITEM ) && !is_enum_item_end( m_enumPointer ) )
	{

⌨️ 快捷键说明

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