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

📄 ctalk.cpp

📁 一个个人开发的rpg游戏<亚特兰蒂斯传奇>的源码
💻 CPP
字号:
//--------------------------------------------------------------------------------------------------------
//                        游戏对话模块
//CTalk.cpp
//游戏引擎中的对话部分
//作者:吴振华(kylinx)(中国科大01级11系)
//E-mail:game-diy@163.com
//创建于:2003/7/13 by Kylinx
//--------------------------------------------------------------------------------------------------------
#include"CTalk.h"
#include"CGame.h"
#include"CMessage.h"
#include"CCursor.h"
#include"CMacro.h"
#include"CFont.h"
#include"CGraph.h"
CRenderText::CRenderText():CRenderTask()
{
	
	m_nCurChar=0;
	m_nLineChar=0;
	m_x=0;
	m_y=0;
	m_dwDelay=0;
	m_dwOldTime=0;
	m_bEnd=false;
}
CRenderText::~CRenderText()
{
}

void CRenderText::EndRender()
{
	m_bEnd=true;
}
void CRenderText::AnalyseString()
{
	int row=1;
	int temppos=0;
	int i=0;
	int textlength=strlen(m_szText);
	while(i<textlength)
	{
		if(m_szText[i]=='<'|| m_szText[i]=='/')
		{
			i+=2;
			continue;
		}
		if((char)m_szText[i]<0)
		{
			i+=2;
			temppos+=2;
		}
		else
		{
			i++;
			temppos++;
		}
		if(temppos>=m_nLineChar)
		{
			temppos=0;
			row++;
		}
	}
	HDC hdc;
	TEXTMETRIC tm;
	m_pDisplay->GetBackBuffer()->GetDC(&hdc);
	::SelectObject(hdc,m_pFont->GetFont());
	::GetTextMetrics(hdc,&tm);
	m_pDisplay->GetBackBuffer()->ReleaseDC(hdc);

	m_nCharWidth=tm.tmAveCharWidth;
	m_nCharHeight=tm.tmHeight+tm.tmExternalLeading;

	
	if(m_dwBkColor!=RGB(0,0,0))
	{
		m_rtArea.left=m_x-tm.tmMaxCharWidth;
		m_rtArea.top=m_y-m_nCharHeight;
		m_rtArea.right=tm.tmMaxCharWidth*2+m_rtArea.left+m_nCharWidth*m_nLineChar;
		m_rtArea.bottom=m_nCharHeight*2+m_rtArea.top+row*m_nCharHeight;					//计算背景矩形范围
	
		if(m_bExt)
		{
			m_rtArea.left=20;
			m_rtArea.bottom+=15;
			m_rtArea.right=620;
		}
	}
	else
	{
		::SetRectEmpty(&m_rtArea);
	}
}
BOOL CRenderText::ShowText(CDisplay*pDisplay,int x,int y,char*str,
						DWORD dwDefaultTextColor,DWORD dwBkColor ,int nBkAlpha,
						int nLineChar,
						DWORD dwDelay,BOOL bExt,CFont*pFont)
{
	LOA_ASSERT(pDisplay);

	m_pDisplay=pDisplay;
	m_x=x;
	m_y=y;
	m_bExt=bExt;
	memset(m_szText,0,1024);
	strncpy(m_szText,str,1024);
	m_nLineChar=nLineChar;
	m_dwDelay=dwDelay;
	m_dwDefaultTextColor=dwDefaultTextColor;
	m_dwBkColor=dwBkColor;
	m_nBkAlpha=nBkAlpha;
	if(!pFont)
	{
		m_pFont=new CFont();
		if(!m_pFont)
			return false;
		m_pFont->CreateFont();
		m_bOwnFont=true;
	}
	else
	{
		m_bOwnFont=false;
		m_pFont=pFont;
	}


	

	AnalyseString();
	return true;
}

void LOA_RENDER_API CRenderText::Release()
{
	if(!m_bOwnFont)
		return;
	if(m_pFont)
	{
		delete m_pFont;
		m_pFont=NULL;
	}
}

