对话框
游戏交互中,经常需要用到弹出式对话框。
在绘制主界面的时候,在最顶层绘制:同时添加监听事件:
void SkGame::show(SkShow* pSkShow, Sint64 iCurMTime) {
if (m_pCurView != NULL) {
/**清空屏幕背景为黑色矩形**/
pSkShow->clear(0x00, 0x00, 0x00, 0xff);
/**绘制游戏场景**/
m_pCurView->show(pSkShow, iCurMTime);
/**绘制对话框**/
g_SkDialogManager.show(pSkShow, iCurMTime);
/**四周边框黑色**/
pSkShow->clearOther(0x00, 0x00, 0x00, 0xff);
}
}
void SkGame::doEvent(SkEvent * event, Sint64 iCurMTime) {
//g_SkComm.log("[%s][%d]%u\n", __FILE__, __LINE__, event->type);
//g_SkComm.print_event(event);
if (m_pCurView != NULL) {
g_SkDialogManager.doEvent(*event, iCurMTime);
m_pCurView->doEvent(*event, iCurMTime);
}
if (SDL_QUIT == event->type.type) {
g_func_event_quit();
}
}
对话框的实现代码:
#ifndef SKDIALOG_H_
#define SKDIALOG_H_
#include "SkComm.h"
#include "SkButton.h"
#include
using namespace std;
/**对话框 ok被点击**/
void sk_button_dialog_ok_pressed(void * pData, sk_park::SkButton * pButton);
namespace sk_park {
/**dialog 基类**/
class SkDialog {
public:
SkDialog();
virtual ~SkDialog();
virtual bool doEvent(SkEvent & stSkEvent, Sint64 iCurMTime);
/**Dialog位置信息,只作为成员属性,按钮绘制的位置需要在绘制时候指定**/
Sint32 m_iPosX;
Sint32 m_iPosY;
/**是否显示**/
bool m_bShow;
/**类型**/
Sint32 m_type;
};
/**信息显示dilog**/
class SkDialogInfo: public SkDialog {
public:
void initInfo(const char * pStr, SkConfXml & conf);
bool doEvent(SkEvent & stSkEvent, Sint64 iCurMTime);
SkButton m_btOk;
SkSurface m_info;
Sint32 m_iWidth;
Sint32 m_iHeight;
SkColor m_bgColor;
};
/**信息确认dilog**/
class SkDialogCheck: public SkDialog {
public:
SkButton m_btYes;
SkButton m_btNo;
SkButton m_btCancle;
};
class SkDialogManager {
public:
void show(void* pSkInput, Sint64 iCurMTime);
bool doEvent(SkEvent & stSkEvent, Sint64 iCurMTime);
void addDialog(SkDialog * pDialog);
void addDelDialog(SkDialog * pDialog);
void clearDelDialog();
set m_dialogSet;
set m_delDialogSet;
};
}
extern sk_park::SkDialog g_SkDialog;
extern sk_park::SkDialogManager g_SkDialogManager;
#endif /* SKDIALOG_H_ */
#include "pch.h"
#include "SkDialog.h"
#include "SkShow.h"
using namespace sk_park;
void sk_button_dialog_ok_pressed(void * pData, sk_park::SkButton * pButton) {
SkDialogInfo * pDialog = (SkDialogInfo *) pData;
g_SkDialogManager.addDelDialog(pDialog);
}
SkDialog::SkDialog() {
m_bShow = true;
m_type = 0;
}
SkDialog::~SkDialog() {
}
bool SkDialog::doEvent(SkEvent & stSkEvent, Sint64 iCurMTime) {
return false;
}
bool SkDialogInfo::doEvent(SkEvent & stSkEvent, Sint64 iCurMTime) {
bool bRet = m_btOk.handleEvent(m_iPosX + m_btOk.m_iPosX,
m_iPosY + m_btOk.m_iPosY, stSkEvent, this);
if (bRet) {
return true;
}
return false;
}
void SkDialogInfo::initInfo(const char * pStr, SkConfXml & conf) {
m_type = 1;
SkString confOk = conf.getKKValueStr("type1", "conf_ok");
SkConfXml confBt;
confBt.init(confOk.c_str());
m_btOk.initConf(confBt);
m_iPosX = conf.getKKValueInt32("pos", "x");
m_iPosY = conf.getKKValueInt32("pos", "y");
m_iWidth = conf.getKKValueInt32("bg", "w");
m_iHeight = conf.getKKValueInt32("bg", "h");
{
SkString sColor;
sColor = conf.getKKValueStr("bg", "color");
g_SkComm.setColorFromStr(sColor, m_bgColor);
}
Sint32 iFontSize = conf.getKKValueInt32("type1", "font_size");
SkString sColor;
SkColor cFontColor;
sColor = conf.getKKValueStr("type1", "font_color");
g_SkComm.setColorFromStr(sColor, cFontColor);
SkFont stFont;
stFont.init("font/simhei.ttf", iFontSize);
SkWord skWord;
skWord.setStr(pStr, stFont, cFontColor.r, cFontColor.g, cFontColor.b,
cFontColor.a, false);
m_info = skWord.m_skSurface;
m_btOk.setFuncPressed(sk_button_dialog_ok_pressed);
}
void SkDialogManager::addDelDialog(SkDialog * pDialog) {
m_dialogSet.erase(pDialog);
m_delDialogSet.insert(pDialog);
}
void SkDialogManager::addDialog(SkDialog * pDialog) {
m_dialogSet.insert(pDialog);
}
void SkDialogManager::clearDelDialog() {
/**dialog垃圾回收**/
if (m_delDialogSet.size() > 0) {
set::iterator it;
for (it = m_delDialogSet.begin(); it != m_delDialogSet.end(); it++) {
SkDialog * pDialog = *it;
delete pDialog;
}
m_delDialogSet.clear();
}
}
void SkDialogManager::show(void* pSkInput, Sint64 iCurMTime) {
SkShow * pSkShow = (SkShow *) pSkInput;
if (m_dialogSet.size() > 0) {
set::iterator it;
for (it = m_dialogSet.begin(); it != m_dialogSet.end(); it++) {
pSkShow->drawDialog(NULL, *it, NULL, iCurMTime);
}
}
}
bool SkDialogManager::doEvent(SkEvent & stSkEvent, Sint64 iCurMTime) {
bool bRet = false;
if (m_dialogSet.size() > 0) {
set::iterator it;
for (it = m_dialogSet.begin(); it != m_dialogSet.end(); it++) {
bool bRet = (*it)->doEvent(stSkEvent, iCurMTime);
if (bRet) {
bRet = true;
break;
}
}
}
return bRet;
}
SkDialog g_SkDialog;
SkDialogManager g_SkDialogManager;
绘制对话框,最好也是可以配置的,这样可以提高开发效率:
下面配置两个对话框:
ViewFirst.DlGameInfo.conf.xml
1
255,100,200,255
600
400
400
350
40
0,0,255,255
conf/view/Dialog.BtOk.conf.xml
ViewFirst.DlGameInfo2.conf.xml
1
0,255,0,155
600
400
50
20
40
0,0,255,255
conf/view/Dialog.BtOk.conf.xml
按钮的配置:
Dialog.BtOk.conf.xml
1
500
300
40
255,0,0,255
0,255,0,255
255,255,0,255
确定
确定
确定
1
255,100,100,70
100,100,100,70
100,100,255,70
绘制对话框的实现代码:
void SkShow::drawDialog(SkRect * pDesArea, SkDialog* pDialog, SkRect * pPicArea,
Sint64 iTime) {
SkRect stRect;
if (pPicArea != NULL) {
stRect.x = pPicArea->x;
stRect.y = pPicArea->y;
} else {
stRect.x = pDialog->m_iPosX;
stRect.y = pDialog->m_iPosY;
}
/**确认对话框**/
if (pDialog->m_type == 1) {
SkDialogInfo * pTmp = (SkDialogInfo *) pDialog;
stRect.w = pTmp->m_iWidth;
stRect.h = pTmp->m_iHeight;
fillRec(&stRect, pTmp->m_bgColor.r, pTmp->m_bgColor.g,
pTmp->m_bgColor.b, pTmp->m_bgColor.a);
stRect.x += 50;
stRect.y += 50;
drawPic(pDesArea, &pTmp->m_info, &stRect);
stRect.x = stRect.x + pTmp->m_btOk.m_iPosX - 50;
stRect.y = stRect.y + pTmp->m_btOk.m_iPosY - 50;
drawButton(pDesArea, &pTmp->m_btOk, &stRect, iTime);
}
}
添加按钮事件:
void button_show_dialog(void * pData, SkButton * pButton) {
SkDialogInfo * pDialog = new SkDialogInfo();
SkConfXml conf;
conf.init("conf/view/ViewFirst.DlGameInfo.conf.xml");
pDialog->initInfo("游戏发行公司:GuuD", conf);
g_SkDialogManager.addDialog(pDialog);
}
void button_show_dialog2(void * pData, SkButton * pButton) {
SkDialogInfo * pDialog = new SkDialogInfo();
SkConfXml conf;
conf.init("conf/view/ViewFirst.DlGameInfo2.conf.xml");
pDialog->initInfo("游戏制作人:Ycg01", conf);
g_SkDialogManager.addDialog(pDialog);
}
示例运行如下: