• Advertisement
Sign in to follow this  

sdl question

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

Advertisement
The same way you do it with any API: You display one image, then another that is a little different, then another one that is a little different still. (This is called page flipping).

To see how to display an image:
SDL doc

Share this post


Link to post
Share on other sites
AFAIK there is no pre-build function for that, bu you can easily roll your own animation system.
The easiest way is to have your animation in separate images, load them into an array of surfaces and index into this array. The current frame would be identical to the array index.
In your game loop you would use a timer to decide when to switch to the next frame
(e.g. when to increment the index).
Once the index reaches the number of animation frames loaded into the array, you can either reset it to zero (loop), stop incrementing it (one-shot animation) or
invert the sign of the frame increment (ping-pong loop).

Once you have this working, you can put individual frames into a single surface (e.g. evenly spaced both horizontally and vertically) and index into the surface by calculating the source rectangle of the crequested frame within the surface.



// sample animation info structure
struct AnimationInfo {
int frameWidth; // frame width in pixels
int frameHeight; // frame height in pixels
int numFrames; // number of frames in image
int currentFrame; // currently displayed frame
int delayInTicks; // number of ticks until frame skip
int currentTick; // current tick number (a tick could be anything from ms to minutes - it's up to you to define it)
int LoopCount; // loop count, 0 -> no loop, 1 -> repeat one time, -1 -> endless loop
int LoopIncrement; // loop increment, 1 -> forward, -1 -> backwards, 0 -> stop
SDL_Surface * frameData; // frame data
};

// calculate frame offset in surface from given frame number
void GetFrameRect( int frame, const AnimationInfo * animation, SDL_Rect * frameRect ) {
frameRect->x = (frame * animation->frameWidth) % animation->frameData->w;
frameRect->y = (frame * animation->frameWidth) / animation->frameData->w;
frameRect->w = animation->frameWidth;
frameRect->h = animation->frameHeight;
}




HTH,
Pat.

Share this post


Link to post
Share on other sites
I forogot to mention, with out them being in a animated format, there are over 150 of them (I have about 14 images I need to motion)

EDIT: or I could learn opengl

Share this post


Link to post
Share on other sites
Quote:
Original post by game mercenary
EDIT: or I could learn opengl

It's absolutely the same with OpenGL. There is no other way than animating the images yourself by displaying one after another.
Please be a little more specific about what you already have/know and what you need to know to implement this (other than how to call the SDL functions - this can be found in the docs and tutorials).

Share this post


Link to post
Share on other sites
Quote:
Original post by game mercenary
I forogot to mention, with out them being in a animated format, there are over 150 of them (I have about 14 images I need to motion)
You could have every frame held in one large image and then when you're rendering the animation, just loop through one by one displaying each frame as you go through the loop.

Share this post


Link to post
Share on other sites
Here is an idea. What if you created a seperate thread for each animation you create? They would all be able to update automaticaly if you had an internal timer going on each thread.

Share this post


Link to post
Share on other sites
Quote:
Original post by Simian Man
The same way you do it with any API: You display one image, then another that is a little different, then another one that is a little different still. (This is called page flipping).


No, this is called animating. Page flipping is the method by which you prevent display flicker. First you draw the next screen of video in a section of memory that is not visible (the back buffer). Then once you're done, you either brute-force copy the back buffer to front buffer, or you instruct the display hardware to swap the back buffer and the front buffer. This is much faster than a brute-force copy because no data is being moved. This method is called page flipping.

Quote:
Original post by PnP Bios
Here is an idea. What if you created a seperate thread for each animation you create? They would all be able to update automaticaly if you had an internal timer going on each thread.


No! Here's what I do (python):



# All time values are floating point values representing seconds or fractions thereof

class Frame:
def __init__(self, surface, duration):
self.surface = surface
self.duration = duration

class Animation:
def __init__(self):
self.frames = []
self.current_frame = None
self.frame_start_time
self.next_frame_time

def play(self, current_time):
self.current_frame = 0
f = self.frames[self.current_frame]
self.frame_start_time = current_time
self.next_frame_time = self.frame_start_time + f.duration
self.update(current_time)

