# SFML - Difficulty with Rect Motion when using 1028x720 image per frame

Hello their just having a little tediously annoying problem that I just can't seem to figure out I've tried numerous things from using for loops on iterators and index values , iterating a index for the usual switch statement "switch(index)" then rendering the image per frame also tried rendering per delta time all leading to pretty poor results such as the frames would change but each frame index would have it's own unique time it took to change too the next frame was rather bizzare actually anyways the problem is "sorry for that long introduction" :

I'd like to render a HD image animated background in my video game using SFML and C++ .

The problem is that it won't change the index slow enough even when using delta time "sf::clock deltaclock = sf::asMilliseconds" , frameratelimiting and or verticlesync also won't move the clip rectangle for the texture correctly enough to give the illusion of an animated hd image...

Id show code but I think the problem doesn't require it at all unless for showing how to do the solution all I want is too be able to simply move a clip rect a certain amount on a 1 HD image per frame for a 3 frame HD spritesheet using SFML and C++.

What that means is I have 3 HD images of 1024 width and 720 height at different locations on a spritesheet and Id like to use a clip rectangle too move across this spritesheet fast and correctly enough to give the illusion that the 3 HD images as a whole 1 HD image are animated in game without any suttering , lagging or way to fast speeds.

one solution I had was too use a sprite sheet and split up the entire background into little tiles and render them all seperatly using a tilemap text file with numerical digits in it representing certain tiles,etc ... but that seems overkill.

• I'm not quite sure if I understand you correctly. Why is not simply changing the source rectangle periodically of a texture render working for you?
– user35344
Sep 19 '16 at 14:23
• Well the animation doesn't appear to be an animation it looks like someone moving an image across a screen no matter how high or low the increments are and because the images are big it takes a lot longer for the rect to move across it ... I don't know how to just switch to the next frame on the spritesheet if you know how please do tell me.. I mean the only way I can think of doing that would be too set pre-defined rect positions however I can see myself running back into super fast moving images or animations... very annoying this problem. @Tyyppi_77 Sep 19 '16 at 14:33
• A common approach is to either use a tool for exporting the frame positions, or place the frames after oneanother on a single image. That way the texture positions can be either loaded on runtime from a content file, or calculated dynamically inside your code.
– user35344
Sep 19 '16 at 14:37
• could you elaborate further I don't know how to actually set the positions of the rect in a ordered sequence "I know that sounds silly" but honestly do I use a for loop , if statement ... what do I use here is my first semi-assumptive pseudo attempt? int indexofimage = 0; indexofimage++; switch(indexofimage) { case : 1 { rect.x = //whatever , rect.y = //whatever , rect,w = //whatever , rect.h = //whatever } break ; case : 2 { rect.x = //whatever , rect.y = //whatever , rect,w = //whatever , rect.h = //whatever } indexofimage = 0; @Tyyppi_77 Sep 19 '16 at 14:42

So from what I could gather what you are looking for is a simple frame-based sprite animation. This is a common approach that's used when games don't animate objects by moving smaller parts of the objects programmatically, but instead prerender the animation states into an image file.

Now, there are a few different approaches to how the images are stored. If your frames aren't stored right next to each other, you might want to use a spritesheet builder too, that will export positions and spritesheets for you. That way, all you probably have to do is to load the rectangle positions from a content file (JSON, XML or something else), to an array, and index that array by your current frame index.

The way I handle frame-based animating, is that I position my frames right next to each other in a separate image file made just for the animation I want to implement. This makes calculating the rectangles super easy. You probably want to save the rectangles also to an array.

Rectangle[] calculateRectangles(int frameWidth, int frameHeight, Image image)
{
Rectangle rectangles[];

for (int y = 0; y < image.Heigth; y += frameHeight)
{
for (int x = 0; x < image.Width; x += frameWidth)
{
rectangles.push_back(Rectangle(x, y, frameWidth, frameHeight));
}
}

return rectangles;
}


The pseudo-code above calculates the rectangles for a generic spritesheet/tileset. It assumes that the whole image is filled with the frames. You could modify this to ignore rectangles after N-rectangles. The code flow should be quite simple to follow trough: it simply goes trough the frames row by row, column by column. You would then save the array returned to the corresponding class.

You then simply increment your frame index once in a while, calculating timed intervals is a different question, but I'm sure SFML offers utilities to do this. On render, you simply then use the rectangle in the array at the correct index.

Just to clarify, the image file could look something like this (I'm not sure about texture size limitations, you could also put the frames all below each other, or two on one row, one on the next).

• So basically what you are saying is I need to pre-calculate or at least know the exact entire rect position for each frame then switch too it using a timed interval? Thanks for the indepth insight their!. @Tyyppi_77 Sep 19 '16 at 15:38
• Yeah, that's a common approach. Your frame images don't often change during runtime.
– user35344
Sep 19 '16 at 15:56
• Thank you very much and I did fix the problem By iterating the top position in a switch statement frame indexed case. You are a star ! .. frame_index++; switch (frame_index) { case 100 : { TopMotion += 120; } break; case 200: { TopMotion += 240; } break; } BG_Sprite.setTextureRect(sf::IntRect(1.0, TopMotion , 1028, 720)); if (TopMotion == 1000) TopMotion = 0; window.draw(BG_Sprite); window.display(); Sep 19 '16 at 16:09
• Oh, all right! I'm glad I could help.
– user35344
Sep 19 '16 at 18:33