Apply velocity in relation to getAngle()

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Nexion
Prole
Posts: 46
Joined: Fri Sep 05, 2008 1:40 pm

Apply velocity in relation to getAngle()

Post by Nexion »

I'm trying to get some simple cannons to work, but my angles keep getting screwed up for some reason.
My current code attempts to get the end of the barrel (which doesn't work quite right either) then throws the bullet outward with the angle of the barrel, but it always has a bias to the right.

Code: Select all

lastclick = 0
function mousepressed(x, y, button)
	if button == love.mouse_left then -- and lastclick + 0.1 <= love.timer.getTime() then
		lastclick = love.timer.getTime()

		local sPosX, sPosY
		local spawner

		if x < 256 then spawner = LBarrelBody elseif x < 768 then spawner = MBarrelBody elseif x > 768 then spawner = RBarrelBody end
		sPosX = spawner:getX() * math.cos(spawner:getAngle()) - spawner:getY() * math.sin(spawner:getAngle())
		sPosY = spawner:getX() * math.sin(spawner:getAngle()) + spawner:getY() * math.cos(spawner:getAngle())
		
		local x1, y1 = love.mouse.getPosition()
		local x2, y2 = spawner:getPosition()
		
		local dirx = math.atan2(y2 - y1, x2 - x1) * 180 / math.pi
		local diry = math.atan2(y1 - y2, x1 - x2) * 180 / math.pi		
		if x1 <= x2 then x1 = x2 + 5 end
		local t = {}
		t.b = phys.newBody(world, spawner:getX() + (dirx / 11), spawner:getY() + (diry / 3), 1)
		t.s = phys.newCircleShape(t.b, 5)
		t.b:setBullet(true)
		t.dirx = dirx
		t.diry = diry
		t.s:setData(t)
		table.insert(bullets, t)
		t.b:setVelocity(t.dirx / 3,t.diry * 2)
	end
end
There are 3 different barrels, only one fires at a time, detected by the location of the mouse on the screen.
Can anyone suggest how to apply velocity to the bullets more accurately then this? Sort of like an object:ApplyVelocityForward(force) using the angle the object is at.
Mr. Strange
Party member
Posts: 101
Joined: Mon Aug 11, 2008 5:19 am

Re: Apply velocity in relation to getAngle()

Post by Mr. Strange »

Well for starters, I think it's less than ideal to be calculating the angle of your gun barrels at the time of firing - I think you would be better off computing their angle every frame, drawing them with that information, and then simply passing that orientation off to the projectiles. This requires a few more calculations, but it will show you right away where your errors are, since the barrels themselves will be mis-aligned.

You are using spawner:getX() and spawner:getY(), but later you use x,y = spawner:getPosition(). Wouldn't it be more sensible (and easier to read) if you did that just once?

Code: Select all

      local spawner
      local x1, y1 = love.mouse.getPosition()
      local x2, y2 = spawner:getPosition()
      local sPosX, sPosY
      local sAngle = spawner:getAngle()

      sPosX = x2 * math.cos(sAngle) - y2 * math.sin(sAngle)
      sPosY = x2 * math.sin(sAngle) + y2 * math.cos(sAngle)
      
      local dirx = math.atan2(y2 - y1, x2 - x1) * 180 / math.pi
      local diry = math.atan2(y1 - y2, x1 - x2) * 180 / math.pi      
      if x1 <= x2 then x1 = x2 + 5 end
All I've done is collapsed some of the stuff you wrote above - nothing has really changed yet.

The thing that jumps out to me is your calculations for sPosX and sPosY - you are scaling your sine and cosine results by the location of your turrets - that seems odd to me.

Here is what I imagine you are trying to do - your turret is at a fixed location, and fires a projectile at the point occupied by the mouse. In that case, you know that the base of your turret, the muzzle, and the mouse point are all collinear, which means your can eliminate lots of redundancy. If the turret has some tracking speed maximum, which would lead to it trailing behind the pointer, then you can't assume that.

Anyway, a reorganized code snippet and a better explanation of your constraints would be a big help.

--Mr. Strange
User avatar
Nexion
Prole
Posts: 46
Joined: Fri Sep 05, 2008 1:40 pm

Re: Apply velocity in relation to getAngle()

Post by Nexion »

Yeah, sorry about the slightly redundant code. I always clean things up after i get them working, which kinda screws me over some times.
User avatar
Nexion
Prole
Posts: 46
Joined: Fri Sep 05, 2008 1:40 pm

Re: Apply velocity in relation to getAngle()

Post by Nexion »

Mr. Strange wrote: The thing that jumps out to me is your calculations for sPosX and sPosY - you are scaling your sine and cosine results by the location of your turrets - that seems odd to me.
I was doing that to try to get the projectile to spawn at the end of the barrel

Here is the update function of the code

Code: Select all

function update(dt) 
	world:update(dt)
	
	mPosX, mPosY = love.mouse.getPosition()
	
	lbPosX, lbPosY = LBarrelBody:getPosition()
	mbPosX, mbPosY = MBarrelBody:getPosition()
	rbPosX, rbPosY = RBarrelBody:getPosition()
	
	LBarrelBody:setAngle(math.deg(math.atan2(mPosY-lbPosY,mPosX-lbPosX)))
	MBarrelBody:setAngle(math.deg(math.atan2(mPosY-mbPosY,mPosX-mbPosX)))
	RBarrelBody:setAngle(math.deg(math.atan2(mPosY-rbPosY,mPosX-rbPosX)))

	for k, v in ipairs(bullets) do
		if v.b:getX() > 1024 or v.b:getX() < 0 or v.b:getY() < 0 then
			table.remove(bullets, k) --Remove the bullets from the table once they're off the screen
                        v.b:destroy() --Remove the bullets from the game space
		end
	end
end

function angleBetween(ax, ay, bx, by) 
	local dotproduct, lengtha, lengthb, result;

	dotproduct = (ax * bx) + (ay * by);
	lengtha = length(ax,ay);
	lengthb = length(bx,by);

	result = math.acos( dotproduct / (lengtha * lengthb) );

	if dotproduct < 0 then
		if result > 0 then
			result = result + math.pi;
		else
			result = result - math.pi;
		end
	end
	
	return result;
end

function length(x,y)
	return math.sqrt(x*x+y*y)
end
Again a little redundancy, but it might help.

I just realized that some of this code I borrowed from another game (since I don't plan on releasing this) and it was screwing up some things.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 9 guests