Love2d(Lua)特定方向移动时玩家传送功能异常问题排查
问题原因分析及修复方案
核心问题1:E键传送的冗余代码导致方向异常
你在love.keypressed的E键处理中,额外添加了针对dx=1且dy=-1的分支,这会导致同时按W+D时,传送操作被执行两次:
if key == "e" then activeunit.x = activeunit.x + 100*activeunit.dx activeunit.y = activeunit.y + 100*activeunit.dy -- 此分支完全冗余,会导致传送距离翻倍 if activeunit.dx == 1 and activeunit.dy == -1 then activeunit.x = activeunit.x + 100 activeunit.y = activeunit.y - 100 end end
当同时按W+D时,先执行一次x+100、y-100,随后又重复执行一次相同操作,最终x增加200、y减少200,完全偏离预期的100像素传送效果,这就是你觉得“传送失效”的原因。而单个方向键操作时,该分支不会触发,传送距离实际是正常的100像素,你可能误将持续移动的距离和单次传送距离混淆,以为是200像素。
核心问题2:未归一化的方向向量导致对角线传送距离超标
当前dx和dy的取值为-1、0、1,当同时按两个方向键时,直接用100*dx和100*dy计算传送位置,会导致实际传送的直线距离为100*√2 ≈141像素(对角线长度),而非预期的100像素。
修复步骤
- 移除冗余的特殊分支
删除E键处理中针对dx=1且dy=-1的if块,让传送逻辑统一:
if key == "e" then activeunit.x = activeunit.x + 100*activeunit.dx activeunit.y = activeunit.y + 100*activeunit.dy end
- 归一化方向向量(可选,实现严格100像素直线传送)
如果希望无论单方向还是对角线,传送的直线距离都是100像素,需要对dx和dy做归一化处理,修改E键传送逻辑:
if key == "e" then -- 计算方向向量的长度 local length = math.sqrt(activeunit.dx^2 + activeunit.dy^2) -- 避免无方向时触发传送 if length > 0 then local normalized_dx = activeunit.dx / length local normalized_dy = activeunit.dy / length activeunit.x = activeunit.x + 100 * normalized_dx activeunit.y = activeunit.y + 100 * normalized_dy end end
- 优化update中的方向判断(可选,解决斜向移动速度过快问题)
原update中同时按左右/上下方向键时,后判断的方向会覆盖前一个的dx/dy,还会导致斜向移动速度比单方向快,可修改为:
function love.update(dt) -- 先重置方向 activeunit.dx = 0 activeunit.dy = 0 if love.keyboard.isDown("left") then activeunit.dx = activeunit.dx - 1 end if love.keyboard.isDown("right") then activeunit.dx = activeunit.dx + 1 end if love.keyboard.isDown("up") then activeunit.dy = activeunit.dy - 1 end if love.keyboard.isDown("down") then activeunit.dy = activeunit.dy + 1 end -- 归一化移动方向,保证各方向移动速度一致 local length = math.sqrt(activeunit.dx^2 + activeunit.dy^2) if length > 0 then activeunit.dx = activeunit.dx / length activeunit.dy = activeunit.dy / length end -- 应用移动 activeunit.x = activeunit.x + activeunit.speed * activeunit.dx * dt activeunit.y = activeunit.y + activeunit.speed * activeunit.dy * dt -- 地面碰撞处理 if activeunit.y > ground then activeunit.y = ground end time = time + dt end
内容的提问来源于stack exchange,提问作者Sirin
相关产品推荐
相关产品推荐

