Compare commits

..

12 Commits

Author SHA1 Message Date
9ad6c8bdfa Merge branch 'feature/audioengine' 2026-01-18 17:56:06 +03:00
99b176342f fix effects in audio:play 2026-01-18 14:03:03 +03:00
dee4ed9719 added effects to audio:play 2026-01-18 14:01:20 +03:00
70ec74ebe3 added filters to audio:play 2026-01-18 13:53:59 +03:00
ae03ee3adb add looping to music 2026-01-18 13:32:45 +03:00
2c8b65e1ae im undone, CROSSFADE DONE 2026-01-18 01:24:24 +03:00
f900e89a82 I HAVE AN ANIMATIONNODE
I HAVE AN UPDATE
OHHHHHHHHHHHHHHHHHH
animationNode:update(dt)

I HAVE A TREE
I HAVE AND AUDIO
OHHHHHHHHHHHHHHHHHHHHH
Tree.audio

I HAVE AN animationNode:update(dt)
I HAVE A Tree.audio
OHHHHHHHHHGKHGKGHKGgghkgh
Tree.audio.animationNode:update(dt)

TUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDUTUTUDUDU
2026-01-17 17:24:04 +03:00
4ee7b62ae4 trying to update to main branch, and SWEAR TO GOD THIS SOMETHING BREAK 2026-01-17 10:57:38 +03:00
ac03a014f6 suck my ass stupid animations, im done 2026-01-17 10:49:53 +03:00
d36b67855a stream type microfix 2026-01-16 16:09:49 +03:00
4883cc0e0c rewrite all COMPLETELY because im suck at this shit fr 🥀🥀🥀 2026-01-16 14:28:56 +03:00
28b0384285 init audio and hurt sound 2025-11-11 16:26:20 +03:00
16 changed files with 177 additions and 1 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

91
lib/audio.lua Normal file
View File

@ -0,0 +1,91 @@
local ease = require "lib.utils.easing"
local AnimationNode = require "lib.animation_node"
--- @alias SourceFilter { type: "bandpass"|"highpass"|"lowpass", volume: number, highgain: number, lowgain: number }
--- @class Audio
--- @field musicVolume number
--- @field soundVolume number
--- @field looped boolean
--- @field animationNode AnimationNode?
--- @field from love.Source?
--- @field to love.Source?
audio = {}
audio.__index = audio
--- здесь мы должны выгружать значения из файлика с сохранением настроек
local function new(musicVolume, soundVolume)
return setmetatable({
musicVolume = musicVolume,
soundVolume = soundVolume,
looped = true
}, audio)
end
function audio:update(dt)
if self.animationNode and self.animationNode.state == "running" then
self.animationNode:update(dt)
self.from:setVolume(self.musicVolume - self.animationNode:getValue() * self.musicVolume)
self.to:setVolume(self.animationNode:getValue() * self.musicVolume)
-- print(self.animationNode.t)
elseif self.animationNode and self.animationNode.state == "finished" then
self.from:stop()
self.animationNode:finish()
self.animationNode = nil
end
end
--- if from is nil, than we have fade in to;
--- if to is nil, than we have fade out from
---
--- also we should guarantee, that from and to have the same volume
--- @param from love.Source
--- @param to love.Source
--- @param ms number? in milliseconds
function audio:crossfade(from, to, ms)
print("[Audio]: Triggered crossfade")
self:play(to)
to:setVolume(0)
self.from = from
self.to = to
self.animationNode = AnimationNode {
function(node) end,
onEnd = function()
self.from:setVolume(0)
self.to:setVolume(self.musicVolume)
print("[Audio]: Crossfade done")
end,
duration = ms or 1000,
easing = ease.easeOutCubic,
}
self.animationNode:run()
end
--- @param source love.Source
--- @param settings SourceFilter?
--- @param effectName string?
function audio:play(source, settings, effectName)
if settings then
source:setFilter(settings)
end
if effectName then
source:setEffect(effectName, true)
end
if source:getType() == "stream" then
source:setLooping(self.looped)
source:setVolume(self.musicVolume)
return source:play()
end
source:setVolume(self.soundVolume)
return source:play()
end
function audio:setMusicVolume(volume)
self.musicVolume = volume
end
function audio:setSoundVolume(volume)
self.soundVolume = volume
end
return { new = new }

View File

