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

📄 eventmanager.cpp

📁 大型3D游戏设计制作详析及源代码对于想了解游戏设计的程序来说
💻 CPP
📖 第 1 页 / 共 2 页
字号:

			cond = ( item->val <= atoi( condition_dest.c_str() ) ) ;
		}
		else if ( op == "==" )
		{
			SPropertyItem* item = Actor.Property( property ) ;

			cond = ( item->val == atoi( condition_dest.c_str() ) ) ;
		}
		else if ( op == "HAS" )
		{
			if ( property == "装备" )
			{
				SPropertyItem* item = Actor.FindTools( condition_dest ) ;

				if ( item == NULL )
				{
					cond = false ;
				}
				else
				{
					cond = true ;
				}
			}
			else if ( property == "技能" )
			{
				try
				{
					SPropertyItem* item = Actor.Skill( condition_dest ) ;

					cond = true ;
				}
				catch (...) 
				{
					cond = false ;
				}
			}
			else
			{
				throw exception( "script error: actor's property expected in if-stmt" ) ;
			}
		}

		/*
		 *	根据解释得来得条件执行
		 */
		if ( cond )
		{
			Executer( then_stmt ) ;
		}
		else
		{
			Executer( else_stmt ) ;
		}
	}
	else if ( cmd == "NEXTEVENT" )
	{
		int id ;

		stream >> id ;

		CPlayer&	Actor = contex->m_ActorManager->GetActiveActor() ;
		int ix = Actor.x ;
		int iy = Actor.y ;

		/*
		 *	修改逻辑地图,下次可触发事件
		 */
		contex->m_LogicMap[contex->m_current_map][ix/CGameLogic::granularity][iy/CGameLogic::granularity] = id ;
	}
	else if ( cmd == "WAYPOINT" )
	{
		string name ;
		string position ;
		string temp ;
		int x, y ;

		stream >> name >> position ;

		CPlayer& Actor = contex->m_ActorManager->GetActor( name ) ;

		while ( position != "STOP" && position != "LOOP" )
		{
			size_t pos = position.find_first_of(',') ;

			temp = position.substr(1, pos-1) ;
			x = atoi( temp.c_str() ) ;

			temp = position.substr(pos+1, position.length()-1) ;
			y = atoi( temp.c_str() ) ;

			Actor.push_way_point( x, y ) ;

			stream >> position ;
		}

		if ( position == "LOOP" )
		{
			Actor.set_task_loop(true) ;
		}
		else
		{
			Actor.set_task_loop(false) ;
		}

	}
	else if ( cmd == "CLEARWAYPOINT" )
	{
		string npc ;

		stream >> npc ;
		this->contex->m_ActorManager->GetActor(npc).flush_all_way_point() ;
	}
	else if ( cmd == "SETFACING" )
	{
		string npc ;
		string point ;

		stream >> npc >> point ;

		if ( point == "UP" )
		{
			this->contex->m_ActorManager->GetActor(npc).facing = 2 ;
		}
		else if ( point == "DOWN" )
		{
			this->contex->m_ActorManager->GetActor(npc).facing = 0 ;
		}
		else if ( point == "LEFT" )
		{
			this->contex->m_ActorManager->GetActor(npc).facing = 1 ;
		}
		else if ( point == "RIGHT" )
		{
			this->contex->m_ActorManager->GetActor(npc).facing = 3 ;
		}
	}
	else if ( cmd == "ACTOR_NEXT_TALKING" )
	{
		string name ;
		string proc ;

		stream >> name >> proc ;

		this->contex->m_ActorManager->GetActor(name).NextTalking( proc ) ;
	}
	else if ( cmd == "ACTORSHOW" )
	{
		string name ;
		stream >> name ;

		/* 人物秀 */
		contex->m_discovery_board.actived = true ;
		contex->m_discovery_board.item = -1 ;//contex->m_ActorManager->GetActor(name).face_Res_id ;
		contex->m_discovery_board.description = contex->m_ActorManager->GetActor(name).self_description.c_str() ;
	}
	else if ( cmd == "CLOSESHOW" )
	{
		contex->m_discovery_board.actived = false ;
	}
	else if ( cmd == "JMP" )
	{
		int addr ;

		stream >> addr ;

		this->pos_in_a_event = pos_in_a_event + addr ;

	}
	else if ( cmd == "INCEXP" )
	{
		// ActiveActor涨经验
		int val ;

		stream >> val ;
		contex->m_ActorManager->GetActiveActor().ChangeProperty("经验", val) ;
	}
	else if ( cmd == "DISABLE_AUTO_ATTACK" )
	{
		string name ;

		stream >> name ;

		contex->m_ActorManager->GetActor(name).AutoAttack( false ) ;
	}
	else if ( cmd == "ENABLE_AUTO_ATTACK" )
	{
		string name ;

		stream >> name ;

		contex->m_ActorManager->GetActor(name).AutoAttack( true ) ;
	}
	else if ( cmd == "SET" )
	{
		string name ;
		string property ;
		int	val ;

		stream >> name >> property >> val ;

		contex->m_ActorManager->GetActor(name).Property(property)->val = val ;
	}
	else if ( cmd == "SET_ANGEL" )
	{
		double angel_up ;
		double angel_left ;

		stream >> angel_up >> angel_left ;
		contex->set_up_walking_angel( angel_up ) ;
		contex->set_left_walking_angel( angel_left ) ;
	}
	else if ( cmd == "THEEND" )
	{
		/* 当前幕通关 */
		contex->m_is_success = true ;
	}
	else if ( cmd == "LOST" )
	{
		string description ;

		stream >> description ;

		contex->m_ActorManager->GetActiveActor().DelTools( description ) ;
	}
	else if ( cmd == "NOOP" )
	{
		// 空指令,什么也不作
		return ;
	}
	else
	{
		cmd.insert(0, "Unrecognized script: ") ;
		throw exception( cmd.c_str() ) ;
	}
}

