🔒 Locked
SDL Beginner Help!
Advertisement
Original Post
Hi i've just started to program with SDL, and am having some trouble. I followed this guide: http://www.aaroncox.net/tutorials/arcade/Introduction.html I don't understand the part where you set the speed of your charachter / program. Anyone got any idea how i can work that into the code? Please explain in detail :). Here is the game: http://rapidshare.com/files/217032701/SDLSpel.rar.html and here is the code(please note that some parts are swedish): #include #include #include #include #include int main(int argc, char **argv) { bool gamerunning = true; bool keysHeld[323] = {false}; // everything will be initialized to false int level = 1; SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER ); SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF); SDL_WM_SetCaption("SDLTest", 0); //Ladda BMP fil SDL_Surface* bakgrund = SDL_LoadBMP("Bakgrund.bmp"); SDL_Surface* gubbe = SDL_LoadBMP("Gubbe.bmp"); // Göm färgen Magneta för bild SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255)); //BakgrundBildens koordinater som ska laddas SDL_Rect bakgrundDel; bakgrundDel.x = 0; bakgrundDel.y = 0; bakgrundDel.w = 640; bakgrundDel.h = 480; //BakgrundBildens koordinater i SDL rutan SDL_Rect bakgrundposition; bakgrundposition.x = 0; bakgrundposition.y = 0; bakgrundposition.w = bakgrundDel.w; bakgrundposition.h = bakgrundDel.h; //GubbBildens koordinater som ska laddas SDL_Rect gubbeDel; gubbeDel.x = 0; gubbeDel.y = 0; gubbeDel.w = 40; gubbeDel.h = 40; //GubbBildens koordinater i SDL rutan SDL_Rect gubbeposition; gubbeposition.x = screen->w / 2 - (gubbeDel.w / 2); gubbeposition.y = (screen->h / 2) - (gubbeDel.h / 2); gubbeposition.w = gubbeDel.w; gubbeposition.h = gubbeDel.h; SDL_Event event; while (gamerunning) { if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { gamerunning = false; } if (event.type == SDL_KEYDOWN) { keysHeld[event.key.keysym.sym] = true; } if (event.type == SDL_KEYUP) { keysHeld[event.key.keysym.sym] = false; } } if (keysHeld[SDLK_ESCAPE]) { gamerunning = false; } if ( keysHeld[SDLK_LEFT] ) { gubbeposition.x -= 1; gubbeDel.x = 40; } if ( keysHeld[SDLK_RIGHT] ) { gubbeposition.x += 1; gubbeDel.x = 40; } if ( keysHeld[SDLK_UP] ) { gubbeposition.y -= 1; gubbeDel.x = 0; } if (keysHeld[SDLK_DOWN]) { gubbeposition.y += 1; gubbeDel.x = 0; } if (level==1) { if (gubbeposition.x == screen->w) { gubbeposition.x = 1; bakgrundDel.x = 640; level += 1; } } if (level==2) { if (gubbeposition.x == screen->w) { gubbeposition.x = 0; bakgrundDel.x = 1280; level += 1; } else if (gubbeposition.x == 0) { gubbeposition.x = screen->w; bakgrundDel.x = 0; level -= 1; } } //Gör skärmen svart efter varje loop SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); //Hämta en del av en .BMP fil. FIL / Del av bild / Yta / bild position SDL_BlitSurface(bakgrund, &bakgrundDel, screen, &bakgrundposition); SDL_BlitSurface(gubbe, &gubbeDel, screen, &gubbeposition); SDL_Flip(screen); SDL_Delay(1); } SDL_FreeSurface(gubbe); SDL_FreeSurface(bakgrund); SDL_Quit(); return 0; }
First of all, welcome to the GameDev forums =)
I'm going to answer your questions, but first let me advice you on how you should do from now on if you want help from people on GameDev ;)
1. Please post long code within code-blocks. This makes posts that contain code much easier to read. Please make posts easy to read if you want help. Many people will not answer posts if they are too difficult to read. See the forum FAQ for info on how to do that.
2. If you post short code, it doesn't matter if it's in code blocks.
3. If you post code: make sure it is commented. In ENGLISH. Not swedish ;)
You're lucky I happened to be swedish, so I could read them without getting upset. :P Even though I'm swedish I always write code and comments in english so that I can quickly ask anybody for help without having to translate everything first.
Okay, so let's get on to the solutions! Yay!
Your game loop (and most other game loops as well) updates like this:
* First do game logic and draw stuff to screen buffer (5 milliseconds)
* Then sit and wait for the next flicker of the screen (lots of milliseconds)
* Instantly swap the old screen image for the new one (0 milliseconds)
* Start loop all over again (0 milliseconds)
One pass through all that is called a frame. Or a tick.
As you can see, the whole process takes 5 + lots + 0 + 0 milliseconds in total. The wait-for-screen part is done within the SDL_Flip(screen); command. All this makes the game loop run with a constant framerate. So your game loop is normally executed some 100 times per second (this may vary depending on the system). You want it to always be like this.
In order to make your character move around faster, you DON'T want to make the game loop run faster. That speed is mostly constant. Instead you want the character to move further for every frame.
You do this by changing all lines that look like this:
gubbeposition.x -= 1;
into lines that look like this:
gubbeposition.x -= gubbeSpeed;
And to be able to do this we must of course have a variable called gubbeSpeed:
bool gamerunning = true;
bool keysHeld[323] = {false}; // everything will be initialized to false
int level = 1;
int gubbeSpeed = 2;
Ta-daaaaaaaa! I just made your "gubbe" move two pixels every frame instead of just one! Try playing around with that value, just for fun.
You will find that he does no longer wrap around the edges when he moves. That's because of this;
if (gubbeposition.x == screen->w)
{
...
}
Which now MIGHT not happen, because of the bigger jumps we just made him do. Instead you should have:
if (gubbeposition.x >= screen->w)
Good luck!
I'm going to answer your questions, but first let me advice you on how you should do from now on if you want help from people on GameDev ;)
1. Please post long code within code-blocks. This makes posts that contain code much easier to read. Please make posts easy to read if you want help. Many people will not answer posts if they are too difficult to read. See the forum FAQ for info on how to do that.
2. If you post short code, it doesn't matter if it's in code blocks.
3. If you post code: make sure it is commented. In ENGLISH. Not swedish ;)
You're lucky I happened to be swedish, so I could read them without getting upset. :P Even though I'm swedish I always write code and comments in english so that I can quickly ask anybody for help without having to translate everything first.
Okay, so let's get on to the solutions! Yay!
Your game loop (and most other game loops as well) updates like this:
* First do game logic and draw stuff to screen buffer (5 milliseconds)
* Then sit and wait for the next flicker of the screen (lots of milliseconds)
* Instantly swap the old screen image for the new one (0 milliseconds)
* Start loop all over again (0 milliseconds)
One pass through all that is called a frame. Or a tick.
As you can see, the whole process takes 5 + lots + 0 + 0 milliseconds in total. The wait-for-screen part is done within the SDL_Flip(screen); command. All this makes the game loop run with a constant framerate. So your game loop is normally executed some 100 times per second (this may vary depending on the system). You want it to always be like this.
In order to make your character move around faster, you DON'T want to make the game loop run faster. That speed is mostly constant. Instead you want the character to move further for every frame.
You do this by changing all lines that look like this:
gubbeposition.x -= 1;
into lines that look like this:
gubbeposition.x -= gubbeSpeed;
And to be able to do this we must of course have a variable called gubbeSpeed:
bool gamerunning = true;
bool keysHeld[323] = {false}; // everything will be initialized to false
int level = 1;
int gubbeSpeed = 2;
Ta-daaaaaaaa! I just made your "gubbe" move two pixels every frame instead of just one! Try playing around with that value, just for fun.
You will find that he does no longer wrap around the edges when he moves. That's because of this;
if (gubbeposition.x == screen->w)
{
...
}
Which now MIGHT not happen, because of the bigger jumps we just made him do. Instead you should have:
if (gubbeposition.x >= screen->w)
Good luck!
Oh! I just read the tutorial you intended. You linked to the wrong page! I had to click around to find the thing about the speed and stuff. Now I better understand exactly what you asked for.
First do the modifications I mentioned in the above post. This gives you a variable speed. But it is FRAME RATE DEPENDENT. That means if you run the same code on some other computer that is twice as fast, your character will move twice as fast, because the game loop ticks twice as fast.
You do not want this. You want all players who download the game to have the same experiences, no matter how fast computers (frame rate) they got.
We accomplish this by multiplying the TimeSinceLastFrame with the speed! Notice that all your position variables must now be doubles.
SDL_Rect gubbeposition; // this is bad because SDL_rect structure only has integers in it.
You need to make your own class, so we can have all positions as doubles. This will be useful in the future. Like this:
And in the beginning of each frame:
And FINALLY your
gubbeposition.x += gubbeSpeed;
commands need to change into
gubbe.x += gubbe.speed*TimeSinceLastFrame;
That's all. So if we got a fast computer, the TimeSinceLast number will be very small, and that will make the gubbe make small jumps between each frame. If we got a slow computer the TimeSincelast number will be large and the gubbe will make bigger jumps. Now we have FRAME RATE INDEPENDENT movement. Now he moves with the same speed on all computers.
You will have to figure out how to draw the image where you want it to go yourself. You'll have to round off the position to an integer somehow, and then somehow pass the right values to the SDL_BlitSurface() function. I recommend creating a helper function which makes things easier in the future. Something like:
void DrawImage(surface, atSurface, atLocationX, atLocationY);
Good luck!
First do the modifications I mentioned in the above post. This gives you a variable speed. But it is FRAME RATE DEPENDENT. That means if you run the same code on some other computer that is twice as fast, your character will move twice as fast, because the game loop ticks twice as fast.
You do not want this. You want all players who download the game to have the same experiences, no matter how fast computers (frame rate) they got.
We accomplish this by multiplying the TimeSinceLastFrame with the speed! Notice that all your position variables must now be doubles.
SDL_Rect gubbeposition; // this is bad because SDL_rect structure only has integers in it.
You need to make your own class, so we can have all positions as doubles. This will be useful in the future. Like this:
class Cgubbe{double x;double y;double speed;string name;};Cgubbe gubbe;gubbe.x=100;gubbe.y=100;gubbe.speed=2.7;gubbe.name="Bosse Svensson";And in the beginning of each frame:
long beginTime = SDL_GetTicks();long timeSinceLastFrame = 0;while(gamerunning){ timeSinceLastFrame = SDL_GetTicks() - beginTime; beginTime = SDL_GetTicks(); // ... main code ...}And FINALLY your
gubbeposition.x += gubbeSpeed;
commands need to change into
gubbe.x += gubbe.speed*TimeSinceLastFrame;
That's all. So if we got a fast computer, the TimeSinceLast number will be very small, and that will make the gubbe make small jumps between each frame. If we got a slow computer the TimeSincelast number will be large and the gubbe will make bigger jumps. Now we have FRAME RATE INDEPENDENT movement. Now he moves with the same speed on all computers.
You will have to figure out how to draw the image where you want it to go yourself. You'll have to round off the position to an integer somehow, and then somehow pass the right values to the SDL_BlitSurface() function. I recommend creating a helper function which makes things easier in the future. Something like:
void DrawImage(surface, atSurface, atLocationX, atLocationY);
Good luck!
Ok thanks alot your 2nd post helped me alot more than the first one :). Sorry that i haven't replied i have been busy working on the game hehe ;). I understand much better from you than that tutorial site so i think i understand how to do it now. I'll try it tomorrow and tell you my results :). Thanks for your time writing all that.
I am still a little unsure though how a class works when i load it with BlitSurface. Will it know the position because it is named .x and .y? And don't i need width and height aswell? Sorry but i am very new in SDL. My game is coming along very fine though, but being able to do this speed change will be nice. I'll try it tomorrow and hope you replied :)
I am still a little unsure though how a class works when i load it with BlitSurface. Will it know the position because it is named .x and .y? And don't i need width and height aswell? Sorry but i am very new in SDL. My game is coming along very fine though, but being able to do this speed change will be nice. I'll try it tomorrow and hope you replied :)
Ok i got it to work now, but it runs choppier than before.
Any way around this? But that is the point i guess, to make it go higher steps if the computer is slowed. I just didn't expect to notice it since it's a simple game and my computer is very good.
Before the charachter slowed down a bit though and now it chops instead so i guess it's just because it's a demanding game. Should i do something to prevent this. Use other pictures than bmp perhaps? or something like that.
Here is the current code if you wanna have a look and tell me if you see something wrong. It's quite much code but i would appreciate it very much if you did. I change the doubles to int very far down in the code.
[Edited by - zippo88 on April 6, 2009 9:22:43 AM]
Any way around this? But that is the point i guess, to make it go higher steps if the computer is slowed. I just didn't expect to notice it since it's a simple game and my computer is very good.
Before the charachter slowed down a bit though and now it chops instead so i guess it's just because it's a demanding game. Should i do something to prevent this. Use other pictures than bmp perhaps? or something like that.
Here is the current code if you wanna have a look and tell me if you see something wrong. It's quite much code but i would appreciate it very much if you did. I change the doubles to int very far down in the code.
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <SDL/SDL.h>#include <windows.h>struct Sgubbe{ double x; double y; double speed; };void BlockDown(SDL_Surface* screen, Sgubbe& gubbeposition){ if (gubbeposition.y >= (screen->h - 40)){ gubbeposition.y = (screen->h - 40); }}void BlockRight(SDL_Surface* screen, Sgubbe& gubbeposition){ if (gubbeposition.x >= (screen->w - 40)){ gubbeposition.x = (screen->w - 40); }}int main(int argc, char **argv){long beginTime = SDL_GetTicks();long timeSinceLastFrame = 0;double gubbespeed;bool gamerunning = true;bool keysHeld[323] = {false}; // everything will be initialized to falseint level = 0;bool map = false;double gubbex;double gubbey;int vaktx;int vakty;bool keySpace;bool repeatBlock = false;bool keyUp;int val = 1;int currentlevel = 1;SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER );SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);SDL_WM_SetCaption("SDLTest", 0);//Ladda BMP filSDL_Surface* meny = SDL_LoadBMP("Meny.bmp");SDL_Surface* bakgrund = SDL_LoadBMP("Bakgrund.bmp");SDL_Surface* minimap = SDL_LoadBMP("Minimap.bmp");SDL_Surface* gubbe = SDL_LoadBMP("Gubbe.bmp");SDL_Surface* vakt = SDL_LoadBMP("Vakt.bmp");// Göm färgen Magneta för bildSDL_SetColorKey(meny, SDL_SRCCOLORKEY, SDL_MapRGB(meny->format, 255, 0, 255));SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255));SDL_SetColorKey(vakt, SDL_SRCCOLORKEY, SDL_MapRGB(vakt->format, 255, 0, 255));//MenyBildens koordinater som ska laddasSDL_Rect bakgrundDel;bakgrundDel.x = 0;bakgrundDel.y = 0;bakgrundDel.w = 640;bakgrundDel.h = 480;//MenyBildens koordinater i SDL rutanSDL_Rect menyDel;menyDel.x = 0;menyDel.y = 0;menyDel.w = 640;menyDel.h = 480;//MenyVal koordinater som ska laddasSDL_Rect menyvalDel;menyvalDel.x = 640;menyvalDel.y = 0;menyvalDel.w = 220;menyvalDel.h = 88;//MenyVal koordinater i SDL rutanSDL_Rect menyvalposition;menyvalposition.x = 435;menyvalposition.y = 15;menyvalposition.w = menyvalDel.w;menyvalposition.h = menyvalDel.h;//BakgrundBildens koordinater som ska laddasSDL_Rect menyposition;menyposition.x = 0;menyposition.y = 0;menyposition.w = menyDel.w;menyposition.h = menyDel.h;//BakgrundBildens koordinater i SDL rutanSDL_Rect bakgrundposition;bakgrundposition.x = 0;bakgrundposition.y = 0;bakgrundposition.w = bakgrundDel.w;bakgrundposition.h = bakgrundDel.h;//Minimaps koordinater som ska laddasSDL_Rect minimapDel;minimapDel.x = 0;minimapDel.y = 0;minimapDel.w = 128;minimapDel.h = 96;//Minimaps koordinater i SDL rutanSDL_Rect minimapposition;minimapposition.x = 0;minimapposition.y = 0;minimapposition.w = minimapDel.w;minimapposition.h = minimapDel.h;//MinimapDotSDL_Rect minimapDot;minimapDot.x = 0;minimapDot.y = 0;minimapDot.w = 4;minimapDot.h = 4;//GubbBildens koordinater som ska laddasSDL_Rect gubbeDel;gubbeDel.x = 0;gubbeDel.y = 0;gubbeDel.w = 40;gubbeDel.h = 40;//GubbBildens koordinater i SDL rutanSgubbe gubbeposition; gubbeposition.x = (screen->w / 2) - (gubbeDel.w / 2); gubbeposition.y = (screen->h / 2) - (gubbeDel.h / 2); gubbeposition.speed = 0.15;SDL_Rect intgubbeposition;intgubbeposition.x;intgubbeposition.y;intgubbeposition.w = gubbeDel.w;intgubbeposition.h = gubbeDel.h;//VaktBildens koordinater som ska laddasSDL_Rect vaktDel;vaktDel.x = 0;vaktDel.y = 0;vaktDel.w = 40;vaktDel.h = 40;//VaktBildens koordinater i SDL rutanSDL_Rect vaktposition;vaktposition.x = (screen->w / 2) - (vaktDel.w / 2);vaktposition.y = (screen->h - vaktDel.h + 4);vaktposition.w = vaktDel.w;vaktposition.h = vaktDel.h;SDL_Event event;while (gamerunning){timeSinceLastFrame = SDL_GetTicks() - beginTime;beginTime = SDL_GetTicks();SDLKey keyHit; if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { gamerunning = false; } if (event.type == SDL_KEYDOWN) { keyHit = event.key.keysym.sym; keysHeld[event.key.keysym.sym] = true; } if (event.type == SDL_KEYUP) { keysHeld[event.key.keysym.sym] = false; } }if (!level == 0){ if (keyHit == SDLK_ESCAPE) { if (!level == 0) currentlevel = level; level = 0; } if ( keysHeld[SDLK_LEFT] ) { gubbeposition.x -= gubbeposition.speed*timeSinceLastFrame; gubbeDel.x = 80; } if ( keysHeld[SDLK_RIGHT] ) { gubbeposition.x += gubbeposition.speed*timeSinceLastFrame; gubbeDel.x = 120; } if ( keysHeld[SDLK_UP] ) { gubbeposition.y -= gubbeposition.speed*timeSinceLastFrame; gubbeDel.x = 0; } if (keysHeld[SDLK_DOWN]) { gubbeposition.y += gubbeposition.speed*timeSinceLastFrame; gubbeDel.x = 40; } if (keyHit == SDLK_m && map == false){ map = true; keyHit = SDLK_RETURN; } if (keyHit == SDLK_m && map == true){ map = false; keyHit = SDLK_RETURN; }} if (level==0){ if (keyHit == SDLK_UP){ if (val > 1){ val -= 1; keyHit = SDLK_SPACE; } } else if (keyHit == SDLK_DOWN){ if (val < 3){ val += 1; keyHit = SDLK_SPACE; } } if (val == 1){ menyvalposition.x = 435; menyvalposition.y = 15; menyvalDel.y = 0; menyvalDel.h = 88; } if (val == 2){ menyvalposition.x = 430; menyvalposition.y = 95; menyvalDel.y = 88; menyvalDel.h = 89; } if (val == 3){ menyvalposition.x = 435; menyvalposition.y = 175; menyvalDel.y = 0; menyvalDel.h = 88; } if (keyHit == SDLK_RETURN){ if (val == 1) level = currentlevel; if (val == 2){ } if (val == 3) gamerunning = false; }} if (level==1){//Kartprickens koordinaterminimapDot.x = 28;minimapDot.y = 20;//Level byte och Block av sidorBlockDown(screen, gubbeposition); if (gubbeposition.y >= 210 && gubbeposition.y <= 230){ if (gubbeposition.x >= screen->w){ gubbeposition.x = 1; bakgrundDel.x = 640; level = 2; } } else BlockRight(screen, gubbeposition);}if (level==2){//Kollision Gubbe -> Vaktif ((gubbeposition.x + 40 >= vaktposition.x) && (gubbeposition.x <= vaktposition.x +40) && (gubbeposition.y + 40 >= vaktposition.y) && (gubbeposition.y <= vaktposition.y +40)){ gubbeposition.x = gubbex; gubbeposition.y = gubbey;}//Flytta Vaktenif (repeatBlock == false && (gubbeposition.x + 41 >= (screen->w / 2) - (vaktDel.w / 2)) && (gubbeposition.x <= (screen->h - vaktDel.h) +41) && (gubbeposition.y + 41) >= (screen->h - vaktDel.h) && (gubbeposition.y <= vaktposition.y +35)){ if (keyHit == SDLK_SPACE) keySpace = true;} if (keySpace == true){ if (vaktposition.y > 435) vaktposition.y -= 1; if (vaktposition.y == 435){ vaktDel.x = 120; vaktposition.x += 1; } if (vaktposition.x == 350){ vaktDel.x = 0; keySpace = false; repeatBlock = true; }}//Kollision Vakt -> Gubbeif ((vaktposition.x + 40 >= gubbeposition.x) && (vaktposition.x <= gubbeposition.x +40) && (vaktposition.y + 40 >= gubbeposition.y) && (vaktposition.y <= gubbeposition.y +40)){ vaktposition.x = vaktx; vaktposition.y = vakty;}//Kartprickens koordinaterminimapDot.x = 92;minimapDot.y = 20;//Level byte och Block av sidor BlockRight(screen, gubbeposition); if (gubbeposition.y >= 210 && gubbeposition.y <= 230){ if (gubbeposition.x <= 0){ gubbeposition.x = 640; bakgrundDel.x = 0; level = 1; } } if (gubbeposition.x >= 290 && gubbeposition.x <= 310){ if (gubbeposition.y == screen->h){ gubbeposition.y = 1; bakgrundDel.y = 480; level = 4; } } else { BlockDown(screen, gubbeposition); }}if (level==3){//Kartprickens koordinaterminimapDot.x = 28;minimapDot.y = 68;//Level byte och Block av sidor BlockDown(screen, gubbeposition); if (gubbeposition.y >= 210 && gubbeposition.y <= 230){ if (gubbeposition.x == screen->w){ gubbeposition.x = 1; bakgrundDel.x = 640; level = 4; } } else { BlockRight(screen, gubbeposition); }}if (level==4){//Kartprickens koordinaterminimapDot.x = 92;minimapDot.y = 68;//Level byte och Block av sidor BlockDown(screen, gubbeposition); BlockRight(screen, gubbeposition); if (gubbeposition.x >= 290 && gubbeposition.x <= 310){ if (gubbeposition.y == 0){ gubbeposition.y = 480; bakgrundDel.y = 0; level = 2; } } if (gubbeposition.y >= 210 && gubbeposition.y <= 230){ if (gubbeposition.x == 0){ gubbeposition.x = 640; bakgrundDel.x = 0; level = 3; } }}gubbex = gubbeposition.x;gubbey = gubbeposition.y;vaktx = vaktposition.x;vakty = vaktposition.y;intgubbeposition.x = (int)gubbeposition.x;intgubbeposition.y = (int)gubbeposition.y;//Gör skärmen svart efter varje loopSDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));//Hämta en del av en .BMP fil. FIL / Del av bild / Yta / bild positionif (!level == 0){SDL_BlitSurface(bakgrund, &bakgrundDel, screen, &bakgrundposition);SDL_BlitSurface(gubbe, &gubbeDel, screen, &intgubbeposition);}if (level == 0){SDL_BlitSurface(meny, &menyDel, screen, &menyposition);SDL_BlitSurface(meny, &menyvalDel, screen, &menyvalposition);}if (level == 2)SDL_BlitSurface(vakt, &vaktDel, screen, &vaktposition);if (map == true){ SDL_BlitSurface(minimap, &minimapDel, screen, &minimapposition); SDL_FillRect(screen, &minimapDot, SDL_MapRGB(screen->format, 0, 0, 0));}SDL_Flip(screen);SDL_Delay(1);}SDL_FreeSurface(gubbe);SDL_FreeSurface(bakgrund);SDL_FreeSurface(minimap);SDL_FreeSurface(meny);SDL_FreeSurface(vakt);SDL_Quit();return 0;}[Edited by - zippo88 on April 6, 2009 9:22:43 AM]
My problem seems to be that the framerate is already too low. capping it i don't think will help. I am running vista 64 bit, and the game slows down if i use 2 big objects in one frame. Like i have the background and then i have a house in it's own image, because the house changes from outside view to inside view depending if you are outside or inside. I don't think rendering 2 objects should make my charachter slow down, and sure it could be as you say the framerate but i think he should walk smoother if my framerate is like 200, and then 150 with the house. I can make a rar of my game and post it here if you want to try and see for yourself the differance.
Walk right and press space on the guard to make him move, and then walk down to get to the level where it runs a bit slower. Note that i haven't added collision detection on the house yet but you can still walk in and out of the house by using the door to the right.
Try it and tell me if it seems correct that it should slow down like 1/4th.
http://rapidshare.com/files/219343870/SDLSpel.rar.html
Walk right and press space on the guard to make him move, and then walk down to get to the level where it runs a bit slower. Note that i haven't added collision detection on the house yet but you can still walk in and out of the house by using the door to the right.
Try it and tell me if it seems correct that it should slow down like 1/4th.
http://rapidshare.com/files/219343870/SDLSpel.rar.html
Ok i tested something. Formatting the surfaces, and it didn't do anything at all for my game. This is how it was before:
//Video
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO );
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("SDLSpel", 0);
//Load PNG Files
SDL_Surface* meny = IMG_Load("Meny.png");
SDL_Surface* bakgrund = IMG_Load("Bakgrund.png");
SDL_Surface* minimap = IMG_Load("Minimap.png");
SDL_Surface* gubbe = IMG_Load("Gubbe.png");
SDL_Surface* vakt = IMG_Load("Vakt.png");
SDL_Surface* hus = IMG_Load("Hus.png");
// Hide Magneta Color
SDL_SetColorKey(meny, SDL_SRCCOLORKEY, SDL_MapRGB(meny->format, 255, 0, 255));
SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255));
SDL_SetColorKey(vakt, SDL_SRCCOLORKEY, SDL_MapRGB(vakt->format, 255, 0, 255));
and i added this:
//Format surfaces
SDL_Surface* SDL_DisplayFormat(SDL_Surface* meny);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* bakgrund);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* minimap);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* gubbe);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* vakt);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* hus);
Is it done correctly? Because it didn't help framerate at all.
Edit: Can you tell me what those new lines does compared to this other line i found: newsurface = SDL_DisplayFormat(surface);
I'm gonna try removing my Format surfaces that i added there and try this:
SDL_Surface* fmeny = SDL_DisplayFormat(meny);
and see if that works any better. Some help would be appreciated of how you use this since wiki didn't explain it very good for a beginner in sdl.
[Edited by - zippo88 on April 9, 2009 12:46:19 PM]
//Video
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO );
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("SDLSpel", 0);
//Load PNG Files
SDL_Surface* meny = IMG_Load("Meny.png");
SDL_Surface* bakgrund = IMG_Load("Bakgrund.png");
SDL_Surface* minimap = IMG_Load("Minimap.png");
SDL_Surface* gubbe = IMG_Load("Gubbe.png");
SDL_Surface* vakt = IMG_Load("Vakt.png");
SDL_Surface* hus = IMG_Load("Hus.png");
// Hide Magneta Color
SDL_SetColorKey(meny, SDL_SRCCOLORKEY, SDL_MapRGB(meny->format, 255, 0, 255));
SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255));
SDL_SetColorKey(vakt, SDL_SRCCOLORKEY, SDL_MapRGB(vakt->format, 255, 0, 255));
and i added this:
//Format surfaces
SDL_Surface* SDL_DisplayFormat(SDL_Surface* meny);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* bakgrund);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* minimap);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* gubbe);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* vakt);
SDL_Surface* SDL_DisplayFormat(SDL_Surface* hus);
Is it done correctly? Because it didn't help framerate at all.
Edit: Can you tell me what those new lines does compared to this other line i found: newsurface = SDL_DisplayFormat(surface);
I'm gonna try removing my Format surfaces that i added there and try this:
SDL_Surface* fmeny = SDL_DisplayFormat(meny);
and see if that works any better. Some help would be appreciated of how you use this since wiki didn't explain it very good for a beginner in sdl.
[Edited by - zippo88 on April 9, 2009 12:46:19 PM]
Wow. The game is much much faster now when i did it like this:
//Video
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO );
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("SDLSpel", 0);
//Ladda BMP fil
SDL_Surface* meny = IMG_Load("Meny.png");
SDL_Surface* bakgrund = IMG_Load("Bakgrund.png");
SDL_Surface* minimap = IMG_Load("Minimap.png");
SDL_Surface* gubbe = IMG_Load("Gubbe.png");
SDL_Surface* vakt = IMG_Load("Vakt.png");
SDL_Surface* hus = IMG_Load("Hus.png");
// Göm färgen Magneta för bild
SDL_SetColorKey(meny, SDL_SRCCOLORKEY, SDL_MapRGB(meny->format, 255, 0, 255));
SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255));
SDL_SetColorKey(vakt, SDL_SRCCOLORKEY, SDL_MapRGB(vakt->format, 255, 0, 255));
SDL_Surface* fmeny = SDL_DisplayFormat(meny);
SDL_Surface* fbakgrund = SDL_DisplayFormat(bakgrund);
SDL_Surface* fminimap = SDL_DisplayFormat(minimap);
SDL_Surface* fgubbe = SDL_DisplayFormat(gubbe);
SDL_Surface* fvakt = SDL_DisplayFormat(vakt);
SDL_Surface* fhus = SDL_DisplayFormat(hus);
//Video
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO );
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("SDLSpel", 0);
//Ladda BMP fil
SDL_Surface* meny = IMG_Load("Meny.png");
SDL_Surface* bakgrund = IMG_Load("Bakgrund.png");
SDL_Surface* minimap = IMG_Load("Minimap.png");
SDL_Surface* gubbe = IMG_Load("Gubbe.png");
SDL_Surface* vakt = IMG_Load("Vakt.png");
SDL_Surface* hus = IMG_Load("Hus.png");
// Göm färgen Magneta för bild
SDL_SetColorKey(meny, SDL_SRCCOLORKEY, SDL_MapRGB(meny->format, 255, 0, 255));
SDL_SetColorKey(gubbe, SDL_SRCCOLORKEY, SDL_MapRGB(gubbe->format, 255, 0, 255));
SDL_SetColorKey(vakt, SDL_SRCCOLORKEY, SDL_MapRGB(vakt->format, 255, 0, 255));
SDL_Surface* fmeny = SDL_DisplayFormat(meny);
SDL_Surface* fbakgrund = SDL_DisplayFormat(bakgrund);
SDL_Surface* fminimap = SDL_DisplayFormat(minimap);
SDL_Surface* fgubbe = SDL_DisplayFormat(gubbe);
SDL_Surface* fvakt = SDL_DisplayFormat(vakt);
SDL_Surface* fhus = SDL_DisplayFormat(hus);
I've capped my FPS now i think. I did it like this:
timeSinceLastFrame = SDL_GetTicks() - beginTime;
beginTime = SDL_GetTicks();
if (timeSinceLastFrame < 12)
SDL_Delay(12 - timeSinceLastFrame);
I didn't read that guide about how to fps cap i just thought of how i could use the timer to do such a thing. And this seems to work quite good. With this i cap my fps at 83.
With this if it's above 83 fps (12 milliseconds / frame) it will delay 12 milliseconds - timeSinceLastFrame. So if the frame took 6 milliseconds (166fps) it will delay another 6 seconds.
Is this a good way to do it you think? It runs fine for my computer and i doubt most computers will go below that fps for this game.
Edit: I made the math for converting fps to milliseconds in the program instead. like this:
//Change this to change the fps cap
const long FPS_CAP = 85;
long msPerFrame = 1000 / FPS_CAP;
and in the gameloop:
//Limit FPS.
timeSinceLastFrame = SDL_GetTicks() - beginTime;
beginTime = SDL_GetTicks();
if (timeSinceLastFrame < msPerFrame)
SDL_Delay(msPerFrame - timeSinceLastFrame);
//
[Edited by - zippo88 on April 9, 2009 7:20:26 PM]
timeSinceLastFrame = SDL_GetTicks() - beginTime;
beginTime = SDL_GetTicks();
if (timeSinceLastFrame < 12)
SDL_Delay(12 - timeSinceLastFrame);
I didn't read that guide about how to fps cap i just thought of how i could use the timer to do such a thing. And this seems to work quite good. With this i cap my fps at 83.
With this if it's above 83 fps (12 milliseconds / frame) it will delay 12 milliseconds - timeSinceLastFrame. So if the frame took 6 milliseconds (166fps) it will delay another 6 seconds.
Is this a good way to do it you think? It runs fine for my computer and i doubt most computers will go below that fps for this game.
Edit: I made the math for converting fps to milliseconds in the program instead. like this:
//Change this to change the fps cap
const long FPS_CAP = 85;
long msPerFrame = 1000 / FPS_CAP;
and in the gameloop:
//Limit FPS.
timeSinceLastFrame = SDL_GetTicks() - beginTime;
beginTime = SDL_GetTicks();
if (timeSinceLastFrame < msPerFrame)
SDL_Delay(msPerFrame - timeSinceLastFrame);
//
[Edited by - zippo88 on April 9, 2009 7:20:26 PM]
I read that SDL_Delay is inaccurate, so i did time based movement again. Although for some reason the fps capping gets much better movement result. Probably because it never needs to move 2 pixels instead of 1. Or it's just me who don't know how to convert from double to int in a good way or something. I do get a warning that i am converting it from double to int. But it runs.
I have set it so i can enable and disable time based movement and enable and disable FPS cap, so i don't have to do time based movement all over again if i want to try it again with a slight change.
So if you've got any tips of what i could change please tell me.
This is what is holding the double values for me.
and here i put them as ints in my SDL_Rect: (right before i draw it to the screen).
Help appreciated as always :)
I have set it so i can enable and disable time based movement and enable and disable FPS cap, so i don't have to do time based movement all over again if i want to try it again with a slight change.
So if you've got any tips of what i could change please tell me.
This is what is holding the double values for me.
if (timeMovement == true){ if ( keysHeld[SDLK_LEFT] ) { gubbepos.x -= gubbepos.speed * timeSinceLastFrame; gubbeDel.x = 80; } if ( keysHeld[SDLK_RIGHT] ) { gubbepos.x += gubbepos.speed * timeSinceLastFrame; gubbeDel.x = 120; } if ( keysHeld[SDLK_UP] ) { gubbepos.y -= gubbepos.speed * timeSinceLastFrame; gubbeDel.x = 0; } if (keysHeld[SDLK_DOWN]) { gubbepos.y += gubbepos.speed * timeSinceLastFrame; gubbeDel.x = 40; }}and here i put them as ints in my SDL_Rect: (right before i draw it to the screen).
if (timeMovement == true){gubbeposition.y = gubbepos.y;gubbeposition.x = gubbepos.x;}Help appreciated as always :)
make a function like lazyfoo does:
this is how i do the frame rate stuff:
SDL_Surface *load_image( std::string filename ){ //Temporary storage for the image that's loaded SDL_Surface* loadedImage = NULL; //The optimized image that will be used SDL_Surface* optimizedImage = NULL; //Load the image loadedImage = SDL_LoadBMP( filename.c_str() ); //If nothing went wrong in loading the image if( loadedImage != NULL ) { //Create an optimized image optimizedImage = SDL_DisplayFormat( loadedImage ); //Free the old image SDL_FreeSurface( loadedImage ); } //Return the optimized image return optimizedImage;}this is how i do the frame rate stuff:
const int SCR_FPS = 60;int ticks = 0;while(1){ //get ticks ticks = SDL_GetTicks(); //all rendering and stuff here //frame rate if(((signed)SDL_GetTicks()-ticks) < (1000/SCR_FPS)) { SDL_Delay((1000/SCR_FPS) - (SDL_GetTicks()-ticks)); }}Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement