📄 ctalk.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 + -