Jump to content
  • Advertisement
Sign in to follow this  
LeftyGuitar

Animating With Separate Image Files

This topic is 1566 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

Hello,

 

I am having trouble getting separate image files to animate smoothley. When I run the program, the image shows up and flickers alot, it also stutters some. I'll post some of my code and see if anyone can help me.

		SDL_RenderClear(MainRend);

		SDL_RenderCopy(MainRend,BackdropTex,NULL,&BackdropRect);

		gAidan.CurrentFrame++;
		if(gAidan.CurrentFrame == 1)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[0],NULL,&gAidan.StandDstRect[0]);
		}
		else if(gAidan.CurrentFrame == 2)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[1],NULL,&gAidan.StandDstRect[1]);
		}
		else if(gAidan.CurrentFrame == 3)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[2],NULL,&gAidan.StandDstRect[2]);
		}
		else if(gAidan.CurrentFrame == 4)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[3],NULL,&gAidan.StandDstRect[3]);
		}
		else if(gAidan.CurrentFrame == 5)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[4],NULL,&gAidan.StandDstRect[4]);
		}
		else if(gAidan.CurrentFrame == 6)
		{
			SDL_RenderCopy(MainRend,gAidan.StandTex[5],NULL,&gAidan.StandDstRect[5]);
		}
		else if(gAidan.CurrentFrame == 7)
		{
			gAidan.CurrentFrame = 0;
		}

		SDL_RenderPresent(MainRend);

I can post more code if it is needed.

Share this post


Link to post
Share on other sites
Advertisement

If this code is executed once per render loop, the image will NOT be drawn 1 frame every 7 frames. This is what causes the flicker.

This is because if CurrentFrame is 6 upon entering this code, it will be incremented to 7. It will then bypass all the other ifs, and go to the == 7 part.

Here, it will be set to 0 (so that it runs 1 next loop), but it will not do any drawing this loop.

You can fix this by doing a separate if check right after incrementing, that sets it to 1.

 

However, there is a lot of (almost) identical code here. You could change all of the above (with the fix I mentioned) into the following:

SDL_RenderClear(MainRend);
SDL_RenderCopy(MainRend,BackdropTex,NULL,&BackdropRect);
 
SDL_RenderCopy(MainRend,gAidan.StandTex[gAidan.CurrentFrame],NULL,&gAidan.StandDstRect[gAidan.CurrentFrame])
 
gAidan.CurrentFrame++;
gAidan.CurrentFrame %= 7;
 
SDL_RenderPresent(MainRend);

If this looks a bit like magic, ask and I'll explain what's going on.

Edited by Lactose!

Share this post


Link to post
Share on other sites

Hello again,

 

I am having trouble getting my image to move. I have it so that when the user presses a key, the character moves left or right. When I press either of those keys, the animation plays, but the character does not move. I'll post my code.

const float MOVEMENT_SPEED = 0.10f;
			
if(event.type == SDL_KEYDOWN && event.key.repeat == 0)
			{
				if(event.key.keysym.sym == SDLK_ESCAPE)
				{
					GameRunning = false;
				}

				if(event.key.keysym.sym == SDLK_LEFT)
				{
					gAidan.Action = gAidan.WALKING;
					gAidan.WalkingDstRect[gAidan.CurrentFrame].x -= (int)gAidan.X_Vel * (int)MOVEMENT_SPEED;
				}
				else if(event.key.keysym.sym == SDLK_RIGHT)
				{
					gAidan.Action = gAidan.WALKING;
					gAidan.WalkingDstRect[gAidan.CurrentFrame].x += (int)gAidan.X_Vel * (int)MOVEMENT_SPEED;
				}
			}

void Render()
{
		SDL_RenderClear(MainRend);

		SDL_RenderCopy(MainRend,BackdropTex,NULL,&BackdropRect);

		SDL_RenderCopy(MainRend,gAidan.StandTex[gAidan.CurrentFrame],NULL,&gAidan.StandDstRect[gAidan.CurrentFrame]);

		gAidan.CurrentFrame++;
		gAidan.CurrentFrame = SDL_GetTicks() / 100 % 6;

		if(gAidan.Action == gAidan.WALKING)
		{
			SDL_RenderCopy(MainRend,gAidan.WalkingTex[gAidan.CurrentFrame],NULL,&gAidan.WalkingDstRect[gAidan.CurrentFrame]);

			gAidan.CurrentFrame++;
			gAidan.CurrentFrame = SDL_GetTicks() / 100 % 6;
		}

		SDL_RenderPresent(MainRend);
}

