【LÖVE 11.3】LÖVE - 免費多平臺的2D遊戲引擎
LÖVE是一個免費多平臺的2D遊戲引擎,主體是以Lua這種手稿語言,它的語法相當簡潔,它是以C++編寫,支援多平臺輸出,在官網有介紹幾個上架的遊戲 - iOS / Android + Windows / macOS / Linux,好像都是可愛的小遊戲…XD,至於為什麼會想學這個呢?因為Unity3D太過強大,而且自己只是想寫一個小品遊戲當成生日禮物送人,工程師的浪漫嘛…XD,笑容可掬的女生,最高…
作業環境
項目 | 版本 |
---|---|
CPU | Apple M1 |
macOS | Big Sur 11.2.3 |
LÖVE | 11.3 |
安裝
brew install --cask love
基礎教學
程式碼範例
- main.lua是程式一開始的進入點,使用love ./就可以開啟遊戲
- 因為上面都有寫簡單的註解了,所以就不多做說明
- 這裡要記錄一下,eqMAC可以讓macOS內建的錄影程式,錄到本身的聲音 (模擬麥克風?)…
-- MARK: 生命週期
-- 一開始載入的時候
function love.load()
initSetting()
end
-- 繪製畫面的時候
function love.draw()
drawPicture()
drawFont(40)
end
-- 定時更新 (60fps => 0.016664166999817 (1/60))
function love.update(deltaTime)
-- print(deltaTime)
end
-- 滑鼠按下去的時候
function love.mousepressed(x, y, button)
-- button == 1 (左鍵)
if (button == 1) then
love.audio.play(music.error)
end
-- button == 2 (右鍵)
if button == 2 then
love.audio.play(music.bgm)
end
--
print(button)
end
-- 按下鍵盤的時候
function love.keypressed(key)
print(key)
end
-- MARK: 小工具
-- 初始設定 (自定義的function)
function initSetting()
screenSize()
soundInfo()
initTitle()
end
-- 設定標題文字
function initTitle()
love.window.setTitle('Hello World')
end
-- 繪圖
function drawPicture()
local imageName = 'image/love2d.png' -- 區域變數
image = love.graphics.newImage(imageName) -- 全域變數
love.graphics.draw(image, 300, 200)
end
-- 繪字
function drawFont(size)
font = love.graphics.newFont('font/jf-openhuninn-1.1.ttf', size) -- 產生字型 + 大小
love.graphics.setFont(font) -- 設定字型
love.graphics.printf('滑鼠左鍵音效 / 右鍵音樂', 0, 480, screen.width, 'center') -- 繪出文字
end
-- 取得畫面大小
function screenSize()
screen = {
width = love.graphics.getWidth(),
height = love.graphics.getHeight(),
}
end
-- 設定音樂曲目
function soundInfo()
music = {
bgm = love.audio.newSource("sound/bgm.mp3", "stream"), -- 一直播 => stream
error = love.audio.newSource("sound/error.wav", "static") -- 短聲音 => static
}
music.bgm:setLooping(true) -- 一直播放
music.bgm:setVolume(0.5) -- 音量50%
end
生命週期
- love.load():一開始載入的時候,一般都是用來設定初始變數使用
- love.draw():繪製畫面
- love.update():定時更新用 => 60fps
- love.mousepressed():滑鼠按下去的時候
- love.keypressed():按下鍵盤的時候 (小寫字母)
程式說明
- love.window.setTitle():設定標題文字
- love.graphics.newImage():讀取圖片
- love.graphics.newFont():產生字型 + 字體大小
- love.graphics.setFont():設定字體
- love.graphics.printf():繪出帶有格式的文字
- love.graphics.draw():繪出圖片
- love.graphics.getWidth():取得畫面寬度
- love.graphics.getHeight():取得畫面高度
- love.audio.newSource():產生影音來源
其它常用
- print():這個就是印在Command上的,Debug用
簡單的射擊遊戲
做一個長成這樣子的Game
基本設定
- 首先之後都會切成好幾個檔,便於管理
- 先設定背景 / 音樂 / 圖形物件,求能動再說
- 使用require()這個function,可以載入其它地方的lua檔
- 下面顯示的Code都是『非完整的』,完整內容請下載git
- 在這裡唯一的資料結構叫Table - {},可以是Array,也可以是Map
-- ./main.lua
-- MARK: 生命週期
function love.load()
importSource()
initSprite()
initSound()
_setTitle('射擊遊戲')
_setScreen(1024, 600)
end
function love.draw()
_drawBackground(sprite.sky)
local size = _getScreenSize()
print(size.width, size.height)
end
-- 載入其它位置的檔案 => 容易維護
function importSource()
require('source.utility')
require('source.setting')
end
-- ./source/setting.lua
-- MARK: - 初始設定
-- 初始化圖形物件 => Table
function initSprite()
sprite = {}
sprite.sky = love.graphics.newImage('sprite/sky.png')
sprite.target = love.graphics.newImage('sprite/target.png')
sprite.crosshairs = love.graphics.newImage('sprite/crosshairs.png')
end
-- 初始化音效 => Table
function initSound()
sound = {
bgm = love.audio.newSource("sound/bgm.mp3", "stream"),
shoot = love.audio.newSource("sound/shoot.wav", "static")
}
sound.bgm:setLooping(true)
sound.bgm:setVolume(0.5)
love.audio.play(sound.bgm)
end
-- ./source/utility.lua
-- MARK: - 公用工具
-- 設定遊戲的Title
function _setTitle(text)
love.window.setTitle(text)
end
-- 畫背景 => 一定要最先畫,不然會蓋過其它的東西
function _drawBackground(image)
love.graphics.draw(image, 0, 0)
end
-- 設定畫面大小
function _setScreen(width, height)
love.window.setMode(width, height)
end
-- 取得畫面大小
function _getScreenSize()
return { width = love.graphics.getWidth(), height = love.graphics.getHeight() }
end
設定文字
- 倒數計時,其中很有趣的是,它的0是『-0』,所以文字會跑版 => -0,所以要修正一下
- 分數 / 開始文字
-- ./main.lua
-- 繪出倒數計時的值
function printTimer()
local time = '時間: '..math.ceil(timer.value)
local size = _getScreenSize()
_print(time, size.width / 2 - font.size / 2 - 40, 5)
end
-- 印出開始的一開始的標題
function printStartTitle()
if game.isOver then
local size = _getScreenSize()
_printf('點這裡就開始了喲!', 0, 250, size.width, 'center')
end
end
-- 繪出分數
function printScore()
local text = '分數: '..game.score
_print(text, 5, 5)
end
-- ./source/setting.lua
-- MARK: - 初始設定
-- 初始化變數
function initParameter()
timer = {
max = 3,
value = 3,
}
end
-- ./source/utility.lua
-- 時間倒數 => -0現象
function _timerCountDown(timer, deltaTime)
local newTimer = timer - deltaTime
if newTimer > 0 then
return newTimer
end
return 0
end
繪出準心及標靶
- 這裡有一個game.isOver的變數,用來記錄遊戲是否結束的狀態
- 主要是準心要跟著滑鼠的位置做移動
-- 畫準心 => 跟著滑鼠移動,一定要最後畫,不然會不見
function drawCrosshairs()
local position, size = _getMousePosition(), _getImageSize(sprite.crosshairs)
_draw(sprite.crosshairs, position.x - size.width / 2, position.y - size.height / 2)
end
-- 畫標靶
function drawTarget()
if game.isOver then
local size = _getImageSize(sprite.target)
_draw(sprite.target, target.x - size.width / 2, target.y - size.height / 2)
end
end
標靶隨機位置
- 最主要是要判斷滑鼠點擊的位置,是否在標靶的半徑內部
function love.mousepressed(x, y, button)
-- button: 1 => 左鍵
if button == 1 then
if not game.isOver then
local distance, targetRadius = _distanceBetween(x, y, target.x, target.y), _getImageSize(sprite.target).height / 2
love.audio.play(sound.shoot)
-- 假如點在圈圈內的話 => 點到加分 + 換位置
if distance < targetRadius then
game.score = game.score + 1
targetRandomPosition()
return
end
end
if game.isOver then
restart()
end
end
end
-- 標靶隨機位置
function targetRandomPosition()
local screenSize, targetSize = _getScreenSize(), _getImageSize(sprite.target)
target.x = _random(targetSize.width / 2, screenSize.width - targetSize.width / 2)
target.y = _random(targetSize.height / 2, screenSize.height - targetSize.height / 2)
end
遊戲發行
直接打包
- 其實.love本身就是個.zip檔,只要把.zip => .love,在系統有安裝love的時候,就可以直接執行了。
- 不過要注意的是,main.love一定要在第一層才可以,不含資料夾…
- 當然用command也是滿方便的
zip -9 -r MyGame.love .
Windows => .EXE
# Windows
copy /b love.exe + MyGame.love MyGame.exe
copy /b love.exe + %1 "%~n1.exe"
#macOS
cat love.exe MyGame.love > MyGame.exe
不能動?加上.dll檔
macOS => .APP
./Contents/Resources
範例程式碼下載
後記
- 學一門新的程式語言真的是滿累人的,寫遊戲,要會的東西更是多了,學海無涯,回頭是岸…XD,難怪薪水高得可怕啊。