# venonumuis

Member

4

1 Neutral

• Rank
Newbie

• Interests
Design
1. ## [SDL] shoot bullet projectile toward mouse position by calculating angle

ok thanks for the links, this is big so i'll come back when i understand better vector knowledge and get some help
2. ## [SDL] shoot bullet projectile toward mouse position by calculating angle

there is a most basic version #include <iostream> #include <SDL.h> #include <math.h> using namespace std; #define PI 3.14159265 #define WIDTH_SCREEN 640 #define HEIGHT_SCREEN 480 int main( int argc, char * argv[] ) { int speed = 60; bool left_m=0; SDL_Rect bullet = {300,200,12,12}; SDL_Init(SDL_INIT_VIDEO); SDL_Window *window; SDL_Renderer *renderer; SDL_CreateWindowAndRenderer(WIDTH_SCREEN,HEIGHT_SCREEN,SDL_WINDOW_RESIZABLE,&window,&renderer); SDL_Texture* bgd1 = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,WIDTH_SCREEN,HEIGHT_SCREEN); while(1) { SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type==SDL_QUIT) return 0; if (e.type==SDL_MOUSEBUTTONDOWN) { switch(e.button.button){ case SDL_BUTTON_LEFT: left_m=true; break;}}} int x, y; SDL_GetMouseState( &x, &y ); const Uint8 *state = SDL_GetKeyboardState(NULL); if (left_m) { bullet.x += speed*(cos(atan2(y-200, x-300))); bullet.y += speed*(sin(atan2(y-200, x-300))); } if (bullet.x<=0||bullet.x>=WIDTH_SCREEN|| bullet.y<=0||bullet.y>=HEIGHT_SCREEN) { left_m=0; bullet.x=300; bullet.y=200; } SDL_SetRenderTarget(renderer, bgd1); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); SDL_RenderFillRect(renderer, &bullet); SDL_SetRenderTarget(renderer, NULL); SDL_RenderCopy(renderer, bgd1, NULL, NULL); SDL_RenderPresent(renderer); SDL_Delay(10); } SDL_DestroyTexture(bgd1); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } like i said i copied what i founded in several forums who uses atan2 etc for shoot projectile toward mouse and it follow exact mouse cursor only if i increase with high speed, if not i have offset of several pixel with a low speed multiplier and this is a problem for me because i want to create sports games, exemple : if speed=10 there will be an offset but if speed=60 no. i understand your code but i dont have .Normalize()﻿; in sdl or c++ so i cant try it, there is a equivalent ? with your code the projectile follow cursor with a low speed ? thanks for the reply
3. ## [SDL] shoot bullet projectile toward mouse position by calculating angle

sorry for my code but i use this basically bullet.x += 10*(cos(atan2(y-200, x-300))); bullet.y += 10*(sin(atan2(y-200, x-300))); what you said is actually the only explanation of the offset when i use atan2 and cos / sin, i thought that for my projectile to go to my cursor with a low speed without declination it must this projectile follow another projectile with a high speed to record the trajectory and follow it, I do not know if it is the right solution thanks for the advice, i write this quicky after seen your reply, but i have already this "offset" with a low speed, and sdl_rect use always integers cause it move by pixels so i dont know if i still use casts ? bullet.x += (int)((float)10*(cos(atan2(y-200, x-300)))); bullet.y += (int)((float)10*(sin(atan2(y-200, x-300)))); thanks for this, what is 1.0f and this division ? my projectile dont move bullet.x *= 1.0f / sqrt(pow((x-300),2) + pow((y-200),2)); bullet.y *= 1.0f / sqrt(pow((x-300),2) + pow((y-200),2)); i know already this too double rx = (x-325); double ry = (y-245); double n = sqrt(pow((rx),2)+pow((ry),2)); double sx = rx/n; double sy = ry/n; but i had this same offset with it at low speed
4. ## C++ [SDL] shoot bullet projectile toward mouse position by calculating angle

