love2d-core
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLÖVE (Love2D) Core
LÖVE (Love2D) 核心指南
Set up and debug the foundation of a LÖVE game in Lua: the callback loop, frame-rate-
independent movement, input, and screen states. Targets LÖVE 11.5.
使用Lua搭建并调试LÖVE游戏的基础框架:包括回调循环、帧率无关的移动、输入处理以及屏幕状态管理。本文针对LÖVE 11.5版本。
When to use
适用场景
- Use when starting a LÖVE game, wiring up /
main.lua, or fixing the core loop, movement that runs at the wrong speed, input handling, or screen switching.conf.lua - Use when the workspace has calling
main.lua, alove.*, or aconf.luafile..love
When not to use: Lua language questions unrelated to LÖVE; physics bodies/joints
(LÖVE uses Box2D via — a separate concern); shader code (
GLSL is its own topic). For cross-engine save/load patterns, use .
love.physicslove.graphicssave-systems- 适用于启动LÖVE游戏项目、配置/
main.lua,或是修复核心循环、移动速度异常、输入处理问题、屏幕切换逻辑时。conf.lua - 适用于工作区中存在调用的
love.*、main.lua或conf.lua文件的场景。.love
不适用场景:与LÖVE无关的Lua语言问题;物理体/关节(LÖVE通过使用Box2D,属于独立范畴);着色器代码(的GLSL是单独主题)。如需跨引擎的保存/加载模式,请使用。
love.physicslove.graphicssave-systemsCore workflow
核心工作流程
- Confirm the entry points. A LÖVE game runs ; it should define
main.lua(one-time setup),love.load()(state), andlove.update(dt)(rendering). Window/version setup goes inlove.draw()(run before modules load).conf.lua - Pin the version. Set in
t.version = "11.5"so LÖVE warns on mismatch.conf.lua - Drive all motion by (delta time, in seconds) so speed is frame-rate independent.
dt - Handle input two ways: polled (in
love.keyboard.isDown, for held keys) and event (updatecallback, for discrete presses).love.keypressed - Manage screens (menu, game, pause) with a small state stack rather than a pile of
flags — see Patterns and
if.references/state-stack.md - Run and observe. Launch with from the project folder; verify the window, motion speed, and input on screen before assuming it works.
love .
- 确认入口文件:LÖVE游戏运行;该文件应定义
main.lua(一次性初始化)、love.load()(状态更新)和love.update(dt)(渲染)。窗口/版本配置需放在love.draw()中(在模块加载前运行)。conf.lua - 锁定版本:在中设置
conf.lua,这样当版本不匹配时LÖVE会发出警告。t.version = "11.5" - 所有运动均由驱动(delta time,单位为秒),确保速度不受帧率影响。
dt - 两种输入处理方式:轮询式(在中使用
update,处理长按按键)和事件式(love.keyboard.isDown回调,处理单次按键)。love.keypressed - 管理屏幕状态(菜单、游戏、暂停)使用小型状态栈,而非大量判断——详见“模式”部分和
if。references/state-stack.md - 运行并观察:从项目文件夹中执行启动游戏;在假设功能正常前,先验证窗口显示、移动速度和屏幕输入是否正常。
love .
Patterns
模式示例
1. main.lua
skeleton (the callback loop + input)
main.lua1. main.lua
骨架(回调循环 + 输入处理)
main.lualua
-- main.lua — LÖVE calls these callbacks for you. Colors are 0–1 in LÖVE 11.x.
function love.load()
-- One-time setup. speed is in PIXELS PER SECOND, not per frame.
player = { x = 100, y = 100, size = 40, speed = 220 }
love.graphics.setBackgroundColor(0.1, 0.1, 0.12)
end
function love.update(dt)
-- Polled input: good for continuous movement while a key is held.
if love.keyboard.isDown("right") then player.x = player.x + player.speed * dt end
if love.keyboard.isDown("left") then player.x = player.x - player.speed * dt end
if love.keyboard.isDown("down") then player.y = player.y + player.speed * dt end
if love.keyboard.isDown("up") then player.y = player.y - player.speed * dt end
end
function love.draw()
love.graphics.setColor(0.2, 0.8, 1.0) -- tint ON
love.graphics.rectangle("fill", player.x, player.y, player.size, player.size)
love.graphics.setColor(1, 1, 1) -- reset tint before text/images
love.graphics.print("Arrow keys to move, Esc to quit", 10, 10)
end
function love.keypressed(key)
-- Event input: fires once per physical press. Use for menus, jumps, toggles.
if key == "escape" then love.event.quit() end
endlua
-- main.lua — LÖVE会自动调用这些回调函数。LÖVE 11.x中颜色值范围为0–1。
function love.load()
-- 一次性初始化。speed单位为像素/秒,而非像素/帧。
player = { x = 100, y = 100, size = 40, speed = 220 }
love.graphics.setBackgroundColor(0.1, 0.1, 0.12)
end
function love.update(dt)
-- 轮询式输入:适合按键长按期间的持续移动。
if love.keyboard.isDown("right") then player.x = player.x + player.speed * dt end
if love.keyboard.isDown("left") then player.x = player.x - player.speed * dt end
if love.keyboard.isDown("down") then player.y = player.y + player.speed * dt end
if love.keyboard.isDown("up") then player.y = player.y - player.speed * dt end
end
function love.draw()
love.graphics.setColor(0.2, 0.8, 1.0) -- 设置颜色 tint ON
love.graphics.rectangle("fill", player.x, player.y, player.size, player.size)
love.graphics.setColor(1, 1, 1) -- 在绘制文本/图像前重置颜色
love.graphics.print("Arrow keys to move, Esc to quit", 10, 10)
end
function love.keypressed(key)
-- 事件式输入:每次物理按键按下触发一次。适用于菜单、跳跃、切换操作。
if key == "escape" then love.event.quit() end
end2. Frame-rate independence (the single most common bug)
2. 帧率无关性(最常见的错误)
lua
-- RIGHT: scaled by dt → same real-world speed at 30 or 240 FPS.
player.x = player.x + player.speed * dt
-- WRONG: "pixels per frame" → moves twice as fast at double the frame rate.
player.x = player.x + player.speedlua
-- 正确:乘以dt → 在30或240 FPS下实际速度一致。
player.x = player.x + player.speed * dt
-- 错误:"像素/帧" → 帧率翻倍时移动速度也翻倍。
player.x = player.x + player.speed3. conf.lua
(window + version; runs before main.lua
)
conf.luamain.lua3. conf.lua
(窗口 + 版本配置;在main.lua
前运行)
conf.luamain.lualua
-- conf.lua — must be its own file; love.conf will NOT run from main.lua.
function love.conf(t)
t.version = "11.5" -- the LÖVE version this game targets (string "X.Y")
t.window.title = "My LÖVE Game"
t.window.width = 800
t.window.height = 600
t.window.vsync = 1 -- number since 11.0: 1 = on, 0 = off, -1 = adaptive
t.window.resizable = false
t.modules.physics = false -- disable modules you don't use to trim startup/memory
endlua
-- conf.lua — 必须是独立文件;love.conf无法在main.lua中运行。
function love.conf(t)
t.version = "11.5" -- 游戏目标的LÖVE版本(字符串格式"X.Y")
t.window.title = "My LÖVE Game"
t.window.width = 800
t.window.height = 600
t.window.vsync = 1 -- 11.0版本起为数值:1=开启,0=关闭,-1=自适应
t.window.resizable = false
t.modules.physics = false -- 禁用未使用的模块以减少启动时间/内存占用
end4. Color is 0–1 in LÖVE 11.x (not 0–255)
4. LÖVE 11.x中颜色值范围为0–1(而非0–255)
lua
-- LÖVE 11.x uses normalized floats. (Pre-11.0 code used 0–255 and will look wrong.)
love.graphics.setColor(1, 0, 0) -- opaque red
love.graphics.setColor(0.2, 0.8, 1.0, 0.5) -- translucent cyan (alpha 0.5)
-- Need to convert old byte values? Use the helper instead of dividing by hand:
love.graphics.setColor(love.math.colorFromBytes(128, 234, 255))lua
-- LÖVE 11.x使用归一化浮点数。(11.0之前的版本使用0–255,直接使用会显示异常。)
love.graphics.setColor(1, 0, 0) -- 不透明红色
love.graphics.setColor(0.2, 0.8, 1.0, 0.5) -- 半透明青色(alpha值0.5)
-- 需要转换旧的字节值?使用辅助函数而非手动除法:
love.graphics.setColor(love.math.colorFromBytes(128, 234, 255))5. Screen states (brief — full manager in references)
5. 屏幕状态(简化版——完整管理器见参考资料)
lua
-- A screen is a table with optional :update(dt), :draw(), :keypressed(key).
-- Keep the active screen on a stack so pause/menu overlays are trivial to pop.
local Stack = require("state_stack") -- see references/state-stack.md for the module
function love.load() Stack.push(require("screens.menu")) end
function love.update(dt) Stack.current():update(dt) end
function love.draw() Stack.current():draw() end
function love.keypressed(key) Stack.current():keypressed(key) endlua
-- 屏幕是一个包含可选:update(dt)、:draw()、:keypressed(key)方法的表。
-- 将活跃屏幕存储在栈中,这样暂停/菜单覆盖层可以轻松弹出。
local Stack = require("state_stack") -- 模块实现见references/state-stack.md
function love.load() Stack.push(require("screens.menu")) end
function love.update(dt) Stack.current():update(dt) end
function love.draw() Stack.current():draw() end
function love.keypressed(key) Stack.current():keypressed(key) endPitfalls
常见陷阱
- Speed varies with FPS → you forgot . Every per-frame change to position, timers, or animation must be scaled by
* dt.dt - placed in
love.conf→ it silently does nothing. It must live inmain.lua, which LÖVE runs before loading modules.conf.lua - Colors washed out or invisible → you used 0–255 values. In 11.x, clamps to white; use
setColor(255,0,0)orsetColor(1,0,0).love.math.colorFromBytes - Everything tinted after one → color is global and persists across draws. Reset with
setColorbefore drawing text/images you want untinted.love.graphics.setColor(1, 1, 1) - Nothing happens on key release/repeat → fires on press (and OS key-repeat); use
love.keypressed(key, scancode, isrepeat)for release, and checklove.keyreleasedif you must ignore held-key repeats.isrepeat
- 速度随FPS变化 → 你忘记乘以。每帧对位置、计时器或动画的修改都必须乘以
dt。dt - 放在
love.conf中 → 它会静默失效。必须放在main.lua中,LÖVE会在加载模块前运行该文件。conf.lua - 颜色显示暗淡或不可见 → 你使用了0–255的数值。在11.x版本中,会被钳位为白色;请使用
setColor(255,0,0)或setColor(1,0,0)。love.math.colorFromBytes - 调用一次后所有内容都被着色 → 颜色是全局状态,会在多次绘制中持续生效。在绘制不需要着色的文本/图像前,使用
setColor重置颜色。love.graphics.setColor(1, 1, 1) - 按键释放/重复时无响应 → 在按键按下(以及系统按键重复)时触发;如需处理按键释放,请使用
love.keypressed(key, scancode, isrepeat),如果需要忽略长按重复,请检查love.keyreleased参数。isrepeat
References
参考资料
- For a complete push/pop screen-state manager (menu → game → pause, with delegated
callbacks), read .
references/state-stack.md
- 如需完整的推入/弹出屏幕状态管理器(菜单→游戏→暂停,带委托回调),请阅读。
references/state-stack.md
Related skills
相关技能
- — saving/loading game state (engine-agnostic).
save-systems - — rebindable, multi-device input architecture.
input-systems - /
pygame-core— the same loop concepts in other lightweight engines.phaser-core
- — 游戏状态的保存/加载(跨引擎通用)。
save-systems - — 可重新绑定的多设备输入架构。
input-systems - /
pygame-core— 其他轻量级引擎中的同类循环概念。phaser-core