mcpField
L
love2d-core

love2d-core

github.com/gamedev-skills开发5.4k5.6k 次安装1 天前更新
代码仓库

关于 love2d-core

面向使用 Lua 开发或调试 LÖVE 游戏基础的技能,涵盖回调、时间缩放移动、输入和屏幕状态管理,目标版本为 LÖVE 11.5。

主要功能

  1. 01配置 main.lua 回调
  2. 02在 conf.lua 中设置窗口与版本
  3. 03使用 delta time 缩放移动
  4. 04处理轮询式与事件式输入
  5. 05通过状态栈管理屏幕
  6. 06使用 LÖVE 11.x 色彩值

适用场景

  1. 01用 main.lua 和 conf.lua 启动 LÖVE 项目
  2. 02修正受帧率影响的移动
  3. 03切换菜单、游戏与暂停屏幕

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill love2d-core

安装后在 Claude Code 中输入/love2d-core确认已加载。

附带文件references/state-stack.md

详细介绍

LÖVE(Love2D)核心

使用 Lua 搭建和调试 LÖVE 游戏的基础:回调循环、帧率无关的移动、输入和屏幕状态。适用于 LÖVE 11.5。

适用场景

  • 在启动 LÖVE 游戏、配置 main.lua/conf.lua,或修复核心循环、速度不正确的移动、输入处理或屏幕切换时使用。
  • 工作区中有调用 love.* 的 main.lua、conf.lua 或 .love 文件时使用。

**不适用场景:**与 LÖVE 无关的 Lua 语言问题;物理刚体/关节(LÖVE 通过 love.physics 使用 Box2D,这是另一项独立内容);着色器代码(love.graphics GLSL 是独立主题)。跨引擎的存档/读档模式请使用 save-systems。

核心工作流

  1. 确认入口。 LÖVE 游戏会运行 main.lua;其中应定义 love.load()(一次性设置)、love.update(dt)(状态更新)和 love.draw()(渲染)。 窗口/版本设置应放在 conf.lua 中(该文件会在模块加载之前运行)。
  2. 固定版本。 在 conf.lua 中设置 t.version = "11.5",这样 LÖVE 就会在版本不匹配时发出警告。
  3. 让所有移动都由 dt 驱动(增量时间,单位为秒),以确保移动不受帧率影响。
  4. **通过两种方式处理输入:**轮询(在 update 中使用 love.keyboard.isDown 检测按住的按键)和事件(通过 love.keypressed 回调处理单次按键)。
  5. 管理屏幕状态(菜单、游戏、暂停)时,使用简洁的状态栈,而不是堆叠一连串 if 标志——参见“模式”和 references/state-stack.md。
  6. **运行并观察。**在项目文件夹中使用 love . 启动;确认窗口、移动速度和屏幕上的输入效果正常后,再判断功能是否可用。

模式

1. main.lua 框架(回调循环 + 输入)
-- 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
end
2. 帧率无关(最常见的问题)
-- 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.speed
3. conf.lua(窗口 + 版本;在 main.lua 之前运行)
-- 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
end
4. 在 LÖVE 11.x 中,颜色取值范围为 0–1(不是 0–255)
-- 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))
5. 屏幕状态(简要说明;完整管理器见参考资料)
-- 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) end

常见问题

  • 速度随 FPS 变化 → 忘记乘以 dt。每帧对位置、计时器或动画进行的任何更改都必须按 dt 缩放。
  • 把 love.conf 放在 main.lua 中 → 这不会产生任何效果。它必须放在 conf.lua 中,因为 LÖVE 会在加载模块之前运行该文件。
  • 颜色褪色或不可见 → 使用了 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/state-stack.md。

相关技能

  • save-systems — 保存/加载游戏状态(与引擎无关)。
  • input-systems — 可重新绑定、多设备输入架构。
  • pygame-core / phaser-core — 其他轻量级引擎中的相同循环概念。

评论

支持 Markdown