Page 1 of 1

Basic Top Down Shooter Help

Posted: Sat Jun 22, 2013 7:04 pm
by evan312
Hello, I'd like to preface this by saying it's my first post so I will try not to miss anything important.

I am making a simple TDS (WASD or arrow keys to move, mouse to rotate, LMB to shoot) mostly just to learn more about LOVE and Lua and have fun, but I ran into a problem. How do I find the point on my players hand to attach a gun and shoot from? I get it to start there, but it strays off when I move my mouse to rotate the direction that the player is facing.

I wrote it first without using the physics module and couldn't figure it out so I rewrote it using the physics module (hoping joints would help me) but soon figured out that I have no idea how to use joints!

here is my code for it with the physics module:

Code: Select all

function love.load()

	player = love.graphics.newImage("images/derp.png")
	bg = love.graphics.newImage("images/bg.png")
	reticule = love.graphics.newImage("images/reticule.png")
	pistol = love.graphics.newImage("images/pistol.png")
	
	love.physics.setMeter(64)
	world = love.physics.newWorld(0, 0, true)
	
	love.mouse.setVisible(false)
	
	bullets = {}
	bulletSpeed = 200
	
	actors = {}
	
	actors.player = {}
	actors.player.body = love.physics.newBody(world, 100, 100, "dynamic")
	actors.player.shape = love.physics.newCircleShape(16)
	actors.player.fixture = love.physics.newFixture(actors.player.body, actors.player.shape)
	
	
	weapons = {}
	
	weapons.pistol = {}
	weapons.pistol.body = love.physics.newBody(world, 200, 200, "dynamic")
	weapons.pistol.shape = love.physics.newCircleShape(.5)
	weapons.pistol.fixture = love.physics.newFixture(weapons.pistol.body, weapons.pistol.shape)
	
	
	joint = love.physics.newWeldJoint(  --joint attempt?
		actors.player.body, weapons.pistol.body, 
		actors.player.body:getX(), actors.player.body:getY(),
		0, 0, false
	) 
end

function love.mousepressed(x, y, button)
    if button == "l" then
		 startX = actors.player.body:getX() -- where bullets start from, I have it at the center of the player right now
         startY = actors.player.body:getY()
         mouseX = x
         mouseY = y
       
         angle = math.atan2((mouseY - startY), (mouseX - startX))
       
         bulletDx = bulletSpeed * math.cos(angle)
         bulletDy = bulletSpeed * math.sin(angle)
       
        table.insert(bullets, {x = startX, y = startY, dX = bulletDx, dY = bulletDy})
    end
	print(pistolX)
end


function love.update(dt)
	
	if love.keyboard.isDown("left","a") == true then
		print(actors.player.body:getX())
		actors.player.body:setX(actors.player.body:getX() - 200*dt)
	end	
	if love.keyboard.isDown("right","d") == true then
		actors.player.body:setX(actors.player.body:getX() + 200*dt)
	end	
	if love.keyboard.isDown("up","w") == true then
		actors.player.body:setY(actors.player.body:getY() - 200*dt)
	end	
	if love.keyboard.isDown("down","s") == true then
		actors.player.body:setY(actors.player.body:getY() + 200*dt)
	end	

	
	mX,mY = love.mouse.getPosition()
	pRot = math.atan2((mY - actors.player.body:getY()), (mX - actors.player.body:getX()))
	print(math.deg(pRot))
	
	
	weapons.pistol.body:setX(actors.player.body:getX() + math.sin(pRot + math.rad(33.69)) * 28.84) -- attempt to find the point
	weapons.pistol.body:setY(actors.player.body:getY() + math.sin(pRot + math.rad(56.31)) * 28.84)  
	
	for i,v in ipairs(bullets) do
		v["x"] = v["x"] + (v["dX"] * dt)
        v["y"] = v["y"] + (v["dY"] * dt)
	end
end



function love.draw()
	love.graphics.setColor(255, 255, 255)
	love.graphics.draw(bg, 0, 0)
	love.graphics.draw(player, actors.player.body:getX(), actors.player.body:getY(), pRot, 2, 2, 16, 16)
	love.graphics.draw(pistol, weapons.pistol.body:getX(), weapons.pistol.body:getY(), pRot, 2, 2)
	love.graphics.draw(reticule, mX, mY)
	
	love.graphics.setColor(64, 64, 64)
	for i,v in ipairs(bullets) do
		love.graphics.circle("fill", v["x"], v["y"], 2)
	end
	

end
Would joints be a good idea to use joints here? or is there a better/easier way?

My pre-physics version is in the .love file if you want to see that too.

Thank you all so much in advance!

Re: Basic Top Down Shooter Help

Posted: Sat Jun 22, 2013 7:46 pm
by Robin
Welcome! I couldn't run your game at first (you put your images right in the .love instead of a subfolder called "images", so I had to change that).

First, you probably don't want to use love.physics here. Right now, it's probably going to hinder you more than help you.

Second, I prefer not to give you the actual solution, but instead all the hints you need to find the solution yourself.

Okay, look at this:
calculate-stuff.png
calculate-stuff.png (2.65 KiB) Viewed 3132 times
The green cross is where your character rotates around (it probably isn't, but let's pretend). The blue cross is where you would like the pistol to be. The red/blue dotted line we call the "Y offset". The red/yellow dotted line we call the "X offset". I'll let you count the pixels, I'd probably mess it up anyway.

Now, in pseudo code:

Code: Select all

X of gun (blue cross) = X of player (green cross) + X offset * math.cos(player rotation) + Y offset * math.sin(player rotation)
Y of gun = Y of player + Y offset * math.cos(player rotation) + X offset * math.sin(player rotation)
You might need to play with pluses and minuses, but that should basically do the trick. Good luck!

Re: Basic Top Down Shooter Help

Posted: Sat Jun 22, 2013 11:51 pm
by evan312
Thanks! I did that:

Code: Select all

pistolX = playerX + (16 * math.cos(pRot)) - (24 * math.sin(pRot)))  
pistolY = playerY + (16* math.cos(pRot)) + (24 * math.sin(pRot))) 
..but i was still getting an "orbit" around the general hand area. After some tinkering, I found that if all the offset numbers are the same, then there is no orbit.

Code: Select all

pistolX = playerX + (22.5* math.cos(pRot)) - (22.5 * math.sin(pRot)))  
pistolY = playerY + (22.5* math.cos(pRot)) + (22.5 * math.sin(pRot))) 
That worked for me with a little offsetting of the image in love.draw() so I am all set, but you would think that the number would be the hypotenuse of the 16-24-? triangle. Pythagoras is telling me that it should be 28 and some decimals, but 22.5 is working.. Anyways thank you so much for the help and time! You are a life saver!

Re: Basic Top Down Shooter Help

Posted: Sun Jun 23, 2013 8:30 am
by Robin
evan312 wrote:That worked for me with a little offsetting of the image in love.draw() so I am all set, but you would think that the number would be the hypotenuse of the 16-24-? triangle. Pythagoras is telling me that it should be 28 and some decimals, but 22.5 is working..
Hm, I think it's probably because of something I forgot, but if it works, great!
evan312 wrote:Anyways thank you so much for the help and time! You are a life saver!
You're welcome. :)