My tanks goes haywire, halp :S

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Marcus Aseth
Prole
Posts: 14
Joined: Wed Apr 05, 2017 11:56 am

My tanks goes haywire, halp :S

Post 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 137 times
User avatar
Marcus Aseth
Prole
Posts: 14
Joined: Wed Apr 05, 2017 11:56 am

Re: My tanks goes haywire, halp :S

Post 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:
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: My tanks goes haywire, halp :S

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Marcus Aseth
Prole
Posts: 14
Joined: Wed Apr 05, 2017 11:56 am

Re: My tanks goes haywire, halp :S

Post by Marcus Aseth »

I see, I'll look into that then.
Thanks! :)
Post Reply

Who is online

Users browsing this forum: No registered users and 99 guests