Love2d Core

作者 gamedev-skillsd4b0e35550c5無授權條款1.3K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫11 天前更新

Structure and debug a LÖVE (Love2D) game in Lua: the love.load/update/draw loop, delta-time movement, input, and screen states. Use when building a LÖVE 11.x game (main.lua, conf.lua, .love).

AI 產生的概覽

指導以 Lua 建立與除錯 LÖVE 11.x 遊戲的核心迴圈、輸入與畫面狀態。

功能
此技能提供以 Lua 建立與除錯 LÖVE(Love2D)遊戲基礎的說明,目標版本為 LÖVE 11.5。內容涵蓋 love.load/update/draw 回呼迴圈、以 delta time 為基礎的移動、輪詢與事件式輸入、conf.lua 視窗與版本設定、0-1 顏色值,以及畫面狀態堆疊。它產出的是程式碼模式與常見陷阱說明,而非可執行的指令碼。
適用情境
適用於開始一個 LÖVE 遊戲、設定 main.lua 或 conf.lua,或修正核心迴圈、移動速度、輸入處理、畫面切換等問題。不適用於一般 Lua 語言問題、物理剛體或著色器程式碼。
執行需求
不附指令碼,僅為說明文件。假定已有 LÖVE 11.x 專案,包含 main.lua、conf.lua 或 .love 檔案,並引用一份搭配的狀態堆疊文件。

LÖVE (Love2D) Core

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.

When to use

  • Use when starting a LÖVE game, wiring up main.lua/conf.lua, or fixing the core loop, movement that runs at the wrong speed, input handling, or screen switching.
  • Use when the workspace has main.lua calling love.*, a conf.lua, or a .love file.

When not to use: Lua language questions unrelated to LÖVE; physics bodies/joints (LÖVE uses Box2D via love.physics — a separate concern); shader code (love.graphics GLSL is its own topic). For cross-engine save/load patterns, use save-systems.

Core workflow

  1. Confirm the entry points. A LÖVE game runs main.lua; it should define love.load() (one-time setup), love.update(dt) (state), and love.draw() (rendering). Window/version setup goes in conf.lua (run before modules load).
  2. Pin the version. Set t.version = "11.5" in conf.lua so LÖVE warns on mismatch.
  3. Drive all motion by dt (delta time, in seconds) so speed is frame-rate independent.
  4. Handle input two ways: polled (love.keyboard.isDown in update, for held keys) and event (love.keypressed callback, for discrete presses).
  5. Manage screens (menu, game, pause) with a small state stack rather than a pile of if flags — see Patterns and references/state-stack.md.
  6. Run and observe. Launch with love . from the project folder; verify the window, motion speed, and input on screen before assuming it works.

Patterns

1. main.lua skeleton (the callback loop + input)

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 endend
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() endend

2. Frame-rate independence (the single most common bug)

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.speed

3. conf.lua (window + version; runs before main.lua)

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/memoryend

4. Color is 0–1 in LÖVE 11.x (not 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 redlove.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. Screen states (brief — full manager in references)

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 modulefunction love.load()              Stack.push(require("screens.menu")) endfunction love.update(dt)          Stack.current():update(dt) endfunction love.draw()              Stack.current():draw() endfunction love.keypressed(key)     Stack.current():keypressed(key) end

Pitfalls

  • Speed varies with FPS → you forgot * dt. Every per-frame change to position, timers, or animation must be scaled by dt.
  • love.conf placed in main.lua → it silently does nothing. It must live in conf.lua, which LÖVE runs before loading modules.
  • Colors washed out or invisible → you used 0–255 values. In 11.x, setColor(255,0,0) clamps to white; use setColor(1,0,0) or love.math.colorFromBytes.
  • Everything tinted after one setColor → color is global and persists across draws. Reset with love.graphics.setColor(1, 1, 1) before drawing text/images you want untinted.
  • Nothing happens on key release/repeat → love.keypressed(key, scancode, isrepeat) fires on press (and OS key-repeat); use love.keyreleased for release, and check isrepeat if you must ignore held-key repeats.

References

  • For a complete push/pop screen-state manager (menu → game → pause, with delegated callbacks), read references/state-stack.md.

Related skills

  • save-systems — saving/loading game state (engine-agnostic).
  • input-systems — rebindable, multi-device input architecture.
  • pygame-core / phaser-core — the same loop concepts in other lightweight engines.

來源與署名

來源:gamedev-skills/awesome-gamedev-agent-skills位於skills/other-engines/love2d-core提交d4b0e35

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架