Code Examples

Примеры кода

Learn by example — from Hello World to full games.

Учитесь на примерах — от Hello World до полноценных игр.

1. Hello World & Moving Text

1. Hello World и движущийся текст

BeginnerНачинающий

The simplest game: move a text label around the screen with the arrow keys. Demonstrates cls, print, btn.

Простейшая игра: перемещайте текстовую метку по экрану стрелками. Демонстрирует cls, print, btn.

lua
function _init()
  x, y = 64, 120
end

function _update()
  if btn(0) then x -= 2 end
  if btn(1) then x += 2 end
  if btn(2) then y -= 2 end
  if btn(3) then y += 2 end

  -- clamp to screen
  x = mid(0, x, 190)
  y = mid(0, y, 248)
end

function _draw()
  cls(1)
  print("HELLO PLUTO-8!", x, y, 7)
  print("USE ARROWS", 88, 240, 6)
end

2. Bouncing Ball

2. Прыгающий мяч

BeginnerНачинающий

A ball bouncing off all four walls with velocity. Demonstrates physics-style movement, boundary collision, and circfill.

Мяч, отскакивающий от всех четырёх стен со скоростью. Демонстрирует физическое движение, граничные коллизии и circfill.

lua
function _init()
  x, y   = 128, 128
  vx, vy = 2, 1.5
  r      = 6        -- ball radius
  col    = 10       -- yellow
end

function _update()
  x += vx
  y += vy

  -- bounce off left/right walls
  if x < r then
    x = r; vx = abs(vx)
    sfx(0)
  elseif x > 256-r then
    x = 256-r; vx = -abs(vx)
    sfx(0)
  end

  -- bounce off top/bottom walls
  if y < r then
    y = r; vy = abs(vy)
    sfx(0)
  elseif y > 256-r then
    y = 256-r; vy = -abs(vy)
    sfx(0)
  end

  -- change color on bounce
  col = flr(rnd(14)) + 1
end

function _draw()
  cls(0)
  -- trail effect: draw faded circles
  circ(x-vx*3, y-vy*3, r, 5)
  circ(x-vx*2, y-vy*2, r, 5)
  circfill(x, y, r, col)
end

2b. Delta Time Movement

2b. Движение с Delta Time

BeginnerНачинающий

Move an object using dt for frame-rate independent speed. Demonstrates the dt global variable and _update(dt) argument.

Перемещение объекта с использованием dt для скорости, независимой от частоты кадров. Демонстрирует глобальную переменную dt и аргумент _update(dt).

lua
local x, y = 128, 128
local speed = 120   -- pixels per second
local timer = 5     -- 5 second countdown

function _update(dt)
  -- smooth movement: speed * dt = pixels this frame
  if btn(0) then x -= speed * dt end
  if btn(1) then x += speed * dt end
  if btn(2) then y -= speed * dt end
  if btn(3) then y += speed * dt end

  -- countdown timer using dt
  timer -= dt
  if timer < 0 then timer = 5 end
end

function _draw()
  cls(1)
  circfill(x, y, 6, 10)
  print("TIME: "..flr(timer), 2, 2, 7)
  print("dt="..sub(tostr(dt),1,5), 2, 10, 6)
end

3. Parallax Starfield

3. Параллакс-звёздное поле

IntermediateСредний

60 stars split into three depth layers, each scrolling at a different speed. Demonstrates table initialisation, modular arithmetic for wrapping, and layered rendering.

60 звёзд, разделённых на три слоя глубины, каждый прокручивается с разной скоростью. Демонстрирует инициализацию таблиц, модульную арифметику для зацикливания и послойный рендеринг.

lua
function _init()
  stars = {}
  for i = 1, 60 do
    add(stars, {
      x     = rnd(256),
      y     = rnd(256),
      layer = flr(rnd(3)),   -- 0=far 1=mid 2=near
    })
  end
end

local speeds = {0.2, 0.6, 1.5}   -- pixels/frame per layer
local colors = {5,   6,   7  }   -- dark→light
local sizes  = {0,   0,   1  }   -- radius (0=pixel, 1=small circ)

