implemented character movement & initial selector
Co-authored-by: Ivan Yuriev <ivanyr44@gmail.com>
This commit is contained in:
parent
e08fb7255f
commit
d07d26680c
@ -6,6 +6,7 @@ local ANIMATION_SPEED = 0.1
|
|||||||
|
|
||||||
local characterId = 1
|
local characterId = 1
|
||||||
|
|
||||||
|
--- @todo Композиция лучше наследования, но не до такой же степени! Надо отрефакторить и избавиться от сотни полей в таблице
|
||||||
--- @class Character
|
--- @class Character
|
||||||
--- @field id integer
|
--- @field id integer
|
||||||
--- @field name string
|
--- @field name string
|
||||||
@ -16,6 +17,8 @@ local characterId = 1
|
|||||||
--- @field skills table
|
--- @field skills table
|
||||||
--- @field class "warrior"|"mage"
|
--- @field class "warrior"|"mage"
|
||||||
--- @field position Vec3
|
--- @field position Vec3
|
||||||
|
--- @field latestPosition Vec3 позиция, где character был один тик назад
|
||||||
|
--- @field runTarget Vec3 точка, в которую в данный момент бежит персонаж
|
||||||
--- @field size Vec3
|
--- @field size Vec3
|
||||||
local character = {}
|
local character = {}
|
||||||
character.__index = character
|
character.__index = character
|
||||||
@ -66,10 +69,34 @@ local function spawn(name, spriteDir, level)
|
|||||||
|
|
||||||
char = setmetatable(char, character)
|
char = setmetatable(char, character)
|
||||||
Tree.level.characters[char.id] = char
|
Tree.level.characters[char.id] = char
|
||||||
|
Tree.level.positionGrid:add(char)
|
||||||
return char
|
return char
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param target Vec3
|
||||||
|
function character:runTo(target)
|
||||||
|
self.state = "run"
|
||||||
|
self.runTarget = target
|
||||||
|
end
|
||||||
|
|
||||||
function character:update(dt)
|
function character:update(dt)
|
||||||
|
if self.state == "run" and self.runTarget then
|
||||||
|
if self.position:floor() == self.runTarget:floor() then -- мы добежали до цели и сейчас в целевой клетке
|
||||||
|
self.state = "idle"
|
||||||
|
self.runTarget = nil
|
||||||
|
else -- мы не добежали до цели
|
||||||
|
local vel = (self.runTarget:subtract(self.position):normalize() --[[@as Vec3]]
|
||||||
|
):scale(2 * dt) -- бежим 2 условных метра в секунду
|
||||||
|
self.position = self.position:add(vel)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.position ~= self.latestPosition then
|
||||||
|
-- типа уведомление о том, что положение (на уровне клеток) изменилось
|
||||||
|
Tree.level.positionGrid:remove(self)
|
||||||
|
Tree.level.positionGrid:add(self)
|
||||||
|
end
|
||||||
|
|
||||||
if love.keyboard.isDown("r") then
|
if love.keyboard.isDown("r") then
|
||||||
self.state = "run"
|
self.state = "run"
|
||||||
end
|
end
|
||||||
|
|||||||
@ -14,6 +14,7 @@ local keymap = {
|
|||||||
cameraMoveRight = control("key", "d"),
|
cameraMoveRight = control("key", "d"),
|
||||||
cameraMoveDown = control("key", "s"),
|
cameraMoveDown = control("key", "s"),
|
||||||
cameraMoveScroll = control("mouse", "3"),
|
cameraMoveScroll = control("mouse", "3"),
|
||||||
|
select = control("mouse", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
function keymap:isDown(key)
|
function keymap:isDown(key)
|
||||||
|
|||||||
10
lib/grid.lua
10
lib/grid.lua
@ -7,12 +7,12 @@ grid.__index = grid
|
|||||||
--- Adds a character id to the grid
|
--- Adds a character id to the grid
|
||||||
--- @param character Character
|
--- @param character Character
|
||||||
function grid:add(character)
|
function grid:add(character)
|
||||||
local centerX, centerY = character.position.x, character.position.y
|
local centerX, centerY = math.floor(character.position.x), math.floor(character.position.y)
|
||||||
local sizeX, sizeY = character.size.x, character.size.y
|
local sizeX, sizeY = character.size.x, character.size.y
|
||||||
|
|
||||||
for y = centerY, centerY + sizeY - 1 do
|
for y = centerY, centerY + sizeY - 1 do
|
||||||
for x = centerX, centerX + sizeX - 1 do
|
for x = centerX, centerX + sizeX - 1 do
|
||||||
grid[x][y] = character.id
|
self[x][y] = character.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -20,12 +20,12 @@ end
|
|||||||
--- Removes a character id from the grid
|
--- Removes a character id from the grid
|
||||||
--- @param character Character
|
--- @param character Character
|
||||||
function grid:remove(character)
|
function grid:remove(character)
|
||||||
local centerX, centerY = character.position.x, character.position.y
|
local centerX, centerY = math.floor(character.position.x), math.floor(character.position.y)
|
||||||
local sizeX, sizeY = character.size.x, character.size.y
|
local sizeX, sizeY = character.size.x, character.size.y
|
||||||
|
|
||||||
for y = centerY, centerY + sizeY - 1 do
|
for y = centerY, centerY + sizeY - 1 do
|
||||||
for x = centerX, centerX + sizeX - 1 do
|
for x = centerX, centerX + sizeX - 1 do
|
||||||
grid[x][y] = nil
|
self[x][y] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -37,7 +37,7 @@ end
|
|||||||
local function generateGrid(width, height)
|
local function generateGrid(width, height)
|
||||||
local g = utils.generateList(width, function(_)
|
local g = utils.generateList(width, function(_)
|
||||||
return utils.generateList(height, function(_)
|
return utils.generateList(height, function(_)
|
||||||
return nil
|
return {}
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ local utils = require "lib/utils"
|
|||||||
--- @class Level
|
--- @class Level
|
||||||
--- @field characters Character[]
|
--- @field characters Character[]
|
||||||
--- @field positionGrid Grid
|
--- @field positionGrid Grid
|
||||||
--- @field selected table
|
--- @field selector Selector
|
||||||
--- @field camera Camera
|
--- @field camera Camera
|
||||||
local level = {}
|
local level = {}
|
||||||
level.__index = level
|
level.__index = level
|
||||||
@ -12,6 +12,7 @@ local function new()
|
|||||||
return setmetatable({
|
return setmetatable({
|
||||||
characters = {},
|
characters = {},
|
||||||
positionGrid = (require "lib/grid").new(30, 30), -- magic numbers for testing purposes only
|
positionGrid = (require "lib/grid").new(30, 30), -- magic numbers for testing purposes only
|
||||||
|
selector = (require "lib/selector").new(),
|
||||||
camera = (require "lib/camera").new()
|
camera = (require "lib/camera").new()
|
||||||
}, level)
|
}, level)
|
||||||
end
|
end
|
||||||
|
|||||||
35
lib/selector.lua
Normal file
35
lib/selector.lua
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
--- @class Selector
|
||||||
|
--- @field id integer
|
||||||
|
local selector = {}
|
||||||
|
|
||||||
|
local function new()
|
||||||
|
return setmetatable({}, selector)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param characterId integer
|
||||||
|
function selector:select(characterId)
|
||||||
|
self.id = characterId
|
||||||
|
end
|
||||||
|
|
||||||
|
function selector:deselect()
|
||||||
|
self.id = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- TODO: сделать обработчик селектора
|
||||||
|
--- @param camera Camera
|
||||||
|
function selector:update(camera, dt)
|
||||||
|
if self.id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local mousePosition = camera:toWorldPosition(Vec3 { love.mouse.getX(), love.mouse.getY() }):floor()
|
||||||
|
local characterPosition = Tree.level.positionGrid[mousePosition.x][mousePosition.y]
|
||||||
|
if Tree.controls:isDown("select") then
|
||||||
|
if characterPosition then
|
||||||
|
self:select(characterPosition)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
new = new
|
||||||
|
}
|
||||||
42
lib/vec3.lua
42
lib/vec3.lua
@ -1,4 +1,4 @@
|
|||||||
--- @class (exact) Vec3
|
--- @class Vec3
|
||||||
--- @field x number
|
--- @field x number
|
||||||
--- @field y number
|
--- @field y number
|
||||||
--- @field z number
|
--- @field z number
|
||||||
@ -12,6 +12,8 @@ local function __tostring(self)
|
|||||||
return "Vec3{" .. self.x .. ", " .. self.y .. ", " .. self.z .. "}"
|
return "Vec3{" .. self.x .. ", " .. self.y .. ", " .. self.z .. "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param other Vec3
|
--- @param other Vec3
|
||||||
--- @return Vec3
|
--- @return Vec3
|
||||||
function __Vec3:add(other)
|
function __Vec3:add(other)
|
||||||
@ -51,31 +53,43 @@ function __Vec3:angle_to(other)
|
|||||||
return (other - self):direction()
|
return (other - self):direction()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __Vec3:floor()
|
||||||
|
return Vec3 { math.floor(self.x), math.floor(self.y), math.floor(self.z) }
|
||||||
|
end
|
||||||
|
|
||||||
|
function __Vec3:invert()
|
||||||
|
return self:scale(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param other Vec3
|
||||||
|
function __Vec3:subtract(other)
|
||||||
|
return self:add(other:invert())
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param other Vec3
|
||||||
|
function __Vec3:equalsTo(other)
|
||||||
|
return
|
||||||
|
self.x == other.x
|
||||||
|
and self.y == other.y
|
||||||
|
and self.z == other.z
|
||||||
|
end
|
||||||
|
|
||||||
---Vec3 constructor
|
---Vec3 constructor
|
||||||
---@param vec number[]
|
---@param vec number[]
|
||||||
---@return Vec3
|
|
||||||
function Vec3(vec)
|
function Vec3(vec)
|
||||||
return setmetatable({
|
return setmetatable({
|
||||||
x = vec[1] or 0,
|
x = vec[1] or 0,
|
||||||
y = vec[2] or 0,
|
y = vec[2] or 0,
|
||||||
z = vec[3] or 0,
|
z = vec[3] or 0,
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
__index = __Vec3,
|
__index = __Vec3,
|
||||||
__tostring = __tostring,
|
__tostring = __tostring,
|
||||||
__add = __Vec3.add,
|
__add = __Vec3.add,
|
||||||
__mul = __Vec3.scale,
|
__mul = __Vec3.scale,
|
||||||
__unm = function(self)
|
__unm = __Vec3.invert,
|
||||||
return __Vec3.scale(self, -1)
|
__sub = __Vec3.subtract,
|
||||||
end,
|
__eq = __Vec3.equalsTo
|
||||||
__sub = function(self, other)
|
|
||||||
return self + -other
|
|
||||||
end,
|
|
||||||
__eq = function(self, other)
|
|
||||||
return
|
|
||||||
self.x == other.x
|
|
||||||
and self.y == other.y
|
|
||||||
and self.z == other.z
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
5
main.lua
5
main.lua
@ -8,9 +8,8 @@ function love.conf(t)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
character.spawn("Hero", Tree.assets.files.sprites.character)
|
local char = character.spawn("Hero", Tree.assets.files.sprites.character)
|
||||||
local hero2 = character.spawn("Hero2", Tree.assets.files.sprites.character)
|
char:runTo(Vec3 { 5, 5 })
|
||||||
hero2.position = Vec3 { 1, 1 }; -- вообще-то мы вообще не хотим как-то взаимодействовать с персонажем за пределами update, но это удобно для тестов
|
|
||||||
|
|
||||||
-- PlayerFaction.characters = { Hero1, Hero2 }
|
-- PlayerFaction.characters = { Hero1, Hero2 }
|
||||||
love.window.setMode(1080, 720, { resizable = true, msaa = 4, vsync = true })
|
love.window.setMode(1080, 720, { resizable = true, msaa = 4, vsync = true })
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user