怎么在lua代码中cocos2dx lua退出游戏整个游戏

1056人阅读
GameScript专题之Lua(11)
本文转自 博客园 &,转载请详细标明作者及出处,以示尊重!!
自从看完PIL之后,就暂时没有时间做更多的尝试,也因此没有弄明白如何将AI脚本,剧情脚本之类的嵌入到C++的硬编码中。最近看了一些AI的文章,并思考了一下,得到以下认识。
首先要说的是,并不是说AI,剧情逻辑必须非脚本语言不可,用C++也可以写,甚至更习惯一些。但是脚本语言有脚本语言的长处,动态类型以及相当人性化的数据构造方式,特别是LUA中的表类型,似乎比较擅长描述这种复杂的AI/剧情结构。当然,为了验证自己的想法,我也写了4K的LUA代码,结果觉得该脚本语言相当不容易构造简洁的内容。
AI从高自低的分别是计划,状态机,模式。我不知道这种划分是基于何种角度,但是我个人的理解是状态机最高,模式作为某个状态下的某个决策所预定义的动作序列,而计划,是为了实现某个目标的一组步骤的组合。
那么硬编码的游戏循环何时调用脚本?答案是,游戏循环执行到调度NPC的AI函数的时候,该AI函数就不再做任何硬编码,而只是简单的dostring(&gameEntitys[npc](\&update\&)&)。就是这么简单,将所有的AI/剧情放置到脚本中。
那么,LUA中 gameEntitys[npc](&update&)是什么意思?简单的说,gameEntitys是一个存储所有NPC的注册表,gameEntitys[npc]将取得该npc的FMS函数,然后给该函数发送update消息告知npc当前的状态进行例行更新。
FMS函数对于每一个对象是唯一的,那么比如某一类对象有共同的AI/剧情,那么该类的每一个对象同用同样的FMS函数的话,成员变量如何维持?要知道在LUA中模拟类还是比较麻烦的。答案是upvalue,也就是所有的对象使用同样的函数来生成自身的FMS,该函数就是FMS_Creator(all_state, init_state)。
在C++编码中,NPC对象完成构造之后,就调用LUA载入对应的状态机/剧情脚本,然后调用FMS_Creator为自己创建FMS函数:
dofile(&npc_ai.lua&)&--引入all_state,init_state
gameEntitys[npc]=FMS_Creator(all_state,&init_state)
当然,NPC析构之后,你也要释放LUA为你分配的资源
gameEntitys[npc]=nil
已经大概说明了如何在C++中启动NPC的LUA逻辑代码了,那么如何在LUA中编写状态机呢?答案是表。每个表代表一个状态,该表下的key表示该状态接受的消息,key对应的值表示该状态接受到key所表示的消息后要执行的决策,包括相应的动作和可能的状态变迁。看代码吧,最直观的表述:
&&name&=&&attack&,&--状态名
&&enter&=&{&&--进入该状态要执行,属于状态的消息
&&&&&--func是函数,param是参数,sucess,unsucess是func执行结果所对应的状态转移
&&&&{func=print,&param=&open&fire&},
&&&&{func=IsEnemyDie,&sucess=&cure&},
&&update={}&&--同enter,不过用于状态在每一帧的更新
&&exit&=&{}&&--同enter,不过用于状态在每一帧的更新
&&other_msg&=&{}&&--同enter,用于表示该状态所接受的其他消息,可以有多个
在LUA中就是可以如此直观的表示每一个状态,其响应的消息以及函数。然后构造该npc接受的状态集合:
all_state&=&{}
all_state[state.name]=state
init_state=state
这样子,就能传递到FMS_Creator中创建出自己独一无二的状态机函数了。
那么剧情脚本呢?其实描述了状态机,剧情脚本是否已经有点眉头了呢?剧情,即为计划,每一个计划由一系列步骤所组成。类似的,对应每个计划的执行会有一个plan()函数,且为了达到独立效果,该函数将会由plan_creator(all_step, first_step)生成。
看参数,显然计划的步骤step就是类似于状态的表,不过key方面略有不同,看代码就明白:
&&name=&find&bill&,
&&cond&=&{&--执行该步骤的前提条件
&&&&&--func是判断条件的函数,param是判断参数
&&&&&{func=IsXXX,&param=&xxx&},
&&&&{func=IsStepFinished,&param=some_step},
&&finish&=&{&&--条件判断成功要执行的动作
&&&&{func=print,&param=&success&},
&&unfinish&=&{&&--条件判断不成功所要执行的动作
&&&&{func=print,&param=&unsuccess&},
至此,要说的基本上说完了。剧情与FMS结合的方式,因为个人认为FMS最高,所以剧情的执行通过plan(),该剧情的执行函数将作为某个状态相应某个消息时函数集合的一分子。因为,总有个状态是要求按计划执行剧情完成目标的,但是,其他状态允许意外使得暂时不能执行剧情,而NPC又不至于疯掉。
需要补充的是,很遗憾LUA不能随意的使用类似于#include,#import的功能,虽然可以dofile,但是其dofile内声明的变量必须是globle的,因为local value的生存范围是chunk,dofile就是在一个chunk内执行代码。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1267576次
积分:13213
积分:13213
排名:第777名
原创:44篇
转载:553篇
评论:194条
本博收藏大部分文章为转载,并在文章开头给出了原创作者及原文出处,如有再转,敬请保留相关信息,这是大家对原创作者劳动成果的自觉尊重!!
早期遗留的部分文章未能及时给出相关原创信息,在此谨致歉意,后续会尽全力予以纠正。如为您带来不便,请于本博下留言,谢谢配合。
(1)(7)(2)(18)(17)(17)(5)(3)(8)(11)(8)(6)(11)(3)(1)(13)(16)(10)(8)(15)(12)(4)(8)(3)(5)(1)(1)(1)(4)(2)(1)(4)(5)(3)(9)(18)(5)(1)(2)(2)(9)(3)(4)(1)(4)(3)(2)(1)(2)(1)(1)(6)(14)(1)(22)(4)(1)(13)(7)(9)(7)(4)(26)(10)(22)(9)(15)(12)(11)(1)(4)(3)(4)(1)(10)(7)(3)(12)(17)(1)(9)(17)(18)17497人阅读
Lua游戏脚本热更新机制 ?
能够在服务器运行期间更新程序逻辑代码以实现修正程序Bug、修改游戏数据的目的。游戏框架代码的热更新暂不考虑。例如:
某个业务处理函数逻辑有Bug,服务器运营期间发现,在不停机情况下及时更新代码修复。
技能数值表策划填写出现手误错误,导致玩家战斗异常,在不停机情况下及时更新内存中的数值表。
更新代码时要保护非代码数据,尽量不用重新载入存盘数据。例如:
登陆用户列表保存在内存中,用户登录模块出现bug需要跟新代码,此段代码更新后,用户列表依然有效,在线用户不受影响。
lua的module机制?
require 会阻止你重新加载相同的模块。当需要更新系统的时候,卸载掉自己编写的模块。方法是:把 package.loaded 里对应模块名下设置为 nil (这样可以保证下次 require 重新加载一次)并把全局表中的对应的模块表置 nil 。
同时把数据记录在专用的全局表下,并用 local 去引用它。初始化这些数据的时候,首先应该检查他们是否被初始化过了。这样来保证数据不被更新过程重置。
Module B中 local shortFunc = ModuleA.longFunc 在更新ModuleA后更新不到,需在之前加上local shortFunc = nil。比较麻烦
此方法用到了module,在Lua5.2中已经弃用module机制,Lua建议用户自己实现更简单的方法。
loadfile机制?
通过loadfile来模拟module机制,可以灵活的根据业务需求加入更多的热更新需求。
loadfile的使用基础?
-------------------------
--代码动态加载模块 v0.1
--基于Lua 5.2版本的loadfile
------------------------
----模块管理表,类似于package.loaded
local Modules = {}
--通过loadfile将新代码载入到newModule
function Load(pathname, modulename)
local newModule = {}
--_ENV被设置为空表,载入文件的访问空间被限制在模块内部
local func, err = loadfile(pathname, &bt&, newModule)
if not func then
print(&ERROR: & .. err)
Modules[moduleName] = newModule
测试模块 Game.lua
---------------------------------
---- 模拟一个游戏定时活动玩法逻辑
---- 活动中获奖用户记录下来,活动结束后发奖
---- 此代码有逻辑错误
-----------------------------------
-- 活动中获奖用户列表
rewardedUser = {}
-- 活动开始结束时间设置
local starttime = {hour = 10, min = 0, sec = 0}
local endtime = {hour = 12, min = 0, sec = 0}
-- 记录活动中中奖用户
function RecordReward(charId)
rewardedUser[char] = true& -- 报错,char = nil
--更新后的正确代码
-- rewardedUser[charId] = true
测试驱动模块 Main.lua
require(&Modules.lua&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
GAME = Load(&Game.lua&)
GAME.RecordReward(1001)& --报错
-- 更新错误以后重新加载
GAME = Load(&Game.lua&)
GAME.RecordReward(1001)& -- rewardedUser = { [1001] = true}
local data =GAME.rewardedUser
local func = GAME.RecordReward
--local 导致当前GAME.RecordReward、GAME.rewardedUser引用被当作upvalue绑定在 closure 里
GAME = Load(&Game.lua&)&
-- GAME.rewardedUser = {}& 被重新载入的代码所取代, { [1001] = true}数据丢失,导致用户无法领奖,业务逻辑发生异常。
GAME.RecordReward(1002)& -- rewardedUser = { [1002] = true}
-- data引用的是保存在upvalue中的旧引用,值为{ [1001] = true} ,与当前GAME.RecordReward不同步了,出现逻辑异常
-- 仍然报错,因为其引用的是保存在upvalue中的旧引用,而不是更新后的GAME.RecordReward
loadfile的使用进阶?
通过上面的代码实验,我们发现以下几个问题
上面的Game.lua 不能访问_G空间
需要持久化的内容没有得到保存
upvalue导致热更新失效
同时我们也可以看到,通过loadfile加载的代码,是以table形式引用的,这就为我们解决上述问题打开了思路。
-------------------------
--代码动态加载模块 v0.1
--基于Lua 5.2版本的loadfile
------------------------
--模块管理表,类似于package.loaded
local Modules = {}
-- string pathname 加载模块文件名,含路径
-- string name 模块名,一般和pathname一直即可
-- boolean reload 是否强制更新重载
-- table module 模块,如果加载失败返回nil
-- string err 如果module为nil,返回错误信息
function Load(pathname, moduleName, reload)
moduleName = moduleName or pathname
local oldModule = Modules[moduleName]
if not oldModule then& -- 第一次加载模块,全新加载
local newModule = {}
--通过metatable机制允许模块环境访问_G
setmetatable(newModule, {__index = _G})
local func, err = loadfile(pathname, &bt&, newModule)
if not func then
print(&ERROR: & .. err)
return nil, err
Modules[moduleName] = newModule
return newModule
else& -- 重复加载,不需要更新时直接返回缓存
if not reload then
return oldModule
--先缓存更新前模块内的table数据
local oldCache = {}
for k, v in pairs(oldModule) do
if type(v) == &table& then
oldCache[k] = v
oldModule[k] = nil
--原模块直接作为新的环境使用
local newModule = oldModule
--原模块被完全更新
local func, err = loadfile(pathname, &bt&, newModule)
if not func then
print(&ERROR: & .. err)
return nil, err
--恢复table数据,既保持原有数据,也保持了其他模块的既有引用
--因为此引用机制只能作用于table,函数upvalue依然得不到更新
for k, v in pairs(oldCache) do
--将metatable换成新的即可实现函数段更新
local mt = getmetatable(newModule[k])
if mt then setmetatable(v, mt) end
--对于已存在的table,数据段保持不变
newModule[k] = v
return newModule
此方法可实现模块内非local table的数据保持和外部对其引用的保持。同时不需要业务模块对此进行特殊处理
模块内local table数据不能保持,建议用来保存固定数据,例如数值表,活动时间等。
其他模块通过 local func = MODULE.Func 的形式引用模块函数无法得到更新,建议不用此形式。或者在每个引用之前加上 local func = nil,强制脚本每次执行时去更新引用。
再次基础上还可扩展模块的初始化和unload方法,实现特殊逻辑需求
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:581550次
积分:7487
积分:7487
排名:第2343名
原创:196篇
转载:310篇
评论:63条
(1)(1)(1)(5)(5)(12)(1)(1)(1)(32)(2)(1)(3)(1)(2)(2)(3)(1)(1)(3)(3)(2)(6)(10)(4)(11)(11)(15)(2)(17)(39)(16)(11)(8)(11)(10)(9)(1)(1)(20)(7)(3)(23)(26)(28)(14)(19)(7)(4)(29)(9)(1)(2)(1)(2)(10)(9)(7)(5)1493人阅读
cocos2d-x(17)
cc.Director:getInstance():endToLua()
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:105954次
积分:1335
积分:1335
排名:千里之外
原创:58篇
评论:12条
(16)(3)(1)(3)(4)(4)(1)(1)(4)(1)(9)(11)|  
|  
|  
|  
|  
只需一步,快速开始
查看: 44197|回复: 103
不用等那位有代碼的朋友,現在直接教你用LUA HACK方法,修改遊戲
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
本帖最后由 wucheong2 于
20:53 编辑
請先下載以下檔案,裡面有INJECTOR(注入器)程序和一些LUA 源代碼
把lua 目錄整在複製放在C:\
裡面有一個檔案叫distiny.lua,就是源代碼
打開遊戲,打開修改器按&Start The Hack&,遊戲中按一下HOME就會執行代碼
先講解一下,預先寫好的代碼
-- Credits goes to different UC members !
local player = managers.player:player_unit()
--以上不用改
-- God Mode 上帝模式
if player then
player:character_damage():set_invulnerable( true )
-- weapons 武器相關,暫時好像試不出效果
NewRaycastWeaponBase._get_spread = function(self) return 0 end
NewRaycastWeaponBase.recoil_multiplier = function(self) return 0 end
-- message on screen 在遊戲畫面,顯示text以內的文字
if managers.hud then
managers.hud:show_hint( { text = &Distiny's LUA Hack loaded!!& } )
-- set current level 設定目前等級
managers.experience:_set_current_level(25)
-- Set offshore money加的金錢
if managers.money then
& && &&&managers.money:_add_to_total()
-- Set skillpoints 設定技能值
managers.skilltree:_set_points(1337)
在 payday 2 latest lua 目錄裡面有完整的修改代碼,可以自己研究一下,可以說任何東西都可以修改.....,比如0秒開鎖....&&等大家研究吧!!
這裡附上我自己修改的代碼,每按一下HOME只加錢和技能5,有需要自己改數量
(247 Bytes, 下载次数: 15147)
23:57 上传
点击文件名下载附件
資料來自,原程序作者:distiny.lua
有人要配件的代碼
先發一下全面具的,自己放在distiny.lua的,按HOME,就能買全部面具
managers.blackmarket:_setup_masks()
for mask_id,_ in pairs(tweak_data.blackmarket.masks) do
& && &&&Global.blackmarket_manager.masks[mask_id].unlocked = true
& && &&&managers.blackmarket:add_to_inventory(&normal&, &masks&, mask_id, false)
全武器配件
for mod_id,_ in pairs(tweak_data.blackmarket.weapon_mods) do
& && &&&tweak_data.blackmarket.weapon_mods[ mod_id ].unlocked = true
& && &&&managers.blackmarket:add_to_inventory(&normal&, &weapon_mods&, mod_id, false)
全面具顏色
for i=1, 7 do
&&managers.lootdrop:debug_drop( 1000, true, i )
win7 64bit无效
64bit win7 无效
不客氣...順心
不客氣...順心
64位系统无效
主题帖子积分
游戏狂人, 积分 1198, 距离下一级还需 802 积分
游戏狂人, 积分 1198, 距离下一级还需 802 积分
我只需要配件。。。
主题帖子积分
游戏狂人, 积分 1236, 距离下一级还需 764 积分
游戏狂人, 积分 1236, 距离下一级还需 764 积分
好好好!!支持
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
还真发,嗯。那我就汉化一下吧。
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
不过你都发出去了。所有代码。就乱套了。我就是想发个解锁武器附件的。再自己做个注入器,中文的。
主题帖子积分
游戏达人, 积分 3044, 距离下一级还需 456 积分
游戏达人, 积分 3044, 距离下一级还需 456 积分
本帖最后由 w 于
00:13 编辑
我只需要配件。。。
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
三思而后行啊
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
managers.blackmarket:_setup_masks()
for mask_id,_ in pairs(tweak_data.blackmarket.masks) do
& & & & Global.blackmarket_manager.masks[mask_id].unlocked = true
& & & & managers.blackmarket:add_to_inventory(&normal&, &masks&, mask_id, false)
以上代碼解鎖全面具!!!!!!!!!!!!!!
主题帖子积分
超级玩家, 积分 704, 距离下一级还需 296 积分
超级玩家, 积分 704, 距离下一级还需 296 积分
游戏有要毁的趋势
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
是啊,本来只是想发个武器附件。这家伙直接给我全贴出来了。
主题帖子积分
游戏狂人, 积分 1198, 距离下一级还需 802 积分
游戏狂人, 积分 1198, 距离下一级还需 802 积分
成功 全武器配件解锁 楼主牛逼
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
x6218659 发表于
还真发,嗯。那我就汉化一下吧。
漢化什麼東西呢,才多少英文個字呀?
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
注入器的代码我会修改一下。顺手汉化一下。方便一点、
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
x6218659 发表于
不过你都发出去了。所有代码。就乱套了。我就是想发个解锁武器附件的。再自己做个注入器,中文的。 ...
有必要把已經有的東西再做一遍?
主题帖子积分
超级玩家, 积分 832, 距离下一级还需 168 积分
超级玩家, 积分 832, 距离下一级还需 168 积分
....襪全解鎖了......強大阿....
主题帖子积分
超级玩家, 积分 832, 距离下一级还需 168 积分
超级玩家, 积分 832, 距离下一级还需 168 积分
哈哈 x6218659 被搶首發& & 腦羞阿~~~~~
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
表示兄弟。把这个删了吧。大家要的只有武器附件。这样做,这款游戏就毁了。
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
x6218659 发表于
注入器的代码我会修改一下。顺手汉化一下。方便一点、
跟本LinGon就是用LUA HACK的,代碼什麼都不是秘密,基本上遊戲中所有的狀態都能修改,比如倒了,就直接變起來等等
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
wucheong2 发表于
漢化什麼東西呢,才多少英文個字呀?
也是。不过要把这个删掉啊,这游戏要毁
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
wucheong2 发表于
跟本LinGon就是用LUA HACK的,代碼什麼都不是秘密,基本上遊戲中所有的狀態都能修改,比如倒了,就直接變 ...
我去,那个源码文件夹那么大一片。
倒是够看一段时间啊。
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
贴个武器附件就行了。
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
x6218659 发表于
表示兄弟。把这个删了吧。大家要的只有武器附件。这样做,这款游戏就毁了。 ...
本人表示不建議大家開外掛在線玩,但LinGon的修改器都出這些功能了,我把這貼刪了有何意義呢?
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
那么那个钻机那个文件,我看过一次。不知道从哪下手。你知道吗?
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
wucheong2 发表于
本人表示不建議大家開外掛在線玩,但LinGon的修改器都出這些功能了,我把這貼刪了有何意義呢?
没让你删帖。。。你把代码改一下就好了。
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
原來已經有朋友在隔壁開了,哈哈
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
wucheong2 发表于
本人表示不建議大家開外掛在線玩,但LinGon的修改器都出這些功能了,我把這貼刪了有何意義呢?
嗯,我在第一贴就说了远离修改,呵呵。只是看大家附件刷的痛苦。。
才打算顺手做个程序。从外面考了一段主程序。表示刚想做。。。VS2012都下好了。
你就发完了
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
算了,不想说了。
主题帖子积分
初级玩家, 积分 90, 距离下一级还需 10 积分
初级玩家, 积分 90, 距离下一级还需 10 积分
x6218659 发表于
那么那个钻机那个文件,我看过一次。不知道从哪下手。你知道吗?
好像是這條
PlayerManager.selected_equipment_deploy_timer = function(self) return 0 end
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
VS安装了我半小时,我擦。太大了
主题帖子积分
高级玩家, 积分 364, 距离下一级还需 236 积分
高级玩家, 积分 364, 距离下一级还需 236 积分
wucheong2 发表于
好像是這條
PlayerManager.selected_equipment_deploy_timer = function(self) return 0 end
这个条单独的也看不明白呢。要连起来看,。
Powered by}

我要回帖

更多关于 安卓退出整个程序代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信