Thursday, September 25, 2008

Understanding Frameworks by example...1

You all must have heard about it, .Net, Swing etc.
So what exactly is this ‘framework’?

Simply put, it is a set of properly organized classes and packages with many features to offer.
In case you want to make one, proper planning and design is a must.

lets take the well known ‘swing ‘ in java
To create a frame all we gotta do is:

new JFrame().setVisible();
If I remember correctly, using windows.h in c++ we need to write a 100+ lines of code just to do that. Creating a simple frame involves registering the handleInstance and some other init steps. Moreover its just a simple frame. It we wanted to add a label to it, it’d take another 20-40 lines to do that. In swing its as simple as:
frame.add(new JLabel());
In a sense most of the code is redundant (no one remembers all that init code, they just copy, paste it and modify it at a few places). That’s where a framework is needed. To avoid redundant stuff and provide several layers of abstraction over the inner mess that’s going on.

Also swing manages repaints very cleverly, suppose we have a frame with blue background and a label with green background. Then the background is to be drawn first onto the screen followed by drawing the label. What’s more, it provides a lot of customization which could be achieved by over-ridding a few key methods.

For example to make the button round all you gotta do is over-ride the necessary shaping method that swing calls internally to display a button.

Now if you’re up to it lets try to design a 2D game framework.

Step 1: Identify the requirements


So what could we do to simplify 2D game designing??
Here’s a few that I figured

1) Screen management (change resolution, manage double buffering etc…)
2) Input management (Keyboard polling and mapping)
3) Animations Management (sprite handling)
4) Sound management (sound effect and stuff)

There are many more to it but I’d like to keep it simple

Step 2: Imagine the usage

For a moment let us assume that the framework is designed.
Then how would it help simplifying game programming??

First we’ll discuss a few basics of game programming
This is typically called ‘The game loop’
loop
{
//Update status of the game objects
//Render graphics onto the screen(typically by using double buffering)

//Provide a certain delay…so that the game doesn’t seem to be
//Running like a cheetah
}
As most of you might have already faced, this poses a severe problem...the delay is the villain here. The game runs at different speeds on different processors because of variable instruction execution speed but a fixed delay. To prevent this, we synchronize the events to a global Timer
prevTime = getTimeInNanos();
loop
{
curTime = getTimeInNanos();
//Update status of the game objects using (curTime – prevTime)
//Render graphics onto the screen
prevTime = curTime;
}
getTimeInNanos() returns an arbitrary timer, it can be the bios timer ticks or OS dependent timer. In JAVA one could use System.nanoTime()

And what about pausing and resuming the game??
The threads sleep and notify needs to be handled within the loop itself

Also we should provide a way to handle screen resolution change…
Also to avoid flickering double buffering must be done
Most of this is almost a necessity to be handled and furthermore this stuff is redundant
So we could add all these features into a class, lets call it Game
public abstract class Game extends Thread
{
Public abstract void init();
public void startGame();
public void stopGame();
public void pauseGame();
public void resumeGame();
public void setScreenRes(int width, int height) throws NotSupportedResException
}
init method is supplied as abstract so that user may customize it to his needs. All the Renderable objects (sprites as a few call it) have the update() and render() associated with it. So why not make a class called Renderable as:
public abstract class Renderable
{
//update status calculations here…parameter time is the num of seconds elapsed since
//last call
Public void abstract update(long time);

//all the graphics are to be drawn onto this graphics object…
public void abstract render(Graphics g);
}
Using abstract methods one of the most commonly used techniques in JAVA.
With this you tell the user to over-ride these methods in order to be used…
(Instead of telling them to create a class which HAS TO contain update(long) and render() functions, which would in turn be used for internal purposes)

Then we could do:
game.addRenderableObject(rendObj);
and in the Game class we could use:
private Arraylist arrRenderable;
addRenderableObject(Renderable rend)
{
arrRenderable.add(rend);
}
the run() in Game can be coded to handle thread start,stop,resume,pause and automatically calls all the registered Renderable objects update and render methods…
this is what how run() would look like:
public void run()
{
init();
prevTime = getTimeMillis();

while(!isStopped)
{
curTime = getTimeMillis() - pausedTime;
pausedTime = 0;

for(int i=0 to numItemsRegistered)
{
arrRenderable.get(i).update(curTime - prevTime);
arrRenderable.get(i).render();
}

if(isPaused)
{
pausedTime = getTimeMillis();
while(isPaused)
{
Graphics g = screen.getGraphics();
screen.drawFrameContents(g);
g.dispose();
scr.updateGraphics();
}
pausedTime = getTimeMillis() - pausedTime;
}
prevTime = curTime;
}
}

public void pauseGame()
{
isPaused = true;
}

public void stopGame()
{
isStopped = true;
}
Hope you got the whole picture here…
I suppose that’s enough stuff for now, I’ll add more in my next post. Do comment…