Basic Top Down Shooter Help

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
evan312
Prole
Posts: 3
Joined: Sat Jun 22, 2013 6:27 pm

Basic Top Down Shooter Help

Post 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!
Attachments
TDS.love
(106.02 KiB) Downloaded 221 times
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Basic Top Down Shooter Help

Post 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 3127 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!
Help us help you: attach a .love.
User avatar
evan312
Prole
Posts: 3
Joined: Sat Jun 22, 2013 6:27 pm

Re: Basic Top Down Shooter Help

Post 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!
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Basic Top Down Shooter Help

Post 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. :)
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 3 guests