# Sprite Movings are Buzzing.

This topic is 2232 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

i am making shoot them up game.

however, bullets are buzzing.

bullet moving is not smooth.

My Develop Environment is MS Visual Studio 2010, Windows 7 and SDL 1.2

below is pseudo-code of my bullet moving logic.
process the code every frame.

double x;

double y;

double Speed;

double speed_acc;
double angle_acc;
double Radian = abs(Angle - 360.0) * (PI / 180.0);

x = x + (Speed * Cos (Radian));

y = y + (Speed * Sin(Radian));

Speed = Speed + speed_acc;

Angle = Angle + angle_acc;

##### Share on other sites
double Radian = abs(Angle - 360.0) * PI / 180.0;

Not sure if above line is the problem, I would caculate the multiply first, because PI / 180 may cause accuracy losing.

##### Share on other sites
Hardly. That division might even be eliminated by the compiler since PI / 180.0 is constant. Precision is seldom a problem in cases like these, you don't even need doubles for that.

But why the abs ? This is definitively a wrong conversion from degree to radians.

Also: I don't see you taking the time passed since the last frame into account (aka delta or deltaTime). Something like: double deltaSpeed = Speed * deltaTime; x = x + deltaSpeed * Cos(Radian); y = y + deltaSpeed * Sin(Radian); 

Edited by Aaru

##### Share on other sites

Use "floats" if you want things to move smoother.

double is a double precision float (which is what he is using), so, no, this is not a valid suggestion at all.

##### Share on other sites
 double Radian = abs(Angle - 360.0) * (PI / 180.0); ... Angle = Angle + angle_acc; 
Three times wrong.

• Angle isn't bounded between 0 and 360, or any other interval.
• When Angle decreases from slightly more than 360 to slightly less than 360, Radian "bounces" from positive and decreasing to positive and increasing.
• You should use only one variable, measured in radians, to avoid a completely useless conversion.

Suggested fix:
 angle=angle+angularVelocity; if(angle>TWO_PI) angle= angle% TWO_PI; if(angle<0.0) angle= TWO_PI -(-angle% TWO_PI); ... cos(angle) 

Edited by Aaru

##### Share on other sites

[quote name='BeerNutts' timestamp='1354726463' post='5007440']
[quote name='Aaru' timestamp='1354722066' post='5007420']
Use "floats" if you want things to move smoother.

double is a double precision float (which is what he is using), so, no, this is not a valid suggestion at all.
[/quote]

It is a valid suggestion. Especially more valid than your useless comment.
[/quote]

I assumed, since this isn't the "For Beginners" forum, that I wouldn't have to explain what double precision float means, but, Aaru, you've proven otherwise.

A float is typically stored using 32-bits. This limits the precision it can obtain. When I say "precision" I mean the values it can represent, both in decimal digits, and in maximum value. A double is typically stored using 64-bits. Although, they could be exactly the same (since the C/C++ standards do not state otherwise), rarely is this the case.

So, in theory, using a float would lessen the precision of the moving sprite, while, practically, it would act exactly the same; thus, your suggestion is completely invalid.

Aaru, what reason do you say using a float would make it smoother?

