How to slow down blitting in SDL?

Started by
7 comments, last by BeerNutts 12 years, 2 months ago
Hello I'm trying to slow down a blit so that I can blit a enemy cleanly without any clashes with rect positions from the SDL_BlitSurface Function

I tried using a interger counter and it didn't work very well.

so I tried using SDL_Timer.h

didn't even do what I want.

any solutions or ideas on how to slow down blitting for a couple of seconds without halting or slowing down the program?
Advertisement
Using timers is the right way to do it. I've never used SDL but you should set up your timer so that you blit your enemy only x times per second.
So if you want to blit your enemy 10 times per second (usually timers work in milliseconds, i have no idea how SDL_Timer.h works) you can use something like:


while (renderloop)
{
if (timer.time >= 100)
{
timer.time = timer.time-100;
BlitEnemy();
}
BlitAllTheRest();
}
I don't understand why you are having problems. Typically, your Update Drawing Function should do this:

Clear Back Buffer
Draw Background to Back Buffer
Draw Enemies to Back Buffer
Draw Objects to Back Buffer
Draw Enemies to Back Buffer
Draw Bullets to Back Buffer
Draw Player to Back Buffer
Blit Back Buffer to Screen Buffer

Repeat.

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)

I don't understand how to code what you written so it works I assume that isn't the full working code so how would I code that in C++ would I start with a class like this


class timer
{
public time
{
int time;
time++;
}
};


or integer counter again?


int timer
int time = 0;
if(timer.time == 100)
{
timer.time = timer.time-100;
do something();
}


BeerNuts "most people just half ass code so it makes it very hard for me to know what to fix or how to fix the code problem till I've seen how to do it directly"


BeerNuts "most people just half ass code so it makes it very hard for me to know what to fix or how to fix the code problem till I've seen how to do it directly"

What? Listen, trying to add a timer to how often you blit an image is a mission of futility. You'e not going to find a proper solution doing it that way. Post us the code of where you are drawing your image, and when the screen surface gets updated. Are you drawing to a back-buffer, and then "Flip" it to the screen?

If you need help, check Lessons 1 and 2 here:
http://lazyfoo.net/SDL_tutorials/

Lesson 2 in particular.

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)


//THE ENEMY DRAWING

////////////
//Enemy
///////////

//////////////////////////////////////////////////
//Orange Ghost Knight Logic
/////////////////////////////////////////////////

//Orange Ghost Knight Moves to 400
if(StorageRect[10].x == 400)
{
//Move OrangeGhostKnight Forward by 40
StorageRect[10].x += 40;
}
//Orange Ghost Knight Moves to 480
if(StorageRect[10].x == 480)
{
//Move OrangeGhostKnight Back by 40
StorageRect[10].x -=40;
}

///////////////
//OGK Timer
///////////////

Enemy1++;
if(Enemy1 == 2)
{
EnemyFrame = 1;
}
if(Enemy1 == 4)
{
EnemyFrame = 2;
}
if(Enemy1 == 6)
{
EnemyFrame = 3;
}
if(Enemy1 == 8)
{
EnemyFrame = 4;
}
if(Enemy1 == 10)
{
EnemyFrame = 1;
Enemy1 = 1;
}
//Put Orange Ghost Knight onto FrameBuffer
OrangeGhostKnightRect = StorageRect[10];
SDL_BlitSurface(OrangeGhostKnightSurf[EnemyFrame],NULL,Screen,&OrangeGhostKnightRect);


/////////////////////////////////////////
//THIS IS THE THE TIMER
////////////////////////////////////////

//////////
//Timer
/////////

//Timer
time++;

//Font Setup
TTF_Font *TimerFont = TTF_OpenFont("wendy.ttf",20);
//Create A Buffer
char buffer[128];
//String Print for buffer
sprintf(buffer, "Level One - BubbleGum Sunset - " " Timer" " " "%d", time);

//Font Style
Text = TTF_RenderText_Blended( TimerFont, buffer, WhiteColor);
//Put Timer Text onto FrameBuffer
TextRect[1] = StorageRect[16];
SDL_BlitSurface(Text,NULL,Screen,&TextRect[1]);




This code happens with other blits in one while loop the hole program is in one hole while loop which does this is in order
1.)logic
2.)draw
3.)update - after the end of the while loop
4.)"repeat"


In a coding sense it goes like this

bool done = false;

while(!done)
{
logic
draw
update
repeat
}
I guess I mis-understood what the line
Hello I'm trying to slow down a blit so that I can blit a enemy cleanly without any clashes with rect positions from the SDL_BlitSurface Function[/quote]
meant. I assumed your "enemy" was getting over-written, and it was not being drawn cleanly since you weren't updating to a back-buffer.

Do you mean, you want to slow now the frame animations, so you can clearly see each animation of the enemy's frame? If that's the case, I should add to your enemy structure a unsigned int UpdateTime variable. That variable would store the last time you did a frame update, and after a certain # of milliseconds, you'd go to the next frame.

So, a simple example would be this (I'm just making up variables in the structre, you may or may not need them):

typedef struct
{
SDL_Rect EnemyRectangle;
float XVelocity;
float YVelocity;
SDL_Surface *AnimationFrames[MAX_ENEMY_FRAMES]; // holds all the surfaces for the animaiton frames, per-loaded
int Health;
int CurrentFrame; // The current frame it's animating on
unsigned int FrameUpdateRate; // Time in Milliseconds each frame should be shown
unsigned int RefireRate; // Time in Milliseconds between the enemy firing a bullet
unsigned int LastFrameUpdate; // Time in Milliseconds the frame was last updated
unsigned int LastBulletFired; // Time in Milliseconds the last bullet was fired.

} TEnemyInfo;

void Draw(TEnemyInfo &EnemyToDraw)
{
// Check the frame to display
unsigned int CurrentTime = timeGetTime();

if (CurrentTime > EnemyToDraw.LastFrameUpdate + EnemyToDraw.FrameUpdateRate)
{
EnemyToDraw.CurrentFrame++;
if (EnemyToDraw.CurrentFrame >= MAX_ENEMY_FRAMES)
{
EnemyToDraw.CurrentFrame = 0;
}
}

// Check if enemy should fire a bullet...

// Update Enemy Location by Velocity

// Draw Enemy
SDL_BlitSurface(EnemyToDraw.AnimationFrames[EnemyToDraw.CurrentFrame],NULL,Screen,&EnemyToDraw.EnemyRectangle);

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)

what would enemytodraw be ? the blit? or something else my blits are just on there own there not wrapped in any kind of functions smile.png
EnemyToDraw is the current enemy you are processing, as stored in the TEnemyInfo structure. I don't know what kind of game you are making, but most games have more than one enemy. So, I just wrote a pseudo-function that takes as an argument one particular enemy to be updated.

That function would get called every Update(), and you would pass it the current enemy being processed. If you have multiple enemies stored in a list, then you would call that function with each enemy to process.

That structure is just an example to give you a clue how to do this. If that isn't clear enough, then I'm not sure what to say. Good Luck.

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)

This topic is closed to new replies.

Advertisement