Mouse click

Previous topic - Next topic

AMateus

Hello,

Been using (, and also evaluating buying it for the future) GLBasic free version for prototyping some ideias for sometime now, and today I faced a problem I couldn't solve (or at least not the way I wanted to :P)

The problem is a simple one: You have a sprite on screen (the coordinates and/or size of it depends on the resolution on the given platform) and I need to get the x,y image coordinates of the mouse click. The goals if, of course, to know where, in the image and in a given radius, the user clicked. For example, if you want to code a game of find the differences in the images, how would you know where in the image the user clicked?
Is there some command that returns this info or we must do the common "if click>= boxleft corner and click <= boxrightcorner blablabla" way?!

Thanks in advance.

Regards,
António

ampos

Code (glbasic) Select

drawimage id,xspr,yspr
getmouse mx,my,b1,b2

xrel=mx-xspr
yrel=my-yspr

if xrel>spr_with or yres>spr_heigh then outside=true


There is a ton of solution out there...

ampos

If you are planing it to use the sprite as a menu image and the mouse click to know which option it chose, just check my lib ZONES()

Kitty Hello

either in a box:

Code (glbasic) Select

MOUSESTATE mx, my, a,b
IF a AND BOXCOLL(mx, my, 1,1,    sprite_left, sprite_top, sprite_width, sprite_height)
   clicked()
ENDIF


or with a circle:
Code (glbasic) Select

MOUSESTATE mx, my, a,b
IF a AND in_circle(mx, my, sprite_centerx, sprite_centery, radius)
...
ENDIF

FUNCTION in_circle: x,y, cx, cy, R
   LOCAL dx = cx-x, dy = dy-y
   IF dx*dx + dy*dy < R*R THEN RETURN TRUE // distance = SQR(dx*dx+dy*dy), so we compare to R*R
RETURN FALSE;
ENDFUNCTION



AMateus

Hello,

Thank you for the replies :)

I don't know if I misunderstood the replies or if I didn't explain me well :)

What I wish to know is, is the player clicks in a given image, what were the coordinates he clicked inside the image.

For example I have a image 320x240. I want to know 1) if he clicked in the image (BOXCOLL could be used here) and 2) in what location of that image. So if, let's say, the image is located in 200,300 and I click on 200,300 it should return 0,0.

Sorry if I'm not explaining clearly, but english is not my first language :)

Regards,
António

Minion

Basically youve almost answered it youself with that post.

Yes, use boxcoll would tell you if you hit the sprite, then all you do, as you already know where youve placed the sprite (200,300) is subtract that from the mouse X and mouse Y cords to give you your position on the sprite.

Kitty Hello

Sprites are no objects that you move. It's just a "bitmap" in memory that you "draw" on the screen. You have to know where you do that. So keep a variable for each box/player/enemy...

AMateus

Hello,

@Minion Of course, you're right. Thanks.
The problem i can see with this solution is the variety of screen resolutions. I was thinking of using the sc function posted sometime ago (by ampos?!) where you draw everything to a screen and then resize that screen and show it:) But I would loose the image position this way. Other solution could be to hardcode all the possible image positions yes.

@Kitty yes I understand that thanks. I was looking for a function that could test for a "mouse to sprite/image" collision :)
Nevermind tho, I'll probably hardcode the possible image positions (regarding the current screen resolution)

Thank you all.

Regards,
António

Ian Price

Here's something like you are asking for with TYPEs - click on a square and it will (light up and) tell you how far into the square you are with the mouse pointer (POS_X, POS_Y).

This routine works for images 32x32 - if you want larger/smaller images, then change the size check routine. However, this routine only checks for a square around the sprite - if the sprite is a different shape then it will still bring up a positive result if the mouse is within the boundaries of the square of your chosen dimension.

Code (glbasic) Select

SETSCREEN 640,480,0

// Mouse state
GLOBAL mx,my,b1,b2

// Sprite/mouse difference
GLOBAL diff_x, diff_y

GLOBAL sprite[] AS Tsprite

SYSTEMPOINTER TRUE

// Run main function
main()


// Sprite TYPE
TYPE Tsprite
x
y
ENDTYPE


// Main function
FUNCTION main:

// Mouse position storage varaibles
LOCAL pos_x, pos_y


// Create 50 sprites randomly on screen
FOR n=0 TO 49
create_sprite(RND(640),RND(480))
NEXT


// Loop unti ESC pressed
WHILE TRUE

// Get mouse position and button status
MOUSESTATE mx,my,b1,b2

// Get mouse position and store it
IF b1
pos_x=mx
pos_y=my
ENDIF

// Draw all sprites
render_sprite()

PRINT "MOUSE POSITION="+mx+","+my,10,10
PRINT "MOUSE CLICK="+pos_x+","+pos_y,10,30
PRINT "DIFFERENCE BETWEEN MOUSE/SPRITE="+diff_x+" "+diff_y,10,50

SHOWSCREEN

WEND

ENDFUNCTION



// Create sprite
FUNCTION create_sprite: x,y

LOCAL s AS Tsprite

  s.x=x
  s.y=y

DIMPUSH sprite[],s

ENDFUNCTION


// Draw sprite
FUNCTION render_sprite:

FOREACH s IN sprite[]

  DRAWRECT s.x,s.y,32,32,RGB(255,0,255)

// Checks to see if mouse pointer is within sprite boundary (32x32) in this case - if it is, then draw a coloured rect
  IF b1 AND mx>s.x-1 AND mx<s.x+32 AND my>s.y-1 AND my<s.y+32
   DRAWRECT s.x, s.y,32,32,RGB(255,0,0)

   diff_x=ABS(s.x-mx)
   diff_y=ABS(s.y-my)
  ENDIF

NEXT

ENDFUNCTION
I came. I saw. I played.

Slydog

#9
QuoteI was looking for a function that could test for a "mouse to sprite/image" collision

The problem is that a 'sprite' isn't located anywhere, it is just a pointer to an image in memory.
When you use the 'DRAWSPRITE' command, you just tell it where to place a copy of that sprite image on the screen.
The sprite isn't considered 'located' at that position.

To better clarify this, consider that it is possible, in the same frame, to draw one sprite in multiple locations.
Where would the sprite be located in this situation?
This is handy for drawing tile maps, you don't need a new sprite for every occurrence of a 'wall' tile, just draw that same wall sprite at every location you need to.

You need to manage mouse clicks and such in code by remembering where you placed all of your sprites (and how large they are!).
I'd start by creating a general 'TSprite' custom TYPE that stores the position and size, plus functions for drawing, and testing for mouse clicks, such as TSprite.IsMouseDown() or something.  This nice thing about this is that when you want faster sprites you can update the TYPE to use POLYVECTORs for displaying instead, and your other code using TSprite doesn't need to change.

I hope this helps.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

AMateus

Hello,

Thank you all for the clarifications and for the code.

I'll post the code when I'm done to benefit all :)

Regards,
António

matchy

To lessen the confusion (and I guess help a little) between sprite image data versus plotting data, replace the sprite bmp with drawrect for now, instead of a drawsprite and stretchsprite as they are irrelevant for a mouse click.