首页 资讯中心 硬件周边 攻略中心 秘籍中心 在线动漫 CG壁纸  
专题栏目: PSP NDS GBA PS2 PS3 XBOX XBOX360 WII
PSP 游戏资料 | 玩家宝典
您的位置:游狐网 >> PSP >> 玩家宝典 >> 软件教程

菜鸟也能为PSP编程 - Lua Player 编程初级指南

[ 时间:2008-5-6 9:40:37 | 来源:电玩巴士 | 收藏本文 ] 【

10——应用音频

  现在该是时候给我们的项目加点响声了。任何游戏都需要声音,这一讲我们就来学学如何在Luaplayer中发声。开始上课!

  luaplayer 可以播放如下音乐格式*:UNI, IT, XM, S3M, MOD, MTM, STM, DSM, MED, FAR, ULT 或 669,WAV 文件可用作声音。MIDI可以先转换为上述格式再使用,比如 Modplug Tracker 就可以转。请记住 luaplayer 不支持 mp3 文件*。在学习了一些音频命令之后我们将结合之前的成果创建一个小程序。

  *译者注:此说法已过时,目前luaplayer已支持mp3,ogg,aa3,oma,omg,详见HM版相关函数。但是由于luaplayer目的在于编游戏,所以对mp3播放的支持程度不高。

  先来看第一个命令,此命令将播放一个音乐文件。

代码:

Music.playFile( string file, bool loop )

  此处的“string file”是指你的音乐文件名,例如“song.xm”。“bool loop”处放置“true”或者“false”。设“true”则一直循环播放该音乐,“false”则只播一遍。下面是个放歌的示例:

代码:

Music.playFile("mysong.mod", true)

  接下来看看这个命令。它们是在开始播放音乐之后使用的:

代码:

Music.pause()
Music.stop()
Music.resume()

  这些命令不用解释你也能看懂。
  Music.pause() 将暂停歌曲播放。
  Music.stop() 将停止歌曲播放。
  Music.resume() 将恢复播放被暂停的歌曲。

  还有一个命令是用来侦测一首歌是否正在播放。这将返回 true 或 false。看一下:

代码:

Music.playing()

  假如说我们想侦测我们的歌曲是否在播放,如果是则打印一条消息到屏幕。我们可以这样做:

代码:

if Music.playing() == true then
screen:print(10,10,"Music is playing",white)
end

  还有一个命令是用来设置音乐文件的音量的。只要在括号中填入一个数值,范围在 0 至 128 之间。下面是命令格式:

代码:

Music.volume(Number)

  现在让我们学学用于音效的声音文件,尤其是 wav 文件。这和播放音乐文件有些区别。下面是如何载入一个声音:

代码:

bonkSound = Sound.load("bonk.wav",false)

  wav 文件作为一个变量被载入,稍后我们就可以用这个变量来指称该声音。此处我们设“false”是以防循环播放。记住设为“true”将循环播放,如果你的确是这么想的话。

  关于 WAV 文件的一个要点是,在 luaplayer 中只能使用单声道的,立体声的不行。你可以通过右键点击文件查看其属性的摘要页来确认这一点。

  现在让我们来再学一些命令。下个命令是播放该文件。使用你载入声音时设的变量名。如下:

代码:

bonkSound:play()

  但是我不建议你这样播放声音文件。这会导致一个常见错误,类似“loop ingettable(无法取得循环)”之类消息。下面是我播放声音文件的方法。不同之处就是用另一个变量取代 bonkSound。

代码:

local sound = bonkSound
voice = sound:play()
--要停止声音使用:
voice:stop()

  还有一个命令与音乐文件的命令类似,侦测声音是否正在播放。命令如下:

代码:

voice:playing()

  还有一些声音和音乐方面的命令等待你去探究,但是这些已足够你使用声音和音乐了。

  现在我们开始做一个小玩意儿。我们将以一个菜单屏幕为起始,用来选择蓝色还是黑色背景。按下 X 时程序会往下执行,而背景色已按照我们的选择设好。此处我们的程序将显示其已被执行多少次。怎么做?嗯,就是每次在菜单屏幕按下 X 时程序就打开一个文件(我们稍后会创建),然后写一个数字进文件。程序也会从该文件中读取该数字并保存在一个变量中。如果你完全退出程序然后再返回,它仍然能显示被执行了多少次,因为这个数据已存在一个文件里了。那么,让我们忙起来吧。

  首先,我想要你用notepad或任何其他编辑器创建一个普通的txt文件。在该文本文件中输入数字 0。保存为 counter.txt。就是一个普通的文本文件。

  然后开始编写我们的 lua 文件。先创建一些要用到的色彩对象:

代码:

white = Color.new(255,255,255)
blue = Color.new(0,0,255)
black = Color.new(0,0,0)

  接着是一些变量。

代码:

