Skip to main content
GameDev.net gamedev.net
🔒 Locked

I quit SDL :(

Started by Paprica Sep 17, 2010 at 9:06 AM 12 replies 2.6k views
Original Post
Paprica
Paprica
It's too simple I guess.

I'm looking for a library that can draw surfaces but treat them as "objects" so that they can actually "move" or accept effects without being needed to be drawn again.
Paprica
Paprica
I know what you mean but take a look at this function I didn't finish writing:
void MoveSurface(SDL_Surface* src, SDL_Surface* dst, SDL_Surface* bg, int x, int y, int delay){	int plusx;	int plusy;	float stepx = 1.0f;	float stepy = 1.0f;	int i = 1;		if(x > src->clip_rect.x)	{		plusx = 1;	}	else if(x < src->clip_rect.x)	{		plusx = -1;	}	else	{		stepx = 0;	}	if(y > src->clip_rect.y)	{		plusy = 1;	}	else if(y < src->clip_rect.y)	{		plusy = -1;	}	else	{		stepy = 0;	}	if(stepx != 0 && stepy != 0)	{		if(diff(x,src->clip_rect.x) > diff(y,src->clip_rect.y))		{			stepy = (float) diff(x,src->clip_rect.x) / (diff(y,src->clip_rect.y) +1);		}		else		{			stepx = (float) diff(y,src->clip_rect.y) / (diff(x,src->clip_rect.x) +1);		}	}	float movex = stepx;	float movey = stepy;	int srcstartx = src->clip_rect.x;	int srcstarty = src->clip_rect.y;	SDL_Surface* old_dst = dst;	SDL_Rect dst_rect;	while (src->clip_rect.x != x || src->clip_rect.y != y)	{		if(src->clip_rect.x != x && i >= movex)		{			dst_rect.w = 1;			dst_rect.h = 1;			if(plusx < 0)			{				dst_rect.x = src->clip_rect.x + src->clip_rect.w - 1;				for(dst_rect.y = src->clip_rect.y;dst_rect.y < src->clip_rect.y + src->clip_rect.h;dst_rect.y++)				{					if(dst_rect.y > srcstarty)					{						SDL_BlitSurface(old_dst,&dst_rect,dst,&dst_rect);					}					else					{						SDL_BlitSurface(bg,&dst_rect,dst,&dst_rect);					}				}			}			else			{				dst_rect.x = src->clip_rect.x;				for(dst_rect.h = 1;dst_rect.h < src->clip_rect.h;dst_rect.h++)				{					if(dst_rect.y + dst_rect.h > srcstarty)					{						SDL_BlitSurface(dst,&dst_rect,dst,&dst_rect);					}					else					{						SDL_BlitSurface(bg,&dst_rect,dst,&dst_rect);					}				}			}			src->clip_rect.x += plusx;			SDL_BlitSurface(src,NULL,dst,&src->clip_rect);			movex += stepx;		}		if(src->clip_rect.y != y && i >= movey)		{			dst_rect.x = src->clip_rect.x;			dst_rect.w = src->clip_rect.w;			dst_rect.h = 1;			if(plusy < 0)			{				dst_rect.y = src->clip_rect.y + src->clip_rect.h - 1;			}			else			{				dst_rect.y = src->clip_rect.y;			}			SDL_BlitSurface(bg,&dst_rect,dst,&dst_rect);			src->clip_rect.y += plusy;			SDL_BlitSurface(src,NULL,dst,&src->clip_rect);			movey += stepy;		}				//SDL_UpdateRect(dst,src->clip_rect.x - 1 ,src->clip_rect.y - 1,src->clip_rect.w + 1, src->clip_rect.h + 1);		SDL_Flip(dst);		i += 1;		SDL_Delay(delay);	}}


All that just for smoothly moving a surface across the screen.
CodeMunkie
CodeMunkie
So every time you want to move an object, your entire game blocks in the while loop until the object reaches it's destination? I think there is a better way. Generally, you have a "game loop" where you get input from the user, compute a game time tick, update object position, update game state, repeat. Since you are doing that over and over, you get the illusion of objects moving around your game world. The game loop is a basic concept of real-time games and is not dependent on which library you choose to use.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
Paprica
Paprica
Kinda thought of executing the function in a separate thread.
Dunge
Dunge
Whichever graphic library you use, it will be the same. Your problem is not with SDL, it's with building a good game architecture in your program. I personally have a "RenderEntity" class, each of then have it's own SDL_Surface and it's own position and move() function. Every frame, I iterate every object (which I have in a list), and blit them using their position if they are visible on the screen.
owl
owl
Quote:
Original post by Servant of the Lord
SFML does that. I personally dislike my images being intelligent and trying to do things for me, but, meh, to each his own.

SFML - Simple Fast Media Library (C++)


This looks good. I'm gonna give it a try. Thanks.
[size="2"]I like the Walrus best.
Paprica
Paprica
Quote:
Original post by Dunge
Whichever graphic library you use, it will be the same. Your problem is not with SDL, it's with building a good game architecture in your program. I personally have a "RenderEntity" class, each of then have it's own SDL_Surface and it's own position and move() function. Every frame, I iterate every object (which I have in a list), and blit them using their position if they are visible on the screen.

I still don't get what you and CodeMunkie mean. Could you post here a simple example?

Let's say I have a background image and a button drawn on it. How do I smoothly move that button inside the game loop without forcing the whole loop operation to wait until it's finished?
CodeMunkie
CodeMunkie
Quote:
Original post by Paprica
Quote:
Original post by Dunge
Whichever graphic library you use, it will be the same. Your problem is not with SDL, it's with building a good game architecture in your program. I personally have a "RenderEntity" class, each of then have it's own SDL_Surface and it's own position and move() function. Every frame, I iterate every object (which I have in a list), and blit them using their position if they are visible on the screen.

I still don't get what you and CodeMunkie mean. Could you post here a simple example?

Let's say I have a background image and a button drawn on it. How do I smoothly move that button inside the game loop without forcing the whole loop operation to wait until it's finished?


It's a great question, and of course there are many solutions. In general, you make small updates on each pass through your game loop, and you run the game loop as fast as possible. So it's really all an illusion, you just do the updates in small steps and run those steps very often so that it looks smooth to the player. The canonical game loop looks like this in pseudo code:
while(running)    delta_time = computeGameTick()    getInput()    updateUI(delta_time)    doAI()    updatePositions(delta_time)    resolveCollisions()    draw()


delta_time is going to be a very small time slice, on the order of 10-16ms (60-100 FPS).
You will need to become familiar with the basics of integration of an object's position over time. Let's say you have an object in motion. The object has a velocity of 100 units/second (units can be meters, pixels, whatever). For simplicity let's say that 1 unit = 1 pixel. Now you need to do some sort of integration over time to update the position of your object. When 1 second of time has passed, your object should have traversed 100 pixels. After 2 seconds, 200 pixels, and so on. So your updatePositions() function might look like this:
function updatePosition(delta_time)    object.x += object.velocity.x * delta_time    object.y += object.velocity.y * delta_time


Let's assume that our object is at x=50,y=100 with velocity.x=100 and velocity.y=0. Look at what happens to object.x over a period of 1 second assuming that we are getting 10ms delta_time time steps:
t0 - object.x = 50 - elapsed time 0.0t1 - object.x = 60 - elapsed time 0.1t2 - object.x = 70 - elapsed time 0.2t3 - object.x = 80 - elapsed time 0.3t4 - object.x = 90 - elapsed time 0.4t5 - object.x = 100- elapsed time 0.5t6 - object.x = 110- elapsed time 0.6t7 - object.x = 120- elapsed time 0.7t8 - object.x = 130- elapsed time 0.8t9 - object.x = 140- elapsed time 0.9t10- object.x = 150- elapsed time 1.0


In 1 second our object has moved 100 pixels, just as we expected. To the user, the transition was smooth and natural looking because we did a small update, then a draw, a small update, then a draw, and so on. And if you look back at the game loop, we also allow user input, AI update, game state updates, and so the entire experience feels very responsive to the user.
Now that is the very basic idea, but there are quite a few things you need to be aware of when doing your integration step. Also, I didn't even discuss HOW to compute the delta_time. I would suggest you do the simplest implementation that you can on your own that works correctly, and then read this article which explores the topic in detail.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
Paprica
Paprica
What about moving the whole surface in a separate thread with SDL_Delay in it?
popsoftheyear
popsoftheyear
@Paprica - Is that what you would also do if you had, say, hundreds of objects that moved around? Or even 20? Instantiate that many threads?
Paprica
Paprica
Wouldn't it be the same as handling those hundred objects in the event loop?
rip-off
rip-off
Certainly not. Threads are a way too complex solution, if it can be called a solution. Threading is a major architectural choice. A thread is expensive to create, you generally want to aim for roughly the same number of threads as logical processors on the computer.

As for your original question, SDL is the "Simple DirectMedia Layer". It is not a high level sprite library. What you are looking for is something between such a sprite library or perhaps approaching a full 2D game engine.
rombust
rombust
Quote:
... What you are looking for is something between such a sprite library or perhaps approaching a full 2D game engine.


I would recommend having a look at ClanLib.

ClanLib contains everything for a full 2D game engine. Although it can be tricky to learn for new users. It has a free BSD style license so it can be used commercially without restriction.

See - http://clanlib.org/wiki/Examples


Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.