use mouse to move things around

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.
mahmoud
Prole
Posts: 3
Joined: Wed Jan 27, 2010 2:30 am

use mouse to move things around

Post by mahmoud »

hello

i'm trying to understand how to make it, but i can't find out how to do it

also how hard would it be to make it interact with other physic object?

thank you

im learning to code with much love

i have another question
can you use a physical object as a character and make it move according to physics? or say a ragdoll character animated but bound to physics, instead of a gif animated character
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: use mouse to move things around

Post by Robin »

I am not entirely sure what your question is, but to set a Box2D body to the location of your mouse, you could use:

Code: Select all

yourbody:setX(love.mouse.getX())
yourbody:setY(love.mouse.getY())
in love.update()
Help us help you: attach a .love.
mahmoud
Prole
Posts: 3
Joined: Wed Jan 27, 2010 2:30 am

Re: use mouse to move things around

Post by mahmoud »

hey thanks
what i would like to do is click on a object and move it around while it remains clicked, like an icon in the desktop
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: use mouse to move things around

Post by bartbes »

Code: Select all

function love.mousepressed(button)
    if btn == "l" and yourshape:testPoint(love.mouse.getPosition()) then
        dragging = true
    end
end

function love.mousereleased(button)
    if btn == "l" then
        dragging = false
    end
end

function love.update(dt)
    if dragging then
        yourbody:setPosition(love.mouse.getPosition())
    end
    --everything else
end
That should do
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Denver, CO
Contact:

Re: use mouse to move things around

Post by TechnoCat »

http://love2d.org/docs/MouseJoint.html

MouseJoint
For controlling objects with the mouse.

Created with love.physics.newMouseJoint.
mahmoud
Prole
Posts: 3
Joined: Wed Jan 27, 2010 2:30 am

Re: use mouse to move things around

Post by mahmoud »

thanks a lot again

I tried to add the code for the mouse, but it's not working i must have done something wrong

here is the love file, i used avalanche of love to learn how to make a world, write stuff, make box, modify shape of an object and gravity

edit: thanks a lot technocat

i have looked through the list and i don't know how i missed that one
i'm too impatient :oops:

mmh i am failling at making it work, is there a demo out there doing what i wish to do so i can see how its done?
Attachments
douk.love
(2.94 KiB) Downloaded 197 times
Xoria
Citizen
Posts: 61
Joined: Sun Jan 31, 2010 1:24 am

Re: use mouse to move things around

Post by Xoria »

I actually need something like this too. >_>
laconix
Prole
Posts: 4
Joined: Fri Feb 05, 2010 6:19 am

Re: use mouse to move things around

Post by laconix »

So I'm going to assume 3 things, firstly; you want to click on the thing to move to start dragging and secondly; you want thorough explanations. But lastly and most importantly I assume you know how to adapt my solution to fit your needs. :)

Note: Numbers in brackets mean the term is explained at the bottom of the post.
Note: Where I have ellipses in the code I only have them for the sake of brevity.
I also apologise in advance for the wall of text...


Boilerplate code:

Code: Select all

function love.load()

end

function love.draw()

end

function love.update(dt)

end
Alright, so firstly add some global variables and some psuedo-constants:

Code: Select all

--globals
phys, gfx, mouse = nil, nil, nil
ball = {} 
ground = {}
drag = false
--pseudo-contstants
BALL_RADIUS = 50
GRAVITY = 500

function love.load()
...
We will need to know when drag something so we have a boolean (true/false) variable for that, we also know many functions will need access to our ball and the ground so we create variables for them too. For values we may need to tweak we have them declared globally at the top so we can easily change the value without looking through many lines of code, we have 2 here one for the radius of our ball and one for our gravity.

Next we use the love.load() callback to set everything up:

Code: Select all

function love.load()
	--i find it annoying to type love before everything :)
	phys = love.physics
	gfx = love.graphics
	mouse = love.mouse
These first 4 lines are just some code I like to use so I know which modules I'm using and so I don't have to type as much. You could easily swap our phys with love.physics (etc.) wherever present in the code.

Code: Select all

	--create physics world
	world = phys.newWorld(gfx.getWidth()+500, gfx.getHeight()+500)
	world:setGravity(0, GRAVITY)