BOOL LOA_RENDER_API CRenderText::IsRenderComplete()
{
	return m_bEnd;
}
void LOA_RENDER_API CRenderText::Render()
{
	if(m_dwBkColor!=RGB(0,0,0))
		m_pDisplay->ColorAlphaBlt(m_dwBkColor,&m_rtArea,m_nBkAlpha);

	HDC hdc;
 
	m_pDisplay->GetBackBuffer()->GetDC(&hdc);
	::SelectObject(hdc,m_pFont->GetFont());
	::SetBkMode(hdc,TRANSPARENT);
	::SetTextColor(hdc,m_dwDefaultTextColor);
	
	char szShowText[256];
	int x=m_x;
	int y=m_y;
	int nCurPos=0;


	for(int i=0;i<m_nCurChar;)
	{
		memset(szShowText,0,256);
		int nTextIndex=0;
		
		while(nCurPos< m_nLineChar && m_szText[i]!='\0')
		{
			if(i>=m_nCurChar)
			{
				::TextOut(hdc,x,y,szShowText,strlen(szShowText));
				goto _out;
			}
			if(m_szText[i]<0)														//如果是汉字
			{
				szShowText[nTextIndex++]=m_szText[i++];
				szShowText[nTextIndex++]=m_szText[i++];
				nCurPos+=2;
				continue;
			}
			else
			{
				if(m_szText[i]=='<')
				{
					::TextOut(hdc,x,y,szShowText,strlen(szShowText));				//显示上面部分的
					i++;
					int color=m_szText[i]-0x30;
					DWORD dwColor=CTalk::s_dwColorTable[color];
					::SetTextColor(hdc,dwColor);
					x+=strlen(szShowText)*this->m_nCharWidth;
					i++;
					goto _end;
				}
				else if(m_szText[i]=='/')											// <cxxx/>
				{
					::TextOut(hdc,x,y,szShowText,strlen(szShowText));				//显示上面部分的
					i++;
					::SetTextColor(hdc,m_dwDefaultTextColor);						//恢复默认颜色
					x+=strlen(szShowText)*this->m_nCharWidth;
					i++;
					goto _end;
				}
				else																//英文
				{
					szShowText[nTextIndex++]=m_szText[i++];
					nCurPos++;
					continue;
				}
			}
		
		}
		::TextOut(hdc,x,y,szShowText,strlen(szShowText));
		y+=m_nCharHeight;
		x=m_x;
		nCurPos=0;

_end:
		;
	}
_out:
	m_pDisplay->GetBackBuffer()->ReleaseDC(hdc);
	if(timeGetTime()-this->m_dwOldTime < this->m_dwDelay)
		return ;
	m_dwOldTime=timeGetTime();

_again:
	if(m_nCurChar>=(int)strlen(m_szText))
		return;
	if(m_szText[m_nCurChar+1]<0)
		m_nCurChar+=2;
	else 
	{
		if(m_szText[m_nCurChar+1]=='<' || m_szText[m_nCurChar+1]=='/')
		{
			m_nCurChar+=2;
			goto _again;
		}
		else
		{
			m_nCurChar++;
		}
	}
}
BOOL CRenderText::IsTextShowFinish()
{
	if(m_nCurChar>=(int)strlen(m_szText))
		return true;
	return false;
}
void CRenderText::SetPosEndThisText()
{
	m_nCurChar=strlen(m_szText);
}
void CRenderText::SetText(char*text)
{
	LOA_ASSERT(text);

	memset(this->m_szText,0,1024);
	strncpy(m_szText,text,1024);
	AnalyseString();
}
void CRenderText::SetPosStartThisText()
{
	m_nCurChar=0;
}
DWORD CTalk::s_dwColorTable[10]=
{
	RGB(0,0,0),
	RGB(0,0,0),
	RGB(255,0,0),
	RGB(0,255,0),
	RGB(0,0,255),
	RGB(255,255,0),
	RGB(255,0,255),
	RGB(0,255,255),
	RGB(127,127,127),
	RGB(255,255,255)
};

