• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Sprite Movings are Buzzing.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

8 replies to this topic

### #1ibuki917  Members

Posted 04 December 2012 - 08:22 PM

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;

### #2wqking  Members

Posted 05 December 2012 - 03:09 AM

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.

http://www.cpgf.org/
cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.
v1.5.5 was released. Now supports tween and timeline for ease animation.

### #3unbird  Members

Posted 05 December 2012 - 03:46 AM

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);


### #4Aaru  Members

Posted 05 December 2012 - 09:41 AM

Edited by Aaru, 06 December 2012 - 11:59 AM.

### #5BeerNutts  Members

Posted 05 December 2012 - 10:54 AM

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.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

### #6LorenzoGatti  Members

Posted 05 December 2012 - 11:47 AM

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)


Omae Wa Mou Shindeiru

### #7Aaru  Members

Posted 05 December 2012 - 12:50 PM

Edited by Aaru, 06 December 2012 - 11:55 AM.

### #8BeerNutts  Members

Posted 05 December 2012 - 01:24 PM

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.

It is a valid suggestion. Especially more valid than your useless comment.

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?
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

### #9Aaru  Members

Posted 06 December 2012 - 11:33 AM

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* SurfProj = NULL;

{
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);

}

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.

#### Attached Files

Edited by Aaru, 06 December 2012 - 11:36 AM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.