When we create the physics world we need to set up an area where the physical objects exist, I use the windows height and width and add a few hundred pixels onto them so the world doesn't stop at the very edge of the window. Next we set the worlds gravity, the first argument to setGravity() is the x gravity and the second is the y gravity. X axis goes from x -> n and y axis goes from y -> n. This means to get gravity that pulls downwards we need a positive number. Which is where our GRAVITY pseudo-constant comes in to provide the value.

Code: Select all

	--create the floor
	ground["body"] = phys.newBody(world, 0, gfx.getHeight() - 10)
	ground["shape"] = phys.newRectangleShape(ground.body, gfx.getWidth() / 2, 5, gfx.getWidth(), 10)
Now to create the ground so our ball doesn't fall into oblivion... To create a newBody() we need to first specify what physical world it belongs to (ours is world, conveniently), then we need to specify the X,Y coordinates of the body. Well, we want it flat against the right of the window so we set the X to 0 and we set the Y to the height of the window (which move is to the very bottom of the screen) and then take 10 pixels (which is going to be the height of our rectangle).
We next create the shape of our physical object. We must first specify it's body; ground.body (remember we stored the body in our ground table as 'body'). Then the X,Y offset from the X,Y position of the body; we need to move half the screen across and 5 pixels up as the rectangle is created with 0,0 (the origin) being in the middle of the rectangle, we want it on the top right. Now we need to specify the width and height of the rectangle, which is the width of the screen (so the ground covers the entire bottom of the screen) and 10 pixels high.

Code: Select all

	--create our ball
	ball["body"] = phys.newBody(world, gfx.getWidth() / 2, gfx.getHeight() / 3)
	ball["shape"] = phys.newCircleShape(ball.body, 0, 0, BALL_RADIUS)
	ball.body:setMassFromShapes()
end
You should understand the first 2 lines, if not just look the up in the LÖVE docs. Now what's happening on the 3rd line? We use the function setMassFromShapes() which will automatically choose the best (or at least a very good) mass value for us.

Take a breather, make a cup of tea. Absorb this. If you understand this, awesome, time to move on. If you don't understand it don't hesitate to PM me!

Okay, ready to move on? Before you do, run you program to make sure it works!

Code: Select all

function love.draw()
	gfx.circle("fill", ball.body:getX(), ball.body:getY(), BALL_RADIUS)
	gfx.rectangle("fill", ground.body:getX(), ground.body:getY(), gfx.getWidth(), 10)
end
All were doing here is drawing a circle and rectangle where they should be. You should glance over the documentation for the body object.

Code: Select all

function love.update(dt)
	if drag then
		ball.body:setPosition(mouse.getPosition())
	end
	world:update(dt)
end
We check whether drag is true (if drag then is equivalent to if drag == true then) and if it is we must be dragging the object so we need to make sure the balls position is the same as you mouses position. So we call the setPosition() function belonging to the body object type. It takes 2 arguments X and Y, the getPosition() takes care of both X and Y for us. :D
Next we call the update() function of the world object, it needs to given the amount of passed since it last updated which, handily, the love.update callback gets passed to it.

Code: Select all

function love.mousepressed(x,y,button)
	if button == "l" then
		if ball.shape:testPoint(mouse.getPosition()) then
			drag = true
			ball.body:setMass(0,0,0,0)
		end
	end
end
Now we check if the 'l' (LEFT) mouse button has been click (see the MouseConstant doc page for a list of button constants).
Now for an extremely important bit, testing whether the mouse is over the ball when we click. We use the testPoint() function of the shape object type. We need to pass it the mouses position, if it is we set our global variable drag to true and set the mass of the ball to nothing using the setMass() function belonging to the body object type. The first and second arguments are the X,Y offset from the center of the ball, the 3rd argument is the mass setting this to 0 makes it unaffected by gravity (you may try setting a mass value to see the effect later on) and the last value is rotational inertia (a little advanced for this post).

Almost done! Just one last callback:

Code: Select all

function love.mousereleased()
	if drag then
		drag = false
		ball.body:setLinearVelocity(0,0)
		ball.body:setMassFromShapes()
	end