def update(self, current_time):
if current_time >= self.next_frame_time:
self.current_frame += 1
if self.current_frame >= len(self.frames):
print "Animation done!"
self.current_frame = self.frames[len(self.frames) - 1]
else:
f = self.frames[self.current_frame]
self.frame_start_time = self.next_frame_time
self.next_frame_time += f.duration


Share this post


Link to post
Share on other sites
I havent read all the posts yet, here is my method of collision detection (all relevant code shown):

declarations.h

struct col
{
bool hit;
int xpos,ypos;
};

col maphit[159][119];
//enough to grid it every 5 pixels

int currentx,currenty;



init.h

for(loop1 = 1;loop1<79;loop1++)
{
for(loop2=1;loop2<59;loop2++)
{

maphit[loop1][loop2].xpos = (loop1*10)+1;
maphit[loop1][loop2].ypos = (loop2*10)+1;
maphit[loop1][loop2].hit = false;
}
}
}

//now assign each one (read on before commenting on this)
collisionsetup();


you.xpos = maphit[0][0].xpos;
you.ypos = maphit[0][0].ypos;
currentx = 0;
currenty = 0;



keyhandle.h

//this goes with the length of my sprite
if ( keys[SDLK_UP])
if ( !maphit[currentx][currenty-1].hit&&
!maphit[currentx+1][currenty-1].hit &&
!maphit[currentx+2][currenty-1].hit &&
!maphit[currentx+3][currenty-1].hit &&
!maphit[currentx+4][currenty-1].hit &&
!maphit[currentx+5][currenty-1].hit
)
{ you.ypos =maphit[currentx][currenty-1].ypos; currenty--; dir=1; }


if ( keys[SDLK_DOWN] )
if ( !maphit[currentx][currenty+6].hit &&
!maphit[currentx][currenty+6].hit &&
!maphit[currentx+1][currenty+6].hit &&
!maphit[currentx+2][currenty+6].hit &&
!maphit[currentx+3][currenty+6].hit &&
!maphit[currentx+4][currenty+6].hit )
{you.ypos =maphit[currentx][currenty+1].ypos; currenty++; dir=2; }


if ( keys[SDLK_LEFT] )
if ( !maphit[currentx-1][currenty].hit &&
!maphit[currentx-1][currenty-1].hit &&
!maphit[currentx-1][currenty-2].hit &&
!maphit[currentx-1][currenty-3].hit &&
!maphit[currentx-1][currenty-4].hit &&
!maphit[currentx-1][currenty-5].hit)
{ you.xpos =maphit[currentx-1][currenty].xpos; currentx--; dir = 3; }


if ( keys[SDLK_RIGHT] )
if ( !maphit[currentx+5][currenty].hit &&
!maphit[currentx+5][currenty-1].hit &&
!maphit[currentx+5][currenty-2].hit &&
!maphit[currentx+5][currenty-3].hit &&
!maphit[currentx+5][currenty-4].hit &&
!maphit[currentx+4][currenty-5].hit)
{ you.xpos =maphit[currentx+1][currenty].xpos; currentx++; dir = 0; }
}



now you must be thinking, cool, but how the **** are you going to be able to find and do each 5x5 square to go with the image. simple, make an engine, this is what I added to it:

at the at the end of every sucessful keypress

cout << "maphit[" << currentx << "] [" << currenty << "].hit = true;\n";



but now I start at 0x0 and I have to go there? where do I delete it? I added these lines to the keyhandling file

if(keys[SDLK_SPACE])
{
flip = true;
}

if(!keys[SDLK_SPACE])
{
flip = false;
}


and in the main loop, if flip it true it doesnt flip the screen and delayes a half second (to avoid errors). when you finish just copy stdout into collisionsetup(). it takes a second at startup but it works and I can make huge maps with semi-advanced collision detection in minutes

Share this post


Link to post
Share on other sites
I just made a Sprite class that could have unlimited animations... Each with it's own delay, and each animation could collide depending on it's width and height, this means that you can have an image 100x100 and then an image 1x1 and they will definitely not collide at the same time with an image at 50x50.

Only downside is that I used many of my own features of my namespace in the class, so I can't show it unless I show CApp::List and CApp::Error. Or, you can make the throw's to return's and CApp::List to std::map, although you will have to change many things to make it work.

Share this post


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

  • Advertisement