• About
    • Resume
A Game Developer also plays some guitar

Category Archives: Lua

新浪微博API for MOAI

November 13, 2012 1:54 pm / 3 Comments / Benny Chen

最近一个星期干了一件事情,因为游戏的需要,为Moai引擎集成了新浪微博的API,这样也算为开源又一次出了份力。

最近一年基本上是游走于游戏的脚本层,很久没有碰引擎代码了,这一周的工作充满了怀旧感,虽然复杂度不算高,但还是勾起了不少当年开发游戏引擎的记忆。

check it out from https://github.com/bennychen/moai-dev, branch: sina_weibo

同时该branch也集成了另一位Moai开发者的截屏API, from http://getmoai.com/forums/post4555.html

如何使用[sample code]


MOAISim.openWindow ( "test", 320, 480 )

viewport = MOAIViewport.new ()
viewport:setSize ( 320, 480 )
viewport:setScale ( 320, 480 )

layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
MOAISim.pushRenderPass ( layer )

gfxQuad = MOAIGfxQuad2D.new ()
gfxQuad:setTexture ( "moai.png" )
gfxQuad:setRect ( -64, -64, 64, 64 )

prop = MOAIProp2D.new ()
prop:setDeck ( gfxQuad )
prop:setLoc ( 0, 80 )
layer:insertProp ( prop )

font = MOAIFont.new ()
font:loadFromTTF ( "arialbd.ttf", " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.?!", 12, 163 )

textbox = MOAITextBox.new ()
textbox:setFont ( font )
textbox:setRect ( -160, -80, 160, 80 )
textbox:setLoc ( 0, -100 )
textbox:setYFlip ( true )
textbox:setAlignment ( MOAITextBox.CENTER_JUSTIFY )
layer:insertProp ( textbox )

--MOAISinaWeiboIOS.init( "you app id", "you app secret", "your callback url" )

function openCompileDialog( txt, imgFileLoc )
	MOAISinaWeiboIOS.compileDialog( txt, imgFileLoc )
	MOAISinaWeiboIOS.setListener( MOAISinaWeiboIOS.DIALOG_POST_CANCEL_CLICKED, function()
		print( "user clicked cancel post" )
		MOAIFileSystem.deleteFile( imgFileLoc )
	end )
	MOAISinaWeiboIOS.setListener( MOAISinaWeiboIOS.REQUEST_RESPONSE_WITH_RESULT, function()
		print( "post successuflly" )
		MOAIFileSystem.deleteFile( imgFileLoc )
	end )
end


function test()
	local frameBounds={
		left=0, 
		top=0, 
		width=1024, 
		height=768
	}

    local tmpFilename=MOAIScreenShotIOS.snapshotToFile( MOAIScreenShotIOS.PORTRAIT, frameBounds )
    print( "Saved at location: ", tmpFilename );
	print( MOAIFileSystem.checkFileExists( tmpFilename ))

	if ( not MOAISinaWeiboIOS.isAuthValid() )
	then
		MOAISinaWeiboIOS.login()
		MOAISinaWeiboIOS.setListener( MOAISinaWeiboIOS.DIALOG_LOG_IN_CANCEL, function() 
			MOAIFileSystem.deleteFile( tmpFilename )
		end )
		MOAISinaWeiboIOS.setListener( MOAISinaWeiboIOS.SESSION_DID_LOGIN, function()
			print( "successfully logged in" )
			openCompileDialog( "test", tmpFilename )
		end )
	else
		print( "already logged in, post" )
		openCompileDialog( "test", tmpFilename )
	end
end

timer = MOAITimer.new()
timer:setSpan( 1 )
timer:setListener( MOAIAction.EVENT_STOP, test )
timer:start()

Posted in: Game Programming, iOS, Lua / Tagged: lua, Moai, weibo, 微博, 新浪

Another Thread @ Moai Forum

October 4, 2011 11:07 am / Leave a Comment / Benny Chen