oldpad = Controls.read()
startcolor = black
gamestate = "menu"

  oldpad 将储存我们上一次按下的按键。
  startcolor 存储我们稍后将在程序第二部分使用的颜色。我们以 black 开始。
  gamestate 则是用来查看该使用哪个函数。我们将创建两个函数。一个是显示菜单的,另一个执行程序余下的工作。既然我们从菜单开始,该变量的起始值就如此设置。

  下一部分就要处理声音了!首先,请下载两个小小的 WAV 文件,放在程序所在目录下。

  现在让我们在程序中载入这些 wav 文件。我们不想让它们循环,所以使用 false。

代码:

menusound = Sound.load("beep.wav",false)
goodbye = Sound.load("goodbye.wav",false)

  够简单吧!还记得上一讲的那些文件命令吗?我们来次回顾吧。此处我们将打开我们之前创建的 counter.txt 文件,并从中读取数值存入变量 counter 中。

代码:

file = io.open("counter.txt", "r")
counter = file:read("*n")
file:close()

  请注意我们使用了"*n"以读入一个数字。

  接着我们将创建一个数据表,用于我们的起始屏幕选择器。这会包含一个我们创建来用作选择器的图像,以及它的 x 和 y 坐标值。数据表下一行的命令则将我们的选择器图像以蓝色清空。代码如下:

代码:

selector = { image = Image.createEmpty(145,15), x = 147,y = 77 }
selector.image:clear(blue)

  现在我们建一个称为 drawMenu() 的函数,执行菜单所有的必要任务。下面是起始行:

代码:

function drawMenu()

  我们将把此函数用作一个循环函数,所以每次循环我们先清屏然后读取按键的输入。代码如下:

代码:

screen:clear()
pad = Controls.read()

  接下来我们将把我们的选择器绘制(blit)到屏幕上,并打印两行字。代码如下:

代码:

screen:blit(selector.x,selector.y,selector.image)
screen:print(150,80,"Start Game (Black)",white)
screen:print(150,100,"Start Game (Blue)",white)

  请注意我们是怎么使用数据表的值来绘制选择器到屏幕上的。这个选择器图像将会上下移动以高亮显示被选择的菜单项。要确保在打印文字之前绘制,否则图像将覆盖文字。

  打印的两行字则是我们给玩家的选项。要么以黑色屏幕开始游戏,要么是蓝色的屏幕。

  在函数的下一部分将检测按键是否按下。先做上键的部分吧。

代码:

if pad:up() and oldpad:up() ~= pad:up() then
selector.y = 77
startcolor = black
local sound = menusound
voice = sound:play()
end

  第一行是说如果上键被按下并且不是最后被按下的按钮则.....

  第二行将 selector 的 y 值设置为 77。这是为了在文本周围贴上图像以便看起来像是被选择的。
然后设置 startcolor 为 black。

  接着使用我之前建议的方法播放 menusound 这个 wav 文件。

  现在处理下键。代码与上面很相似,除了图像向下一点,颜色改为蓝色以外。代码如下:

代码:

if pad:down() and oldpad:down() ~= pad:down() then
selector.y = 97
startcolor = blue
local sound = menusound
voice = sound:play()
end

  现在来处理 X 按钮。

代码:

if pad:cross() and oldpad:cross() ~= pad:cross() then
gamestate = "game"
counter = counter + 1
file = io.open("counter.txt","w")
file:write(counter)
file:close()
end
end

  此处我们将 gamestate 设为“game”以便菜单的代码不再执行(在我们编写了后面的代码之后)。我们以 1 为基数递增 counter 变量。然后打开 txt 文件,写入 counter 的新值,替换文件里的旧值。不要忘了关闭文件。

  注意,多出来的那个 end 是用来终结函数的。这个函数已完成了!

  我们下一个函数将执行离开菜单后的游戏代码。这个函数相当小巧简单,全部代码如下:

代码:

function playGame()
screen:clear(startcolor)
pad = Controls.read()
screen:print(100,100,"This program has been executed " .. counter .. " times.",white)
screen:print(100,110,"Press Start to exit to Menu",white)

if pad:start() then
gamestate = "menu"
local sound = goodbye
voice = sound:play()
end
end

  在此函数中,请注意我们使用了在菜单中通过 startcolor 变量选择的颜色清屏。打印了两个消息,检查了 start 按键的按下。按下 start 键将把 gamestate 设回 menu 并播放一个 wav 文件。

  接下来开始我们的程序主循环。由于使用了函数,此处很简短。在循环中我们将检查游戏的状态并执行该状态的函数。代码如下!

代码:

while true do

if gamestate == "menu" then
drawMenu()
end

if gamestate == "game" then
playGame()
end

screen.flip()
oldpad = pad
end

  ...接下来... Oh yeah!已经完成啦!运行试试看吧。