First, I apologize for another "I can't make this" question.
Currently I'm trying to implementing turn-based time system.
.love file is what I made - you can move player and enemies will move towards player using Jumper library.
But this is my problem: I want to apply different "speed" for each entities.
Example: movedelay for "player" entity is 100 units, and "snake" entity is 80 units.
Let's assume one "turn" is 100 units - so in 4 turns, player entity can move 4 times and snake entity can move 5 times.
http://www.gamesetwatch.com/2008/08/col ... ion_on.php
https://journal.stuffwithstuff.com/2014 ... game-loop/
I checked links above, and they are using one big main while() loop - but I'm not sure where should I place it.
If anyone can give me any advice, it would be really appreciated.
Implementing turn-based time system
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Re: Implementing turn-based time system
That means that in some turns, the snake will move once, and in some other turns, the snake will move twice. Is that what you mean?
If so, there are two ways of implementing it. One is using decimals, the other is using integers. The decimals way is simpler but it is prone to rounding errors.
With decimals, the snake moves 5/4 or 1.25 times the speed of the player. So, you have a variable, steps, and you add 1.25 to it at every step. You then compare the difference in the integral part before and after incrementing, and that's the number of movements that the snake can take:
Code: Select all
local snakeSteps = 0
local snakeRatio = 5/4
function love.keypressed(k)
local moveX, moveY = 0, 0
if k == "left" then moveX = -1 end
if k == "right" then moveX = 1 end
if k == "up" then moveY = -1 end
if k == "down" then moveY = 1 end
if moveX ~= 0 or moveY ~= 0 then
-- Player takes turn and moves once
movePlayer(moveX, moveY)
-- Snake's turn
local oldSnakeSteps = math.floor(snakeSteps)
snakeSteps = snakeSteps + snakeRatio
-- Move the snake as many times as the difference indicates
for i = 1, snakeSteps - oldSnakeSteps do
moveSnake()
end
end
end
Code: Select all
local snakeSteps = 0
local snakeNum = 5 -- numerator of fraction indicating ratio
local snakeDen = 4 -- denominator of fraction indicating ratio
function love.keypressed(k)
local moveX, moveY = 0, 0
if k == "left" then moveX = -1 end
if k == "right" then moveX = 1 end
if k == "up" then moveY = -1 end
if k == "down" then moveY = 1 end
if moveX ~= 0 or moveY ~= 0 then
-- Player takes turn and moves once
movePlayer(moveX, moveY)
-- Snake's turn
snakeSteps = snakeSteps + snakeNum
while snakeSteps >= snakeDen do
moveSnake()
snakeSteps = snakeSteps - snakeDen
end
end
end
No, forget about that. The main loop is already created in Löve and I don't recommend fiddling with it.
Re: Implementing turn-based time system
Thanks pgimeno , I checked https://ironypolicy.wordpress.com/2014/ ... oguelikes/ and solved it:
First, I added "energy" and "energygen" field for each entities, and changed "movedelay" to "movecost".
"energy" represents how much energy entity has, "energygen" represents how much energy will generated by each turn, and "movecost" is how much energy needed to move.
"energygen" is not shared among entities because if entity move faster or slower somehow(like "haste" or "slow" effect), modifying energygen value will be easier than modifying every movecost/attackcost/castcost...(if I add those later.)
Before:
After:
Then, I fixed love.keypressed callback function - if player has less than 0 energy, turn(s) will be processed until player regenerate enough amount of energy to act.
Before:
After:
Finally, I added while loop in tick() function - if entity has enough energy to move, move entity while it has enough energy to move.
Before:
After:
Final product is working well(at least I think). I attach modified .love file here.
First, I added "energy" and "energygen" field for each entities, and changed "movedelay" to "movecost".
"energy" represents how much energy entity has, "energygen" represents how much energy will generated by each turn, and "movecost" is how much energy needed to move.
"energygen" is not shared among entities because if entity move faster or slower somehow(like "haste" or "slow" effect), modifying energygen value will be easier than modifying every movecost/attackcost/castcost...(if I add those later.)
Before:
Code: Select all
entities = {
{type = "player", x = 2, y = 2, movedelay = 100}, -- player is always entity #1
{type = "goblin", x = 14, y = 9, movedelay = 100},
{type = "snake", x = 2, y = 9, movedelay = 80},
{type = "troll", x = 14, y = 2, movedelay = 120}
}
Code: Select all
entities = {
{type = "player", x = 2, y = 2, energy = 0, energygen = 100, movecost = 100}, -- player is always entity #1
{type = "goblin", x = 14, y = 9, energy = 0, energygen = 100, movecost = 100},
{type = "snake", x = 2, y = 9, energy = 0, energygen = 100, movecost = 80},
{type = "troll", x = 14, y = 2, energy = 0, energygen = 100, movecost = 120}
}
Before:
Code: Select all
function love.keypressed(key)
local playertookaction = false
-- h(←) j(↓) k(↑) l(→) y(↖) u(↗) b(↙) n(↘) p(perform pathfinding to mouse cursor)
if key == "h" or key == "left" then -- move left
playertookaction = move(player(), -1, 0)
elseif key == "j" or key == "down" then -- move down
playertookaction = move(player(), 0, 1)
elseif key == "k" or key == "up" then -- move up
playertookaction = move(player(), 0, -1)
elseif key == "l" or key == "right" then -- move right
playertookaction = move(player(), 1, 0)
elseif key == "y" then -- move left-up
playertookaction = move(player(), -1, -1)
elseif key == "u" then -- move right-up
playertookaction = move(player(), 1, -1)
elseif key == "b" then -- move left-down
playertookaction = move(player(), -1, 1)
elseif key == "n" then -- move right-down
playertookaction = move(player(), 1, 1)
elseif key == "." then
playertookaction = true
elseif key == "r" then
reset()
elseif key == "p" then -- perform pathfinding to mouse pointer
end
if playertookaction == true then
tick()
end
end
Code: Select all
function love.keypressed(key)
local playertookaction = false
-- h(←) j(↓) k(↑) l(→) y(↖) u(↗) b(↙) n(↘) p(perform pathfinding to mouse cursor)
if key == "h" or key == "left" then -- move left
playertookaction = move(player(), -1, 0)
elseif key == "j" or key == "down" then -- move down
playertookaction = move(player(), 0, 1)
elseif key == "k" or key == "up" then -- move up
playertookaction = move(player(), 0, -1)
elseif key == "l" or key == "right" then -- move right
playertookaction = move(player(), 1, 0)
elseif key == "y" then -- move left-up
playertookaction = move(player(), -1, -1)
elseif key == "u" then -- move right-up
playertookaction = move(player(), 1, -1)
elseif key == "b" then -- move left-down
playertookaction = move(player(), -1, 1)
elseif key == "n" then -- move right-down
playertookaction = move(player(), 1, 1)
elseif key == "." then
playertookaction = true
elseif key == "r" then
reset()
elseif key == "p" then -- perform pathfinding to mouse pointer
end
if playertookaction == true then
player().energy = player().energy - player().movecost
while player().energy < 0 do
player().energy = player().energy + player().energygen
tick()
end
end
end
Before:
Code: Select all
function tick()
-- process turn and move another monsters
turn = turn + 1
-- make non-player creatures move
local k, v, path
for k, v in pairs(entities) do
if v.type ~= "player" then
-- perform pathfinding and track player
path = pathfind(v, player())
if path[1] ~= nil then
move(v, path[1].x, path[1].y)
end
end
end
end
Code: Select all
function tick()
-- process turn and move another monsters
turn = turn + 1
-- make non-player creatures move
local k, v, path
local creature_moved
for k, v in pairs(entities) do
if v.type ~= "player" then
-- perform pathfinding and track player
v.energy = v.energy + v.energygen
while(v.energy >= v.movecost) do
path = pathfind(v, player())
if path[1] ~= nil then
move(v, path[1].x, path[1].y)
end
v.energy = v.energy - v.movecost
end
end
end
end
Re: Implementing turn-based time system
Great that you solved it. That actually follows the exact same scheme as the integer solution I posted, where snakeSteps is v.energy, snakeNum is v.energygen and snakeDen is v.movecost.
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 4 guests