Does Moai support an API like ‘setTimeout’?

http://getmoai.com/forums/moai-sdk-developer-support/does-moai-support-an-api-like-settimeout/

Me
Hi,
Does Moai support an API like JavaScript’s setTimeout, which schedules a function execution after a specified time. I noticed there is a Moai class called MOAITimer, so I’m wondering if this class could be used for this purpose? I know a ‘setTimeout’ function could be easily realized on Lua level using MOAISim:getElapsedTime() and Lua’s ‘pcall’ function, but I’m just lazy and wonder if there is a shortcut that Moai has provided?
Thank you~

Josh
Moai doesn’t support that, but for convenience I’ll share the Lua function I use for this exact purpose:
(Hide some code)
EDIT: updated while investigating bug mentioned below. Will ensure this code works once bug is fixed.

Me
Thank you for the sharing, but the function gives the following error after I run:

cannot use ‘…’ outside a vararg function near ‘…’

I think ‘…’ are also needed for “function()” in the 5th line, so I added it.
However, after I ran the following code

function printAStr( str )	
    print( str )
end
callWithDelay( 1, printAStr, "helloWorld" )

It prints “userdata: 0x3192c4” instead of “helloWorld”, any clue for this? I think the core issue is how to pass arguments to the callback function of timer’s listener?

Josh
I made two mistakes in my function, which I have corrected above. You are correct I forgot to pass the … properly, and I also forgot that the timer listener callback receives the timer as the first parameter, which is why you were seeing the userdata print out in your test.

Me
seems still unworkable for the arguments pass…
Ok, so my question is how to pass arguments to callback function of timer’s listener?

Josh
It looks like there may be a bug in the listener with the last release. I’ve opened a bug on the issue. I also realized yet another error in my above code, and have corrected it. Hopefully that’s the last edit I have to do. 🙂

Patrick
Thanks for finding the bug. Won’t be able to get to it for a day or so. Sorry for the trouble!

Patrick
OK, finally had time to look at this. It looks like it’s working correctly. The code I used is below.

MOAISim.openWindow ( "test", 320, 480 )
function callWithDelay ( delay, func, ... )
  local timer = MOAITimer.new ()
  timer:setSpan ( delay )
  timer:setListener ( MOAITimer.EVENT_TIMER_LOOP,
    function ()
      timer:stop ()
      timer = nil
      func ( unpack ( arg ))
    end
  )
  timer:start ()
end

function printAStr ( str ) print( str ) end
callWithDelay ( 1, printAStr, "helloWorld" )

Me
It works! Thanks a lot 🙂

Posted in: Game Programming, Lua / Tagged: callWithDelay, lua, Moai, setTimeout

1st Day of Golden Week

October 1, 2011 11:51 pm / 4 Comments / Benny Chen

黄金周第一天,将之前开发的Pacman移植到了iPad上。因为Moai引擎,移植变得很容易,只需要把input层做一些修改。我的第一个iOS上的game demo就此诞生 😀

已经将代码更新到了github – https://github.com/bennychen/Moai-based-Pacman

Posted in: Game Programming, iOS, Lua / Tagged: ios, ipad, Moai, pacman

基于Lua的State Pattern

September 4, 2011 12:56 pm / Benny Chen

代码来自于最近写的Pacman,更多请查看 – https://github.com/bennychen/Moai-based-Pacman

class.lua实现了在Lua中创建类的模拟,非常方便。class.lua参考自http://lua-users.org/wiki/SimpleLuaClasses

-- class.lua
-- Compatible with Lua 5.1 (not 5.0).

function class(base, init)
   local c = {}    -- a new class instance
   if not init and type(base) == 'function' then
      init = base
      base = nil
   elseif type(base) == 'table' then
    -- our new class is a shallow copy of the base class!
      for i,v in pairs(base) do
         c[i] = v
      end
      c._base = base
   end
   -- the class will be the metatable for all its objects,
   -- and they will look up their methods in it.
   c.__index = c

   -- expose a constructor which can be called by <classname>(<args>)
   local mt = {}
   mt.__call = function(class_tbl, ...)
   local obj = {}
   setmetatable(obj,c)

