From 1c02ba5468dd76fc94a26249e865b8cb95957322 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Mon, 24 Nov 2025 13:35:34 +0700 Subject: [PATCH] little love2d example --- .luarc.json | 3 + .vscode/launch.json | 11 +++ README.md | 2 +- develop/all.lua | 2 - develop/samples/systems.lua | 129 --------------------------- example/conf.lua | 10 +++ example/main.lua | 173 ++++++++++++++++++++++++++++++++++++ 7 files changed, 198 insertions(+), 132 deletions(-) delete mode 100644 develop/samples/systems.lua create mode 100644 example/conf.lua create mode 100644 example/main.lua diff --git a/.luarc.json b/.luarc.json index 377a4bf..f21c07a 100644 --- a/.luarc.json +++ b/.luarc.json @@ -28,6 +28,9 @@ "ignoreDir": [ ".vscode", "develop/3rdparty" + ], + "library": [ + "${3rd}/love2d/library" ] } } diff --git a/.vscode/launch.json b/.vscode/launch.json index b3ef320..63e9400 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -27,6 +27,17 @@ "lua": "luajit", "file": "${workspaceFolder}/develop/all.lua" } + }, + { + "name": "Launch Evolved Example (LÖVE)", + "type": "lua-local", + "request": "launch", + "program": { + "command": "love" + }, + "args": [ + "${workspaceFolder}/example" + ] } ] } diff --git a/README.md b/README.md index 203bd31..a2644ff 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ luarocks install evolved.lua ## Quick Start -To get started with `evolved.lua`, read the [Overview](#overview) section to understand the basic concepts and how to use the library. After that, check the [Samples](develop/samples), which demonstrate complex usage of the library. Finally, refer to the [Cheat Sheet](#cheat-sheet) for a quick reference of all the functions and classes provided by the library. +To get started with `evolved.lua`, read the [Overview](#overview) section to understand the basic concepts and how to use the library. After that, check the [Example](example), which demonstrate complex usage of the library. Finally, refer to the [Cheat Sheet](#cheat-sheet) for a quick reference of all the functions and classes provided by the library. ## Overview diff --git a/develop/all.lua b/develop/all.lua index aaa6343..2c2ff16 100644 --- a/develop/all.lua +++ b/develop/all.lua @@ -1,5 +1,3 @@ -require 'develop.samples.systems' - require 'develop.testing.build_tests' require 'develop.testing.cancel_tests' require 'develop.testing.clone_tests' diff --git a/develop/samples/systems.lua b/develop/samples/systems.lua deleted file mode 100644 index a2cc625..0000000 --- a/develop/samples/systems.lua +++ /dev/null @@ -1,129 +0,0 @@ ----@diagnostic disable: unused-local - -local evo = require 'evolved' - -evo.debug_mode(true) - ----@class evolved.vector2 ----@field x number ----@field y number - ----@param x number ----@param y number ----@return evolved.vector2 ----@nodiscard -local function vector2(x, y) - ---@type evolved.vector2 - return { x = x, y = y } -end - -local consts = { - delta_time = 0.016, - physics_gravity = vector2(0, 9.81), -} - -local groups = { - awake = evo.spawn(), - physics = evo.spawn(), - graphics = evo.spawn(), - shutdown = evo.spawn(), -} - -local fragments = { - force = evo.spawn(), - position = evo.spawn(), - velocity = evo.spawn(), -} - -local queries = { - physics_bodies = evo.builder() - :include(fragments.force, fragments.position, fragments.velocity) - :spawn(), -} - -local awake_system = evo.builder() - :group(groups.awake) - :prologue(function() - print '-= | Awake | =-' - evo.builder() - :set(fragments.force, vector2(0, 0)) - :set(fragments.position, vector2(0, 0)) - :set(fragments.velocity, vector2(0, 0)) - :spawn() - end):spawn() - -local integrate_forces_system = evo.builder() - :group(groups.physics) - :query(queries.physics_bodies) - :execute(function(chunk, entities, entity_count) - local delta_time, physics_gravity = - consts.delta_time, consts.physics_gravity - - ---@type evolved.vector2[], evolved.vector2[] - local forces, velocities = chunk:components( - fragments.force, fragments.velocity) - - for i = 1, entity_count do - local force, velocity = forces[i], velocities[i] - - velocity.x = velocity.x + (physics_gravity.x + force.x) * delta_time - velocity.y = velocity.y + (physics_gravity.y + force.y) * delta_time - end - end):spawn() - -local integrate_velocities_system = evo.builder() - :group(groups.physics) - :query(queries.physics_bodies) - :execute(function(chunk, entities, entity_count) - local delta_time = - consts.delta_time - - ---@type evolved.vector2[], evolved.vector2[], evolved.vector2[] - local forces, positions, velocities = chunk:components( - fragments.force, fragments.position, fragments.velocity) - - for i = 1, entity_count do - local force, position, velocity = forces[i], positions[i], velocities[i] - - position.x = position.x + velocity.x * delta_time - position.y = position.y + velocity.y * delta_time - - force.x = 0 - force.y = 0 - end - end):spawn() - -local graphics_system = evo.builder() - :group(groups.graphics) - :query(queries.physics_bodies) - :execute(function(chunk, entities, entity_count) - ---@type evolved.vector2[] - local positions = chunk:components( - fragments.position) - - for i = 1, entity_count do - local entity, position = entities[i], positions[i] - - print(string.format( - '|-> {entity %d} at {%.4f, %.4f}', - entity, position.x, position.y)) - end - end):spawn() - -local shutdown_system = evo.builder() - :group(groups.shutdown) - :epilogue(function() - print '-= | Shutdown | =-' - evo.batch_destroy(queries.physics_bodies) - end):spawn() - -do - evo.process(groups.awake) - - for _ = 1, 10 do - evo.process(groups.physics) - evo.process(groups.graphics) - end - - evo.process(groups.shutdown) -end diff --git a/example/conf.lua b/example/conf.lua new file mode 100644 index 0000000..6f8aeda --- /dev/null +++ b/example/conf.lua @@ -0,0 +1,10 @@ +if os.getenv('LOCAL_LUA_DEBUGGER_VSCODE') == '1' then + require('lldebugger').start() +end + +---@type love.conf +function love.conf(t) + t.window.title = 'Evolved Example' + t.window.width = 640 + t.window.height = 480 +end diff --git a/example/main.lua b/example/main.lua new file mode 100644 index 0000000..c5ed76b --- /dev/null +++ b/example/main.lua @@ -0,0 +1,173 @@ +local evolved = require 'evolved' + +local STAGES = { + ON_SETUP = evolved.builder() + :name('STAGES.ON_SETUP') + :build(), + ON_UPDATE = evolved.builder() + :name('STAGES.ON_UPDATE') + :build(), + ON_RENDER = evolved.builder() + :name('STAGES.ON_RENDER') + :build(), +} + +local UNIFORMS = { + DELTA_TIME = 1.0 / 60.0, +} + +local FRAGMENTS = { + POSITION_X = evolved.builder() + :name('FRAGMENTS.POSITION_X') + :default(0) + :build(), + POSITION_Y = evolved.builder() + :name('FRAGMENTS.POSITION_Y') + :default(0) + :build(), + VELOCITY_X = evolved.builder() + :name('FRAGMENTS.VELOCITY_X') + :default(0) + :build(), + VELOCITY_Y = evolved.builder() + :name('FRAGMENTS.VELOCITY_Y') + :default(0) + :build(), +} + +local PREFABS = { + CIRCLE = evolved.builder() + :name('PREFABS.CIRCLE') + :prefab() + :set(FRAGMENTS.POSITION_X) + :set(FRAGMENTS.POSITION_Y) + :set(FRAGMENTS.VELOCITY_X) + :set(FRAGMENTS.VELOCITY_Y) + :build(), +} + +--- +--- +--- +--- +--- + +evolved.builder() + :name('SYSTEMS.STARTUP') + :group(STAGES.ON_SETUP) + :prologue(function() + local screen_width, screen_height = love.graphics.getDimensions() + + local circle_list, circle_count = evolved.multi_clone(100, PREFABS.CIRCLE) + + for i = 1, circle_count do + local circle = circle_list[i] + + local px = math.random() * screen_width + local py = math.random() * screen_height + + local vx = math.random(-100, 100) + local vy = math.random(-100, 100) + + evolved.set(circle, FRAGMENTS.POSITION_X, px) + evolved.set(circle, FRAGMENTS.POSITION_Y, py) + + evolved.set(circle, FRAGMENTS.VELOCITY_X, vx) + evolved.set(circle, FRAGMENTS.VELOCITY_Y, vy) + end + end):build() + +evolved.builder() + :name('SYSTEMS.MOVEMENT') + :group(STAGES.ON_UPDATE) + :include(FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y) + :include(FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y) + :execute(function(chunk, _, entity_count) + local delta_time = UNIFORMS.DELTA_TIME + local screen_width, screen_height = love.graphics.getDimensions() + + ---@type number[], number[] + local position_xs, position_ys = chunk:components( + FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y) + + ---@type number[], number[] + local velocity_xs, velocity_ys = chunk:components( + FRAGMENTS.VELOCITY_X, FRAGMENTS.VELOCITY_Y) + + for i = 1, entity_count do + local px, py = position_xs[i], position_ys[i] + local vx, vy = velocity_xs[i], velocity_ys[i] + + px = px + vx * delta_time + py = py + vy * delta_time + + if px < 0 and vx < 0 then + vx = -vx + elseif px > screen_width and vx > 0 then + vx = -vx + end + + if py < 0 and vy < 0 then + vy = -vy + elseif py > screen_height and vy > 0 then + vy = -vy + end + + position_xs[i], position_ys[i] = px, py + velocity_xs[i], velocity_ys[i] = vx, vy + end + end):build() + +evolved.builder() + :name('SYSTEMS.RENDERING') + :group(STAGES.ON_RENDER) + :include(FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y) + :execute(function(chunk, _, entity_count) + ---@type number[], number[] + local position_xs, position_ys = chunk:components( + FRAGMENTS.POSITION_X, FRAGMENTS.POSITION_Y) + + for i = 1, entity_count do + local x, y = position_xs[i], position_ys[i] + love.graphics.circle('fill', x, y, 10) + end + end):build() + +evolved.builder() + :name('SYSTEMS.DEBUGGING') + :group(STAGES.ON_RENDER) + :epilogue(function() + local fps = love.timer.getFPS() + local mem = collectgarbage('count') + love.graphics.print(string.format('FPS: %d', fps), 10, 10) + love.graphics.print(string.format('MEM: %d KB', mem), 10, 30) + end):build() + +--- +--- +--- +--- +--- + +---@type love.load +function love.load() + evolved.process(STAGES.ON_SETUP) +end + +---@type love.update +function love.update(dt) + UNIFORMS.DELTA_TIME = dt + evolved.process(STAGES.ON_UPDATE) +end + +---@type love.draw +function love.draw() + evolved.process(STAGES.ON_RENDER) +end + +---@type love.keypressed +function love.keypressed(key) + if key == 'escape' then + love.event.quit() + end +end