Showing posts with label framework. Show all posts
Showing posts with label framework. Show all posts

Wednesday, October 29, 2008

Understanding frameworks by example...2


Step 3: Check your code so far, revise and optimize


All might seem rosy at the moment but when you try out this code…you’ll notice that

1) Frame rates vary widely, some systems show FPS of up to 150 and some about 30
To ensure frame-rate consistency we’ll add ensureMinFPS() and ensureMaxFPS() functions. This can be done by skipping calls too render() function, also known as frame skipping.

That means we update status like 3 times but only draw it once onto the screen. The result is that the sprite may seem to be moving with large steps and may damage smoothness. But that’s the PC's problem nothing to do with us. Also we could add a convenience method getCurrentFPS(), just to check the performance.

2) For animating a moving object like a man, we’ll have to cycle through a set of images…
This requires some handling which is again redundant. So we’ll add AnimatedSprite class. This class may contain methods such as addFrame(Image img, long persistenceTime);

We’ll extend this class with Renderable.class so that its update and render methods can be utilized by the Game.class when registered with it.
@Override
public void update(long time)
{
Image curFrame = frames.get(curFrameIndex);
animTime += elapsedTime;

if(animTime >= curFrameduration)
{
curFrameIndex++;

//provides roll-over for animTime accurately...
animTime = animTime % curFrame.duration;

if(curFrameIndex == frames.size())
curFrameIndex = 0;
}
}
But sprites can move to...So we could use xSpeed, ySpeed and update them using:
xPos += xSpeed * (elapsedTime);
yPos += ySpeed * (elapsedTime);
this xPos and yPos could be utilized in render()
drawImage(getCurFrame() ,xPos,yPos);

Now re-run your code again. This time when you add sufficient renderable objects to your game, you’ll notice Overlapping.

i.e., the object added first is drawn first…
how will it seem if the graphics of a tree is being drawn after drawing man??


Forgive me for my crappy drawing…that’s the best I can come up with!
The problem occurs because in run() method of Game.class, we use:
for(int i=0 to numRenderable)
{
arrRenderable.get(i).update(curTime - prevTime);
arrRenderable.get(i).render();
}
avoid this we could modify addRenderableObject as
//image with smallest index is drawn 1st…
addRenderableObject (Renderable rend, int index)
{
arrRenderable.add(rend, index);
}
Now that the drawing order can be determined, overlapping won’t be a problem.

So far we have managed:
- Screen management, ensure min frame rate, a generic Renderable class that can be used with Game class followed by easier Animation handling.

Now imagine that you’re coding the game using THIS framework, suppose the game works on 500 images…you probably will have to load all the images @ startup and show a progress bar like loading or something…Now we’ll integrate this feature into this framework

Lets design a class called ResourceBox, that holds all the images.
public abstract class ResourceBox
{
Private HashMap hm = new HashMap();

//this is where you’ll load all the images…or ne other stuff
Public abstract void init();

Public void add(String id, Image img)
{
hm.put(id, img);
}

//methods such as remove, replace and so on…
//Include a method getImage(String Id)
}
We first create a ResourceBox object as:
ResourceBox rb = new ResourceBox()
{
@Override
Public void init()
{
//Load whatever resources you want…
//Ex – add(“man”, imgMan);
}
}
Remember the Game class…?
How do we register this object with the game class??
Game(ResourceBox rb)
{
//Copy this ref into a private variable within game class
}
This is how the game would run previously:
run()
{
Init();
Game loop
{

}
}
Here we plug in a bit of code:
run()
{
Init();
If(rb != null)
rb.init();
Game loop
{

}
}
Also we’ll add a utility method to game class as:
public ResourceBox getResourceBox();
This method is needed as we could use:
Image man = gameObj.getResourceBox().get(“man”);
Cool eh?

What about the progress bar??
We can’t provide an implementation as it would restrict the user from customizing/ making his own style of progress bar. More-over the user defined Loading screen or whatever must be shown when rb.init() method is called.

We’re gonna try some sort of an event listener kinda thingy. Here goes:

Include a method in ResourceBox.class
public void registerListener(Listener l);

//This is how Listener’s defined
Public class Listener
{
Public abstract void onInit(Graphics g);
}
First of all user’s gotta create an obj of Listener class for which you HAVE TO override the onInit() method
Listener l = new Listener()
{
@Override
Public void onInit(Graphics g)
{
//Draw your stuff on this graphics context…
//Ex = ((Graphics2D)g).do any thing();
}
}
Now we’ll also include a method getRegisteredListener() in ResourceBox.class
We now modify the game class run method as follows:
run()
{
Init();
if(rb != null)
{
Listener l = rb.getRegisteredListener();
If(l != null)
{
// Assuming we have some hypothetical screen management class
Graphics g = ScreenManager.getGraphics();
l.onInit(g);
}
rb.init();
g.dispose();// or clear…
}

Game loop
{

}
}
Now user can show a progress bar or…loading screen with his/her own graphics style…
So here’s a short summary,

- Abstract methods and stuff is absolutely integral in designing a good framework
(Primarily to give user the control of things, just as swing lets us control the shape of a button)

- You might need event listeners in case where your internal handling code needs to call something…like the onInit() we just discussed (swing provides action listeners etc…to a button which are automatically called on mouse click on that component, hope you can associate this with the onInit())

- Let your imagination run wild…experiment, try, you’ll eventually be able to write the top notch code. Okay, enough philosophy I suppose lets move further.

Go back to step 2:

The best way to add new feature(s) to your framework is like I said can be done by imagining the usage. So let’s start with some analysis...how do we integrate sounds? After all any game would suck without sounds…

In my next blog I’ll put up a nice UML diagram of the concepts so far and also discuss sound integration. As always, do comment and help me improve my posts.

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…