--[[ @inconsistent_dg
for calculating horizontal (X+Z) and vertical (Y) speed in 3D games.
in some cases "speed" might be the wrong term, since it's only
finding distance traveled. should be able to remake for use in a 2D game
--]]
local prevX = 0
local prevY = 0
local prevZ = 0
local prevFrameCount = emu.framecount()
while true do
memory.usememorydomain("Main RAM") -- change/remove this if needed
-- DS required it in my case
local currentX = memory.read_s32_le(0x0EBD78) -- replace with your X
local currentY = memory.read_s32_le(0x0EBD7C) -- replace with your Y
local currentZ = memory.read_s32_le(0x0EBD80) -- replace with your Z
-- get difference in frame count
local currentFrameCount = emu.framecount()
local frameDifference = currentFrameCount - prevFrameCount
-- calculate horizontal speed
local speed = 0
if frameDifference ~= 0 then
local deltaX = currentX - prevX -- delta means change in value
local deltaZ = currentZ - prevZ -- delta means change in value
local distance = math.sqrt(deltaX * deltaX + deltaZ * deltaZ)
-- pythagorean theorem
speed = math.floor(distance / frameDifference + 0.5)
-- if you don't want it to round down, then remove math.floor
-- speed = distance / frameDifference
end
-- calculate vertical speed
local speedY = 0
if frameDifference ~= 0 then
local deltaY = currentY - prevY
speedY = math.floor(deltaY / frameDifference + 0.5)
-- no pythagorean theorem because Y = one axis
end
-- displays
gui.text(1, 80, "Horizontal Speed: " .. speed)
gui.text(1, 100, "Vertical Speed: " .. speedY)
-- update previous
prevX = currentX
prevY = currentY
prevZ = currentZ
prevFrameCount = currentFrameCount
emu.frameadvance() -- needed to not crash
end