/*
 *	按照当前指针取出脚本,调用解释程序
 */
bool CEventManager::Continue_Doing()
{
	
	// 逻辑等待状态不执行脚本
	if ( is_logic_waiting() )
	{
		return false ;
	}

	if ( pos_in_a_event == FindProc(now_event).end() )
	{
		is_doing_event = false ;
		return false ;
	}

	string preProcess = *pos_in_a_event ;
	string argu = "%1" ;

	// 处理参数
	for ( int i = 0; i < 9; i++ )
	{
		argu[1] = i + '1' ;

		while (1)
		{
			size_t pos = preProcess.find(argu) ;

			if ( pos == string::npos )
			{
				break ;
			}

			preProcess.erase(pos, 2) ;
			preProcess.insert(pos, Arguments_list[i]) ;
		}
		
	}

	stringstream stream ;
	stream.rdbuf()->str( preProcess ) ;	

	// 得到当前script,指针加一
	pos_in_a_event++ ;

	Executer( stream ) ;

	return false ;
}

/*
 *	跳转到某事件执行:类似jump
 */
void CEventManager::Do_Event(int ID, std::vector<std::string>* ArguList)
{
	char buf[16] ;

	string name = itoa( ID, buf, 10 ) ;
	Do_Event(name, ArguList) ;
}

void CEventManager::Do_Event( const string& Proc, std::vector<std::string>* ArguList)
{
	now_event = Proc ;

	// 如果参数列表不为空,
	if ( ArguList != NULL )
	{
		// 加入新的参数列表
		Arguments_list = *ArguList ;
	}

	pos_in_a_event = FindProc( Proc ).begin() ;
	is_doing_event = true ;
	wait_for_enter = false ;

	// 记录数据便于统计
	call_record.insert(Proc) ;
}

/*
 *	调用某事件执行,类似call
 */
void CEventManager::Call_Event(int ID, std::vector<std::string>* ArguList)
{
	char buf[16] ;

	string name = itoa( ID, buf, 10 ) ;
	Call_Event(name) ;
}

void CEventManager::Call_Event(const string& Proc, std::vector<std::string>* ArguList)
{
	CallInfo info ;

	/*
	*	保存现场,压入调用栈
	*/
	info.proc_name = now_event ;
	info.ip = pos_in_a_event - FindProc(now_event).begin() ;
	info.Scene = this->BackBmpResName ;
	info.Mask = this->MaskBmpResName ;
	info.logical_map = this->contex->m_current_map ;

	// 现场环境和当前参数列表压栈
	Call_Stack.push_back( info ) ;
	Arguments_Stack.push_back( Arguments_list ) ;

	// 如果参数列表不为空,
	if ( ArguList != NULL )
	{
		// 加入新的参数列表
		Arguments_list = *ArguList ;
	}
	else
	{
		Arguments_list.clear() ;
	}

	/* 准备新环境 */
	now_event = Proc ;

	pos_in_a_event = FindProc(Proc).begin() ;
	is_doing_event = true ;
	wait_for_enter = false ;

	// 记录调用,便于统计
	call_record.insert(Proc) ;
}

