Sprite point to cursor

Advanced game related topics
Blankname
Enthusiast
Enthusiast
Posts: 120
Joined: Sun Oct 14, 2012 9:11 am

Sprite point to cursor

Post by Blankname »

I'm writing my first game in PB :D and this kind of math in PB isn't my strong side. I am wondering how to calculate the angle for RotateSprite3D() based on the players current position (using Player\x and Player\y) and the mouses current position (MouseX() and MouseY()). This is for a 2D top down shooter (using 3D sprite for rotate all is fine except the angle). I am also trying to keep this so it will work regardless to the screen resolution (using #Setting_Resolution_X for width and #Setting_Resolution_Y for height).

Thanks!
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Sprite point to cursor

Post by luis »

The difference between the two points gives you a vector, this is the distance between the two points, if you need it.
Then you calc the slope of the line passing through the two points.
The arcotangent of the slope is the angle (direction) of the vector.
Look on internet for a course on 2d vectors (it's easy stuff, don' be alarmed), coding the answer by yourself would be better and you'll learn something you can use again in the future :wink:

This is very nice (skip the matrices and read only the vectors parts) -> http://programmedlessons.org/VectorLessons/
"Have you tried turning it off and on again ?"
Blankname
Enthusiast
Enthusiast
Posts: 120
Joined: Sun Oct 14, 2012 9:11 am

Re: Sprite point to cursor

Post by Blankname »

luis wrote:The difference between the two points gives you a vector, this is the distance between the two points, if you need it.
Then you calc the slope of the line passing through the two points.
The arcotangent of the slope is the angle (direction) of the vector.
Look on internet for a course on 2d vectors (it's easy stuff, don' be alarmed), coding the answer by yourself would be better and you'll learn something you can use again in the future :wink:

This is very nice (skip the matrices and read only the vectors parts) -> http://programmedlessons.org/VectorLessons/
Not helping me much, I have never done any kind of graphic programming. I know I have to use ATan() and that's about it, I can code any desktop software. I'm just new to 2D/3D game programming. It would be ten times more beneficial to me (for me) if someone could post an example of what I am trying to do (would help if using the variables and constants I posted above). Some people like reading hours of material to learn how to do a single thing, I am not like that. I have a photographic memory when it comes to learning. Meaning once I see how its done, I will know how its done for future use (also leads to learning how to improve/modify it). Below is an example of what I am trying to do, update the angle on mouse movement so the sprite can be rotated every frame (smooth and precise aim). I recon I would need to be using this same angle for drawing my bullets as well (one step at a time, I can most likely figure that out on my own). Tho it may look like I got it down pat, my game doesn't no where function as I intend. The picture is to only give you reference of the type of angle calculation that I need (from player x\y to crosshair x\y).

Image
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Sprite point to cursor

Post by Comtois »

may be this can help ?

Code: Select all

;PB 4.02 6 mai 2007
;updated for 5.11

EnableExplicit ; Force la déclaration de toutes les variables 

Structure Vecteur
  x.f
  y.f
EndStructure


;Declare les procédures
Declare Norme(*V.Vecteur)

;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris. 
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D. 
InitSprite3D() 
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
ExamineDesktops()
OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"Tut Sprite3D et Souris")

;-Déclaration des variables
Define Angle, dist, Vitesse.f = 3
Define.Vecteur Direction, Sprite, Destination

Macro DISTANCE(p1, p2)
  Sqr((p1\x - p2\x) * (p1\x - p2\x) + (p1\y - p2\y) * (p1\y - p2\y))
EndMacro

;Creation d'une texture
CreateSprite(0,64,64,#PB_Sprite_Texture)

;On dessine un triangle plein dans la texture
StartDrawing(SpriteOutput(0))
LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0))
LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0))
StopDrawing()

;Creation d'un sprite3D utilisant la texture définie précédemment 
CreateSprite3D(0,0)

