Advertisement

Accelerating towards mouse cursor

Started by June 15, 2003 03:02 PM
7 comments, last by witty 21 years, 8 months ago
Right, I am writing a game where the player plays as this ball that flys around and shoots ships with lasers (I know it sounds lame, but I''m doing it to learn my way around SDL) I''m using SDL on Linux and have hit (another) brick wall.What I need to do is have this ball accelerate towards the mouse cursor when the button is pressed at a uniform acceleration. I have the mouse code working and the pointer is visible on screen, but I can''t figure out how to work out the velocities. For the player, I have the x and y position on screen, and the x,y velocity. I also have the x and y position of the mouse on screen. Using these variables, what do I need to do in order to make the player zoom towards the pointer when the button is pressed? I can post the code I have at the moment, but I haven''t even implemented alpha channels and it doesn''t clean up after blits and I don''t want to get laughed at on my first attempt.
here''s the code if it will help.
/* These header files are needed */#include "SDL/SDL.h"#include "stdio.h"#include "stdlib.h"int main() {   SDL_Surface *screen;   SDL_Surface *image;   SDL_Surface *mouse;   SDL_Rect rect, dest;   int x,y, yvel, xvel, gravity, count, gcount, mousex, mousey, tangent;   Uint8 buttons;  /* Initialise the video subsytem       */  /* If it returns a non-null value, die */   if (SDL_Init(SDL_INIT_VIDEO) != 0)    {       printf("Unable to initialise SDL: %s\n",SDL_GetError());      return 1;    }/* Make sure the program exits cleanly */atexit(SDL_Quit);/* Set 800x600 windowed mode */screen = SDL_SetVideoMode(800,600,16,0);if (screen==NULL) {printf("Unable to set video mode: %s\n",SDL_GetError());return 1;}x = 5;y = 5;yvel = 0;xvel = 5;gravity = 3;rect.x = 0;rect.y = 0;rect.w = 78;rect.h = 78;dest.x = 0;dest.y = 0;dest.w = 64;dest.h = 64;image = SDL_LoadBMP("ball.bmp");mouse = SDL_LoadBMP("pointer.bmp");for(gcount=0;gcount<200;gcount++) {for(count=0;count<5;count++) {if (x+xvel > (800-78)) {		    xvel = 3-(xvel);		    x=(800-78); 		    printf("bounce"); }if (y+yvel > (600-78)) {		    yvel = 0-(yvel-3);		    y=(600-78);		    printf("bounce");}if (x+xvel <0) {		    xvel = 3-xvel;		    x=0; 		    printf("bounce");}if (y+yvel < 0) {		    yvel = 0;		    y=0;		    printf("bounce"); }		    x+=xvel;y+=yvel;dest.x=(int)x;dest.y=(int)y;SDL_PumpEvents();buttons = SDL_GetMouseState(&mousex,&mousey);// I''ve forgotten how I was going to do this.//if(buttons && SDL_BUTTONS(1) != NULL) {//	tangent = (mousey-y)/(mousex-x);//	//	} rect.w = 78;rect.h = 78;SDL_BlitSurface(image,▭,screen,&dest);dest.x=mousex;dest.y=mousey;rect.w=50;rect.h=50;SDL_BlitSurface(mouse,▭,screen,&dest);SDL_UpdateRect(screen,0,0,0,0);}yvel+=gravity;}SDL_Delay(3000);/***************************************//**    SDL Graphics init complete     **//***************************************/printf("Graphics subsystem initialised\n");printf("Quitting...\n");return 0; } 

Its messy I know, but you should be able to get the basic gist of it.
Advertisement
You said it yourself: have the ball accelerate toward the mouse. The direction of the acceleration vector is the same as the director of the vector (mouse)-(ball). I didn't actually read the code, so if you are having a different problem, sorry, and hang on, I'll read the code eventually.

edit: are you having problems with making the acceleration work? You should have an "update" segment of code where the positions are incremented by v*dt. In that segment, you also increment the velocity by a*dt.

[edited by - vanillacoke on June 15, 2003 7:01:05 PM]
You know what I never noticed before?
But HOW?
I can get the gradient to accelerate along with (mouse.y-player.y)/(mouse.x-player.x) but how do I make it accelerate at the angle in a uniform way.
        /M Mouse       / |      /  |   z /   |    /    |y   /     |  /      | /       |P________|Player  x  

I want it to go at a steady speed up the line marked z. I could do it by going along the bottom say 2 pixels/frame and working out what the y position would be, but depending on the gradient of the line z, the speed wouldn't be constant and may even lead to some really big jumps (ie if the mouse was clicked above the player, the gradient of z would be infinite, and the program would crash due to a division by zero.
The actual code is somewhat irrelevant, as I will chop that about once I have the algorithms I need, this was just for testing the blitting and gravity code, Pretty much all of the code I'm working on now will end up in the update() routine of the player's object.