-- below 2 lines are updated based on the Comments from 'http://lua-users.org/wiki/SimpleLuaClasses'
--   if init then
--      init(obj,...)
   if class_tbl.init then
      class_tbl.init(obj,...)
   else 
      -- make sure that any stuff from the base class is initialized!
      if base and base.init then
      base.init(obj, ...)
      end
   end
   return obj
   end
   c.init = init
   c.is_a = function(self, klass)
      local m = getmetatable(self)
      while m do 
         if m == klass then return true end
         m = m._base
      end
      return false
   end
   setmetatable(c, mt)
   return c
end

State基类,包含三个stub函数,enter()和exit()分别在进入和退出state时被执行,onUpdate()函数将会在state被激活时的每帧被执行。

require "class"

State = class()

function State:init( name )
	self.name = name
end

function State:enter()
end

function State:onUpdate()
end

function State:exit()
end

StateMachine类,该类集成了Moai的MOAIThread类。MOAIThread类似于Lua中的coroutine,但是在Moai中被yield的MOAIThread,会在game loop的每帧中被自动resume,见StateMachine:updateState函数,利用此特点,来实现每帧执行State:onUpdate函数。

require "State"

StateMachine = class()

function StateMachine:init()
	self.currentState = nil
	self.lastState = nil
end

function StateMachine:run()
	if ( self.mainThread == nil )
	then
		self.mainThread = MOAIThread.new()
		self.mainThread:run( self.updateState, self )
	end
end

function StateMachine:stop()
	if ( self.mainThread )
	then
		self.mainThread:stop()
	end
end

function StateMachine:setCurrentState( state )
	if ( state and state:is_a( State ) )
	then
		if ( state == self.currentState )
		then
			print( "WARNING @ StateMachine::setCurrentState - " ..
				   "var state [" .. state.name .. "] is the same as current state" )
			return
		end
		self.lastState = self.currentState
		self.currentState = state
		if ( self.lastState )
		then
			print( "exiting state [" .. self.lastState.name .. "]" )
			self.lastState:exit()
		end
		print( "entering state [" .. self.currentState.name .. "]" )
		self.currentState:enter()
	else
		print( "ERROR @ StateMachine::setCurrentState - " ..
			   "var [state] is not a class type of State" )
	end
end

function StateMachine:updateState()
	while ( true )
	do
		if ( self.currentState ~= nil )
		then
			self.currentState:onUpdate()
		end
		coroutine.yield()
	end
end

如何利用State和StateMachine类的示例,首先定义两个state。
SampleState.lua

require "State"

State1 = class( State ) 

function State1:init()
	State.init( self, "State1" )
end

function State1:enter()
	self.i = 0
end

function State1:exit()
	self.i = 0
end

function State1:onUpdate()
	print( self.name .. " is updated" )
	self.i = self.i + 1
	print( "self.i=" .. self.i )
	if ( self.i == 10 )
	then
		print( state2 )
		SM:setCurrentState( state2 )
		self.i = 0
	end
end

-----------------------

State2 = class( State ) 

function State2:init()
	State.init( self, "State2" )
end

function State2:onUpdate()
	print( "State2 is updated" )
end

test.lua

require "StateMachine"
require "SampleState"

SM = StateMachine()
SM:run()
state1 = State1()
state2 = State2()
SM:setCurrentState( state1 )
Posted in: Game Programming, Lua / Tagged: finite state machine, FSM, lua, state pattern, 状态模式

基于Moai的Pacman

August 29, 2011 10:49 pm / 4 Comments / Benny Chen

