【问题标题】:Move an object to a target location in a straight path沿直线路径将对象移动到目标位置
【发布时间】:2013-07-24 09:24:57
【问题描述】:

我又遇到了一个问题。所以,我正在电晕中制作游戏。我希望对象沿直线移动到触摸坐标。我知道我可以简单地使用transition.to() 函数,但物理引擎在转换期间无法正常工作。我编写了以下代码,但当然,圆圈不会直线移动。

function controls(event)
    if event.phase == "began" or event.phase == "moved" then
        follow = true
        touchX = event.x; touchY = event.y
    end

    if event.phase == "ended" then
        follow = false
    end
end

function playerMotion()
    if follow == true then
        if circle.y < touchY then
            circle.y = circle.y + 1
        elseif circle.y > touchY then
            circle.y = circle.y - 1
        end

        if circle.x < touchX then
            circle.x = circle.x + 1
        elseif circle.x > touchX then
            circle.x = circle.x - 1
        end
    end
end

希望我的问题足够清楚。

【问题讨论】:

    标签: lua coronasdk


    【解决方案1】:

    你需要比这个函数更复杂的东西。这样做只是“接近”目的地。它不遵循一条笔直的道路。

    要完成你想做的事,你需要做几件事:

    1. 找到你的位置。
    2. 找到目的地的位置。
    3. 计算从开始位置到结束位置的水平距离。
    4. 相同,但垂直除外。
    5. 现在,如果您将其添加到您的起始对象,您将立即到达目的地。我们怎样才能让它慢慢地移动?只需将垂直和水平距离除以“速度”变量即可。这是对象在一帧内移动的速率。
    6. 对于每一帧,通过添加刚刚找到的 x 和 y 分量来更新对象。
    7. 检查您是否已到达目的地。如有必要,重复步骤 6。 (或者:跟踪您行进的水平和垂直距离,并将其与原始结果进行比较。)

    你有它!

    【讨论】:

      【解决方案2】:

      试试我的示例应用。您可以使用它或为您的项目获得想法。

      您也可以在一个空白项目中对其进行测试,看看它是如何工作的。

      _W = display.contentWidth
      _H = display.contentHeight
      
      local physics = require("physics")
      
      physics.start()
      physics.setGravity(0,0)
      
      local circle = display.newCircle(0,0,20)
      circle.name = "circle"
      circle.x = _W/2
      circle.y = _H/2
      circle.tx = 0
      circle.ty = 0
      physics.addBody(circle)
      circle.linearDamping = 0
      circle.enterFrame = function(self,event)
          print(self.x,self.tx)
      
          --This condition will stop the circle on touch coordinates
          --You can change the area value, this will detect if the circles's x and y is between the circles's tx and ty
          --If area is 0, it may not stop the circle, area = 5 is safe, change if you want to
          local area = 5
          if self.x <= self.tx + area and self.x >= self.tx - area and
             self.y <= self.ty + area and self.y >= self.ty - area then
              circle:setLinearVelocity(0,0) --set velocity to (0,0) to fully stop the circle
          end
      end
      
      --Add event listener for the monitoring the coordinates of the circle
      Runtime:addEventListener("enterFrame",circle)
      
      
      Runtime:addEventListener("touch",function(event)
          if event.phase == "began" or event.phase == "moved" then
              local x, y = event.x, event.y
              local tx, ty = x-circle.x, y-circle.y --compute for the toX and toY coordinates
              local sppedMultiplier = 1.5 --this will change the speed of the circle, 0 value will stop the circle
      
              --sets the future destination of the circle
              circle.tx = x 
              circle.ty = y
      
              circle:setLinearVelocity(tx*delay,ty*delay) --this will set the velocity of the circle towards the computed touch coordinates on a straight path.
          end
      end)
      

      【讨论】:

        【解决方案3】:

        这是将圆移动到接触点的数学运算:

            theta = atan2(touchY - circle.y,touchX - circle.x)
            velx = cos(theta)
            vely = sin(theta)
            circle.x += velx
            circle.y += vely
        

        随着圆越来越接近接触点,速度将接近 0。

        【讨论】:

        • Lua中不存在复合赋值运算符+=;我假设这是某种伪代码。速度不会接近零,但始终为 1,因为 theta 将保持不变(如果您不想要单位速度,您应该将 velxvely 缩放一些速度因子)。 circle 位置永远不会完全达到touch 位置,而是会以围绕touch 位置振荡而结束。这在实践中可能很好,但它可能看起来很紧张。如果您希望圆圈停止,则必须在圆圈“接近”接触点时停止。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多