heroes-of-nerevelon/character.lua
Neckrat 3f15874f8c drawing character
Co-authored-by: Ivan Yuriev <ivanyr44@gmail.com>
2025-08-03 02:23:30 +03:00

129 lines
4.6 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local anim8 = require "lib/anim8"
require 'lib/vec3'
local AssetBundle = require "lib/asset_bundle"
local CHARACTER_SIZE = 64
--- Для anim8, представляет из себя с какого по какого представлены спрайты для анимации
local ANIMATION_SIZE = '1-6'
--- Скорость между кадрами в анимации
local ANIMATION_SPEED = 0.1
-- Константы ниже представляют из себя номер строки (с единицы), в которой находится та или иная анимация
local IDLE_ROW = 1
local RUN_ROW = 2
local ATTACK_ROW = 3
--- @class Character
local Character = {}
Character.name = ""
---------- Animations -----
--- мы должны определиться со спрайтшитами и подобным, всё что здесь написано лишь пример
---
--- предполагается, что у всех будет одинаковое кол-во кадров в анимации и их скорость произведения
Character.animationTable = {
idle = {},
run = {},
attack = {}
-- etc etc
}
--- чтобы не обновлять все анимации одновременно, храним нужную анимацию здесь
--- меняем вместе с Character.animation
Character.state = "idle"
--- когда нужно сменить анимацию с idle на run например, меняем именно это поле
Character.spriteSheet = {
animationSpeed = 0.1,
width = 96,
height = 64,
idle = '1-6',
run = '1-8',
attack = '1-11',
hurt = '1-6'
}
---------- Statistics -----
Character.stats = {}
--- TODO: придумать формулу расчёта статов относительно уровня
Character.stats.level = 1
Character.stats.initiative = 10
Character.stats.damage = 5
Character.stats.defence = 0
Character.stats.hp = 30
Character.player = {}
--- TODO: мнимая надежда на спеллмейкинг
---
--- правда я абсолютно хз, как он будет смотреться
--- в контексте рогалика, но посмотрим
---
--- мб это будет метаспеллмейкинг на овощах
Character.skills = {}
Character.class = ""
Character.position = Vec3({})
--- Обёртка над Character:Create
-- CreateCharacter = Character.create
--- Создаёт персонажа, которым будет управлять или игрок или компьютер
--- @param name string
--- @param spriteDir table
--- @param level? integer
function CreateCharacter(name, spriteDir, level) -- aka Character.create(self, name, imagePath, level)
-- TODO: добавить asset_loader, где все необходимые ассеты будут грузиться в одном месте,
-- а здесь мы добавляем ассет на загрузку в очередь
-- local image = love.graphics.newImage(imagePath)
local animationGrid = {}
-- n: name; i: image
for n, i in pairs(spriteDir) do
local aGrid = anim8.newGrid(96, 64, i:getWidth(), i:getHeight())
local tiles = '1-' .. math.ceil(i:getWidth() / 96)
animationGrid[n] = aGrid(tiles, 1)
end
--local animationGrid = anim8.newGrid(96, 64, image:getWidth(), image:getHeight())
local char = {
name = name,
animationTable = {
}
}
char.animationTable.idle = anim8.newAnimation(animationGrid["idle"], ANIMATION_SPEED)
char.animationTable.run = anim8.newAnimation(animationGrid["run"], ANIMATION_SPEED)
char.animationTable.attack = anim8.newAnimation(animationGrid["attack"], ANIMATION_SPEED, function()
char.state = "idle"
end)
char.animationTable.hurt = anim8.newAnimation(animationGrid["hurt"], ANIMATION_SPEED, function()
char.state = "idle"
end)
return setmetatable(char, { __index = Character })
end
function Character:update(dt)
if love.keyboard.isDown("r") then
self.state = "run"
end
if love.keyboard.isDown("i") then
self.state = "idle"
end
if love.keyboard.isDown("u") then
self.state = "attack"
end
if love.keyboard.isDown("h") then
self.state = "hurt"
end
self.animationTable[self.state]:update(dt)
end
function Character:draw(camera)
self.animationTable[self.state]:draw(AssetBundle.files.sprites.character[self.state], self.position.x,
self.position.y, nil, 1 / camera.pixelsPerMeter, 1 / camera.pixelsPerMeter, 38, 47)
end