(2D) Selecting and dragging an object with mouse

Blitz3D Forums/Blitz3D Beginners Area/(2D) Selecting and dragging an object with mouse

smokingkipper(Posted 2005) [#1]
hey all

I have created a few boxes on screen via a Type and I want to be able to select them with my mouse cursor and while my left mouse button is held down, be able to drag them to another location.

I have got this working to some extent by testing for a collision with my cursor image and my box image, and if True then setting the box X,Y to equal the cursor image X,Y until I release the mouse button. However if I move the mouse around at a reasonably quick pace, the mouse cursor breaks free from the box image and so the collision test fails.

After spending quite some time on this (real newbie here :op ) I have decided to ask for some help...Maybe there is a more elegant solution instead of using the image collision function?

I have tried avoiding the collision function call and just testing to see if...

mouseX() > imgBoX and (mouseX() < (imgBoX+imgSize)
mouseY() > imgBoY and (mouseY() < (imgBoY+imgSize)

but the result is much the same

then I tried to make sure the mouseX() and mouseY() never stray too far from the Box image centre by bringing them back a few pixels if the cursor image moves too far from the Box images centre.

I hope I am being clear.

Anyway, any help with this would be appreciated..cheers guys.


n8r2k(Posted 2005) [#2]
I am not sure what you are doing exactly but you can try out my example of clicking and dragging in the code archivies at http://www.blitzbasic.com/codearcs/codearcs.php?code=1315 right now its not commented, so just post if you need help.


BobR3D(Posted 2005) [#3]
Don't keep on testing for collisions or congruency (overlapping) WHILE you're dragging... you've already detected that the mouse cursor was over the rectangle when you clicked the button.

Just set the rectangle's origin point equal to the mouseX and mouseY every loop, and the rectangle will ALWAYS be drawn at the mouse pointer. The rectangle will essentially move at the same speed as you're moving the mouse- fast or slow.

Once you detect that the mouse button has been released, draw the rectangle at the final MouseX and MouseY location and THEN start detecting collision again.



If you want the rectangle to "follow" the mouse pointer, but move at a constant speed, then you'll have to use a "waypoint" method.

Every loop you'll have to set the destination waypoint for the rectangle to be the MouseX and MouseY, and move the rectangle toward that point at its constant speed.

Since you're still detecting the mouse button is held down, you won't need to check for collision, just keep moving the rectangle toward the mouse pointer, whereever it may be, UNTIL the mouse button is released, and THEN stop updating the waypoint, so the last waypoint will be the mouseX and mouseY when the button was released.

Keep moving the rectangle toward the last waypoint until it reaches that point and THEN start detecting collisions again.


Ross C(Posted 2005) [#4]
Here's some code i did for someone a while back for this.

Graphics 800,600




pointer=CreateImage(2,2)
SetBuffer ImageBuffer(pointer)
Color 140,140,180
Rect 0,0,2,2,1
Color 255,255,255

image=CreateImage(10,10)
SetBuffer ImageBuffer(image)
Rect 0,0,10,10,1
ix=300
iy=300

cx=0;offset for dragging
cy=0;offset for dragging

SetBuffer BackBuffer()

While Not KeyHit(1)
Cls

	If MouseDown(1) Then
		If ImagesOverlap(pointer,MouseX(),MouseY(),image,ix+cx,iy+cy) And drag=0 Then
				drag=1
				cx=ix-MouseX()
				cy=iy-MouseY()
		End If
	Else
		drag=0
		ix=ix+cx
		iy=iy+cy
		cx=0
		cy=0
	End If
	
	
	If drag=1 Then
		ix=MouseX()
		iy=MouseY()
	End If
	
	
	DrawImage image,ix+cx,iy+cy
	DrawImage pointer,MouseX(),MouseY()
	Flip
Wend