CTalk::CTalk()
{
	m_pTalkQueue=KGDQueue<char*>::ForeCreate();
}
CTalk::~CTalk()
{
	Clear();
	delete m_pTalkQueue;
}
void CTalk::Clear()
{
	if(m_pTalkQueue)
	{
		m_pTalkQueue->Clear();
	}
}

BOOL CTalk::ShowMessage(CGame*pGame,char*szMsg,DWORD dwDelay,int x,int y,
						CFont*pFont,DWORD dwTextColor,DWORD dwBkColor,int nBkAlpha,
						DWORD dwLineChar,BOOL bWaitKey)
{
	
	CRenderText*pTalk=new CRenderText();
	pTalk->ShowText(pGame->GetDisplay(),x,y,szMsg,dwTextColor,dwBkColor,nBkAlpha,dwLineChar,dwDelay,false,pFont);
	pTalk->CreateTask();


	RECT rect=pTalk->GetRect();

	CIconAni*pIconAni=new CIconAni();
	if(!pIconAni->InitIconAniDefault(rect.right-48,rect.bottom-15,pGame->GetDisplay()))
		return false;
	pIconAni->CreateTask(true,false);
	
 
	pGame->GetRender()->AddTask(pIconAni);
	pGame->GetRender()->AddTask(pTalk);
	
	MSG msg;
	while(pGame->IsPlayGame())
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL,0,0)) 
				return msg.wParam;
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		else if(pGame->IsActive())
		{
			//------------------------------------------------------------------//
			pGame->GetMessageQueue()->ExecuteMessage();
			if(bWaitKey)
			{
				BYTE key=pGame->GetKeyBoard()->ReadLastBufferKey();
				if( (key==DIK_SPACE && pGame->GetKeyBoard()->WaitKey(DIK_SPACE,100))
					|| (key==DIK_RETURN && pGame->GetKeyBoard()->WaitKey(DIK_RETURN,100)) )
				{
					 
					if(pTalk->IsTextShowFinish())							//如果显示完成,跳出
						goto _out;
					else
					{
						pIconAni->ActiveTask();								//否则,设置为显示完成,并显示动态的图标
						pTalk->SetPosEndThisText();
					}
					
				}
				if(pTalk->IsTextShowFinish())
				{
					pIconAni->ActiveTask();
				}
			}
			else
			{
				if(pTalk->IsTextShowFinish())
					break;
			}
			pGame->NpcRandomMove();
			pGame->SortAndShowRole();
			pGame->UpdateScreen();
		}
		else
			WaitMessage();
	}
