返回信息流工作生活找不到兴奋点,于是自己打算做些东东,以下是计划。
目前实现难点已经基本解决。关键在组织及架构。目前准备[一]中...
======================================
游戏脚本引擎需求计划
一, 联系元素。
在已经比较成熟的游戏中,不需要新建元素来附和脚本。所以脚本引擎需要能较好地适应并联系已有的游戏元素并提供可编辑的操作脚本,同时给出向原游戏提供通知事件的接口。
二, 提供树状结构以组织元素。
在常用的元素组织方式中,树状和消息链(绘画链是消息链的反向)是必要的。同时要支持元素在运行时的插入和删除,以及考虑此类操作对消息链的影响。
三, 提供面对完整DEMO的接口。
需要一个完整的DEMO,以描述脚本引擎是如何跟完整的游戏系统联系的,相关的联系子系统有输入,显示,(声音…)消息中转等。
这是一条镜像帖。来源:北邮人论坛 / soft-design / #17587同步于 2007/5/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
[原创]游戏脚本引擎需求计划
kissme
2007/5/13镜像同步19 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
【 在 kissme 的大作中提到: 】
: 工作生活找不到兴奋点,于是自己打算做些东东,以下是计划。
: 目前实现难点已经基本解决。关键在组织及架构。目前准备[一]中...
: ======================================
: ...................
附件(66KB) output.rar
1基本完成,将三个控件给关联上了.逻辑在LUA文本文件中.
int FuncTest(lua_State* L)
{
int argc = lua_gettop(L);
if (argc == 1 && lua_isnumber(L,1))
{
CString strTmp;
strTmp.Format("%f",lua_tonumber(L,1));
AfxMessageBox(strTmp);
}
if (argc >= 2)
{
CString strTmp;
if (lua_isuserdata(L,1))
{
Lunar<CBaseNode>::userdataType* node =
(Lunar<CBaseNode>::userdataType*)lua_touserdata(L,1);
CLuaEdit* pCtrl = (CLuaEdit*)node->pT;
if (strcmpi(lua_tostring(L,2),"GetValue") == 0)
{
pCtrl->GetWindowText(strTmp);
lua_pushnumber(L,atof(strTmp));
}
else if (strcmpi(lua_tostring(L,2),"SetValue") == 0)
{
double fRet = lua_tonumber(L,3);
strTmp.Format("%f",fRet);
pCtrl->SetWindowText(strTmp);
}
}
}
return 1;
}
class CLuaEdit : public CEdit ,public CBaseNode
{
};
class CDemo1ADlg : public CDialog
{
// Construction
public:
CDemo1ADlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CDemo1ADlg)
enum { IDD = IDD_DEMO1A_DIALOG };
CLuaEdit m_edtC;
CLuaEdit m_edtB;
CLuaEdit m_edtA;
...
}
BOOL CDemo1ADlg::OnInitDialog()
{
...
// TODO: Add extra initialization here
m_edtA.SetWindowText(_T("2"));
m_edtB.SetWindowText(_T("3"));
m_edtC.SetWindowText(_T("0.04"));
CScriptFactory* p = (CScriptFactory*)CScriptFactory::GetInstance();
p->RegFunc("FuncTest",FuncTest);
p->AttachObj("edtA","CBaseNode",(DWORD)((CBaseNode*)&m_edtA));
p->AttachObj("edtB","CBaseNode",(DWORD)(CBaseNode*)&m_edtB);
p->AttachObj("edtC","CBaseNode",(DWORD)(CBaseNode*)&m_edtC);
p->DoFile("Demo1A.lua");
}
void CDemo1ADlg::OnButton1()
{
// TODO: Add your control notification handler code here
CScriptFactory* p = (CScriptFactory*)CScriptFactory::GetInstance();
p->DoString("edtC_OnClick(getglobal(\"edtC\"))");
}
BOOL CDemo1ADlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
CScriptFactory* p = (CScriptFactory*)CScriptFactory::GetInstance();
delete p;
return CDialog::DestroyWindow();
}
////////////////////
添加的代码,本来封装在静态库中的,谁知没做好,代码还是会漏出.
只好帖所添代码了,没法给DEMO1A的代码,因为给了单独BUILD不了.
下次改进.
【 在 kissme 的大作中提到: 】
: 工作生活找不到兴奋点,于是自己打算做些东东,以下是计划。
: 目前实现难点已经基本解决。关键在组织及架构。目前准备[一]中...
: ======================================
: ...................
附件(66.7KB) output.rar
新变化:
使用XML进行UI布局,LUA进行逻辑控制。
支持树状元素。下个例子估计会是动态创建了。
新增代码:
BOOL CDemo1ADlg::OnInitDialog()
{
...
CScriptFactory* p = (CScriptFactory*)CScriptFactory::GetInstance();
//////////////////////////////////////////////////////////////////////////
p->RegFunc("FuncTest",FuncTest);
p->AttachObj("edtA","CBaseNode",(DWORD)((CBaseNode*)&m_edtA));
p->AttachObj("edtB","CBaseNode",(DWORD)(CBaseNode*)&m_edtB);
p->AttachObj("edtC","CBaseNode",(DWORD)(CBaseNode*)&m_edtC);
//////////////////////////////////////////////////////////////////////////
Lunar<CLuaEdit>::Register(p->m_L);
m_pLuaEdit = (CLuaEdit*)p->CreateUINode("CLuaEdit","edtD");
m_pLuaEdit->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
CRect(10, 10, 100, 30), this, 1);
m_pLuaEdit->SetWindowText(_T("5"));
//////////////////////////////////////////////////////////////////////////
// p->DoFile("Demo1A.lua");
p->BeginFindTree(&m_Tree,"Demo1A.xml");
}
int FuncTest(lua_State* L)
{
int argc = lua_gettop(L);
if (argc == 1 && lua_isnumber(L,1))
{
CString strTmp;
strTmp.Format("%f",lua_tonumber(L,1));
AfxMessageBox(strTmp);
}
if (argc >= 2)
{
CString strTmp;
if (lua_isuserdata(L,1))
{
Lunar<CBaseNode>::userdataType* node =
(Lunar<CBaseNode>::userdataType*)lua_touserdata(L,1);
CLuaEdit* pCtrl = (CLuaEdit*)node->pT;
if (strcmpi(lua_tostring(L,2),"GetValue") == 0)
{
pCtrl->GetWindowText(strTmp);
lua_pushnumber(L,atof(strTmp));
}
else if (strcmpi(lua_tostring(L,2),"SetValue") == 0)
{
double fRet = lua_tonumber(L,3);
strTmp.Format("%f",fRet);
pCtrl->SetWindowText(strTmp);
}
else if (strcmpi(lua_tostring(L,2),"SetRect") == 0)
{
int x = lua_tointeger(L,3);
int y = lua_tointeger(L,4);
int w = lua_tointeger(L,5);
int h = lua_tointeger(L,6);
pCtrl->Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
CRect(x, y, x + w, y + h), AfxGetMainWnd(), 1000 + x);
}
}
}
return 1;
}
昨天遇到一个恶心问题。
在考虑删除节点时,由于使用的是userdata,是自动释放的!
我当然不希望到最后时才释放了,所以想事先释放了。
但lua对这个的管理很“负责”,多次尝试都没有让lua认为特定userdata为垃圾...
简单地说吧。如果我写
userdata a = new userdata
如果没有地方引用的话,只要我调用gc()(其实没这句话,只是类似的语句,懒得查了)
a就会被当垃圾收掉,但昨天看了半天文档和代码,发现实际DEMO进行了这样的操作:
userdata a = new userdata
mt.[a.name] = a (mt为一常table)
明白了吧,a new出来后就成了mt的一个子值,就是说a在某处被用到了,
所以lua不会认为是垃圾... =+=
我千辛万苦把mt的a值给DEL,发现还是回收不了,再查发现我做了个无意的操作:
Node[a.name] = a (为了不污染环境的处理)
再DEL,谁知还是不能垃圾收集!放弃了。
打算做成把a中的实物指针DEL后设置标志为不可用。
PS:改成 a = {void* pObj;bool bVaild;}
原来没人看啊...
整个下午做了一个树节点删除的算法,已经基本完成了。
恶心死我了,又看内存又设断点的,就差没用WinDBG了。
2是基本完成了,因为从表现上跟上个版本没区别,所以
不放DEMO了。
下次是个小DEMO,重在逻辑集合在脚本上。
【 在 kissme 的大作中提到: 】
: 工作生活找不到兴奋点,于是自己打算做些东东,以下是计划。
: 目前实现难点已经基本解决。关键在组织及架构。目前准备[一]中...
: ======================================
: ...................
完成了一个较完整的DEMO,将UI和游戏逻辑整合到脚本中。
这个仅仅用MFC的框架简单搭了一下。
下个DEMO可能将涉及较完整的显示,输入,声音等子系统引擎,
看脚本是如何与这些东东整合的。
【 在 kissme 的大作中提到: 】
: 工作生活找不到兴奋点,于是自己打算做些东东,以下是计划。
: 目前实现难点已经基本解决。关键在组织及架构。目前准备[一]中...
: ======================================
: ...................
附件(274.6KB) tmp.rar
南方网,上传不方便。
为了吸引大家,只好用美女图,没办法呀,唉。