Page 1 of 1

My tanks goes haywire, halp :S

Posted: Wed Apr 19, 2017 9:15 am
by Marcus Aseth
So I have this tank that drives around just fine using "w,a,s,d", but as soon I try to turn,everything go insane... xD
I am staring at the code for 3 hours or more, and I can't figure out a fix :cry: Need help :\
I have the piece of the code properly set up with console print, so I would really appreciate if someone can take a look at it :3

The troublesome part is in the helpers.lua file, at the updateShape function, code below.
basically it uses the currSpeed and vector.direction to properly move around the 4 points of my rectangle tank, but if you try to rotate, it start spinning incontrollably.
I think the problem is in this line :

Code: Select all

local angle = math.atan2(shape[i + 1] - self.pivot.y, shape[ i ] - self.pivot.x) + self.vector.direction
because below it, shape[ i ] and shape[i + 1] get set to the new angle, so the next update when the function is called again it stacks the self.vector.direction one more time, and keep spinning around.
And I'm too tired to find the smart solution here I guess :crazy:
Any suggestions?

Code: Select all

 local function updateShape(self, dt)
  local shape = self.shape

  --update pivot
  self.pivot.x = self.pivot.x + self.currSpeed * dt * math.cos(self.vector.direction)
  self.pivot.y = self.pivot.y + self.currSpeed * dt * math.sin(self.vector.direction)

  --update points
  for i = 1, #shape - 1, 2 do
    --x,y
    shape[i] = shape[i] + self.currSpeed * dt * math.cos(self.vector.direction)
    shape[i + 1] = shape[i + 1] + self.currSpeed * dt * math.sin(self.vector.direction)
  end

  --debug
  print("direction: " .. string.format("%.2f",self.vector.direction))
  print("pivot X,Y: (" .. string.format("%2d",self.pivot.x) .. ", " .. string.format("%2d",self.pivot.y) .. ")")

  --add rotation
  local step = 0
  --- -[[
  for i = 1, #shape - 1, 2 do --check x,y pairs for the 4 points of the rectangle (8 total values)
    --distance from current point to pivot
    local distance = math.sqrt(math.pow(shape[i] - self.pivot.x, 2) + math.pow(shape[i + 1] - self.pivot.y, 2))
    --angle from pivot to point
    local angle = math.atan2(shape[i + 1] - self.pivot.y, shape[i] - self.pivot.x) + self.vector.direction
    --debug
    print("X" .. i - step .. ",Y" .. i - step .. " Point angle:" .. string.format("%.2f",angle)) step = step + 1

    --x,y
    shape[i] = self.pivot.x + distance * math.cos(angle)
    shape[i + 1] = self.pivot.y + distance * math.sin(angle)
  end
  --]]
end
Tank.love
(7.74 KiB) Downloaded 178 times

Re: My tanks goes haywire, halp :S

Posted: Wed Apr 19, 2017 9:39 am
by Marcus Aseth
Well, I guess that writing this topic somehow helped me to think, I came up with this (bad)solution inside that function:

Code: Select all

 --add rotation
  local step = 0
  --- -[[
  for i = 1, #shape - 1, 2 do --check x,y pairs for the 4 points of the rectangle (8 total values)
    --distance from current point to pivot
    local distance = math.sqrt(math.pow(shape[i] - self.pivot.x, 2) + math.pow(shape[i + 1] - self.pivot.y, 2))
    --angle from pivot to point
    local angle = math.atan2(self.staticShape[i + 1] - self.pivot.y, self.staticShape[i] - self.pivot.x) + self.vector.direction
    --debug
    print("X" .. i - step .. ",Y" .. i - step .. " Point angle:" .. string.format("%.2f", angle)) step = step + 1

    --x,y
    shape[i] = self.pivot.x + distance * math.cos(angle)
    shape[i + 1] = self.pivot.y + distance * math.sin(angle)
    self.staticShape[i] = self.staticShape[i] + self.currSpeed * dt * math.cos(self.vector.direction)
    self.staticShape[i+1] = self.staticShape[i + 1] + self.currSpeed * dt * math.sin(self.vector.direction)
  end
Basically at the creation of the tank I'm storing a second copy of the points that make up the shape called "staticShape", this follow the pivot of the tank around but has a fixed rotation so it's only used as a reference to calculate how much stuff needs to be rotated around based on vector.direction, or something like that(at this point I am not even sure why it works anymore xD).
It works but doesn't seems elegant to have to store the points twice...
Any other solutions? :crazy:

Re: My tanks goes haywire, halp :S

Posted: Wed Apr 19, 2017 11:02 am
by s-ol
you shouldn't/don't need to modify the position of every vertex each frame like this. Calculating rotated and moved vertex positions is exactly what the GPU is designed to do, and you are not letting it take care of it.

look up 2d transforms on the wiki and here on the forum. in particular the love api functions you are interested in are going to be:
love.graphics.translate
love.graphics.rotate
love.graphics.push / pop

it is definetely worth your time trying to really understand what transformations are and how they work.

with that, your logic is going to change a bit and you are going to end up storing these major pieces of data:
- the shape (only created once and used for drawing)
- the position (as a vector)
- the rotation

then in your update function, you will just update the rotation based on inputs and the position based on the rotation and inputs.

in the draw you just transform to where the tank should be and point to, then draw the shape.

Re: My tanks goes haywire, halp :S

Posted: Wed Apr 19, 2017 11:24 am
by Marcus Aseth
I see, I'll look into that then.
Thanks! :)