Luaplayer 编程深入篇(一)图形缓存



掌叔
2008-08-01 14:54:07

摘自:tgbus
作者:Isword_

非常感谢Luaplayer语言的开发者为我们提供了那么好的开发环境,让PSP的开发变得如此简易。
Luaplayer对于一些小游戏或者是对于游戏的速度要求不太高的游戏的制作还是非常胜任的,因为他的语法简单而不乏强大。

下面就开始进入正题,首先先来说说图像缓存的概念,图像缓存即为储存图像数据而开辟的一块内存区,为将图像显示到屏幕上最准备。而luaplayer也为我们提供了图像的缓存,它是以双缓存的形式存在,即offscreen和onscreen。那么我们有什么办法来调用这两个缓存呢?可以通过 screen.flip()来实现,它的作用就是循环切换offscreen和onscreen。我面先来看一段代码:

[code=lua]
oldpad = Controls.read()
red = Color.new(255, 0, 0)
screen:print(160, 100, "Look! I made text appear!", red)
screen.flip()
while true do
pad = Controls.read()
if pad:up() and oldpad:up() ~= pad:up() then
screen:print(160, 120, "Look! I made text appear!", red)
else
end
screen.waitVblankStart()
oldpad = pad
end
[/code]

运行之后,发现了什么?屏幕上先会在160,100处显示一行红色的字“Look! I made text appear!”,按下UP键之后,160,120处并没有显示任何字。这是怎么回事?有人说在第8行后面应该加上screen.flip(),那好,我们不妨加上试试看。运行之后,屏幕上先会在160,100处显示一行红色的Look! I made text appear!,按下UP键之后,原先在160,100处的字消失,而在160,120处显示一行红色的Look! I made text appear!,接着再按下UP键,160,100和160,120处的字都出现了。再按下UP键,160,100处的字再次消失,160,120处还在。这到底是怎么一回事?好像越来越复杂了。别急,我面就从缓存的角度来入手分析一下。
前面说过了,screen.flip()的作用就是循环切换offscreen和onscreen的,当运行了screen.flip()函数, onscreen缓存就处于了等待刷新状态,所有的screen:之后的绘图代码将对onscreen缓存失效,而相反offscreen缓存就处于了绘图状态,所有的screen:之后的绘图代码将对offscreen缓存有效。再次运行screen.flip()函数后,onscreen缓存和 offscreen缓存的状态将被切换,而screen.waitVblankStart()函数只对等待刷新状态的缓存有效。那么知道了这些,之前代码运行后的情况就可以想明白了,在这里就不多说了。

由于luaplayer为我们提供的图像缓存操作起来并不是太方便,所以我们有必要自己来开辟一个图像缓存,怎么来做呢?这就要介绍一下另一个函数 Image.createEmpty(width, height),它的作用很浅显,就是创建一个空的图像缓存区,最大宽度和高度是512。比如:
[code=lua]
canvas = Image.createEmpty(480, 272)
[/code]
这样就开辟了一个名为canvas的图像缓存。想要在canvas上画图也很简单和screen类似,比如:
[code=lua]
canvas:print(160, 100, "Look! I made text appear!")
canvas:blit(0,0,Image)
[/code]
要把canvas缓存里的图形刷新到屏幕上也很简单,如代码:
[code=lua]
screen:blit(0, 0, canvas)
screen.flip()
screen.waitVblankStart()
[/code]
下面写一个完整的使用自己开辟的缓存来显示图形的例子,自己运行一下看看效果吧
[code=lua]
canvas = Image.createEmpty(480, 272)
canvas:clear(Color.new(255,255,255))
canvas:print(160, 100, "Look! I made text appear!")
screen:blit(0, 0, canvas)
screen.flip()
while true do
screen.waitVblankStart()
end
[/code]
活学活用,提供几个有用的通用函数
[code=lua]
local function SaveScreen(left,top,width,height,scr)
scr = scr or screen
if scr ~= screen then
tmp_canvas = Image.createEmpty(width,height)
tmp_canvas:blit(0,0,scr,left,top,width,height)
else
screen.flip()
tmp_canvas = Image.createEmpty(width,height)
tmp_canvas:blit(0,0,scr,left,top,width,height)
screen.flip()
end
end

local function ShowScreen(left,top,width,height,scr)
scr = scr or screen
scr:blit(left,top,tmp_canvas,0,0,width,height)
tmp_canvas = nil
end
[/code]
上面两个函数是相对的,SaveScreen的作用是保存屏幕中任意位置任意大小的图形,ShowScreen则是在屏幕中任意位置显示任意大小的图形,注意:SaveScreen和ShowScreen中的参数width,height应该保持一致不然会出错。


kamiu123
2009-07-23 23:37:02

使用LUADS一定要记得释放你调用的任何 资源,不然会造成内存溢出死机


kamiu123
2009-07-23 23:38:10

那个垃圾解释器不会在程序退出时释放资源,搞得我编程时关机无数次


qdujunjie
2009-09-15 22:21:41

使用Luaplayer的朋友能不能加我QQ呢:327837296