;Sprite pour la souris
CreateSprite(1,5,5)
StartDrawing(SpriteOutput(1))
Box(0,0,5,5,RGB(0,255,0))
StopDrawing() 

Repeat
  ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
  ;La partie invisible du buffer remplace alors complètement La partie visible. 
  FlipBuffers()
  
  ;Efface l'écran courant avec la couleur specifiée. 
  ClearScreen(RGB(0,0,100))
  
  ;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes 
  ;KeyboardInkey(), KeyboardPushed() et KeyboardReleased(). 
  ExamineKeyboard()
  
  
  ;Destination 
  If ExamineMouse()
    Destination\x = MouseX()
    Destination\y = MouseY()
  EndIf
  
  ;Direction
  Direction\x = Destination\x - Sprite\x 
  Direction\y = Destination\y - Sprite\y
  Angle=Degree(ATan2(Direction\x, Direction\y))
  Norme(@Direction)
  
  ;Deplacement sprite
  dist = DISTANCE(Destination, Sprite)
  
  If dist < Vitesse
    Sprite\x + Direction\x * dist
    Sprite\y + Direction\y * dist   
  Else 
    Sprite\x + Direction\x * Vitesse
    Sprite\y + Direction\y * Vitesse
  EndIf
  
  ;Affiche le sprite 3D
  If Start3D()
    DisplaySprite3D(0, Sprite\x, Sprite\y)
    RotateSprite3D(0,Angle,0)
    Stop3D()
  EndIf    
  
  ;Affiche la souris
  DisplaySprite(1, Destination\x, Destination\y)
  
Until KeyboardPushed(#PB_Key_Escape)
End

Procedure Norme(*V.Vecteur)
  Define.f Norme
  
  Norme.f = Sqr(*V\x * *V\x + *V\y * *V\y)
  If Norme 
    *V\x / Norme
    *V\y / Norme
  EndIf
EndProcedure 
Please correct my english
http://purebasic.developpez.com/
Blankname
Enthusiast
Enthusiast
Posts: 120
Joined: Sun Oct 14, 2012 9:11 am

Re: Sprite point to cursor

Post by Blankname »

Comtois wrote:may be this can help ?

Code: Select all

;PB 4.02 6 mai 2007
;updated for 5.11

EnableExplicit ; Force la déclaration de toutes les variables 

Structure Vecteur
  x.f
  y.f
EndStructure


;Declare les procédures
Declare Norme(*V.Vecteur)

;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier. 
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris. 
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D. 
InitSprite3D() 
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur. 
ExamineDesktops()
OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"Tut Sprite3D et Souris")

;-Déclaration des variables
Define Angle, dist, Vitesse.f = 3
Define.Vecteur Direction, Sprite, Destination

Macro DISTANCE(p1, p2)
  Sqr((p1\x - p2\x) * (p1\x - p2\x) + (p1\y - p2\y) * (p1\y - p2\y))
EndMacro

;Creation d'une texture
CreateSprite(0,64,64,#PB_Sprite_Texture)

;On dessine un triangle plein dans la texture
StartDrawing(SpriteOutput(0))
LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0))
LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0))
StopDrawing()

;Creation d'un sprite3D utilisant la texture définie précédemment 
CreateSprite3D(0,0)

;Sprite pour la souris
CreateSprite(1,5,5)
StartDrawing(SpriteOutput(1))
Box(0,0,5,5,RGB(0,255,0))
StopDrawing() 