Hello programmers. I have a problem for a few months that I left out to focus on something else because I did not have the solution but I really need it now. I had already looked at the solution and what came back most often is to calculate the angle of the trajection with atan2 and then to normalize with cos for x and sin for y I do it and it works only if my speed multiplier is greater than 60 or something like that, otherwise with a lower speed the projectile is still moving towards my cursor but with a multiple pixel offset of the exact cursor position and it's worse if I drop more my speed. so my problem is that the projectile goes to my cursor only with a high speed, this is a problem for me because I want to create sports games where the ball does not necessarily go very fast for example in a basketball game, then are there other techniques to achieve what I want to do? here is my code, I do not know the problem comes from a small synthax fault, of course there are other lines about collision and other things so sorry if it's too long but it's not complicated at all #include <exception> #include <string> #include <iostream> #include <SDL.h> #include <time.h> #include <math.h> #include <stdlib.h> #include <stdio.h> #include <vector> #include <fstream> using namespace std; #define PI 3.14159265 #define sgn(X) (((X)==0)?(0):(((X)<0)?(-1):(1))) #define WIDTH_SCREEN 640 #define HEIGHT_SCREEN 480 #define TILE_SIZE 32 #define LARGEUR_MONDE 4000 #define HAUTEUR_MONDE 480 #define NB_TILES_X LARGEUR_MONDE/TILE_SIZE #define NB_TILES_Y HAUTEUR_MONDE/TILE_SIZE #define CACHE_SIZE 256 bool BoxCollision(SDL_Rect box1,SDL_Rect box2); int TileMapCollision(SDL_Rect test,int tile_map[CACHE_SIZE][CACHE_SIZE], int largeur_tile,int hauteur_tile,float vx, float vy); int BoxCollisionVelocity(SDL_Rect box1,float vx,float vy,SDL_Rect box2,float vx2,float vy2); struct Obj { SDL_Rect r; int vx, vy, type; }; int main( int argc, char * argv[] ) { unsigned int lastTime = 0, currentTime = 0; float dt=0.f,perso_vx=0.f,perso_vy=0.f,v=-1; int tile_type=0,cv=0; bool save_map=0,left_m=0,left=0,right=0,up=0,down=0; SDL_Rect r = {WIDTH_SCREEN/2-r.w/2,HEIGHT_SCREEN/2-r.h/2,32,32}; SDL_Rect bullet = {-100,-100,12,12}; SDL_Rect platform1 = {1000,200,128,32}; SDL_Rect camera = {r.x-(WIDTH_SCREEN/2-r.w/2),r.y-(HEIGHT_SCREEN/2-r.h/2),WIDTH_SCREEN,HEIGHT_SCREEN}; SDL_Init(SDL_INIT_VIDEO); SDL_Window *window; SDL_Renderer *renderer; SDL_CreateWindowAndRenderer(WIDTH_SCREEN,HEIGHT_SCREEN,SDL_WINDOW_RESIZABLE,&window,&renderer); SDL_Texture* bgd1 = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,LARGEUR_MONDE,HAUTEUR_MONDE); while(1) { SDL_Event e; lastTime = currentTime; currentTime = SDL_GetTicks(); dt = (currentTime - lastTime)/1000.0f; while (SDL_PollEvent(&e)) { if (e.type==SDL_QUIT) return 0; if (e.type==SDL_KEYDOWN) { switch (e.key.keysym.sym){ case SDLK_LEFT: left = true; break; case SDLK_RIGHT: right = true; break; case SDLK_UP: up = true; break; case SDLK_DOWN: down = true; break; case SDLK_c: save_map=true; break; case SDLK_KP_1: tile_type=1; break; case SDLK_KP_2: tile_type=2; break; case SDLK_KP_3: tile_type=3; break; case SDLK_KP_4: tile_type=4; break; case SDLK_KP_5: tile_type=5; break; } } if (e.type==SDL_KEYUP) { switch (e.key.keysym.sym){ case SDLK_LEFT: left = false; break; case SDLK_RIGHT: right = false; break; case SDLK_UP: up = false; break; case SDLK_DOWN: down = false; break; case SDLK_c: save_map=false; break; } } if (e.type==SDL_MOUSEBUTTONDOWN) { switch(e.button.button){ case SDL_BUTTON_LEFT: left_m=true; break; } } if (e.type==SDL_MOUSEBUTTONUP) { switch(e.button.button){ //case SDL_BUTTON_LEFT: left_m=false; break; } } } //r.x += perso_vx; //r.y += perso_vy; platform1.x+=v; cv+=v; if (cv<=-1000||cv>=1000) v=-v; int x, y; SDL_GetMouseState( &x, &y ); const Uint8 *state = SDL_GetKeyboardState(NULL); if (left_m) { bullet.x += 10*(cos(atan2(y-200, x-300))); bullet.y += 10*(sin(atan2(y-200, x-300))); } if (bullet.x<=camera.x||bullet.x>=camera.x+WIDTH_SCREEN|| bullet.y<=camera.y||bullet.y>=camera.y+HEIGHT_SCREEN) { left_m=0; bullet.x=300; bullet.y=200; } cout<<10*cos(atan2(y-200, x-300))<<endl; if (state[SDL_SCANCODE_LEFT]) perso_vx = -4; if (state[SDL_SCANCODE_RIGHT]) perso_vx = 4; if (!state[SDL_SCANCODE_RIGHT]&&!state[SDL_SCANCODE_LEFT]) perso_vx = 0; if (state[SDL_SCANCODE_UP]) perso_vy = -4; else if (state[SDL_SCANCODE_DOWN]) perso_vy = 4; else perso_vy = 0; if (!BoxCollisionVelocity(r,perso_vx,0,platform1,0,0)) r.x+=perso_vx; else// if (perso_vx>=0&&v<0) r.x+=v; for (int i = 0; i < abs(perso_vx); ++i) if (!BoxCollisionVelocity(r,sgn(perso_vx),0,platform1,0,0)) r.x+=sgn(perso_vx); if (!BoxCollisionVelocity(r,0,perso_vy,platform1,0,0)) r.y+=perso_vy; else for (int i = 0; i < abs(perso_vy); ++i) if (!BoxCollisionVelocity(r,0,sgn(perso_vy),platform1,0,0)) r.y+=sgn(perso_vy); camera.x = r.x-(WIDTH_SCREEN/2-r.w/2); camera.y = r.y-(HEIGHT_SCREEN/2-r.h/2); if (camera.x <= 0) camera.x = 0; if (camera.x + WIDTH_SCREEN >= LARGEUR_MONDE) camera.x = LARGEUR_MONDE - WIDTH_SCREEN; if (camera.y <= 0) camera.y = 0; if (camera.y + HEIGHT_SCREEN >= HAUTEUR_MONDE) camera.y = HAUTEUR_MONDE - HEIGHT_SCREEN; SDL_SetRenderTarget(renderer, bgd1); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_SetRenderDrawColor(renderer, 200, 100, 50, 255); SDL_RenderFillRect(renderer, &platform1); SDL_RenderFillRect(renderer, &bullet); SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); SDL_RenderFillRect(renderer, &r); SDL_SetRenderTarget(renderer, NULL); SDL_RenderCopy(renderer, bgd1, &camera, NULL); SDL_RenderPresent(renderer); SDL_Delay(10); } SDL_DestroyTexture(bgd1); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } int BoxCollisionVelocity(SDL_Rect box1,float vx,float vy,SDL_Rect box2,float vx2,float vy2) { SDL_Rect r1 = {box1.x+vx,box1.y+vy,box1.w,box1.h}; SDL_Rect r2 = {box2.x+vx2,box2.y+vy2,box2.w,box2.h}; if (BoxCollision(r1,r2)) return true; else return false; } int TileMapCollision(SDL_Rect test,int tile_map[CACHE_SIZE][CACHE_SIZE], int largeur_tile,int hauteur_tile,float vx,float vy) { int xmin = (test.x+vx)/largeur_tile; int xmax = (test.x+test.w-1+vx)/largeur_tile; int ymin = (test.y+vy)/hauteur_tile; int ymax = (test.y+test.h-1+vy)/hauteur_tile; for (int i = ymin; i <= ymax; i++) { for (int j = xmin; j <= xmax; j++) { if(tile_map[i][j]>1) return 1; } } return 0; } bool BoxCollision(SDL_Rect box1, SDL_Rect box2) { if((box2.x >= box1.x + box1.w) // trop à droite || (box2.x + box2.w <= box1.x) // trop à gauche || (box2.y >= box1.y + box1.h) // trop en bas || (box2.y + box2.h <= box1.y)) // trop en haut return false; else return true; }
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!