一键导入
dragonruby
2D game development — game loops, sprites, input, collisions, scenes, DRGTK, args.outputs/state/inputs.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
2D game development — game loops, sprites, input, collisions, scenes, DRGTK, args.outputs/state/inputs.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Associations, validations, queries, migrations, eager loading, N+1 queries, scopes, callbacks, app/models/, db/migrate/.
Decorator patterns for Rails views — presentation logic separated from models, *_decorator.rb, app/decorators/.
Ruby MCP server development — tools, prompts, resources, transport, the mcp gem, LLM tool integrations.
Terminal UI development — widgets, layouts, events, Tea MVU, terminal rendering.
Testing with FactoryBot — matchers, test doubles, shared examples, describe/it/expect blocks, *_spec.rb files, test strategy.
| name | dragonruby |
| description | 2D game development — game loops, sprites, input, collisions, scenes, DRGTK, args.outputs/state/inputs. |
This skill provides comprehensive guidance for building 2D games with DragonRuby Game Toolkit (DRGTK). Use for game loop implementation, sprite rendering, input handling, collision detection, animation, and scene management.
def boot args
args.state = {}
end
def tick args
# Called 60 times per second
args.state.player ||= { x: 640, y: 360, w: 50, h: 50, path: 'player.png' }
# Handle input
args.state.player.x += 5 if args.inputs.right
args.state.player.x -= 5 if args.inputs.left
# Render
args.outputs.sprites << args.state.player
end
| Concept | Purpose |
|---|---|
def tick(args) | Main game loop (60 FPS) |
args.outputs | Render sprites, labels, primitives |
args.state | Persistent game data storage |
args.inputs | Keyboard, mouse, controller input |
args.grid | Screen dimensions (1280x720) |
Geometry | Collision detection helpers |
(0, 720) ─────────────── (1280, 720)
│ │
│ 1280 × 720 │
│ │
(0, 0) ─────────────── (1280, 0)
Use args.outputs.primitives for FIFO (first-in, first-out) render order control.
args.outputs.primitives << {
x: 100, y: 100, w: 64, h: 64,
path: 'sprites/player.png',
angle: 45,
anchor_x: 0.5, anchor_y: 0.5,
r: 255, g: 255, b: 255, a: 255,
flip_horizontally: false
}
args.outputs.primitives << {
x: 640, y: 360,
text: "Score: #{args.state.score}",
size_px: 22,
anchor_x: 0.5, anchor_y: 0.5,
r: 255, g: 255, b: 255
}
# Filled rectangle (use primitive_marker: :solid)
args.outputs.primitives << {
x: 0, y: 0, w: 100, h: 100,
r: 255, g: 0, b: 0,
primitive_marker: :solid
}
# For many rectangles, use path: :solid for better performance
args.outputs.primitives << { x: 0, y: 0, w: 100, h: 100, path: :solid, r: 255, g: 0, b: 0 }
# Outline rectangle
args.outputs.primitives << { x: 0, y: 0, w: 100, h: 100, r: 0, g: 0, b: 0, primitive_marker: :border }
Use args.state with ||= for lazy initialization:
def tick args
args.state.player ||= { x: 640, y: 360 }
args.state.enemies ||= []
args.state.score ||= 0
args.state.scene ||= :title
end
# Directional (arrows, WASD, gamepad)
args.inputs.up / down / left / right
# Magnitude values
args.inputs.left_right # -1, 0, or 1
args.inputs.up_down # -1, 0, or 1
args.inputs.keyboard.key_down.space # Pressed this frame
args.inputs.keyboard.key_held.space # Held down
args.inputs.keyboard.key_up.space # Released this frame
args.inputs.mouse.click # Any button clicked
args.inputs.mouse.x / .y # Position
args.inputs.mouse.inside_rect?(rect) # Collision check
if Geometry.intersect_rect?(player, enemy)
enemy.dead = true
args.state.score += 1
end
# Clean up dead entities
args.state.enemies.reject! { |e| e.dead }
# Frame-based animation
sprite_index = 0.frame_index(count: 6, hold_for: 8, repeat: true)
args.state.player.path = "sprites/player-#{sprite_index}.png"
def tick args
args.state.scene ||= :title
send("#{args.state.scene}_tick", args)
end
def title_tick args
args.outputs.labels << { x: 640, y: 400, text: "Press SPACE", anchor_x: 0.5 }
args.state.scene = :gameplay if args.inputs.keyboard.key_down.space
end
def gameplay_tick args
# Game logic here
end
||= for state initialization$gtk.reset during development to reset stateargs.outputs.primitives for FIFO render order controlprimitive_marker: :solid or :border for rectangle typesFPS = 60)For detailed API documentation and patterns:
references/core.md - Game loop, args object, rendering, coordinatesreferences/input.md - Keyboard, mouse, controller input patternsreferences/entities.md - Entity spawning, collision, lifecyclereferences/game-logic/state.md - Timers, scoring, scene transitionsreferences/game-logic/persistence.md - Save/load, file I/O patternsreferences/audio.md - Sound effects, music playback, audio controlsreferences/rendering/primitives.md - Sprites, labels, solids, borders, layeringreferences/rendering/animation.md - frame_index, spritesheets, easing functionsWorking code in examples/:
examples/core/ - Hello world, sprites, labels, state, coordinatesexamples/input/ - Directional, keyboard, mouse, movementexamples/entities/ - Storage, factories, collision, lifecycleexamples/game-logic/ - Timers, scoring, save/load, state transitionsexamples/audio/ - Sound effects, background music, pause/resumeexamples/rendering/ - Sprites, labels, animation, layeringdef tick args
# Game logic
end
$gtk.reset # Add at end during development
$gtk.reset # Immediate reset
$gtk.reset_next_tick # Reset before next tick (safer)
args.outputs.debug << "Frame: #{Kernel.tick_count}"
args.outputs.debug.watch args.state.player