-
getting direction
im making a game were the player is in the center of the map
and shoots.
for now i only shoot straight ahead of the player that is the bullets xpos and the players xpos are the same.
i was thinking to change this so that you can shoot using the mouse and in 360 degrees instead.
how can i get the direction of the mouse so the bullets go in the same direction that the mouse is pointing?
-
do you know any trigonometry? if you don't, learn about sin/cos/tan stuff and also arctan, for sure, with those equations you can easily figure out the angle to rotate at
what i would use is just:
arctan((mouse.y-player.y)/(mouse.x-player.x))
and that will give you the angle in radians that you need to shoot at, then once you have that angle, just apply that to the shooting direction, and voila
or you could just have bullet.yvel=mouse.y-player.y; bullet.xvel=mouse.x-player.x;
and that would give you the same effect, but faster and easier :)
-edit-
oh yah, don't forget to scale the velocity, and if you aren't in ortho coordinates, you'll need to convert the position of the ship (i'm guessing it's in the center, so it would always be at x=screenx/2; y=screeny/2;) and then go off that, otherwise if you're in ortho, just do the above equation and that'll work fine
-
First get the mouse coords from the DIMOUSESTRUCT in DirectX.
I will use mouse.x and mouse.y here.
This code is nearly the same as another post in this game programming section - in fact it is only about 2 or 3 posts down from this one.
Don't use sin cos or tan to do this. There is an easier way to extract the x and y increments. Simply subtract the two vectors and then normalize them. This does require the use of square root which is slow, but cos sin and tan will not execute at lightspeed either, and arctan inherently requires the use of sqrt. So logically since we will take a hit using arctangent we might as well take a hit using normalization.
Code:
int diffx=mouse.x-player.x;
int diffy=mouse.y-player.y;
int totaldist=sqrt((diffx*diffx)+(diffy*diffy));
double xincrement=(double)diffx/(double)totaldist;
double yincrement=(double)diffy/(double)totaldist;
bullet.x+=(xincrement*bullet.speed);
bullet.y+=(yincrement*bullet.speed);
And if you don't like the sqrt function here is an approximation function that has an error of about 3.5%. Because of this the bullets might not track directly to the mouse pointer, which is why I would not use it.
Code:
#define MIN(a,b) (if (a<b)?a:b)
int FastDist2D(int diffx,int diffy)
{
int mn=MIN(diffx,diffy)l
return (x+y-(mn>>1)-(mn>>2)+(mn>>4))
}
...
...
int diffx=mouse.x-player.x;
int diffy=mouse.y-player.y;
int totaldist=FastDist2D(diffx,diffy);
double xincrement=(double)diffx/(double)totaldist;
double yincrement=(double)diffy/(double)totaldist;
bullet.x+=(xincrement*bullet.speed);
bullet.y+=(yincrement*bullet.speed);
-
thanks to you both btw i changed the ship to a little soldier instead casue i played a game a while ago named soldat you may have heard of it, its really cool i fixed the shooting.
i use allegro btw.
but one small problem remains:
when i move the player the bullets still are at the same position
i tried to fix it and update the bullets pos to the players pos
it works the bullets are fired from the players pos but still when it its supposed to hit a wall it thinks that youre shooting from the original spawn position so if there is a wall at for example 32 pixels left of the player at the spawn it collides correctly but say you move the player to the right a bit and shoot at left the bullets still go 32 pixels and think there is a wall there.
do you get this?
let me know if you want to see some code
thanks
-
Gonna need some code or a program example on that one. You lost me.
-
ok here is the code
Code:
#include <allegro.h>
#include <math.h>
#include <time.h>
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "alleg.lib")
#define MAPSIZE 30
#define GRID_WIDTH 15
#define GRID_HEIGHT 15
#define TILE_SIZE 32
#define MAX_BULLET 200
#define PLSPEED 6
#define GRAV 9.82
#define TILE_T 1
#define TILE_W 0
#define MAX_FUEL 100
float cx;
float cy;
int level[MAPSIZE][MAPSIZE]={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0},
{0,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
{0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
BITMAP*front[1];
BITMAP* player;
BITMAP *buffer;
BITMAP *skott1;
void drawMap( BITMAP *bmp );
volatile long speed_counter = 0;
void increment_speed_counter();
int pos(int x, int y)
{
return level[(y/TILE_SIZE)][(x/TILE_SIZE)%MAPSIZE];
}
float getangle(int musx,int musy,float xpos,float ypos)
{
float angle;
angle=atan2(ypos-musy,xpos-musx);
return angle;
}
int main()
{
allegro_init();
install_timer();
if(!install_mouse())
{
allegro_message( "error mouse\n % s\n" , allegro_error );
}
install_keyboard();
set_color_depth(16);
if( set_gfx_mode(GFX_AUTODETECT,480,480,0,0)<0)
{
allegro_message( "error gfx\n % s\n" , allegro_error );
if(set_gfx_mode(GFX_SAFE,480,480,0,0)<0)
{
allegro_message( "error gfxsafe\n % s\n" , allegro_error );
}
}
front[TILE_T]=load_bitmap("wall.bmp",0);
front[TILE_W]=load_bitmap("bg.bmp",0);
player=load_bitmap("pla.bmp",0);
buffer=create_bitmap(640,480);
float n=10.0;
float x=0;
float y=0;
float px=0;
float py=0;
float skottx;
float skotty;
float skottang;
float ang;
int fuel=MAX_FUEL;
int time=0;
time=clock();
int fired = 0;
px=240;
py=240;
while(!key[KEY_ESC])
{
(mouse_y>240)?(n++):n--;
ang=getangle(mouse_x,mouse_y,px,py);
//textprintf(screen,font,40,90,makecol(255,255,255),"%i",fuel);
//textprintf(screen,font,40,100,makecol(255,255,255),"%i",time);
if(mouse_b & 2&&mouse_y<py&&mouse_x<(px+50)&&mouse_x>(px-50)&&fuel>=0)
{
fuel--;
py-= PLSPEED *sin(ang);
}
if(fuel<=0)
{
time++;
if(time>120)
{
time=0;
fuel=MAX_FUEL;
}
}
if(mouse_b & 1&&!fired)
{
fired=1;
skottx=px;
skotty=py;
skottang = atan2(skotty - mouse_y , skottx - mouse_x);
}
if(fired)
{
skottx-=5 *cos(skottang);
skotty-=5 *sin(skottang);
if(pos((int)skottx,(int)skotty)==1) // or x see the difference?
fired=0;
}
if(pos(x,y+32)==0)
{
py++;
}
if(key[KEY_RIGHT]&&pos(x+31,y)==0)
{
cx+=4;
}
if(key[KEY_LEFT]&&pos(x-1,y)==0)
{
cx-=4;
}
textprintf(screen, font, 0, 0, 255, "X: %5d Y: %5d", mouse_x, (int)py);
x=cx +px;
y=cy +py;
putpixel(screen,mouse_x,mouse_y,700);
poll_mouse();
clear_bitmap(buffer);
drawMap( buffer );
if(fired)
{
circlefill(buffer,(int)skottx,(int)skotty,3,makecol(255,0,0));
}
draw_sprite(buffer,player,px,py);
show_mouse(screen);
blit(buffer,screen,0,0,0,0,640,480);
}
destroy_bitmap(front[0]);
destroy_bitmap(front[1]);
destroy_bitmap(buffer);
remove_mouse();
allegro_exit();
return 0;
}//main
END_OF_MAIN()
void drawMap( BITMAP *bmp )
{
for ( int i = 0; i < 30; i++ )
{
for ( int j = 0; j < 30; j++ )
{
int p =pos(i*TILE_SIZE+cx,j*TILE_SIZE+cy);
blit( front[p], buffer, 0, 0, ( i * 32 ) - ( (int)cx % 32 ), ( j * 32 ) - ( (int)cy % 32 ), 32, 32 );
}
}
}
and the pics are attached too