[edited by - witty on June 16, 2003 6:28:40 AM]
I forgot o say, I want it so that the acceleration of the ball doesn't depend on the distance of the mouse from the object, just the angle.

[edited by - witty on June 16, 2003 6:30:52 AM]
here's some code:
int playerX=...;int playerY=...;int VelX=...;int VelY=...;int MouseX=...;int MouseY=...;int len=sqrt((playerX-MouseX)*(playerX-MouseX)+(playerY-MouseY)*(playerY-MouseY));if(len!=0){   VelX=(MouseX-playerX)/len;   VelY=(MouseY-playerY)/len;}

note: the above algo does not take into effect momentum. btw if you want to know what i did i simply normalized the vector that points from the player to the mouse :D



doh, nuts. Mmmm... donuts
My website

[edited by - brassfish89 on June 16, 2003 10:55:03 PM]
You can't have "steady speed" and acceleration. What exactly are you trying to do? If you haven't read about vectors, you should do so. You never need to store angles (which is what I think you mean by gradient) if you use vectors.

Are you SURE that you want the acceleration to depend on the angle? I ask because that doesn't really make any sense

[edited by - vanillacoke on June 17, 2003 1:27:57 AM]
You know what I never noticed before?
Advertisement
What I think he''s aiming at is some sort of cap as to how fast the ball can move. Easily fixed with friction though.

You don''t seem to be using a vector class. Do create one or use google to find a good one. It really makes the vector math a lot easier/more beautiful

To the acceleration matter, simply do:
vAcceleration = (vMouseposition - vPlayerposition).Normalize() * k

And accounting for friction(which in this case is drag), add something like this below:
vAcceleration -= vVelocity * µ

Then tweak the value of k and µ ''till you get some nice result.
delete this;
Right I fixed it myself, actually using the method:
void playerclass::update_player() { int mx, my; double h, fy, fx; if (mouseinput.button1) { /* work out the X,Y distances between the ball + mouse*/   mx=mouseinput.x_pos-X;   my=mouseinput.y_pos-Y;/* Work out the hypotanuse for use in trig functions*/   h=sqrt((mx*mx)+(my*my));/* Vertical component = V sin(x) (V= Velocity)*//* Sin(x) = Opposite/Hypotanuse */   dY+=ACCELERATION * (my/h);/* Horizontal component = V cos(x) (V= Velocity, x= angle)*//* cos(x) = adjacent/Hypotanuse */   dX+=ACCELERATION * (mx/h);   }if(check_collisions()) return; X+= (float) dX; Y+= (float) dY; /* Make the ball accelerate towards the mouse when LMB is pressed*/ /* Gravity - What goes up, must come down */dY+= GRAVITY;    return;} 

I wanted the acceleration to be independent of the angle. I was doing some physics homework and came across a question where I needed to work out the horizontal and vertical components of a projectile being fired at an angle and speed, these equations immediately came to mind:
horizontal=v*cos(x)
vertical=v*sin(x)
well, the cosine and sine could easily be done with a bit of trig (sine=o/h, cos=a/h) so I wrote this and it worked. Thanks for posting your replys though.
I believe this is the same sort of question as was asked in this thread (Exact Angle Between 2D Points ATAN2 ?).

If you wish to get a vector in a direction from one point to another point, and you wish for that vector to be a constant magnitude (length), then the easiest way to do this is like so: (I will cut n paste my answer from the above thread, which solves this for an enemy ship firing a bullet at a specific speed S directly towards the player's ship):

Px = player's x coordinate
Py = player's y coor.

Ex = enemy's x coor
Ey = you know

S = rate of movement of bullet / frame

Dx = Px-Ex (difference in x)
Dy = Py-Ey (difference in y)

Dmag = sqrt( Dx ^ 2 + Dy ^ 2) (distance enemy is from player)

Now, here's the cool part:

Vx = Dx / Dmag * S
Vy = Dy / Dmag * S

Vx,Vy = the x and y increment rates of the bullet / frame.


Although this is calculation a speed, you can use the same formula to calculate a velocity. Again, this value is S in the above method. Also note that there is a division by 0 if both coordinates are the same.

Jason Doucette - online resume page: www.jasondoucette.com
projects / games, real-time graphics, artificial intelligence, world records, wallpapers / desktops / backgrounds
"Great minds discuss ideas, average minds discuss events, small minds discuss people." - Anna Eleanor Roosevelt, 1884-1962

[edited by - Jason Doucette on June 21, 2003 9:06:15 PM]
Jason Doucette / Xona.comDuality: ZF — Xbox 360 classic arcade shmup featuring Dual Play

This topic is closed to new replies.

Advertisement