關於Lua Player學習指南是本文要介紹的內容,主要是來學習Lua中關於Player的內容。你應該對lua程式設計語言的基礎有所瞭解,而LuaIDE在純的Lua環境下對你實驗很有協助,在那裡你可以鍵入一些程式並且一步一步的運行,來觀察其中的變數是如何改變的,還有一種方式就是下載windows版本的Lua(lua.exe),以命令列的方式來啟動lua.exe,然後在裡面輸入Lua運算式,比如像”for i=1,10 do io.write(i..”/n”) end”。
Hello World
首先按照readme檔案中描述的步驟安裝Lua Player.完成之後讓我們從一個簡單的指令碼開始吧:
- -- create a new Color object
- green = Color.new(0, 2
-
- -- show some text on offscreen
- screen:print(200, 100, "Hello World!", green)
-
- -- flip visible and offscreen
- screen.flip()
-
- -- wait forevever
- while true do
- screen.waitVblankStart()
- end
把上面這些內容輸入到文字文件中,並以”script.lua”作為他的檔案名稱,把它放到你的記憶棒用來存放EBOOT.PBP的同一個目錄中.當你啟動Lua player之後,你的可愛的psp螢幕上應該可以看到這個枯燥的圖片:
psp 的螢幕的解析度是480*272(單位像素)的.”Color.new”這條語句建立了一個新的顏色對象.參數分別是red,green,blue和alpha(可選),每一個參數的變化範圍都是從0到255.這其實就是RGB顏色模型. "screen:print"這條語句在螢幕上顯示出了一些文本,其中前兩個參數是要顯示的文本在螢幕中的位置x,y座標值,這兩個參數後面緊接著要顯示的文本和一個可選的顏色參數(預設是黑色).座標值x是從螢幕的左邊開始的,座標值y是從螢幕頂端往下增長的.
這裡我們使用了兩個螢幕緩衝:一個離屏緩衝和一個可視緩衝。所有的繪圖函數都是作用在離屏緩衝上的。這就意味著直到調用了screen.flip(),離屏緩衝和可視緩衝才能互相交換,從而顯示出你要顯示出的文字來。這其實就是所謂的雙緩衝技術。這種技術是通過一種叫做page-flipping(翻頁技術)來實現的,這就是問什麼它的名字叫做“flip“啦。
在最後的那個while迴圈中 無限的調用了waitVblankStart這個函數。如果你不以類似這樣的方式結尾的話,當你的指令碼結束時,你將不會看到你所想要看到的結果,因為你如果從Lowser中啟動它的話你看到的將是Lowser的圖形介面,如果把它作為一個單獨的指令碼來啟動並執行話你看到將是螢幕上顯示是否還要重新運行一遍的提示。如果你只是用一個空迴圈而沒有用那些等待函數的話,這將會佔用大量的cpu資源。
動畫
理解儲存在記憶體中的像素是如何顯示在螢幕上的對於編寫遊戲是非常重要的。許多顯示裝置包括psp的顯示原理,其實都和老式的陰極射線管的原理相類似。一條光線從螢幕的左上端開始一條線一條線往下掃描。
在最底部時這條光要返回左上端時要花費一些時間而這段時間就叫做垂直空白vblank),這是因為在掃描線在返回起始掃描位置時它是處在非啟用狀態的。當然了,在psp中其實並沒有這條掃描線。但是你可以就認為它是這麼工作的。當執行”screen.waitVblankStart()”後,指令碼將會等待到這次vblank的開始.在vblank期間將不會顯示任何像素點,這就給了我們時間來進行離屏和顯示屏之間的切換,從而避免了螢幕閃爍。
下面讓我們看看通過同步的頁面切換來實現的動畫是個什麼樣的吧:
- System.usbDiskModeActivate()
- green = Color.new(0, 255, 0)
- time = 0
- pi = math.atan(1) * 4
- while true do
- screen:clear()
-
- x = math.sin(pi * 2 / 360 * time) * 150 + 192.5
- screen:print(x, 100, "Hello World!", green)
- timetime = time + 1
- if time >= 360 then
- time = 0
- end
-
- screen.waitVblankStart()
- screen.flip()
-
- pad = Controls.read()
- if pad:start() then
- break
- end
- end
在while迴圈當中,首先對離屏進行清屏,然後在離屏上面寫上一些文字,然後指令碼等待vblank的開始,之後在交換可見屏和離屏。Psp的垂直重新整理率是60Hz,這就意味著文字需要六秒鐘的時間才會回到原來的地方sin函數的周期是2*pi,所以一個完整的周期就是從0度到360度,而每秒鐘增加六十次,所以一個周期就要花費6秒)。在代碼的最後通過檢查是否按下了start這個按鍵,來退出迴圈。
你可以使用這條語句作為你自己的程式的開始。System.usbDiskModeActivate()這條語句啟動了usb模式,在迴圈的最後是按鍵代碼:當你按下start按鍵後,Lua Player程式就重新運行你的程式一遍。這個就讓我們在開發時有了一個快速的周轉時間:首先在psp上運行你的指令碼程式,當你開啟了usb功能時,你就可以通過usb驅動來在一個文字編輯器開啟你的指令碼,儲存你對指令碼改動,然後只要每按下start按鍵就可以馬上運行經過改動後的指令碼了。
映像
首先拷貝下面這個圖片到你的psp上,並以background.png作為它的檔案名稱:
然後還有這個圖片,把它命名為smiley.png
下面就這個笑臉的動畫程式了:
- System.usbDiskModeActivate()
- green = Color.new(0, 255, 0)
- time = 0
- pi = math.atan(1) * 4
- background = Image.load("background.png")
- smiley = Image.load("smiley.png")
- while true do
- screen:blit(0, 0, background, 0, 0, background:width(), background:height(), false)
-
- x = math.sin(pi * 2 / 250 * time) * 200 + 220.5
- y = 172 - math.abs(math.sin(pi * 2 / 125 * time) * 150)
- screen:blit(x, y, smiley)
- timetime = time + 1
- if time >= 500 then
- time = 0
- end
-
- screen.waitVblankStart()
- screen.flip()
-
- pad = Controls.read()
- if pad:start() then
- break
- end
- end
你可以看到我們上面這個程式的主迴圈體的大體結構和前面例子的結構是很像的。不過這次沒有使用screen:clear()這個函數拉,而是調用了screen:blit,通過它來描繪了背景。然後screen:blit(x, y, smiley)這一句則在背景之上描繪了另一個映像。這裡用到的參數比較少,因為我們對blit函數使用了預設的參數,我們把alpha這個參數設為真。這意味著所有在這幅圖片中透明的像素點是不會被參與blit過程。
比如說某些映像程式會這樣顯示你的圖片:
我們可以看到當Lua Player中alpha這個參數被設為真時,各自花紋圖案是透明的並沒有被描繪出來。
如果你有很多物體要畫在螢幕上的話,使用多層技術可能會更快一些:通過Image.createEmpty建立一個空的映像空的映像預設是由透明的像素點構成的),把你遊戲中的靜態部分描繪到這個映像上,然後對於vblank後的每次迴圈,首先在螢幕上畫出背景,然後是包含靜態部分的那個圖片,最後再畫那些動態部分。具體你可參閱snake這個遊戲是怎麼做到的。
控制
你可以通過control類來使用你psp上的控制組件。Controls.read()能夠讀取到psp控制組件的目前狀態,舉個例子來說當x鍵按下時,那麼cross這個函數就會返回真值(true)否著就會返回假值(false)。analogX 和 analogY可以返回類比類比搖杆的位置,它的範圍是-128到127,但是即使當搖杆在中間位置時也會產生些小於32的數值。下面是一個畫圖程式。通過類比搖杆來移動游標,按下cross來繪畫,select是按鈕,start鍵則是結束。
- red = Color.new(255, 0, 0);
- black = Color.new(0, 0, 0);
- white = Color.new(255, 255, 255);
-
- canvas = Image.createEmpty(480, 272)
- canvas:clear(white)
-
- brush = {}
- eraser = {}
-
- x0 = 0
- y0 = 0
- x1 = 0
- y1 = 0
- while true do
- pad = Controls.read()
- dx = pad:analogX()
- if math.abs(dx) > 32 then
- x0x0 = x0 + dx / 64
- end
- dy = pad:analogY()
- if math.abs(dy) > 32 then
- y0y0 = y0 + dy / 64
- end
- if pad:cross() then
- canvas:drawLine(x0, y0, x1, y1, black)
- end
- x1 = x0
- y1 = y0
- screen:blit(0, 0, canvas, 0, 0, canvas:width(), canvas:height(), false)
- screen:drawLine(x1 - 5, y1, x1 + 5, y1, red)
- screen:drawLine(x1, y1 - 5, x1, y1 + 5, red)
- screen.waitVblankStart()
- screen.flip()
- if pad:start() then break end
- if pad:select() then screen:save("screenshot.tga") end
- end
小結:淺析關於Lua Player學習指南的內容介紹完了,希望通過本文的學習能對你有所協助!