在 2d 游戏中改变实体在转向(寻找)行为中的角度(旋转)
Change angle (rotation) of entity in steering (seeking) behavior in 2d game
我正在 Lua 中使用 LOVE2D 开发 2d space 射击游戏,但由于我不是数学和物理专家,所以我遇到了一些关于为敌人实施转向行为的问题。
我终于为玩家树敌 "seeking" 看起来像:
使其工作的代码(公式取自这个答案 - ):
function Enemy:seek ()
local dx = self.player.x - self.x - self.xvel
local dy = self.player.y - self.y - self.yvel
-- normalize
local len = math.sqrt(dx * dx + dy * dy)
dx, dy = dx / len, dy / len
return dx, dy
end
然后我在 update
中使用我的 seek
函数:
function Enemy:update (dt)
-- seeking acceleration
local dx, dy = self:seek()
-- what is the proper way of calculating enemies rotation?
-- self.rotation = math.atan2(dx, dy) + ANGLE_ACCELERATION * dt
-- update velocity
self.xvel = self.xvel + dx * MAX_SPEED * dt -- * math.cos(self.rotation) it's not needed anymore?
self.yvel = self.yvel + dy * MAX_SPEED * dt -- * math.sin(self.rotation) it's not needed anymore?
-- moving entity in camera
_.checkWorldBounds(self)
local futureX = self.x + self.xvel * dt
local futureY = self.y + self.yvel * dt
local nextX, nextY, collisions, len = self.world:move(self, futureX, futureY, self.collisionFilter)
self.x = nextX
self.y = nextY
self.xvel = self.xvel * 0.99
self.yvel = self.yvel * 0.99
end
所以现在唯一的问题是敌人的旋转没有改变,虽然 space船的前面应该总是朝向玩家的一侧。
我试过 math.atan2(dx, dy)
但它使实体不断旋转。
缺少什么或我做错了什么?
我不是在找人为我编写代码(尽管这会非常好),但我会非常感谢一些公式或建议。
如果您感兴趣,源代码可在 - https://github.com/voronianski-on-games/asteroids-on-steroids-love2d
我无法告诉您代码有什么问题,但希望这对您有所帮助。
-- these are the coordinates of the point to which your object should be facing
local playerx, playery = 100, 100
-- these are the current coordinates of the object that needs to have its facing changed
local shipx, shipy = 200, 200
-- the angle to which your object should be rotated is calculated
angle = math.atan2(playery - shipy, playerx - shipx)
请注意,通过使用 body:setAngle(angle)
('body' 是您的对象主体),您的对象将立即旋转到给定角度。如果你想让它们以一定的速度旋转,你可以使用:
local currentAngle = body:getAngle()
local adjustedAngle
if currentAngle > angle then
adjustedAngle = currentAngle - rotationSpeed * dt
elseif currentAngle < angle then
adjustedAngle = currentAngle + rotationSpeed * dt
else
adjustedAngle = currentAngle
end
body:setAngle(adjustedAngle)
另请注意,ship/body/object 的 'front' 位于 x-axis 的右侧。换句话说,角度是根据 x-axis 计算的,0 表示对象面向右侧。
我正在 Lua 中使用 LOVE2D 开发 2d space 射击游戏,但由于我不是数学和物理专家,所以我遇到了一些关于为敌人实施转向行为的问题。
我终于为玩家树敌 "seeking" 看起来像:
使其工作的代码(公式取自这个答案 - ):
function Enemy:seek ()
local dx = self.player.x - self.x - self.xvel
local dy = self.player.y - self.y - self.yvel
-- normalize
local len = math.sqrt(dx * dx + dy * dy)
dx, dy = dx / len, dy / len
return dx, dy
end
然后我在 update
中使用我的 seek
函数:
function Enemy:update (dt)
-- seeking acceleration
local dx, dy = self:seek()
-- what is the proper way of calculating enemies rotation?
-- self.rotation = math.atan2(dx, dy) + ANGLE_ACCELERATION * dt
-- update velocity
self.xvel = self.xvel + dx * MAX_SPEED * dt -- * math.cos(self.rotation) it's not needed anymore?
self.yvel = self.yvel + dy * MAX_SPEED * dt -- * math.sin(self.rotation) it's not needed anymore?
-- moving entity in camera
_.checkWorldBounds(self)
local futureX = self.x + self.xvel * dt
local futureY = self.y + self.yvel * dt
local nextX, nextY, collisions, len = self.world:move(self, futureX, futureY, self.collisionFilter)
self.x = nextX
self.y = nextY
self.xvel = self.xvel * 0.99
self.yvel = self.yvel * 0.99
end
所以现在唯一的问题是敌人的旋转没有改变,虽然 space船的前面应该总是朝向玩家的一侧。
我试过 math.atan2(dx, dy)
但它使实体不断旋转。
缺少什么或我做错了什么?
我不是在找人为我编写代码(尽管这会非常好),但我会非常感谢一些公式或建议。
如果您感兴趣,源代码可在 - https://github.com/voronianski-on-games/asteroids-on-steroids-love2d
我无法告诉您代码有什么问题,但希望这对您有所帮助。
-- these are the coordinates of the point to which your object should be facing
local playerx, playery = 100, 100
-- these are the current coordinates of the object that needs to have its facing changed
local shipx, shipy = 200, 200
-- the angle to which your object should be rotated is calculated
angle = math.atan2(playery - shipy, playerx - shipx)
请注意,通过使用 body:setAngle(angle)
('body' 是您的对象主体),您的对象将立即旋转到给定角度。如果你想让它们以一定的速度旋转,你可以使用:
local currentAngle = body:getAngle()
local adjustedAngle
if currentAngle > angle then
adjustedAngle = currentAngle - rotationSpeed * dt
elseif currentAngle < angle then
adjustedAngle = currentAngle + rotationSpeed * dt
else
adjustedAngle = currentAngle
end
body:setAngle(adjustedAngle)
另请注意,ship/body/object 的 'front' 位于 x-axis 的右侧。换句话说,角度是根据 x-axis 计算的,0 表示对象面向右侧。