/*
 *	切换场景操作,包括逻辑和图像
 */
void CEventManager::ChangeScene(const std::string& scene_name, const std::string& mask_name, int logical_map)
{
	GameRes* res_info ;
	int	pid ;

	res_info = this->contex->GetRes(scene_name) ;
	BackBmpResName = scene_name ;

	(*LoadBackGround)( res_info->filename.c_str(), res_info->color_key, &pid ) ;
	this->BackBmpID = pid ;

	res_info = this->contex->GetRes(mask_name) ;
	MaskBmpResName = mask_name ;
	(*LoadBGMask)( res_info->filename.c_str(), res_info->color_key , &pid ) ;
	this->MaskBmpID = pid ;

	// 切换逻辑地图
	this->contex->UseLogicalMap(logical_map) ;

	// 继续执行脚本,以获得场景转换之后的初始化
	while ( !wait_for_enter && this->Has_something_todo() ) 
	{
		this->Continue_Doing() ;
	}
}

/*
 *	输入事件号(由于触发事件从256开始编号,所以ID应该大于256),返回后续事件号
 */
int CEventManager::Following_Event(int ID )
{
	std::map<int, int>::iterator pos = relation_lib.find( ID ) ;

	if ( pos == relation_lib.end() )
	{
		return -1 ;		
	}
	else
	{
		return (*pos).second ;
	}
}

void CEventManager::PosIterator(int cs, size_t ip, std::vector< std::string>::iterator& pos)
{
	char buf[16] ;
	string ProcName = itoa(cs, buf, 10) ;

	// 转换到新过程的调用
	this->PosIterator(ProcName, ip, pos) ;
}

void CEventManager::PosIterator(const std::string& proc, size_t ip, std::vector< std::string>::iterator& pos)
{
	try
	{
		std::vector<std::string>& code = FindProc( proc ) ;

		pos = code.begin() + ip ;
	}
	catch (exception e) 
	{
		string err = "script error: call non-exsisted procedure " ;
		
		err += proc ;

		throw logic_error( err ) ;
	}
	
}

std::vector<std::string>& CEventManager::FindProc( const std::string& ProcName )
{
	list< pair<string, vector<string > > >::iterator iter = event_lib.begin() ;

	for ( ; iter != event_lib.end(); ++iter )
	{
		if ( (*iter).first == ProcName )
		{
			return (*iter).second ;
		}
	}

	string err = "script error: procedure not found " ;

	err += ProcName ;

	throw logic_error( err ) ;
}

std::vector<std::string>& CEventManager::FindProc( int ProcID )
{
	char buf[16] ;
	string ProcName = itoa(ProcID, buf, 10) ;

	return FindProc( ProcName ) ;
}

void CEventManager::Return_from_Event()
{
	CallInfo& info = Call_Stack.back() ;
	Arguments_list = Arguments_Stack.back() ;

	/* 恢复现场 */
	now_event = info.proc_name ;
	PosIterator(now_event, info.ip, pos_in_a_event ) ;

	is_doing_event = true ;
	wait_for_enter = false ;

	if ( info.Scene != this->BackBmpResName && info.Mask != this->MaskBmpResName )
	{
		this->ChangeScene( info.Scene, info.Mask, info.logical_map ) ;
		this->m_background_state = BackGround_Fadein ;
		this->m_is_in_state = false ;
	}

	Call_Stack.pop_back() ;
	Arguments_Stack.pop_back() ;
}

void CEventManager::Wait(size_t count )
{
	GetFrameCount( &m_frame_count ) ;

	m_waiting_frame = count ;
	m_is_doing_logic_wait = true ;
}

bool CEventManager::is_logic_waiting()
{
	size_t now ;

	if ( m_is_doing_logic_wait )
	{
		GetFrameCount( &now ) ;

		if ( now - m_frame_count > m_waiting_frame )
		{
			m_is_doing_logic_wait = false ;
			return false ;
		}
		else
		{
			return true ;
		}
	}
	else
	{
		return false ;
	}
}

⌨️ 快捷键说明

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