##### Share on other sites
I wrote a simple program in SDL that shows a way of implementing Projectile Motion without any "buzzing".
Controls : ( R) : resets the balls position, "hold" (Space) : plays with the angle in a cool way
Hope It helps.

 #include <SDL.h> #include <SDL_image.h> #include <cmath> #define PI 3.14159265358979323846 #define WWIDTH 640 #define WHEIGHT 480 #define SPRITESIZE 48 bool Running = true; float DeltaTime = 0.0f; int X = WWIDTH/2; int Y = WHEIGHT/2; float SpeedX = 0.0f; float SpeedY = 0.0f; float MaxSpeedX = 2.01f; float MaxSpeedY = 2.01f; float AccelX = 5.0f; float AccelY = 5.0f; int Angle = 45; SDL_Surface* SurfDisplay = NULL; SDL_Surface* SurfBack = IMG_Load("./Background.jpg"); SDL_Surface* SurfProj = NULL; void LoadData() { SDL_Surface* SurfTemp = IMG_Load("./Projectile.png"); SurfProj = SDL_DisplayFormatAlpha(SurfTemp); SDL_FreeSurface(SurfTemp); } bool Init() { // Init if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { return false; } // Vidio Init if((SurfDisplay = SDL_SetVideoMode(WWIDTH, WHEIGHT, 32, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL) { return false; } //Set Window Title SDL_WM_SetCaption("Projectile Motion",""); // Hide the Mouse Cursor SDL_ShowCursor(0); // Key Repeat SDL_EnableKeyRepeat(1, SDL_DEFAULT_REPEAT_INTERVAL / 3); //Load Projectile.png LoadData(); } bool Draw(SDL_Surface* SurfDest, SDL_Surface* SurfSrc, int X, int Y) { if(SurfDest == NULL || SurfSrc == NULL) { return false; } SDL_Rect DestR; DestR.x = X; DestR.y = Y; SDL_BlitSurface(SurfSrc, NULL, SurfDest, &DestR); return true; } void OnEvent(SDL_Event* AnEvent) { switch(AnEvent->type) { case SDL_QUIT: Running = false; break; case SDL_KEYDOWN: switch(AnEvent->key.keysym.sym) { case SDLK_ESCAPE: Running = false; break; case SDLK_r: //Reset Projectile X = WWIDTH/2; Y = WHEIGHT/2; Angle = 45; break; case SDLK_SPACE: //Cool Projectile Motion Path Angle += tan(1* acos(1* asin(.1))); break; } break; case SDL_MOUSEBUTTONDOWN: break; } } void OnLoop() { SpeedX += AccelX * cos(Angle*PI/180) * DeltaTime; SpeedY += AccelY * sin(-Angle*PI/180) * DeltaTime; if(SpeedX > MaxSpeedX) SpeedX = MaxSpeedX; if(SpeedX < -MaxSpeedX) SpeedX = -MaxSpeedX; if(SpeedY > MaxSpeedY) SpeedY = MaxSpeedY; if(SpeedY < -MaxSpeedY) SpeedY = -MaxSpeedY; X += SpeedX; Y += SpeedY; //Keep Projectile In Window if(Y < 0){SpeedY *= -1; Angle = -Angle-360;} if(Y > WHEIGHT - SPRITESIZE){SpeedY *= -1; Angle = -Angle+360;} if(X < 0){SpeedX *= -1; Angle = -Angle+180;} if(X > WWIDTH - SPRITESIZE){SpeedX *= -1; Angle = -Angle-180;} //Keep Angle Within The Range of +/- 360 if(Angle >= 360){Angle -= 360;}; if(Angle <= -360){Angle += 360;}; char Buffer[255]; sprintf(Buffer, "Projectile Motion. Current Angle: %d", Angle); SDL_WM_SetCaption(Buffer, Buffer); } void OnDraw(SDL_Surface* screen) { //Draw The Background Draw(screen,SurfBack,0,0); //Draw The Projectile Draw(screen,SurfProj,X,Y); //Flip the Display Buffer SDL_Flip(SurfDisplay); } void Cleanup() { SDL_FreeSurface(SurfDisplay); SurfDisplay = NULL; SDL_Quit(); exit(0); } int main(int argc, char* argv[]) { SDL_Event Event; Uint32 LastTime = NULL; Init(); while(Running) { DeltaTime = ((SDL_GetTicks() - LastTime) / 1000.0f) * 32.0f; while(SDL_PollEvent(&Event)) { OnEvent(&Event); } OnLoop(); OnDraw(SurfDisplay); LastTime = SDL_GetTicks(); SDL_Delay(1); } Cleanup(); return 0; } 

Attached is the .exe to try it out. Edited by Aaru

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634046
• Total Posts
3015219
×