Modern languages like Java or C# allow programmers to create new objects dynamically using class name ( ie. Class.forName() in Java ). This feature is not easy available in C++. The question is why to use any class factory at all? Basically, if you're a game programmer you should already know about such things like serialization and deserialization processes. Also, if you own a class factory then it's way easier to control all the allocations and memory usage.
I'm gonna show here is more like idea rather than fully working solution. Although it works on my side, here I had to cut down the code to make it clearer and to not reveal any commercial parts of course.
My major goal was to create a mechanism that didn't require any changes in any class ( for example I didn't want to have to implement any factory base class and stuff ). To use it you just have to call one macro anywhere inside any function ( and of course include proper header but this is kinda obvious ;) ).
Let's see some code. First I have implemented class CClassFactoryWorker. It's template based solution which gets new implementation for each class T. Also it stores a class name so it's gonna be easier to check if it really created an object of correct class.
template <typename T> class CClassFactoryWorker { public: static T * GetClass() {
std::cout << "returning class " << s_ClassName << std::endl;
Second part is an actual factory class. First take a look at the code below:
class CClassFactory { public:
typedef void * ( *ptr ) ( void );
template void RegisterClass( T * n, const char * name ) { ptr p = (ptr)(CClassFactoryWorker::GetClass); strcpy( CClassFactoryWorker::s_ClassName, name ); s_cfl.push_back( pair( HashString( name ), p ) ); }
void * GetClass( int idx ) { ptr p = (ptr)(pair(s_cfl[idx]).second); return p(); }
As you can see, there's type definition of a function pointer. It's just generic type that I could use for casting GetClass() functions. It always fits since any object pointer can be converted to (void*). RegisterClass() adds that function pointer and also hash value of string that represents the class name to the end of static vector. GetClass() is very simplified and it doesn't do any lookup yet, I just wrote this version this way to get clearer picture of whole thing. GetClass() takes one argument which is an index of element in s_cfl vector. Very last thing is to declare macro which does all the registration:
And this is all. Now you should be able to use it as below:
int main() { A * base = new A();
REGISTER_CLASS( A ); // registering class A REGISTER_CLASS( B ); // registering class B
CClassFactory::s_Singleton.GetClass(0); // create object of class A ( index 0 in s_cfl ) CClassFactory::s_Singleton.GetClass(1); // create object of class B ( index 1 in s_cfl )
return 0; }
Just in case, code I pasted in this blog is created for showing purposes and I don't guarantee it's gonna even compile ( ie. you may not have HashString() function ). I hope it's gonna help you to write your own class factory.
While I was checking out XNA stuff I saw many tutorials and examples of animated particles. WIth XNA it’s rather simple task. I tried to go a little harder way and implement similar solution on J2ME compatible device.
Particles are objects which have their own lifetime and specific motion behavior. After the time is up they just simply disappear. Particle system must handle multiple objects considering that they may own different motion behavior and also different lifetime.
Because mobile devices are rather slow I decided to use a bit more memory and created sprite images for each shading/blending level. All sprites are generated by the midlet. There are no PNG files but for making more fancy particles I’d rather go with PNG images. In this case there was no such need. There’s lot to be optimize yet but I’ve made my particle system in half an hour just for checking if the idea works ;).
for (int i = 1; i < SHADING_LEVELS; i++) { alphaValue += alphaStep;
for (int p = 0; p < particlePixels[0].length; p++) { int originalAlpha = (particlePixels[0][p] >> 24) & 0xFF; int newAlpha = originalAlpha - (alphaValue >> Maths.FP); if (newAlpha < 0) { newAlpha = 0; } particlePixels[i][p] = ((newAlpha & 0xFF) << 24) | (particlePixels[0][p] & 0xFFFFFF); } }
}
Each particle owns the following properties:
- life time in millis - x and y coords - motion listener
The motion listener uses ParticleSprite.ParticleMotionListener inner interface:
public interface ParticleMotionListener { public void updateParticlePosition(ParticleSprite s, int x, int y, int timeInMillis, int tickNumber); }
The method updateParticlePosition() takes current sprite, its coordinates, time that tells how “old” particle is in millis and number of tick/update as arguments. Variable timeInMillis and tickNumber are initialized with first particle update. tickNumber is initially set to 0 and timeInMillis takes current time as default.
All particles are part of particles pool. For current case I used Vector type to keep all elements together but it might be better to allocate an array of N elements and instead of adding/removing it from Vector better way could be to enable/disable specific particle. Maybe next time I will update it. I also implemented release pool that holds all elements which are marked to be terminated. In other words the update goes through following steps:
For each particle: - update current particle - if particle life time is over, mark particle to be removed and add it to release pool For each particle marked to be removed: - get particle object - remove its reference from particle pool - after all is done clear release pool
This is how updateSystem() method is implemented:
public static void updateSystem() { final int size = particleCount = vecParticleSystemPool.size();
if ( size == 0 ) { return; }
final long currentTime = System.currentTimeMillis();
final int removeSize = vecParticleRemoveSystemPool.size();
for ( int i = 0; i < removeSize; i++ ) { ParticleSprite sprite = (ParticleSprite)vecParticleRemoveSystemPool.elementAt(i); vecParticleSystemPool.removeElement( sprite ); }
Painting is even simpler, I don’t think it requires any additional comment:
public static void paintSystem(Graphics g) { final int size = vecParticleSystemPool.size(); for (int i = 0; i < size; i++) { ParticleSprite sprite = (ParticleSprite) vecParticleSystemPool.elementAt(i); int level = (int) (sprite.m_lastUpdateTime * SHADING_LEVELS) / sprite.m_lifetime;
This is actually everything. As you can see it’s not very complex.
The application handles two modes. First is auto smoke. It just generates smoke-like effect. Second mode is called DRAGGING and lets user make particles by dragging stylus/finger over the screen. Of course it’s only working if device has touch screen. Otherwise there’s no use for DRAGGING mode.
You might be worried about overall performance and if it’s worth using in any game. Certainly it requires good device. It won’t work with low-end phones so particles should be optional for better phones. I did some tests and phones like SE K700i, K750, K610, W890, W910i handled it really well and they can draw particles in game. Moreover, they can call initSystem() method and reinitializing is immediate. It means they may change color or size of particle on fly.
It’s hard to not notice that use of memory is pretty big. Lets say we have 16 shading levels and particles 32×32. This will take 64kb of ram for single particle. If we want to have more particle patterns ( for example different colors ) then we’ll have to use even more memory. Of course we can reduce number of shading levels but there’s one more optimization that comes to my head. Basically, each particle is a circle. It means we can generate only one quarter ( left top quarter ) and draw other quarters using manipulations. This will reduce amount of used memory by 4 times! 32×32 particles will take 16kb of ram. Sure it’s gonna work well only with devices with really fast drawRGB() but this is a battle and all tricks are allowed
To show better use of the system when I find a little of time I’ll try to make the effect a part of game-like application. For now take a look at simple demo:
“Circuit” is very simple game. The idea is based on the minigame from “Ratchet & Clank: ToD” for PS3. The player controls a ball to close a circuit whenever impulse is about to jump from one end of track onto another. The goal is to unlock electronic lock. Each impulse may split or collide with another one ( which makes them both disappear ). In oroginal PS3 minigame a player was supposed to use Six-Axis controller. Mobile game uses the accelerometer to control the ball.
As a base device I used SonyEricsson W910i which supports JSR256 quite well. Very first thing I had to do was enabling and implementing entire sensor related functionality.
I moved entire sensor implementation to the separated class which is called Accelerometer. This is how it looks:
/* dataReceived() is not optimized yet and contains some weird calcs */ public void dataReceived(SensorConnection connection, Data[] data, boolean b) {
int[] x = data[0].getIntValues(); int[] y = data[1].getIntValues();
The class implements simple features: - reading sensor asynchronously - reading sensor synchronously - sensor threshold - sensor sensitivy
Game uses only asynchronous reading because it’s simply faster. Method dataReceived() processes all data provided by sensor. It’s not optimized at all but still it works fast. So I’ve left it as it is for now.
Since it’s possible to read the sensor, the game can use it and change into ball motion. This implies simple physics. Nothing special, just combining gravity and friction forces:
if (doVibraX || doVibraY) { DeviceControl.startVibra( 80, 20 ); }
}
At the end of method you may notice a line containing startVibra(). The phone vibrates whenever ball hits any edge of screen. It makes nice illusion that ball weights and moreover it really feels like it hits specified edge. Method updatePositionBySensor() keeps maximum speed limited so the ball will never move too fast.
One of my very first visual effects I’ve ever programmed was simple fire effect. I wrote it ages ago for my old PC when I was learning how to use Vesa mode under DOS. Now, quite a few years later I thought it could be pretty nice to bring the effect back on mobiles using J2ME and fast on most of MIDP2 devices drawRGB() method.
The technique didn’t change at all. It’s still the same. As first it’s needed to make good palette. The better palette, the better fire looks. I just used PNG image with 1-pixel in height and 256 pixels in width. Of course it’s possible to make the palette on fly by simple gradient generation method but this time I just wanted to skip it and get to the main stream. The colors have been grabbed and placed inside the integer array ( using getRGB() ).
// the brightest color must be white: palette[ LAST_COLOR ] = 0xFFFFFF;
// ..and the darkest is black: palette[ 0 ] = 0x0;
// Clean the pixelBuffer final int bufferSize = VIEWPORT_SCREEN_WIDTH * VIEWPORT_HEIGHT;
for ( int i = 0; i < bufferSize; i ++ ) { pixelBuffer[ i ] = 0; if ( i < VIEWPORT_TOTAL_LENGTH ) { colorIndexBuffer[ i ] = 0; } }
} catch ( Exception e ) {} }
The method above does several other things too. It clears all the buffers. It may looks bit strange that colorIndexBuffer is not same size as pixelBuffer. Due to some performance reasons I have implemented upscaling, so the fire is painted using smaller array and then it may fill entire screen. The array called colorIndexbuffer stores actuall colors indices as the technique can’t base on colors 32-bit values.
The algorithm works pretty simple. To be able to “burn” pixels it’s necessary to set some pixels from the bottom of the framebuffer on fire. This must be done as much random as possible. Also it’s good to feed the fire every n-frames. The less n is the more fire we’ll see. But also setting n to low ( like 1 or 2 ) will not give good effect. ‘n’ should be adjusted later. When fire is set up then every pixel from the framebuffer is recalculated to get average color index from 4 its neigbours and itself, in other words we need to get all 5 values and divide by 5. Then store new index in the array. Dividing by five is done by two bit shifts and addition.
There’s not much more to say about the effect. Here’s the code of main tick method which updates framebuffer.
int m_lightUpCounter = 1;
public void tick() { if ( ! start ) return;
int sx = VIEWPORT_WIDTH; int offset = VIEWPORT_TOTAL_LENGTH - 1;
// First it's needed to light up the fire at the lowest row int idx = VIEWPORT_TOTAL_LENGTH - 1 - VIEWPORT_WIDTH; int idx_screen = VIEWPORT_SCREEN_TOTAL_LENGTH - 1 - VIEWPORT_SCREEN_WIDTH;
int x = VIEWPORT_WIDTH_M_1;
try { // Now we need to calculate colors for each pixel and fill both buffers with data while ( true ) {
int newIndex = 0;
final int topOffset = idx - VIEWPORT_WIDTH; final int bottomOffset = idx + VIEWPORT_WIDTH; final int p_bottom = VIEWPORT_TOTAL_LENGTH - bottomOffset;
while ( sx != 0 ) { int i = NUMBER_OF_LIGHT_UPS; int value = 0;
while ( ( value = rnd.nextInt() ) == lastVal );
lastVal = value;
rnd.setSeed( value );
while ( i != 0 && sx != 0 ) { // We need to know if we should put the pixel or not. if ( ( m_lightUpCounter & ( 1 << STEPS ) ) != 0 ) { if ( ( value & 3 ) == 1 ) { colorIndexBuffer[ offset ] = LAST_COLOR;
“Wolfenstein 3D” is well know title created by ID Software. It’s the first title which can be really called First Person Shooter ( although it’s not the first game which uses first person camera view ).
My version is simple attempt of moving the game from PC to mobiles but with one important feature - or rather without - no 3D api in use ( neither JSR184 nor Mascot nor OpenGL/ES ). I just wanted to prove that current generation phone can handle simple raycaster engine. Obviously, there are number of devices which will never support this simple technology due to poor J2ME implementation but also there are many ( especially Sony Ericssons ) which do it really good.
It started from very simple test. I have created a map of few walls, no textures, just perpendicular lines, no optimization. After first trial I received something like shows the picture on the left.
Walls shading is very first feature I have added. Then game was using fillRect() to draw each vertical line. It worked fast but it looked nothing like old Wolfenstein! What I did need was texturing. So the hardest part of implementation was about to come. But let me first to tell about how my raycaster engine works as it’s bit different than one made by Id Software.
Raycaster engine I have made is well optimized for mid-end mobile devices. It has a few assumptions like:
- walls are always perpendicular
- block of single wall piece can never be different length which means it’s always cube
To optimize the engine I came out with several ideas which seem to work quite well:
- Each piece ( let’s assume it’s square because we look at the map from top-view ) has for edges and they are marked. This way we know which edges must be checked and drawn. It’s something like simple backface culling ;)
- The map is splitted into several areas to limit the number of edges to check.
- I implemented “viewing rect”. Viewing rect is the area which is desgnated by 3 factors:
* Camera position * Left edge of viewing angle * Right edge of viewing angle
Viewing rect limits the area which must be computed and drawn. Also by having these 3 factors it’s possible to find corresponding sectors of map which also should be included into computation process.
After designing map model it became important to find the best way of checking ray intersection point with nearest edge. This is the place which differs pretty much from original Wolfenstein3D.
First by the FOV angle all the vertices are sorted and only ones whichshould be checked becomes a part of sorted array.:
final int p_fov = player_angle + FOV_HALF; final int m_fov = player_angle - FOV_HALF;
final int view_x = player_x + ( ( Maths.sin( m_fov ) << VIS_SHIFT ) >> FP ); final int view_z = player_z - ( ( Maths.cos( m_fov ) << VIS_SHIFT ) >> FP );
final int view_x_2 = player_x + ( ( Maths.sin( p_fov ) << VIS_SHIFT ) >> FP ); final int view_z_2 = player_z - ( ( Maths.cos( p_fov ) << VIS_SHIFT ) >> FP );
final int vis_player_x = player_x + ( ( Maths.sin( player_angle ) << VIS_SHIFT ) >> FP ); final int vis_player_z = player_z - ( ( Maths.cos( player_angle ) << VIS_SHIFT ) >> FP );
final int r_x1 = Math.min( Math.min( Math.min( view_x, view_x_2 ), vis_player_x ), player_x ); final int r_x2 = Math.max( Math.max( Math.max( view_x, view_x_2 ), vis_player_x ), player_x ); final int r_y1 = Math.min( Math.min( Math.min( view_z, view_z_2 ), vis_player_z ), player_z ); final int r_y2 = Math.max( Math.max( Math.max( view_z, view_z_2 ), vis_player_z ), player_z );
int num = 0;
final int v_num = vertices.length;
for ( int i = 0; i < v_num; i += 4 ) { final int v_x1 = vertices[ i ]; final int v_y1 = vertices[ i + 1 ]; final int v_x2 = vertices[ i + 2 ]; final int v_y2 = vertices[ i + 3 ];
Looks pretty complex but it isn’t at all and moreover it’s a very fast method. This code can be launched every single frame and won’t affect overall performance. This is also where “viewing rect” is implemented. Of course not entire map is being checked but only sectors. How to find sectors? Simply, by checking of each point of viewing rect and finding at which area it is placed. In worst case we’ll have to check for sectors . Still looks scary? So now think that we do not have to check every single edge but only visible ones and those at which camera looks! Practically there are about 10 to 20 edges to check every frame. This is number which every midrange device can handle and will not cause much of performance problem.
From code above you may see that I use lot calls for sin() and cos(). There are just pre-computed arrays and every calculations is being sped up by avoiding of multiplications and using bit shifting instead.
When edges and vertices are sorted we can start to shoot rays. From each pixel lying along screen x-axis we need to shoot one ray and check on which edge it stops and how far it is from an eye. The engine shoots the ray from camera position and ( since we know exact maximum viewing distance which is constant ) uses simplified intersection check between two lines. Why is it simplified? Because we know that all the edges are always perpendicular. This assumption cut downs all the calculations to minimum. Also, there are some special cases which can be handled by even more reduced code.
How the engine checks the distance? Let’s say we have one vertical edge.
The camera shoots a ray which intersects the edge. What we need to know is the y-position of our ray at x-edge point. Using linear equation the engine finds coordinate:
cx = ( ( ( dz ) << FP ) / factor_a ) + player_x;
The equation above uses factor_a variable which is:
This gives to more divisions, which cost CPU cycles but engine tries to reduce their number to very minimum. Since we know x-edge position then it’s time to find a distance. There are two ways of how we do it. Less accurate and ( in this case ) slower ( but tricky and it’s good to know it as it lets to not use square root, also games uses it for sorting sprites ):
public static int approx_distance( int dx, int dy ) { int min, max;
if ( dx < 0 ) dx = -dx; if ( dy < 0 ) dy = -dy;
if ( dx < dy ) { min = dx; max = dy; } else { min = dy; max = dx; }
// coefficients equivalent to ( 123/128 * max ) and ( 51/128 * min ) return ((( max << 8 ) + ( max << 3 ) - ( max << 4 ) - ( max << 1 ) + ( min << 7 ) - ( min << 5 ) + ( min << 3 ) - ( min << 1 )) >> 8 ); }
or more accurate and faster:
d = ( ( dy << FP ) / cos );
‘cos’ is value of cosinus function for specific angle. All sin and cos functions are pre-calculated so they are minor thing for total performance. At the moment game uses second method.
It’s easy to figure out one thing - if we want to simplify calculations the way I shown above then it’s gonna be needed to split edges into two types - vertical and horizontal. And this is done in the engine. For each type of edge there’s different procedure provided. Same as for special cases which are whenever the eye shoots ray which is parallel or perpendicular to the edge.
How to draw textures?
This is the most requiring part of code and I had to totally focus on optimizing it. All used texture are like originals: 64×64 with 8-bit indexed palette. I wrote Texture class that can load textures as PNG and raw data. Also, it creates mipmaps for improving overall graphics quality. Textures are being drawn by vertical lines. This is where all scaling is done too. The scaling function considers 3 cases:
- Vertical line is bigger than texture height, - Vertical line is smaller than texture height - Vertical line is equal with texture height
Third case is rather obvious - we do not have to calculate any scaling but copy all pixels to the buffer. First two cases reduces number of calculations by using smaller dimension as a base. If the texture is smaller then function goes through all texture pixels and finds their position at the column. Of course there are going to be blank holes between pixels after scaling but knowing previous and last pixel position we can just simply fill missing pixel with same color. This gives us always 64 iterations ( or less, depending on texture size ) even if the column takes entire screen. Same thing is done if scaled size is smaller than texture height.
There’s one more optimization. All calculations are mirrored. You cannot look up and down in the game so this makes things simpler. Scaling function calculates only half of the texture ( top part ) and copies pixels from the other half. Less dividing and shifting. This divides number of iterations by two.
Project is still in development and is more like tech-demo than game. This is how it currently looks:
My name is Adam Bialogonski. My history as a programmer started in early 1990s. I had always been a self-learner with interest for new technologies, eager to gain knowledge and experience. I have been working with many different languages and platforms, however after a success of my J2ME title in 2002, mobile games became my main field in professional work.
From 2001 I was working as a games developer at Pulsar Electronics (now Pulsar Mobile) in Poland. At the beginning we were developing for PC. On January 2002 I created my first J2ME game as a personal project, however it was later published by the company I was working for. It was first commercial title developed and published in Poland and it was a great success after which the company have been fully focused on mobile games industry. By July 2004 I developed around 30 titles for them (including Samurai, Mars Patrol, Penguin, GenX).
In 2004 I accepted a position of a games developer at Macrospace Ltd. based in London, UK and continued my work with J2ME and developing games for mobiles. In 2005, after fusion and rebranding, Macrospace became Glu Mobile Ltd. Since I joined I had opportunities to work on many popular titles, such as: Anakonda, Sonic the Hedgehog, Zuma, Diner Dash, Call of Duty 4: Modern Warfare, Stranded, Project Gotham Racing, Brian Lara International Cricket, Chaos Engine and many more.
I am also working on some personal projects, that you can read about on this blog.
My name is Adam Bialogonski. My history as a programmer started in early 1990s. I had always been a self-learner with interest for new technologies, eager to gain knowledge and experience. I have been working with many different languages and platforms, however after a success of my J2ME title in 2002, mobile games became my main field in professional work.