function _update()
  for s in all(stars) do
    s.y += speeds[s.layer + 1]
    if s.y > 256 then
      s.y = 0
      s.x = rnd(256)
    end
  end
end

function _draw()
  cls(0)
  for s in all(stars) do
    local l = s.layer + 1
    if sizes[l] == 0 then
      pset(flr(s.x), flr(s.y), colors[l])
    else
      circfill(flr(s.x), flr(s.y), sizes[l], colors[l])
    end
  end
  print("PLUTO-8", 96, 120, 7)
  print("PARALLAX DEMO", 72, 132, 6)
end

4. Snake Game

4. Игра «Змейка»

IntermediateСредний

Classic Snake with growing tail, food spawning, wall and self-collision. Shows a state machine (title / playing / game-over), grid-based movement and table manipulation.

Классическая змейка с растущим хвостом, появлением еды, столкновением со стенами и собой. Демонстрирует конечный автомат (заголовок / игра / конец), сеточное движение и работу с таблицами.

lua
local GRID = 8       -- tile size in pixels
local W, H = 32, 32  -- grid dimensions

function _init()
  state = "title"
end

function start_game()
  snake  = {{x=16, y=16}}
  dir    = {x=1, y=0}
  next_d = {x=1, y=0}
  score  = 0
  timer  = 0
  spawn_food()
  state  = "play"
end

function spawn_food()
  food = {x=flr(rnd(W)), y=flr(rnd(H))}
end