@ -19,6 +19,9 @@ level.__index = level
local function new(type, template)
local size = Vec3 { 30, 30 } -- magic numbers for testing purposes only
print(type, template, size)
Tree.audio:play(Tree.assets.files.audio.music.level1.battle)
return setmetatable({
size = size,
characters = {},

52
lib/music.lua Normal file
View File

@ -0,0 +1,52 @@
-- --- @class Music
-- --- @field source table<string, love.Source> audio streams, that supports multitrack (kind of)
-- --- @field offset number
-- music = {}
-- music.__index = music
-- --- @param path string accepts path to dir with some music files (example: "main_ambient"; "player/theme1" and etc etc)
-- local function new(path)
-- local dir = Tree.assets.files.audio.music[path]
-- --- @type table<string, love.Source>
-- local source = {}
-- print(dir)
-- for _, v in pairs(dir) do
-- print(v.filename)
-- source[v.filename] = v.source
-- print(v.filename)
-- end
-- print('[music]: new source: ', table.concat(source, ' '))
-- return setmetatable({ source = source, offset = 0 }, music)
-- end
-- function music:update()
-- for _, v in ipairs(self.source) do
-- v:seek()
-- end
-- end
-- --- pause stemfile or music at all
-- --- @param filename? string
-- function music:pause(filename)
-- if filename then
-- self.source[filename]:pause()
-- else
-- for _, v in pairs(self.source) do
-- v:pause()
-- end
-- end
-- end
-- --- play music stemfile by his name
-- --- @param filename string
-- --- @return boolean
-- function music:play(filename)
-- print('[music]: ', table.concat(self.source, ' '))
-- self.source[filename]:seek(self.offset, "seconds")
-- return self.source[filename]:play()
-- end
-- return { new = new }

9
lib/sound.lua Normal file
View File

@ -0,0 +1,9 @@
-- --- @class Sound
-- --- @field source love.Source just a sound
-- sound = {}
-- local function new()
-- return setmetatable({}, sound)
-- end
-- return { new }

View File

@ -52,7 +52,9 @@ function walk:cast(caster, target)
local sprite = caster:has(Tree.behaviors.sprite)
if not sprite then return true end
AnimationNode {
function(node) caster:has(Tree.behaviors.tiled):followPath(path, node) end,
function(node)
caster:has(Tree.behaviors.tiled):followPath(path, node)
end,
onEnd = function() caster:has(Tree.behaviors.spellcaster):endCast() end,
}:run()
@ -100,7 +102,10 @@ function regenerateMana:cast(caster, target)
}
AnimationNode {
function(node)
local audioPath = Tree.assets.files.audio
sprite:animate("hurt", node)
Tree.audio:crossfade(audioPath.music.level1.battle,
audioPath.music.level1.choral, 5000)
end,
onEnd = function() caster:has(Tree.behaviors.spellcaster):endCast() end
}:run()
@ -163,7 +168,16 @@ function attack:cast(caster, target)
children = {
AnimationNode {
function(node)
local audioPath = Tree.assets.files.audio
targetSprite:animate("hurt", node)
--- @type SourceFilter
local settings = {
type = "bandpass",
volume = 1,
highgain = 0.1,
lowgain = 0.1
}
Tree.audio:play(audioPath.sounds.hurt, settings)
end
}
}

View File

@ -9,9 +9,11 @@ Tree = {
Tree.fonts = (require "lib.utils.font_manager"):load("WDXL_Lubrifont_TC"):loadTheme("Roboto_Mono") -- дефолтный шрифт
Tree.panning = require "lib/panning"
Tree.controls = require "lib.controls"
Tree.audio = (require "lib.audio").new(1, 1)
Tree.level = (require "lib.level.level").new("procedural", "flower_plains") -- для теста у нас только один уровень, который сразу же загружен
Tree.behaviors = (require "lib.utils.behavior_loader")("lib/character/behaviors") --- @todo написать нормальную загрузку поведений
-- Tree.audio = (require "lib.audio").new(1, 1)
-- Tree.behaviors.map = require "lib.character.behaviors.map"
-- Tree.behaviors.spellcaster = require "lib.character.behaviors.spellcaster"
-- Tree.behaviors.sprite = require "lib.character.behaviors.sprite"

View File

@ -50,6 +50,10 @@ function AssetBundle.loadFile(path)
return love.graphics.newShader(path);
elseif (ext == "lua") then
return require(string.gsub(path, ".lua", ""))
elseif (ext == "ogg") and string.find(path, "sounds") then
return love.audio.newSource(path, 'static')
elseif (ext == "ogg") and string.find(path, "music") then
return love.audio.newSource(path, 'stream')
end
return filedata
end

View File

@ -52,6 +52,7 @@ function love.update(dt)
testLayout:update(dt) -- потом UI, потому что нужно перехватить жесты и не пустить их дальше
Tree.panning:update(dt)
Tree.level:update(dt)
Tree.audio:update(dt)
Tree.controls:cache()