_out:
	pIconAni->EndTask();
	pTalk->EndTask();
	
	return true;
}
BOOL CTalk::AddTalk(char*szTalk)
{
	LOA_ASSERT(szTalk);

	return m_pTalkQueue->EnQueue(szTalk);
}
BOOL CTalk::ShowTalk(STRenderRole*pRole,CGame*pGame,BOOL bShowDown,
					 DWORD dwDefaultTextColor,
					 DWORD dwDefaultBkColor,DWORD dwDelay,BOOL bWaitKey,int nBkAlpha)
{
	if(m_pTalkQueue->GetLength()==0)
		return false;

	int x,y;
	x=200;
	if(bShowDown)
	{
		y=400;
	}
	else
	{
		y=50;
	}
	char*szText;
	m_pTalkQueue->DeQueue(szText);

	CRenderText*pTalk=new CRenderText();
	pTalk->ShowText(pGame->GetDisplay(),x,y,szText,dwDefaultTextColor,dwDefaultBkColor,nBkAlpha,50,dwDelay,true,NULL);
	pTalk->CreateTask();

	CFont font;
	font.CreateFont();

	RECT rect=pTalk->GetRect();

	CIconAni*pIconAni=new CIconAni();
	if(!pIconAni->InitIconAniDefault(rect.right-48,rect.bottom-15,pGame->GetDisplay()))
		return false;
	pIconAni->CreateTask(true,false);

	pGame->GetRender()->AddTask(pTalk);
	pGame->GetRender()->AddTask(pIconAni);

	CRenderRoleHeadPic*pRoleHead=new CRenderRoleHeadPic();

	if(pRoleHead->InitRender(0,bShowDown?480:0,pGame->GetDisplay(),pRole))
	{
		pRoleHead->CreateTask();
		pGame->GetRender()->AddTask(pRoleHead);	
	}
	else
	{
		delete pRoleHead;
		pRoleHead=NULL;
	}
	
	int OrgMapStartX=pGame->GetRenderMap()->m_xStart;
	int OrgMapStartY=pGame->GetRenderMap()->m_yStart;
	
	MSG msg;
	while(pGame->IsPlayGame() && m_pTalkQueue->GetLength()>=0)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL,0,0)) 
				return msg.wParam;
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
		else if(pGame->IsActive())
		{
			//------------------------------------------------------------------//
			pGame->GetMessageQueue()->ExecuteMessage();
			if(bWaitKey)
			{
				BYTE key=pGame->GetKeyBoard()->ReadLastBufferKey();
				if( (key==DIK_SPACE && pGame->GetKeyBoard()->WaitKey(DIK_SPACE,100)) 
					|| (key==DIK_RETURN && pGame->GetKeyBoard()->WaitKey(DIK_RETURN,100)) )
				{
					 
					if(pTalk->IsTextShowFinish())							//如果显示完成,跳出
					{
						if(m_pTalkQueue->GetLength()==0)
							goto _out;
						m_pTalkQueue->DeQueue(szText);
						pTalk->SetText(szText);
						pTalk->SetPosStartThisText();
					}
					else
					{
						pIconAni->ActiveTask();								//否则,设置为显示完成,并显示动态的图标
						pTalk->SetPosEndThisText();
					}
					
				}
				if(pTalk->IsTextShowFinish())
				{
					pIconAni->ActiveTask();
				}
				else
				{
					pIconAni->PauseTask();
				}
			}
			else
			{
				if(pTalk->IsTextShowFinish())
				{
					if(m_pTalkQueue->GetLength()==0)
							goto _out;
					m_pTalkQueue->DeQueue(szText);
					pTalk->SetText(szText);
					pTalk->SetPosStartThisText();
				}
			}
			pGame->NpcRandomMove();
 	 		pGame->SortAndShowRole();
			
			if(pGame->IsDither())
			{
				pGame->GetRenderMap()->m_xStart=OrgMapStartX+rand()%10;
				pGame->GetRenderMap()->m_yStart=OrgMapStartY+rand()%10;
			}

			pGame->GetMapSurface()->ShowAniTileToAniSurface();				//更新动态图块

			pGame->GetDisplay()->Clear();

			pGame->GetRender()->Render();											//流水线方式渲染

			pGame->ShowFPS();
			
			HDC hdc;
			pGame->GetDisplay()->GetBackBuffer()->GetDC(&hdc);
			::SelectObject(hdc,font.GetFont());
			::SetBkMode(hdc,TRANSPARENT);
			::SetTextColor(hdc,RGB(255,255,255));
			::TextOut(hdc,x-40,y-20,pRole->pRole->szName,strlen(pRole->pRole->szName));
			pGame->GetDisplay()->GetBackBuffer()->ReleaseDC(hdc);
			pGame->GetDisplay()->Present();
		}
		else
			WaitMessage();
	}
_out:
	pIconAni->EndTask();														//结束这个任务
	pTalk->EndTask();														//结束这个任务
	if(pRoleHead)
	{
		pRoleHead->EndTask();
	}
	pGame->GetRenderMap()->m_xStart=OrgMapStartX;
	pGame->GetRenderMap()->m_yStart=OrgMapStartY;

	return true;
}

⌨️ 快捷键说明

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