最近一两个星期,在业余时间利用Moai引擎重写了当年曾经用DirectX实现过的Pacman游戏。基于Lua的代码基本上是重写,只是保留使用了之前的2D资源。重写的目的一是通过这个来熟悉Moai引擎,二是希望用一个比较好的OO结构来重新实现Pacman,三则纯粹因为好玩。

把所有的代码,资源和文档都已经上传到了github,github真的是个好东东。

https://github.com/bennychen/Moai-based-Pacman

介绍:

This is a prototype game based on the Moai game platform – http://getmoai.com. With various APIs for drawing and handling different 2D elements that Moai has supported, it clones a 2D Pacman game.

I programmed the game for several objectives. Firstly, because I am just new to Moai, I try to familiarize myself with Moai’s various APIs and game development based on it. I did encounter some issues when programming the game. Some were because I am a newbie for Moai, and some were testified later that were from Moai engine itself. Although the process was time-consuming, but to my pleasure, this is somewhat a contribution to the open source Moai engine itself. I feel a great joy to be part of it. Secondly, the whole game is based on OO. So I tried to program the whole game with a decent OO structure. Most importantly, some of the Lua classes or files, hopefully, can be reused in my other future potential games.

All in all, I programmed Moai-based Pacman for fun and share my code, related game assets and documents here. If there can be any help for you who are interested in Moai and OO game programming, that would be my best honer.

Posted in: Game Programming, Lua, My Projects / Tagged: 2d, github, Moai, oo, pacman

Lua相关问题整理(4) – 让Lua的eval函数支持赋值语句

November 28, 2010 12:22 pm / Leave a Comment / Benny Chen

上一篇文章提到了在Lua中实现类似于JavaScript中的eval函数,遗憾是该eval函数不支持赋值语句,原因是Lua的赋值运算符是不支持返回值。所以如果要让该eval函数也支持赋值语句,就需要一个额外的工作,让它鉴别一个语句是不是赋值语句,如果是,则return的是被赋值后变量的值。为此,我写了一个isAssignmentExpression函数,比较粗糙,不过够用了,基本思想是检测语句中第一个出现的”=“操作符,且该”=“不能在一对引号当中。

