LÖVE游戏引擎 #
一、LÖVE 简介 #
1.1 什么是 LÖVE #
LÖVE(Love2D)是一个使用 Lua 编程语言开发 2D 游戏的开源框架。它提供了图形渲染、音频播放、输入处理、物理模拟等功能。
1.2 核心特点 #
- 简单易用:API 设计直观
- 跨平台:支持 Windows、macOS、Linux
- 轻量级:框架小巧,启动快速
- 开源免费:Zlib/libpng 许可证
1.3 游戏循环 #
lua
function love.load()
-- 初始化代码
end
function love.update(dt)
-- 更新逻辑
end
function love.draw()
-- 绘制画面
end
二、安装与配置 #
2.1 安装 LÖVE #
bash
# macOS
brew install --cask love
# Windows
# 下载安装包:https://love2d.org/
# Linux
sudo apt install love
2.2 创建项目 #
text
mygame/
├── main.lua -- 主入口
├── conf.lua -- 配置文件
├── assets/ -- 资源文件
│ ├── images/
│ ├── sounds/
│ └── fonts/
└── lib/ -- 库文件
2.3 配置文件 #
lua
-- conf.lua
function love.conf(t)
t.title = "My Game"
t.version = "11.4"
t.window.width = 800
t.window.height = 600
t.window.fullscreen = false
t.window.vsync = true
end
2.4 运行游戏 #
bash
# 运行游戏
love mygame
# 打包游戏
love --game mygame
三、基本功能 #
3.1 图形绘制 #
lua
function love.load()
x = 100
y = 100
radius = 50
end
function love.draw()
-- 设置颜色(RGBA,0-1)
love.graphics.setColor(1, 0, 0)
-- 绘制圆形
love.graphics.circle("fill", x, y, radius)
-- 绘制矩形
love.graphics.rectangle("fill", 200, 100, 100, 50)
-- 绘制线条
love.graphics.line(0, 0, 800, 600)
-- 绘制文本
love.graphics.print("Hello, LÖVE!", 10, 10)
end
3.2 加载图片 #
lua
function love.load()
image = love.graphics.newImage("assets/player.png")
x = 100
y = 100
end
function love.draw()
love.graphics.draw(image, x, y)
end
3.3 键盘输入 #
lua
function love.load()
x = 400
y = 300
speed = 200
end
function love.update(dt)
if love.keyboard.isDown("left") then
x = x - speed * dt
end
if love.keyboard.isDown("right") then
x = x + speed * dt
end
if love.keyboard.isDown("up") then
y = y - speed * dt
end
if love.keyboard.isDown("down") then
y = y + speed * dt
end
end
function love.draw()
love.graphics.circle("fill", x, y, 20)
end
function love.keypressed(key)
if key == "escape" then
love.event.quit()
end
end
3.4 鼠标输入 #
lua
function love.load()
x = 400
y = 300
end
function love.update(dt)
-- 获取鼠标位置
local mx, my = love.mouse.getPosition()
-- 跟随鼠标
x = x + (mx - x) * 0.1
y = y + (my - y) * 0.1
end
function love.mousepressed(x, y, button)
if button == 1 then
print("左键点击:", x, y)
end
end
function love.draw()
love.graphics.circle("fill", x, y, 20)
end
四、游戏对象 #
4.1 玩家类 #
lua
local Player = {}
Player.__index = Player
function Player:new(x, y)
local instance = setmetatable({}, self)
instance.x = x
instance.y = y
instance.width = 32
instance.height = 32
instance.speed = 200
instance.vx = 0
instance.vy = 0
return instance
end
function Player:update(dt)
-- 输入处理
self.vx = 0
self.vy = 0
if love.keyboard.isDown("left") then self.vx = -self.speed end
if love.keyboard.isDown("right") then self.vx = self.speed end
if love.keyboard.isDown("up") then self.vy = -self.speed end
if love.keyboard.isDown("down") then self.vy = self.speed end
-- 更新位置
self.x = self.x + self.vx * dt
self.y = self.y + self.vy * dt
end
function Player:draw()
love.graphics.setColor(0, 1, 0)
love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end
return Player
4.2 使用玩家类 #
lua
local Player = require("player")
function love.load()
player = Player:new(400, 300)
end
function love.update(dt)
player:update(dt)
end
function love.draw()
player:draw()
end
五、动画 #
5.1 精灵动画 #
lua
function love.load()
sprite = love.graphics.newImage("assets/spritesheet.png")
-- 创建动画帧
frames = {}
local frame_width = 32
local frame_height = 32
for i = 0, 3 do
frames[i + 1] = love.graphics.newQuad(
i * frame_width, 0,
frame_width, frame_height,
sprite:getDimensions()
)
end
current_frame = 1
frame_time = 0
frame_duration = 0.1
end
function love.update(dt)
frame_time = frame_time + dt
if frame_time >= frame_duration then
frame_time = 0
current_frame = current_frame + 1
if current_frame > #frames then
current_frame = 1
end
end
end
function love.draw()
love.graphics.draw(sprite, frames[current_frame], 100, 100)
end
5.2 使用动画库 #
bash
# 安装 anim8 库
# 将 anim8.lua 放入 lib 目录
lua
local anim8 = require("lib.anim8")
function love.load()
sprite = love.graphics.newImage("assets/spritesheet.png")
local grid = anim8.newGrid(32, 32, sprite:getWidth(), sprite:getHeight())
animation = anim8.newAnimation(grid('1-4', 1), 0.1)
end
function love.update(dt)
animation:update(dt)
end
function love.draw()
animation:draw(sprite, 100, 100)
end
六、碰撞检测 #
6.1 简单碰撞 #
lua
local function check_collision(a, b)
return a.x < b.x + b.width and
a.x + a.width > b.x and
a.y < b.y + b.height and
a.y + a.height > b.y
end
6.2 使用物理引擎 #
lua
function love.load()
-- 创建世界
world = love.physics.newWorld(0, 9.81 * 64, true)
-- 创建地面
ground = {}
ground.body = love.physics.newBody(world, 400, 550, "static")
ground.shape = love.physics.newRectangleShape(800, 50)
ground.fixture = love.physics.newFixture(ground.body, ground.shape)
-- 创建球
ball = {}
ball.body = love.physics.newBody(world, 400, 200, "dynamic")
ball.shape = love.physics.newCircleShape(20)
ball.fixture = love.physics.newFixture(ball.body, ball.shape, 1)
ball.fixture:setRestitution(0.7) -- 弹性
end
function love.update(dt)
world:update(dt)
end
function love.draw()
love.graphics.setColor(0.5, 0.5, 0.5)
love.graphics.polygon("fill", ground.body:getWorldPoints(ground.shape:getPoints()))
love.graphics.setColor(1, 0, 0)
love.graphics.circle("fill", ball.body:getX(), ball.body:getY(), ball.shape:getRadius())
end
七、音频 #
7.1 播放音效 #
lua
function love.load()
jump_sound = love.audio.newSource("assets/jump.wav", "static")
bg_music = love.audio.newSource("assets/music.mp3", "stream")
bg_music:setLooping(true)
bg_music:play()
end
function love.keypressed(key)
if key == "space" then
jump_sound:play()
end
end
八、游戏状态 #
8.1 状态管理 #
lua
local Game = {}
Game.__index = Game
function Game:new()
local instance = setmetatable({}, self)
instance.state = "menu"
instance.score = 0
return instance
end
function Game:update(dt)
if self.state == "menu" then
-- 菜单逻辑
elseif self.state == "playing" then
-- 游戏逻辑
elseif self.state == "gameover" then
-- 结束逻辑
end
end
function Game:draw()
if self.state == "menu" then
love.graphics.print("Press SPACE to start", 300, 300)
elseif self.state == "playing" then
love.graphics.print("Score: " .. self.score, 10, 10)
elseif self.state == "gameover" then
love.graphics.print("Game Over! Score: " .. self.score, 300, 300)
end
end
function Game:keypressed(key)
if self.state == "menu" and key == "space" then
self.state = "playing"
elseif self.state == "gameover" and key == "space" then
self.state = "menu"
self.score = 0
end
end
return Game
九、完整示例 #
9.1 简单躲避游戏 #
lua
local player = {x = 400, y = 500, width = 40, height = 40, speed = 300}
local enemies = {}
local score = 0
local spawn_timer = 0
local game_over = false
function love.load()
math.randomseed(os.time())
end
function love.update(dt)
if game_over then return end
-- 玩家移动
if love.keyboard.isDown("left") then
player.x = player.x - player.speed * dt
end
if love.keyboard.isDown("right") then
player.x = player.x + player.speed * dt
end
-- 边界检测
player.x = math.max(0, math.min(800 - player.width, player.x))
-- 生成敌人
spawn_timer = spawn_timer + dt
if spawn_timer > 0.5 then
spawn_timer = 0
table.insert(enemies, {
x = math.random(0, 800 - 30),
y = -30,
width = 30,
height = 30,
speed = 200 + math.random(100)
})
end
-- 更新敌人
for i = #enemies, 1, -1 do
local e = enemies[i]
e.y = e.y + e.speed * dt
-- 碰撞检测
if check_collision(player, e) then
game_over = true
end
-- 移除出界敌人
if e.y > 600 then
table.remove(enemies, i)
score = score + 1
end
end
end
function love.draw()
-- 绘制玩家
love.graphics.setColor(0, 1, 0)
love.graphics.rectangle("fill", player.x, player.y, player.width, player.height)
-- 绘制敌人
love.graphics.setColor(1, 0, 0)
for _, e in ipairs(enemies) do
love.graphics.rectangle("fill", e.x, e.y, e.width, e.height)
end
-- 绘制分数
love.graphics.setColor(1, 1, 1)
love.graphics.print("Score: " .. score, 10, 10)
if game_over then
love.graphics.print("Game Over! Press R to restart", 300, 300)
end
end
function love.keypressed(key)
if key == "r" and game_over then
enemies = {}
score = 0
game_over = false
end
end
function check_collision(a, b)
return a.x < b.x + b.width and
a.x + a.width > b.x and
a.y < b.y + b.height and
a.y + a.height > b.y
end
十、总结 #
LÖVE 是开发 2D 游戏的优秀框架:
- 简单易用:直观的 API
- 功能丰富:图形、音频、输入、物理
- 跨平台:支持主流操作系统
- 社区活跃:丰富的库和教程
下一章,我们将学习 Lua 的应用场景。
最后更新:2026-03-27