function _update()
  if state == "title" then
    if btnp(4) then start_game() end
    return
  end
  if state == "over" then
    if btnp(4) then state = "title" end
    return
  end

  -- read input (don't allow 180° reverse)
  if btn(0) and dir.x ~= 1  then next_d={x=-1,y=0} end
  if btn(1) and dir.x ~= -1 then next_d={x=1,y=0}  end
  if btn(2) and dir.y ~= 1  then next_d={x=0,y=-1} end
  if btn(3) and dir.y ~= -1 then next_d={x=0,y=1}  end

  timer += 1
  if timer < 6 then return end  -- move every 6 ticks (5 moves/sec)
  timer = 0
  dir = next_d

  -- new head position
  local head = snake[1]
  local nx = (head.x + dir.x) % W
  local ny = (head.y + dir.y) % H

  -- check self-collision
  for s in all(snake) do
    if s.x == nx and s.y == ny then
      sfx(1); state = "over"; return
    end
  end

  -- grow or trim tail
  local ate = (nx == food.x and ny == food.y)
  table.insert(snake, 1, {x=nx, y=ny})
  if ate then
    score += 10; sfx(0); spawn_food()
  else
    table.remove(snake)
  end
end

function _draw()
  cls(0)
  if state == "title" then
    print("SNAKE",      104, 110, 11)
    print("PRESS Z",    96,  130, 7)
    return
  end

  -- food
  rectfill(food.x*GRID, food.y*GRID, GRID, GRID, 8)

  -- snake body
  for i, s in ipairs(snake) do
    local c = (i == 1) and 11 or 3
    rectfill(s.x*GRID+1, s.y*GRID+1, GRID-2, GRID-2, c)
  end

  -- HUD
  print("SCORE:"..score, 2, 2, 7)

  if state == "over" then
    rectfill(70, 108, 116, 40, 0)
    rect(    70, 108, 116, 40, 8)
    print("GAME OVER", 88,  118, 8)
    print("PRESS Z",  96,  132, 7)
  end
end

5. Sprite Animation & Flip

5. Анимация спрайтов и отражение

BeginnerНачинающий

Walk-cycle animation using sprite frames, with horizontal flipping for left/right direction. Shows how to combine movement, timers and spr() flags.

Анимация цикла ходьбы через кадры спрайтов с горизонтальным отражением для направления влево/вправо. Показывает, как объединить движение, таймеры и флаги spr().

lua
-- Assumes sprites 1-4 are a 4-frame walk cycle
local WALK_FRAMES = {1, 2, 3, 4}
local ANIM_SPEED  = 6     -- ticks per frame

function _init()
  px, py     = 120, 120
  facing     = 1          -- 1=right, -1=left
  anim_t     = 0
  anim_frame = 1
  moving     = false
end

function _update()
  moving = false

  if btn(0) then
    px -= 2; facing = -1; moving = true
  end
  if btn(1) then
    px += 2; facing =  1; moving = true
  end
  if btn(2) then py -= 2; moving = true end
  if btn(3) then py += 2; moving = true end

  -- advance animation only when moving
  if moving then
    anim_t += 1
    if anim_t >= ANIM_SPEED then
      anim_t = 0
      anim_frame = (anim_frame % #WALK_FRAMES) + 1
    end
  else
    anim_frame = 1   -- idle = frame 1
    anim_t = 0
  end
end

function _draw()
  cls(3)
  -- ground
  rectfill(0, 200, 256, 56, 4)

  local sprite_n = WALK_FRAMES[anim_frame]
  local flip_x   = (facing == -1)   -- flip left

  spr(sprite_n, px, py, 1, 1, flip_x)

  print("MOVE: ARROWS", 74, 8, 7)
end

6. Code Modules

6. Модули кода

BeginnerНачинающий

Split your code into modules. Helper module defines utility functions, Main module uses them. Demonstrates the module system.

Разделите код на модули. Вспомогательный модуль определяет утилиты, модуль Main их использует. Демонстрирует систему модулей.

lua
-- Module "Helper":
function lerp(a, b, t)
  return a + (b - a) * t
end

function clamp(v, lo, hi)
  return max(lo, min(hi, v))
end

-- Module "Main":
function _init()
  x = 128
end

function _update()
  x = lerp(x, mx(), 0.2)
end

function _draw()
  cls(0)
  circfill(clamp(x, 10, 246), 128, 10, 10)
end

7. Sound Effects

7. Звуковые эффекты

BeginnerНачинающий

Play different SFX presets on button presses. Demonstrates sfx() with all 8 built-in sounds.

Воспроизведение разных пресетов SFX по нажатию кнопок. Демонстрирует sfx() со всеми 8 встроенными звуками.

lua
local names = {
  "HIT", "BUMP", "STEP", "BEEP",
  "COIN", "JUMP", "BOOM", "WIN"
}
local sel = 0

function _update()
  if btnp(3) then sel = (sel + 1) % 8 end
  if btnp(2) then sel = (sel - 1) % 8 end
  if btnp(4) then sfx(sel) end
end

function _draw()
  cls(1)
  print("SFX TESTER", 80, 20, 7)
  for i = 0, 7 do
    local c = (i == sel) and 10 or 6
    print(i..": "..names[i+1], 80, 50+i*14, c)
  end
  print("UP/DOWN=SEL  Z=PLAY", 40, 200, 5)
end

8. Leaderboard Game

8. Игра с лидербордом

IntermediateСредний

Full template with title screen, gameplay, score saving and leaderboard display. Demonstrates save_score, load_score, get_leaderboard.

Полный шаблон с титульным экраном, геймплеем, сохранением результатов и отображением лидерборда. Демонстрирует save_score, load_score, get_leaderboard.

lua
function _init()
  score = 0
  best  = load_score()
  state = "title"
  top   = {}
end

function _update()
  if state == "title" then
    if mbtnp(0) then
      sfx(3)
      state = "play"
    end
  elseif state == "play" then
    score += 1
    if score > 100 then
      save_score(score)
      top = get_leaderboard(5)
      state = "over"
    end
  elseif state == "over" then
    if mbtnp(0) then
      score = 0
      state = "title"
    end
  end
end

function _draw()
  cls(1)
  if state == "title" then
    print("TAP TO PLAY", 78, 120, 7)
    print("BEST: "..tostr(best), 90, 134, 10)
  elseif state == "play" then
    print("SCORE: "..tostr(score), 4, 4, 7)
  elseif state == "over" then
    print("GAME OVER", 90, 40, 8)
    print("YOUR SCORE: "..tostr(score), 70, 60, 7)
    print("TOP PLAYERS:", 70, 85, 10)
    for i, e in pairs(top) do
      print(i..". "..e.name.."  "..tostr(e.score), 55, 95+i*12, 6)
    end
    print("TAP TO RETRY", 78, 170, 11)
  end
end

9. PlutoFL Libraries — Space Dodge

9. Библиотеки PlutoFL — Space Dodge

IntermediateСредний

A complete game using PlutoFL libraries: scene for state management, gameobject for entities, timer for enemy spawning, and geom for distance checks. Shows how libraries reduce boilerplate.

Полная игра на библиотеках PlutoFL: scene для управления состояниями, gameobject для сущностей, timer для спавна врагов и geom для проверки расстояний. Показывает, как библиотеки сокращают шаблонный код.

lua
local scene = require("scene")
local go = require("gameobject")
local timer = require("timer")
local geom = require("geom")

scene.reg("game", {
  enter = function()
    go.clear()
    score = 0
    go.new({x=128,y=200,tag="player",
      update=function(s)
        if btn(0) then s.x=s.x-3 end
        if btn(1) then s.x=s.x+3 end
        s.x = mid(4, s.x, 252)
      end,
      draw=function(s)
        rectfill(s.x-4,s.y-4,8,8,11)
      end
    })
    timer.every(0.8, function()
      go.new({x=rnd(248),y=0,tag="enemy",
        update=function(s)
          s.y=s.y+1.5
          if s.y>260 then
            s.alive=false
            score=score+1
          end
        end,
        draw=function(s)
          circfill(s.x,s.y,4,8)
        end
      })
    end)
  end,
  update=function()
    go.update(); timer.update()
    local p=go.all("player")[1]
    if not p then return end
    for _,e in pairs(go.all("enemy")) do
      if geom.dist(p.x,p.y,e.x,e.y)<10 then
        scene.go("over")
      end
    end
  end,
  draw=function()
    cls(0); go.draw()
    print("SCORE:"..score,2,2,7)
  end
})

scene.reg("over", {
  enter=function()
    go.clear(); timer.clear()
    save_score(score)
  end,
  update=function()
    if btnp(4) then scene.go("game") end
  end,
  draw=function()
    cls(0)
    print("GAME OVER",90,100,8)
    print("SCORE: "..score,90,115,7)
    print("PRESS Z",96,140,6)
  end
})

function _init() scene.go("game") end
function _update() scene.update() end
function _draw() scene.draw() end

10. Physics — Bouncing Balls

10. Физика — прыгающие мячи

IntermediateСредний

A physics demo using the physics library: circles with gravity, bouncing off walls and each other. Tap/click to create an explosion. Demonstrates physics.world, physics.circle, physics.step, physics.blast.

Демо физического движка с библиотекой physics: круги с гравитацией, отскакивающие от стен и друг от друга. Нажмите/кликните, чтобы создать взрыв. Демонстрирует physics.world, physics.circle, physics.step, physics.blast.

lua
local phys = require("physics")
local w = phys.world(0, 0.3)

function _init()
  -- walls
  phys.body(w, "static", 0, 240, 256, 16)
  phys.body(w, "static", -8, 0, 8, 256)
  phys.body(w, "static", 256, 0, 8, 256)
  -- balls
  for i = 1, 15 do
    local b = phys.circle(w, "dynamic",
      32 + rnd(192), rnd(100),
      3 + rnd(5))
    b.bounce = 0.5 + rnd(0.4)
    b.tag = flr(rnd(14)) + 1
  end
end

function _update()
  phys.step(w)
  if mbtnp(0) then
    phys.blast(w, mx(), my(), 50, 6)
  end
end

function _draw()
  cls(0)
  for _,b in ipairs(w.bodies) do
    if b.shape == "c" then
      circfill(b.x, b.y, b.r, b.tag or 10)
    else
      rectfill(b.x, b.y, b.w, b.h, 5)
    end
  end
  print("TAP TO EXPLODE", 60, 2, 7)
  print("BODIES: "..#w.bodies, 60, 12, 6)
end