Repeat
  ;Inverse le buffer d'arrière plan avec le buffer visible à l'écran. 
  ;La partie invisible du buffer remplace alors complètement La partie visible. 
  FlipBuffers()
  
  ;Efface l'écran courant avec la couleur specifiée. 
  ClearScreen(RGB(0,0,100))
  
  ;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes 
  ;KeyboardInkey(), KeyboardPushed() et KeyboardReleased(). 
  ExamineKeyboard()
  
  
  ;Destination 
  If ExamineMouse()
    Destination\x = MouseX()
    Destination\y = MouseY()
  EndIf
  
  ;Direction
  Direction\x = Destination\x - Sprite\x 
  Direction\y = Destination\y - Sprite\y
  Angle=Degree(ATan2(Direction\x, Direction\y))
  Norme(@Direction)
  
  ;Deplacement sprite
  dist = DISTANCE(Destination, Sprite)
  
  If dist < Vitesse
    Sprite\x + Direction\x * dist
    Sprite\y + Direction\y * dist   
  Else 
    Sprite\x + Direction\x * Vitesse
    Sprite\y + Direction\y * Vitesse
  EndIf
  
  ;Affiche le sprite 3D
  If Start3D()
    DisplaySprite3D(0, Sprite\x, Sprite\y)
    RotateSprite3D(0,Angle,0)
    Stop3D()
  EndIf    
  
  ;Affiche la souris
  DisplaySprite(1, Destination\x, Destination\y)
  
Until KeyboardPushed(#PB_Key_Escape)
End

Procedure Norme(*V.Vecteur)
  Define.f Norme
  
  Norme.f = Sqr(*V\x * *V\x + *V\y * *V\y)
  If Norme 
    *V\x / Norme
    *V\y / Norme
  EndIf
EndProcedure 
Thanks this will help a lot. :mrgreen:
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Sprite point to cursor

Post by luis »

Blankname wrote:Some people like reading hours of material to learn how to do a single thing, I am not like that.
You would learn to do a lot more than a single thing, how all fits together, and how to build upon that.
It pays off later on.

Code: Select all

Structure XY 
 X.f
 Y.f
EndStructure
  
Procedure V2_VectorFromPoints (*p1.XY, *p2.XY, *vout.XY)
 *vout\X = *p2\X - *p1\X
 *vout\Y = *p2\Y - *p1\Y
EndProcedure

Procedure.f V2_GetLength (*v.XY)
 ProcedureReturn Sqr((*v\X)*(*v\X) + (*v\Y)*(*v\Y))
EndProcedure

Procedure.f V2_GetAngle (*v.XY)
 Protected fAngle.f = Degree(ATan(*v\Y / *v\X))
 
 If *V\X < 0.0 And *V\Y > 0.0
    ; Quadrant II
    fAngle = 180.0 + fAngle 
 ElseIf *V\X < 0.0 And *V\Y < 0.0
    ; Quadrant III
    fAngle = 180.0 + fAngle 
 ElseIf *V\X > 0.0 And *V\Y < 0.0
    ; Quadrant IV
    fAngle = 360.0 + fAngle 
 EndIf
     
 ProcedureReturn fAngle 
EndProcedure


; EXAMPLE

Define you.XY ; your position
Define target.XY ; the target position
Define V.XY ; the vector from the two points

you\x = 100
you\y = 100

target\x = 150
target\y = 150

V2_VectorFromPoints (@you, @target, @V)
Debug V2_GetLength (@V)
Debug V2_GetAngle (@V)
You can customize the angle origin (the zero) as you prefer, or squeeze all in one proc and optimize it.
I put it this way for clarity.

EDIT (two weeks later): Oh, don't mention it.
"Have you tried turning it off and on again ?"
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Sprite point to cursor

Post by em_uk »

Thanks for the code guys. I'm currently trying to put together a game but have never used techniques likes this.

The last "game" I wrote was on a Spectrum 128K +2, in BASIC and it was rubbish.

Math is not my strong point and there are huge gaps in my knowledge (I had a terrible school growing up, my History teacher would smoke and drink beer in our class just to give you the picture) so I'm trying to learn as much as I can.

I would never have thought of using code like this before, but the more I read and study the more I can feel my brain catching on.

Really appreciate it ;)
----

R Tape loading error, 0:1
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Sprite point to cursor

Post by luis »

em_uk wrote: I would never have thought of using code like this before, but the more I read and study the more I can feel my brain catching on.
It's one the best sensations I know :)

Thanks.
"Have you tried turning it off and on again ?"
Post Reply