这个 lua 代码可以改进吗?
2018-6-7 22:2:46
收藏:0
阅读:124
评论:2
能否重构下面的代码,使其更简洁或更清晰?我还附上了下面的图片来帮助说明我的想法。
local playerAreaPos = {
{x = playerPos.x, y = playerPos.y - 1, z = playerPos.z}, -- 北
{x = playerPos.x, y = playerPos.y + 1, z = playerPos.z}, -- 南
{x = playerPos.x + 1, y = playerPos.y, z = playerPos.z}, -- 东
{x = playerPos.x - 1, y = playerPos.y, z = playerPos.z}, -- 西
{x = playerPos.x - 1, y = playerPos.y + 1, z = playerPos.z}, -- 西南
{x = playerPos.x + 1, y = playerPos.y + 1, z = playerPos.z}, -- 东南
{x = playerPos.x - 1, y = playerPos.y - 1, z = playerPos.z}, -- 西北
{x = playerPos.x + 1, y = playerPos.y - 1, z = playerPos.z} -- 东北
}
local posTable = {
{x = playerPos.x, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH"},
{x = playerPos.x, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH"},
{x = playerPos.x, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH"},
{x = playerPos.x, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH"},
{x = playerPos.x + 2, y = playerPos.y, z = playerPos.z, dir = "EAST"},
{x = playerPos.x + 3, y = playerPos.y, z = playerPos.z, dir = "EAST"},
{x = playerPos.x - 2, y = playerPos.y, z = playerPos.z, dir = "WEST"},
{x = playerPos.x - 3, y = playerPos.y, z = playerPos.z, dir = "WEST"},
{x = playerPos.x - 2, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH_WEST"},
{x = playerPos.x - 3, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH_WEST"},
{x = playerPos.x + 2, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH_EAST"},
{x = playerPos.x + 3, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH_EAST"},
{x = playerPos.x - 2, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH_WEST"},
{x = playerPos.x - 3, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH_WEST"},
{x = playerPos.x + 2, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH_EAST"},
{x = playerPos.x + 3, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH_EAST"}
}
for i = 1, #posTable do
if targetPos == Position(posTable[i]) then
if posTable[i].dir == "NORTH_EAST" then
print("TELEPORT TO: ", playerAreaPos[8].x, playerAreaPos[8].y)
elseif posTable[i].dir == "NORTH_WEST" then
print("TELEPORT TO: ", playerAreaPos[7].x, playerAreaPos[7].y)
elseif posTable[i].dir == "NORTH" then
print("TELEPORT TO: ", playerAreaPos[1].x, playerAreaPos[1].y)
elseif posTable[i].dir == "SOUTH_WEST" then
print("TELEPORT TO: ", playerAreaPos[5].x, playerAreaPos[5].y)
elseif posTable[i].dir == "SOUTH_EAST" then
print("TELEPORT TO: ", playerAreaPos[6].x, playerAreaPos[6].y)
elseif posTable[i].dir == "SOUTH" then
print("TELEPORT TO: ", playerAreaPos[2].x, playerAreaPos[2].y)
elseif posTable[i].dir == "EAST" then
print("TELEPORT TO: ", playerAreaPos[3].x, playerAreaPos[3].y)
elseif posTable[i].dir == "WEST" then
print("TELEPORT TO: ", playerAreaPos[4].x, playerAreaPos[4].y)
end
end
end

该函数的目的是将 posTable 中的敌人传送到 playerAreaPos,同时确保它们在相应的行内传送,这意味着如果它们距离主人公向北 3 格,则会被传送到主人公向北 1 格。
点赞
用户9866482
有许多种方法来实现你的问题,但我打算使用一些数学方法,然后再对它们进行一些考虑。
看一下下面的图表,我们的英雄和敌人之间有一个最小距离,当敌人落入范围内时,它将被传送到英雄的半径限制内,之后,敌人只有在英雄将其扔得远离半径限制时才能传送。
考虑到这些问题,我做了这个实现:
-- returns math functions as local functions
local deg = math.deg
local sin = math.sin
local cos = math.cos
local atan2 = math.atan2
-- returns the distance between two points
local lengthOf = function ( dots )
local dx, dy = dots.x[2]-dots.x[1], dots.y[2]-dots.y[1]
return (dx*dx + dy*dy)^.5
end
-- returns the degrees between two points
-- note: 0 degrees is 'east'
local angleBetweenPoints = function ( dots )
local x, y = dots.x[2]-dots.x[1], dots.y[2]-dots.y[1]
local radian = atan2(x, y)
local angle = deg(radian)
angle = angle < 0 and (360 + angle) or angle
return angle
end
--设置你的英雄
local hero = {}
hero.posX, hero.posY = 0, 0
hero.radius = 10
--设置敌人
local foe = {}
foe.posX, foe.posY = 0, 18
foe.radius = 8
foe.theta = 0
foe.teleported = false
foe.distToHero = 18
foe.points = {}
foe.curDist = 0
--这部分将是像框架一样的东西
foe.points = {x={hero.posX,foe.posX}, y={hero.posY,foe.posY}}
foe.curDist = lengthOf( foe.points )
if foe.distToHero<=foe.curDist and not foe.teleported then
foe.theta = angleBetweenPoints ( foe.points )
foe.posX = hero.radius*sin( foe.theta ) -- 是的,它是反的
foe.posY = hero.radius*cos( foe.theta ) -- 是的,它是反的
foe.teleported = true
else
foe.teleported = false -- 如果敌人被远离英雄击中
end
print(foe.posX,foe.posY)
--打印输出:0, 10
上述实现在地形上放置许多敌人需要大量计算,我的建议是使用C API 或 Box2D,Box2D使用传感器夹具来发生碰撞,并且对这种情况非常有用。当前有许多具有这些功能的Lua SDK,因此您可以快速启动。
2018-06-07 16:43:10
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

local enemyPos = {x = 11, y = 22, z = 33} local playerPos = {x = 10, y = 20, z = 30} local beam_length = 3 if enemyPos.z == playerPos.z then local dx = enemyPos.x - playerPos.x local dy = enemyPos.y - playerPos.y local ax, ay = math.abs(dx), math.abs(dy) local len_max, len_min = math.max(ax, ay), math.min(ax, ay) if len_max >= 2 and len_max <= beam_length and len_min % len_max == 0 then print("TELEPORT TO: ", playerPos.x + dx / len_max, playerPos.y + dy / len_max) end end本段代码定义了敌人(enemyPos)和玩家(playerPos)的位置变量,并定义了射线长度(beam_length)。
如果敌人和玩家在同一层(z轴相等),则进行以下计算:计算敌人与玩家在x轴上的距离(dx)和在y轴上的距离(dy),在取它们的绝对值后求出最大长度(ax)和最小长度(ay)。
然后,计算出最大和最小长度(len_max和len_min)。如果满足最大长度大于等于2且小于等于射线长度(beam_length),且最小长度可以整除最大长度,则输出“TELEPORT TO: ”和玩家最终的位置(x和y坐标)。