end
All we are doing here is when the mouse is released we check whether we a dragging the ball (remember that we set drag to true when we are dragging) is we are we set drag to false (meaning we are no longer dragging the ball). The next line will give the ball zero liner velocity when you let go, so it no longer retains any of the velocity it had when you picked it up. setLinearVelocity() takes 2 arguments, the X and Y velocity. This can be useful for making the ball continue travelling in the direction your mouse was moving, maybe you can add this in yourself! And finally we reset the mass to the automatically selected value, done!

Run it! You should have a fully functioning program! Have fun with it!

If yours isn't working have a glance over mine:
draganddrop.love
Completed drag and drop .love file
(1.72 KiB) Downloaded 221 times
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Denver, CO
Contact:

Re: use mouse to move things around

Post by TechnoCat »

I added a mouse throw type thing in.

Code: Select all

--globals
phys, gfx, mouse = nil, nil, nil
ball = {}
ground = {}
drag = false
mx = 0
mxp = 0
my = 0
myp = 0
--pseudo-contstants
BALL_RADIUS = 50
GRAVITY = 500

function love.load()
   --i find it annoying to type love before everything :)
   phys = love.physics
   gfx = love.graphics
   mouse = love.mouse
   --create physics world
   world = phys.newWorld(gfx.getWidth()+500, gfx.getHeight()+500)
   world:setGravity(0, GRAVITY)
   --create the floor
   ground["body"] = phys.newBody(world, 0, gfx.getHeight() - 10)
   ground["shape"] = phys.newRectangleShape(ground.body, gfx.getWidth() / 2, 5, gfx.getWidth(), 10)
   --create our ball
   ball["body"] = phys.newBody(world, gfx.getWidth() / 2, gfx.getHeight() / 3)
   ball["shape"] = phys.newCircleShape(ball.body, 0, 0, BALL_RADIUS)
   ball.body:setMassFromShapes()
end

function love.draw()
   gfx.circle("fill", ball.body:getX(), ball.body:getY(), BALL_RADIUS)
   gfx.rectangle("fill", ground.body:getX(), ground.body:getY(), gfx.getWidth(), 10)
end

function love.update(dt)
	mxp, myp = mx, my
	mx, my = mouse.getPosition()
   if drag then
      ball.body:setPosition(mx,my)
   end
   world:update(dt)
end

function love.mousepressed(x,y,button)
   if button == "l" then
      if ball.shape:testPoint(mouse.getPosition()) then
         drag = true
         ball.body:setMass(0,0,0,0)
      end
   end
end

function love.mousereleased()
   if drag then
      drag = false
      ball.body:setLinearVelocity((mx-mxp)*20, (my-myp)*20)
      ball.body:setMassFromShapes()
   end
end
Xoria
Citizen
Posts: 61
Joined: Sun Jan 31, 2010 1:24 am

Re: use mouse to move things around

Post by Xoria »

Code: Select all

--globals

planet1 = {}

planet1drag = false
--planet1 pseudo-contstants
planet1_RADIUS = 50


function love.load()
  
   

   --create world
   world = love.physics.newWorld(love.graphics.getWidth()+500, love.graphics.getHeight()+500)
   world:setGravity(0, 0)
   
   --create our planet1
    planet1["body"] = love.physics.newBody(world, love.graphics.getWidth() / 2, love.graphics.getHeight() / 3)  planet1["shape"] = love.physics.newCircleShape(planet1.body, 0, 0, planet1_RADIUS)
   planet1.body:setMassFromShapes()
end










function love.draw()
   if love.mouse.isDown("l") then
love.graphics.circle("fill", planet1.body:getX(), planet1.body:getY(), planet1_RADIUS)
   end


 
end


function love.update(dt)
   if planet1drag then
      planet1.body:setPosition(love.mouse.getPosition())
   end
   world:update(dt)
end

function love.mousepressed(x,y,button)
   if button == "r" then
      if planet1.shape:testPoint(love.mouse.getPosition()) then
         planet1drag = true
         planet1.body:setMass(0,0,1,0)
      end
   end
end

function love.mousereleased()
   if planet1drag then
      planet1drag = false
      planet1.body:setLinearVelocity(0,0)

      planet1.body:setMassFromShapes()
   end
end
Here , I intended to click to DRAW the object while still being able to move it around. How do I make this work? I only see the circle if mouse is down.. Also how can I attach an image to the circle?
Post Reply

Who is online

Users browsing this forum: egoal, Google [Bot] and 181 guests