I can post more code if it is needed.

Share this post


Link to post
Share on other sites

(int)MOVEMENT_SPEED takes the float variable 0.10f and casts it to an integer value. Since integer values can't represent decimal values, the value you end up with is 0.

Whatever X_Vel is, it will be multiplied by 0, which results in 0 movement.

 

Either store the position as a float (and cast to int if needed for rendering only), OR multiply as floats first, and cast the result of the float multiply to an int.

Depending on the variable values, the second option might not work (it might still get truncated to 0 when cast to int).

 

I would recommend using the first option.

Share this post


Link to post
Share on other sites

I'm still confused here. I changed the position variables to integer values, and the character still won't move. Though the animation does play. Also, after the I close the program, I get some kinda of memory leak error or something.

Share this post


Link to post
Share on other sites

I changed the position variables to integer values, and the character still won't move.

What Lactose! wrote means that the casting to int makes the value of the effective speed to be zero, and multiplying with zero gives zero, and adding zero does not change anything:

 

1.)  const float MOVEMENT_SPEED = 0.10f;

=> MOVEMENT_SPEED = 0.1

 

2.) gAidan.WalkingDstRect[gAidan.CurrentFrame].x -= (int)gAidan.X_Vel * (int)MOVEMENT_SPEED;

=> (int)MOVEMENT_SPEED => (int)0.1 => (int)round(0.1) => (int)0 => 0

=> no change, because gAidan.WalkingDstRect[gAidan.CurrentFrame].x -= 0 

 

What you need to do instead is:

With gAidan.X_Pos being a float, and gAidan.X_Vel being a float, and MOVEMENT_SPEED being a float:

 

1.) updating position (notice that only floats are used, so above problem is avoided)

gAidan.X_Pos -= gAidan.X_Vel * MOVEMENT_SPEED;

 

2.) later, for rendering

gAidan.WalkingDstRect[gAidan.CurrentFrame].x = (int)gAudan.X_Pos;

 

BTW: With small enough numbers the integer value of X_Pos may change after a few frames only, but that would be totally correct.

Edited by haegarr

Share this post


Link to post
Share on other sites

Thanks for the help. I've tried those, and it still just stays in place while playing the animation.

 

gAiden.X_Pos = 0.15f;

gAiden.Y_Pos = 0.15f;

MOVEMENT_SPEED = 0.10f;

 

Those are the values I have set for those variables.

Share this post


Link to post
Share on other sites
gAiden.X_Pos = 0.15f;
gAiden.Y_Pos = 0.15f;
MOVEMENT_SPEED = 0.10f;
 
Those are the values I have set for those variables.

X_Pos and Y_Pos are irrelevant for the calculations, but X_Vel and Y_Vel are not. Have you confused those names? If not, what are the values of X_Vel and Y_Vel?

 

If you read my post above carefully, then you should understand that integer values have no decimal digits! If you have a X_Vel of 0.15 and a speed of 0.1, then each step is as wide as 0.015. Rounding occurs at 0.5, so you need to accumulate 0.015 for 34 times to see it move 1 pixel the first time.

 

 

EDIT: Ugh, I forgot that casting to integer doesn't round but truncates. In that case the first movement will of course happen when the accumulation exceeds 1.0 but not 0.5. However, that has no influence on the principle.

Edited by haegarr

Share this post


Link to post
Share on other sites

Ooops, I'm sorry, Those are the values of X_Vel and Y_Vel.

 

X_Vel = 0.15f;

Y_Vel = 0.15f;

X_Pos = 10;

Y_Pos = 100;

 

    gAidan.WalkingDstRect[0].x = gAidan.X_Pos;
    gAidan.WalkingDstRect[0].y = gAidan.Y_Pos;

 

I'm wondering now, should I change to where it says gAidan.WalkingDstRect[0].x = gAidan.X_Pos to gAidan.WalkingDstRect[gAidan.CurrentFrame].x = gAidan.x_Pos?

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!