-- Lua code
function isAssignmentExpression( str )
	local i = 1;
	local curChar;
	local quotesType = "none" -- none, single or double
	local isEscaping = false

	curChar = string.sub( str, 1, 1 )
	while ( curChar ~= "" ) do
		if ( curChar == "'" and
			 isEscaping == false and
			 quotesType ~= "double" )
		then
			if ( quotesType == "single" )
			then quotesType = "none"
			elseif ( quotesType == "none" )
			then quotesType = "single"
			end
		end

		if ( curChar == """ and
			 isEscaping == false and
			 quotesType ~= "single" )
		then
			if ( quotesType == "double" )
			then quotesType = "none"
			elseif ( quotesType == "none" )
			then quotesType = "double"
			end
		end

		if ( curChar == "\" and isEscaping == false )
		then isEscaping = true
		else isEscaping = false
		end

		if ( curChar == "=" and quotesType == "none" )
		then
			if ( string.sub( str, i+1, i+1 ) ~= "=" )
			then
				return true, string.sub( str, 1, i - 1 )
			else
				return false
			end
		end

		i = i + 1
		curChar = string.sub( str, i, i )
	end

	return false
end

function eval( str )
	local bAssign
	local var
	bAssign, var = isAssignmentExpression( str )
	if ( bAssign )
	then
		print( "Assignment, var=" .. var )
		loadstring( str )()
		return loadstring( "return " .. var )()
	else
		return loadstring( "return " .. str )()
	end
end

-- 以下是一组测试
print( eval( "3+4" ) )
-- 7
function Multiply( a, b )
	return a*b
end
print( eval( "Multiply( 3, 4 )" ) ) 
-- 12
print( eval( "i" ) ) 
-- nil
print( eval( "i = 1" ) ) 
-- Assignment, var=i    
-- 1
print( eval( "i = i + 1" ) ) 
-- Assignment, var=i    
-- 2
print( eval( "i" ) ) 
-- 2
print( eval( "i+1" ) ) 
-- 3
print( eval( "i, j = 4, 5" ) ) 
-- Assignment, var=i, j    
-- 4	   5
print( eval( "i = {}" ) ) 
-- Assignment, var=i    
-- table: 003CD818
print( eval( "i[ "0" ] = 0" ) ) 
-- Assignment, var=i[ "0" ]     
-- 0
print( eval( "i[ "\"0=" ] = 1" ) ) 
-- Assignment, var=i[ ""0=" ]     
-- 1
print( eval( "i.name="hello"" ) ) 
-- Assignment, var=i.name     
-- hello
print( eval( "i[0], i.name = 4" ) ) 
-- Assignment, var=i[0], i.name     
-- 4	  nil
print( eval( "i == 10" ) ) 
-- false
Posted in: Game Programming, Lua / Tagged: eval, lua, 赋值语句

Lua相关问题整理(3)

November 27, 2010 5:04 pm / Leave a Comment / Benny Chen
  1. 在注册给Lua的C函数中为Lua提供默认参数

    使用luaL_optstring, luaL_optnumber, luaL_optinteger等Lua API,如下示例,函数有一个默认字符串参数,默认值为””,这样在Lua中调用whatever的时候,whatever()或者whatever( “whatever”)均可。(Oh…whatever…随便…都行…)

    // C code
    int Whatever( lua_State *L )
    {
    	string str = luaL_optstring( L, 1, "" );
    	//...omitted code...
    }
    lua_register( L, "whatever", Whatever );
    
  2. 建立Lua字符串到C enum的映射

  3. 使用luaL_checkoption这个Lua API,它可以把从Lua传来的string转换为相应的C string array中的index,从而可以建立Lua字符串和C enum的映射。以下是个简单的示例:

    // C code
    enum PlayerType
    {
    	PLAYER_TYPE_UNDEFINED = -1,
    	PLAYER_TYPE_KING = 0, // 主公
    	PLAYER_TYPE_INSURGENT, // 反贼
    	PLAYER_TYPE_LOYAL, // 忠臣
    	PLAYER_TYPE_TREACHEROUS, //内奸-_^
    	NUM_PLAYER_TYPE // just a sentinel
    };
    
    const char * const PlayerTypeList[NUM_PLAYER_TYPE + 1] =
    {
    	"KING",
    	"INSURGENT",
    	"LOYAL",
    	"TREACHEROUS",
    	NULL
    };
    
    static int testPlayerType( lua_State *L )
    {
    	PlayerType type = static_cast< PlayerType >( 
    						luaL_checkoption( L, 1, 
    						"INSURGENT", PlayerTypeList ) );
    	std::cout << "Type index is " << type 
    		      << " - " << PlayerTypeList[type] 
    		      << std::endl;
    	return 0;
    }
    
    lua_register( L, "setPlayerType", setPlayerType )
    

    首先enum PlayerType定义了一组角色类型,来自人人都爱的三国杀:-)。

    接着PlayerTypeList定义了一个字符串数组,给Lua使用。注意需要保证enum和字符串数组的对应,比如PlayerTypeList[PLAYER_TYPE_KING]是“KING”,同时,PlayerTypeList必须以NULL结尾。

    在定义给Lua的函数testPlayerType中,就可以用luaL_checkoption将Lua传来的字符串参数转换为相应enum的值。luaL_checkoption还支持默认参数,比如在上面例子中,将第三个参数设为“INSURGENT”,如果Lua中没有提供任何参数,则PlayerType就为与“INSURGENT”相对应的PLAYER_TYPE_INSURGENT。

    以下是一组测试及结果:

    --Lua code
    testPlayerType( "KING" ) -- Type index is 0 - KING
    testPlayerType() -- Type index is 1 - INSURGENT
    testPlayerType( "whatever" ) -- bad argument #1 to 'testPlayerType' (invalid option 'whatever')
    
  4. 在Lua中实现eval函数

    众所周知,JavaScript中有一个著名的eval函数,它用于把一个字符串当作一段JS代码去执行,在Lua中没有提供类似的函数,但稍微包装下Lua的库函数loadstring即可实现,以下是代码。

    --Lua code
    function eval( str )
    	local func = loadstring( "return " ..str );
    	return func()
    end
    

    这样已经可以了,不过相比于JS的eval函数,功能稍微差一些,因为它不支持赋值语句,这是Lua语言天然的原因,因为Lua的赋值运算符没有返回值,在其他语言中常见传递赋值的“i=j=1”(先赋值j=1,然后将(j=1)的返回值j赋值给i),在Lua中是不允许的。所以当eval执行的是赋值运算(比如i=1)的时候,return i=1就会出错。

    下面是一些测试例子:

    --Lua code
    print( eval( "3+4" ) ) -- OK, 打印7
    
    function Multiply( a, b )
    	return a*b
    end
    
    print( eval( "Multiply( 3, 4 )" ) ) -- OK,打印12
    
    print( eval( "i = 1" ) ) -- 错误, attempt to call a nil value
    i = 1
    print( eval( "i" ) ) -- OK,打印1
    print( eval( "i = i + 1" ) ) -- 错误, attempt to call a nil value
    
  5. 实现luaL_checkbool

    不知道为什么Lua的API没有提供luaL_checkbook函数,不过很容易实现:

    // C code
    BOOL luaL_checkbool( lua_State *luaVM, int numArg )
    {
    	BOOL b = FALSE;
    	if ( lua_type( L, numArg ) == LUA_TBOOLEAN )
    	{
    		b = lua_toboolean( L, numArg );
    	}
    	else
    	{
    		luaL_typerror( L, numArg, lua_typename( L, LUA_TBOOLEAN ) )
    	}
    	return b;
    }
    
Posted in: C++, Game Programming, Lua / Tagged: enum, eval, lua, luaL_checkbool, 默认参数

Lua相关问题整理(2)- 如何在C中为Lua提供同步调用接口

November 7, 2010 10:25 pm / Leave a Comment / Benny Chen

这个问题的具体描述是——C注册给Lua一个函数,但Lua调用该C函数并不能立即获得结果(比如需要访问远程服务器获取值),如何能让Lua停止并等待,直到获取到结果后,才继续执行接下来的脚本。

举个例子,比如说有一个C函数login,我们试图通过调用该函数以执行用户的登录操作并获取验证结果。首先看下面这段C代码:

// C code
int login( lua_State *L )
{
	string user = luaL_checkstring( L, 1 );
	string password = luaL_checkstring( L, 2 );

	// 该函数将user和password发送到服务器后立即返回,
	// 绝不要在此处阻塞,这将严重影响效率
	sendAuthenticationInfo( user, password );

	return 0;
}
// 注册给Lua
lua_register( L, "login", login );

可以看到,因为该函数需要访问远程的登录服务器,在系统中一般都采取异步操作(让系统阻塞等待结果是不可接受的)。但是这样Lua开发人员调用login函数时,也只能异步等待结果,下面是Lua中处理登录操作的代码。

-- Lua code
-- 当用户点击“登陆”按钮后,执行该函数
function onClickLoginBtn()
	local user = ...
	local password = ...
	login( user, password ) -- 只是发送login命令
end

--当获取login结果后的回调函数
function onGetLoginResult( bPass )
	if bPass == true then
		print( "Authentication succeeded." )
		...omitted code...
	else
		print( "Authentication failed." )
		...omitted code...
	end
end

这段Lua代码很好理解,首先onClickLoginBtn是一个按钮事件处理函数,当用户点击了”登录“按钮后,会触发该函数。该函数首先从界面上获取用户输入的user和password,然后调用了上面C中所定义的login函数。正如前面的C代码所写的,login函数不会马上得到认证结果,所以执行后马上退出。另一个函数是onGetLoginResult,这个Lua函数需要当C系统中获取到认证结果后被回调执行,以真正执行login的后续操作。所以,我们还需要在C中添加回调的代码。

// C code
// 当服务器端返回认证结果后
BOOL loginResult = ...
lua_getglobal( L, "onGetLoginResult" );
lua_pushboolean( L, loginResult );
lua_call( L, 1, 0 );

在这里,我们在C中hardcode了回调onGetLoginResult的代码,这很丑陋,不过可以避免,比如可以给前面注册给Lua的login函数增加一个参数callbackFunctionName,以让Lua显式的告诉系统当获取登录结果后的回调函数名称。

再次回到本文一开始所提出的问题,尽管在系统中的异步调用不可避免,但我们希望在Lua中能够有同步机制,即Lua脚本在得到验证结果后才允许被继续执行,如何才能做到这一点呢。

Lua有一个非常棒的coroutine机制,在Lua代码中可以通过协同程序来进行多线程,可以使用coroutine.yield和coroutine.resume来对协同程序进行挂起和恢复。需要达到上面所提出的目标,只需在系统中使用与coroutine.yield和coroutine.resume相对应的Lua C API——lua_yield和lua_resume即可。如下所示,login函数有些小改变:

// C code
int login( lua_State *L )
{
	string user = luaL_checkstring( L, 1 );
	string password = luaL_checkstring( L, 2 );
	sendAuthenticationInfo( user, password );
	return lua_yield( L, 0 );
}
// 注册给Lua
lua_register( L, "login", login );

可以看到,与前面的区别只有login函数的最后一句,调用了lua_yield后再返回,而不是return 0,这样就可以达到阻塞Lua脚本的目的。事实是,lua_yield是一个比较特殊的函数,它只能作为注册的C函数的返回值使用,否则调用失败。

当系统获得服务器端的登陆验证结果后,通过lua_resume即可恢复之前被阻塞的Lua。

// C code
// 当服务器端返回认证结果后
BOOL loginResult = ...
lua_pushboolean( L, loginResult );
lua_resume( L, 1 );

上面的代码是当你的系统中只有一个Lua虚拟机的情形,如果使用了多个Lua虚拟机,事情稍微有一点点复杂,login函数还需要将当前调用的lua_State存储下来,以便lua_resume的时候,可以知道恢复的是哪一个被阻塞的虚拟机。

OK,当C中有这样的实现后,Lua程序人员将会为此而高兴,因为Lua代码变得如此简洁。

-- Lua code
-- 当用户点击“登陆”按钮后,执行该函数
function onClickLoginBtn()
	local user = ...
	local password = ...
	if login( user, password ) == true then
		print( "Authentication succeeded." )
		...omitted code...
	else
		print( "Authentication failed." )
		...omitted code...
	end
end

系统or平台开发人员应当尽可能的为用户考虑,正如上面第二种解决方法所追求的那样。

Posted in: C++, Game Programming, Lua / Tagged: C++, coroutine, login, lua, resume, yield, 同步调用

Lua相关问题整理(1)

November 7, 2010 10:17 pm / Leave a Comment / Benny Chen
  1. (Under Linux)cannot find ‘dlsym’ ‘dlopen’ ‘dlerror’ ‘dlclose’

    需要同时链接”dl“库

  2. (Under Linux)编译lua报错luaconf.h:275:31: error: readline/readline.h: No such file or directory

    需要下载并安装GNU Readline Library

  3. PANIC: unprotected error in call to Lua API (unable to get ModuleFileName)

    1: 不推荐的解决方式:将Project Properties->Configuration Properties->General下的Character Set从unicode改成multi-set;
    2: 彻底的解决方式,参考此链接:http://lua-users.org/lists/lua-l/2006-06/msg00427.html

  4. 如何将Lua文本文件转化为Lua块文件(chunk file)

    调用LuaAPI – lua_dump

    关于lua_dump: about lua_dump: Dumps a function as a binary chunk. Receives a Lua function on the top of the stack and produces a binary chunk that, if loaded again, results in a function equivalent to the one dumped. As it produces parts of the chunk, lua_dump calls function writer (see lua_Writer) with the given data to write them.

  5. 如何在C中调用Lua脚本层的库函数

    void BeginLuaLibCall( lua_State *L, const string &libName, const string &functionName )
    {
         lua_pushstring( L, libName.c_str() );
         lua_gettable( L, LUA_GLOBALSINDEX );
         lua_pushstring( L, functionName.c_str() );
         lua_gettable( L, -2 );
    }
    
    void EndLuaLibCall( lua_State *L )
    {
         lua_pop( L, -1 );
    }
    

    示例:调用table.getn(该函数用来获取一个table的size)

    // 利用上面的函数
    BeginLuaLibCall( L, "table", "getn" );
    // 假设你的脚本中有一个table变量myTable,获取它到栈顶
    lua_getglobal( L, "myTable" ); 
    // 执行table.getn( t )
    lua_call( L, 1, 1 ); 
    // 打印结果
    std::cout << lua_tonumber( L, -1 ) ) << std::endl;
    // 将结果弹出栈
    lua_pop( L, -1 );
    // 将名叫“table”的table弹出栈
    EndLuaLibCall( L);
    
Posted in: Game Programming, Lua / Tagged: chunk, dl, function, library, lua, readline

LinkedIn

Milan Petrovic

Categories

  • In My Life (25)
    • A Day in the Life (8)
    • English Learning (2)
    • Learn a Word (7)
    • Something In The Way (8)
  • Music Heaven (8)
    • Guitar (1)
    • In Concert (1)
    • Lyrics (3)
  • OK Computer (54)
    • 3D (3)
    • C++ (10)
    • Computer Graphics (15)
    • Game Programming (23)
    • iOS (6)
    • Linux (1)
    • Lua (9)
    • My Projects (3)
    • Some Experiences (9)
    • Talking in Code (2)
    • Unity (2)
  • Quotations (2)
  • Uncategorized (1)
  • Visca Barça (24)
    • FCB BJ (5)

Recent Posts

  • [译]优化你的手机游戏(没有延迟的,才是健康的)- 一篇给游戏美术设计师读的文章
  • 新浪微博API for MOAI
  • 稍后继续
  • Unity Developer ++
  • Another Thread @ Moai Forum
  • 1st Day of Golden Week
  • 为SyntaxHighlighter添加新语言
  • 基于Lua的State Pattern
  • Class Diagram of Pacman
  • 基于Moai的Pacman

Recent Comments

  • 约修亚_RK on 为SyntaxHighlighter添加新语言
  • 爱装的小男孩 on 小心DLL链接静态库时的内存错误
  • happyfire on Game Loop的几种实现方式
  • William on 新浪微博API for MOAI
  • Benny Chen on 新浪微博API for MOAI
  • your man on 新浪微博API for MOAI
  • 你家男人 on 稍后继续
  • 逍遥 on 关于对std::vector的遍历
  • papa on Unity Developer ++
  • T客网 ︱ Techpot » Blog Archive » iOS开发与OpenGL ES相关问题整理(1) on iOS开发与OpenGL ES相关问题整理(1)

Tags

2d 3D 3dsmax 3ds max air Apply architecture Asia tour barca Beijing bilbao binary search blocked bob boost bruce springsteen C++ capo CGContextDrawImage Champions League Change DLL DX10 eval exporter flash framework frustum culling game game engine iniesta ios linux lua Moai opengles pacman plug-in plugin 北京 导出插件 崩溃 巴萨 游戏引擎 踢球
© Copyright 2026 - A Game Developer
Infinity Theme by DesignCoral / WordPress