• Advertisement
Sign in to follow this  

Sprite Movings are Buzzing.

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

If you intended to correct an error in the post then please contact us.

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;


//speed(angle) addition per frame. (addition may be 0.0 if unneccerary)

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;


please help me.. and thank you for reading my question!

Share this post


Link to post
Share on other sites
Advertisement
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);

Share this post


Link to post
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 this post


Link to post
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)

Share this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement