SDL游戏之路(十九)--对话框



对话框

游戏交互中,经常需要用到弹出式对话框。

在绘制主界面的时候,在最顶层绘制:同时添加监听事件:

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 <set>
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<SkDialog *> m_dialogSet;
	set<SkDialog *> 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<SkDialog *>::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<SkDialog *>::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<SkDialog *>::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

<?xml version="1.0" encoding="utf-8"?>
<root>
	<dl>
		<!-- 对话框类型: 1:info 2:yes-no-cancle -->
		<type>1</type>
	</dl>
	<bg>
		<!-- dialog场景的背景颜色 r,g,b,a -->
		<color>255,100,200,255</color>
		<w>600</w>
		<h>400</h>
	</bg>
	<pos>
		<x>400</x>
		<y>350</y>
	</pos>
	<type1>
		<font_size>40</font_size>
		<font_color>0,0,255,255</font_color>
		<conf_ok>conf/view/Dialog.BtOk.conf.xml</conf_ok>
	</type1>
</root>

ViewFirst.DlGameInfo2.conf.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
	<dl>
		<!-- 对话框类型: 1:info 2:yes-no-cancle -->
		<type>1</type>
	</dl>
	<bg>
		<!-- dialog场景的背景颜色 r,g,b,a -->
		<color>0,255,0,155</color>
		<w>600</w>
		<h>400</h>
	</bg>
	<pos>
		<x>50</x>
		<y>20</y>
	</pos>
	<type1>
		<font_size>40</font_size>
		<font_color>0,0,255,255</font_color>
		<conf_ok>conf/view/Dialog.BtOk.conf.xml</conf_ok>
	</type1>
</root>

按钮的配置:

Dialog.BtOk.conf.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
	<bt>
		<!-- 按钮类型: 1:文字按钮  2:图片按钮 -->
		<type>1</type>
	</bt>
		<!-- 相对位置 -->
	<pos>
		<x>500</x>
		<y>300</y>
	</pos>
	<type1>
		<font_size>40</font_size>
		<color_in>255,0,0,255</color_in>
		<color_out>0,255,0,255</color_out>
		<color_pressed>255,255,0,255</color_pressed>
		<str_in>确定</str_in>
		<str_out>确定</str_out>
		<str_pressed>确定</str_pressed>
		<!-- 是否有背景色 -->
		<bg_color>1</bg_color>
		<bg_in>255,100,100,70</bg_in>
		<bg_out>100,100,100,70</bg_out>
		<bg_pressed>100,100,255,70</bg_pressed>
	</type1>
</root>

绘制对话框的实现代码:

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);
}


示例运行如下:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值