Zpět na domů

LuaJIT Scratch-analog: 12k skriptů na 30 FPS

Článek rozebírá vývoj vysoce výkonného vizuálního interpretu na LuaJIT a LÖVE2D, schopného spouštět 12289 skriptů na slabém hardwaru. Popsána modulární architektura, struktura bloků, rekurzivní interpretace a sestavení do EXE. Kód příkladů zachován pro analýzu middle/senior vývojáři.

12 tisíc skriptů Scratch na LuaJIT: rozbor kódu
Advertisement 728x90

Vysokovýkonný vizuální interpretr na LuaJIT a LÖVE2D: 12 tisíc skriptů na slabém hardwaru

Začátečník vytvořil vizuální editor programovacích bloků, který dokáže spustit 12 289 skriptů s bloky IF, ROTATE a WHILE TRUE na jednom jádru slabého notebooku při stabilních 30 FPS. Projekt je postaven na LuaJIT s knihovnou LÖVE2D, která zajišťuje multiplatformnost: Windows, macOS, Linux, Android, iOS. Interpretr je oddělen od editoru, sestavení do samostatného EXE již funguje.

Volba LuaJIT je podmíněna bajtkódem a JIT kompilací pro vysokou rychlost provádění. LÖVE2D byl použit pro jednoduchou syntaxi a autorovy zkušenosti s Roblox Studio. VS Code sloužil jako hlavní editor.

Architektura projektu

Projekt je rozdělen na moduly pro škálovatelnost:

Google AdInline article slot
  • Main.lua — hlavní editor.
  • Micropaint.lua — editor sprite.
  • GameLoader.lua — zavaděč her.
  • BlockList.lua — registr bloků (518 řádků, s funkcí vykreslování).

GUI je implementováno ručně přes love.graphics bez externích knihoven. Příklad vykreslování tlačítek:

--TLAČÍTKO: Načíst
love.graphics.rectangle("line", 230, 10, 120, 40)
love.graphics.print("Načíst", 240, 10)
--TLAČÍTKO: Vytvořit
love.graphics.rectangle("line", 360, 10, 100, 40)
love.graphics.print("Vytvořit", 370, 10)

Zpracování kliknutí s podrobnými komentáři:

--TLAČÍTKO Vytvořit
if x > 360 and x < 460 and y > 10 and y < 50 then
    createNewGame()
end
--TLAČÍTKO NAČÍST 
if x > 230 and x < 350 and y > 10 and y < 50 then
    if gload3) == "suc" then
        GameLoaded = true 
        love.window.showMessageBox( "HOTOVO!","Hra s názvem "..game.name.." byla načtena")
    else
        love.window.showMessageBox( "CHYBA","Během načítání došlo k chybě")
    end
end

Komentáře usnadňují údržbu, i když GUI knihovny by kód vyčistily.

Google AdInline article slot

Struktura bloků a vykreslování

Bloky jsou popsány v tabulkách s metadaty. Příklad bloku náhodných čísel:

t[#t+1] = {
    type = 3, --TYP BLOKU 1 - OBYČEJNÝ 2 - PROVÁDĚNÍ 3 - DATA
    isStarter = false, --JE TO BLOK ZAČÁTKU SKRIPTU???
    DisplayName = "Náhodná hodnota (od, do)", -- ZOBRAZOVANÝ NÁZEV
    name = "random", -- SYSTÉMOVÝ NÁZEV
    args = 2, -- POČET ARGUMENTŮ
    containBlocksIn = false, -- MÁ BLOKY UVNITŘ
    color = {0, 0, 0}
}

Bloky podporují vnořování: argumenty mohou být jiné bloky. Vykreslování přes RenderBlock() s pokusem o rekurzi (částečně implementováno). Bílé čtverce jsou vstupní pole.

Interpretr v jednom vlákně pro jednoduchost. Bloky se dělí na typy: obyčejné, provádění, data. Provádění argumentů rekurzivně, výsledek v args[i].data.

Google AdInline article slot

Interpretace bloků

Kód interpretru kontroluje name a vypočítá hodnotu:

if name == "getX" then --Získat X
        return sprite.pos.x
    elseif name == "getY" then --Získat Y
        return sprite.pos.y
    elseif name == "random" then --Náhodné číslo
        return love.math.random(tonumber(args[1].data),tonumber(args[2].data))
    elseif name == "getrotation" then --Rotace
        return sprite.rotation
    elseif name == "getcostume" then --Kostým
        return sprite.costumeNumber
    elseif name == "getsize" then --Velikost 
        return sprite.size
    elseif name == "mathplus" then --Plus
        return tonumber(args[1].data) + tonumber(args[2].data)
    elseif name == "mathminus" then --Mínus
        return tonumber(args[1].data) - tonumber(args[2].data)
    elseif name == "mathmultiply" then --Násobit
        return tonumber(args[1].data) * tonumber(args[2].data)
    elseif name == "mathdivide" then --Dělit
        return tonumber(args[1].data) / tonumber(args[2].data)
end

Lua pole jsou indexována od 1. LÖVE2D nepodporuje češtinu přímo — použity systémové fonty (Comic Sans a další) přes love.graphics.newFont.

Sestavení a nasazení

Sestavení do EXE:

  • Love Fusion zabalí DLL a soubory do EXE.
  • Enigma Virtual Box spojí vše do jednoho spustitelného souboru.

Podpora APK/HTML v plánech. Demonstrace: 12 300 vláken s IF/ROTATE/WHILE TRUE na 30 FPS.

Co je důležité:

  • LuaJIT + LÖVE2D zajišťují 12k+ skriptů na slabém CPU.
  • Modulární architektura: interpretr oddělen od editoru.
  • Ruční GUI přes love.graphics, vnořené bloky s rekurzivním prováděním.
  • Multiplatformní sestavení do EXE/APK/HTML.
  • Bloky typizovány (data/provádění), argumenty vypočítány rekurzivně.

— Editorial Team

Advertisement 728x90

Číst dál