Gorilla3D

Blogs of my work and thoughts

Subscribe to RSS feed

My First iPhone Game Part#3

So after a lot of procrastination I made some progress. I have basic scene logic, which is clearing up all resources and loading the resources needed for the next scene. A scene can be a game menu, or the game itself. As for finding out if it was possible to remove an image or view, its a big nope. Basically you'll have to reuse existing views you've already created and for images, just swap them out. This is a big issue, but if you think about it, at least your application will not crash because your trying to access an image that is not in memory.

The Map

After that I moved onto the map, which presented a bit of an issue. DragonFire SDK does not let you write a c structure to file. In fact it must be a char*, array of characters. So whats the problem? Well let say I have a map 4x4, this will be represented with 16 characters to save to file. Now think, how many letters can you fit inside a single character? Well, if you guess it, then its one character! The max range of one character is 0 to 255 in a decimal format. Oh wait, it can't be that because its not unsigned char* your working with, its (signed) char*. So the max range is -128 to 127, which is still 255 possible types of tiles. The most logical step is to just convert the tile id from an integer to a char*. So an unsigned short, let say 15,000 is 2 bytes, which will end up being 5 chars hence 5 bytes. Congratulations you just limited yourself to 2.5x smaller the size of possible max map size! I am not very happy with that result. Sticking with 255 possible tiles is not a solution for me. I want more then 512, 1,024, 5,000, heck 32,767 possible tiles would be a perfect number right? So here are the steps I took to at least write the map to file.

First I get the tile id, and convert it to a string. However when you convert an integer to a string you don't have a fixed string size. This becomes an issue when you want to have simple logic to grab the first 3 numbers in the integer, and then the last 3 numbers. So for now after the number is converted I force a length of 6 bytes to overcome this.
//-- Convert tile id to a string
short numberLength = 0;
std::stringstream out;
out << map[i];
tileString = out.str();

//-- This helps prevent an overflow of two chars
numberLength = tileString.length();

//-- If I don't resize to a fixed size, then substr will fall out of range
tileString.resize(6);


The basics are, split the one number into two numbers and if the first number is greater then 255, then push the remainder onto the second number. This becomes an issue with numbers like 999, as it will fall over to the second number with a value of 744 which is greater then 255. So to get around this, I just have some basic logic, if the number is smaller then 5 digits, then just chop the number in 2 digits each rather then 3 digits each. Limiting the char to 2 digits for number smaller then 10,000 allows me to utilize the full range of numbers up to 32,767. It could go even higher, but 32,767 is a very decent number that I will not hit any time soon.
//-- Split the string number into two parts, so they each fit in a char

//-- Part One
int one, two, placeholder;
int start, stop;
placeholder = 0;
start = 0;
stop = 3;
if (numberLength < 5) {
	start = 0;
	stop = 2;
}
if((std::istringstream (tileString.substr(start, stop).c_str()) >> one).fail()) {
	one = 0;
}

//-- If this number is too big then add the remainder to the placeholder
if (one > 255) {
	placeholder = one - 255;
	one = 255;
}

//-- Part Two
start = 3;
stop = 3;
if (numberLength < 5) {
	start = 2;
	stop = 2;
}
if((std::istringstream (tileString.substr(start, stop).c_str()) >> two).fail()) {
	two = 0;
}

//-- Apply any placeholder
two += placeholder;

//-- Save to map
mapStr[i * 2] = one - 128;
mapStr[(i * 2) + 1] = two - 128;


Other then that, this concludes another part into my iphone game progress. I have not had any more force quits when running on my iphone after compile by the DragonFire SDK build server. Oh I did notice there are a few undocumented functions like FileDelete. I am still a happy with DragonFire and can't wait to finish my map loader and saver. I think the next post will be my map editor, which will most likely be browser based, which PHP code on the backend to pack the binary maps.

Still reading? Probably a good reason why. This is because you want to tell me on how wrong I am about being able to get a short integer to fit into 2 bytes, and still being able to decompress it. Well my friend you are right. I have no way to read back a tile id, if the value was shifted between two bytes. And it took me a day to sleep on it to even think about this. So here is the resulting code to resolve this issue. I ended up having to use one extra byte.

//-- Convert tile id to a string
std::stringstream out;
out << map[i];
tileString = out.str();

//-- If I don't resize to a fixed size, then substr will fall out of range
tileString.resize(6);

//-- Split the string number into trhee parts, so they each fit in a char
int digits[3];
for (int d = 0; d < 3; d++) {
	if((std::istringstream (tileString.substr(d * 2, 2).c_str()) >> digits[d]).fail()) {
		digits[d] = -1;
	}
	
	//-- Save to map
	mapStr[(i * 3) + d] = digits[d];
}


I instead need at least 3 chars, 3 bytes to compress a short into. Each byte will go up to 99, but no more, fitting perfectly into a single char, 3 times. This means I can have a max tile id of 999,999 tile ids. This much more then the 65,535 possible ids in a short, but again this will do. The resulting code is much more compact and well simple. This will make my maps 50% smaller then before but I still save 60% in memory compare to using one byte per number.

So the big question is how big of a map can I fit into memory before I need to read in a new map? Well as long as I keep the number of layers low, let say 5 layers. The first layer will be the ground tiles. The second layer will be decoration. The third layer will be characters / npc. The fourth layer will be walls and object the character will go behind and the last layer will be for clouds. I really don't need to describe the last layer in a map, this will be auto generated. So then, what will one map size be? Well let's try this:

x = (256 tiles * 3 bytes) // The x will always hold the tile id.
y = 256 // the y stuff?
z = 4 // layers

x * y * z = 768 kilobytes of memory

My First iPhone Game Part#2

So I started to draw some thoughts on controls. It would be nice to have the player just press and drag the character to where they want. This would act a lot like Google Map's little yellow man. I have always found it painful to implant controls on top of the game screen, because there is no physical indicator to tell your finger is not longer in the bound of the control, its hard to know until your character stops. Then your lost for a few seconds seeing what finger is doing the wrong thing. When in a stressful situation its so easy to have this happen promoting death and frustration to the end user. There is always the notion of walking in a game, but if your just dropping your character everywhere you lose that delay. I am expecting to implement that delay by the screen panning to the center of the character. While the screen is panning you'll lose the ability to move your character. I could also super impose a limited drop range. This could be effected by the weight of items in your bag, or special attributes like dexterity. It would also work in multi-player situations, as the the screen is panning the character would really be moving on the other player's screen. It would be interesting to see as this is a lot like chess. You'd have to expect where the other opponent would be moving to, to cast your spell, shoot your bow, or run from.

I've been messing with the DragonFire SDK a bit more and still pondering the question of how to manage views, images, text, etc when you don't need them other then making them invisible. I've been busy wrapping the SDK into c++ classes. Their SDK is c based, so although you can use c++ with it, you're not in a very good position unless you do extra work like I am.

Here my c++ wrapper work on their SDK
Shabb::View v = Shabb::View("Ball.png");
v.getWidth();
v.setX(23);
v.setTouch(OnTouched);


Here is the c code for the same functionality as above.
int v = ViewAdd("Ball.png", 0, 0);
int width = ViewGetWidth(v);
ViewSetxy(v, 23, ViewGety(v));
int TouchHandle = TouchAdd(0, 0, ViewGetWidth(v), ViewGetHeight(v), OnTouched, 0);
int ViewSetTouch(ViewHandle, TouchHandle); 


I've also went ahead and upgraded to their Ultimate Iphone package since I've been reading about bad experiences with the SDK. I've been down this boat before (Titanium Mobile SDK) and so I would like to test on my device early before I complete the game and find out something I did, needs to be junked. It took a little over a day, to register my device (just like their website says). I used their contact form to email them and 3 days later no response. So I just emailed them directly and 10 minutes later I got a response. Their site states 6 hours, so overall that is a great response time. I did get a quick demo to compile on their server. I successfully installed it on my phone and overall excited to see it really worked. Again coming from Titanium Mobile SDK, setup is so easy and really just amazing. However the build process is very tedious. Once your ready to test on your device, you upload it to their server you get the file in about 10-20 seconds. Make sure you click and spam the "Check Status", because refreshing the page will have you sitting there for hours. Once I got the demo running I started on my own game. I quickly found it crashing on my device and not the emulator. After 2 hours of zipping, uploading, unzipping, dragging, replacing and rerunning, I got it to not crash. It was over a stupid printf call.

Here is what I had:
	std::map<std::string, Shabb::View>::iterator p;

	for(p = sviews.begin(); p != sviews.end(); p++) {
		std::string name = p->first;
		Shabb::View v = p->second;
		v.hide();
		printf("Deleting: %s\n", name);
	}


Here is the resulting code that worked:
	std::map<std::string, Shabb::View>::iterator p;

	for(p = sviews.begin(); p != sviews.end(); p++) {
		std::string name = p->first;
		Shabb::View v = p->second;
		v.hide();
		printf("Deleting: %s\n", name.c_str());
	}


Now with the visual c++ compiler, the output of the printf resulted in funky characters. I thought nothing of it, just was a weird thing. Well turns out, it wasn't just a fluke, since it resulted in a crash on iOS. There is not a compile error, and I don't receive the log from the build system when completed. Overall this was about 2 hours of work, I felt like a real programmer, "Real programmers don't use debuggers". Obviously its not a fun process, hopefully I will become better at this and avoid stupid mistakes.

I would love to see their starter SDK free as I can see a huge up taking on this when it comes to making games even on the PC. Their SDK is lightweight, simple and so far is great.

Until Next Time,
~ Joseph Montanez

My First iPhone Game Part#1

I made a bold move from android to ios a few months back. Overall I am very happy with the move. I think the biggest win over is never having a phone that lags. Anyways I started game devlopment on an android device which had become overly complicated for no reason. This game was for my girlfriend and well, it went no where. So now we both have iPhones and it is no longer is possible to make her a game. I have always been a Linux and windows guy. So I did some searching for a way to make games for ios without an intel Mac OSX. I found dragonfire sdk, a way to make games on the iPhone on a windows machine with visual studio, c or c++.

Right now I've only purchase the starter kit for the iPhone, mainly because I was unsure about the development. It took about 5 minutes to get started and it became appearnt that this was about the easiest game develment process I've ever been apart of. The sdk has a very small set of functions it's like when I was learning quick basic. Even with the limited function set, it's just the right amount to do real work. However I am currently running into one major issue. When you add a graphic, view, text, button... How do you remove it? I tried deleting the pointer but that just segment faults the program. So for now the only work around I have to work with is to set the item to invisible and then reuse it later. So if I load up 3 views and then just need one, I hide those two. However if I now need 4 views, then I'd grab the 2 empty ones and create one more view.

Anyways that's my development so far. I really do like the dragonfire sdk, so hopefully in the next post I can provide a better outlook on use of the sdk and provide a little bit information on the game I am working on.

Free Pascal Templates / Generics / Containers

,

No matter what you want to call them Free Pascal has had them since 2.2, before Embarcadero's Delphi compiler had them. Creating your own generics in Free Pascal can be a bit cumbersome especially when you just want a container to use. So FPC has created the FGL unit that has the basics to get real work done. Here is an example:

{ Compile with "fpc list.pas" }
program list;

{ fgl contains the templates we need. }
uses
	fgl;

{ We have to create a type using the template }
Type  
	TIntegerList = specialize TFPGList<Integer>;

var
	{ Now we have a list container! }
	NumberList : TIntegerList;
	I, Item : Integer;
begin
	I := 1;
	{ Create the List }
	NumberList := TIntegerList.Create;

	{ Add some stuff to the List }
	NumberList.Add(I);
	NumberList.Add(23);

	{ Iterate through the list }
	for Item in NumberList do
	begin
		WriteLn('Item: ', Item);
	end;

	{ Destroy the List }
	NumberList.Destroy;
end.

Simple Microsecond Timers in Vala

Using TimeVal

There are a few ways to produce a time. Some include seconds, some include microseconds (μ). For me I'd rather use the built-in methods. TimeVal is apart of the GLib library. TimeVal, when initialized it will grab the current timestamp automatically. Respectively the results are able to yield microseconds as a hole number. For more information about TimeVal visit Valadoc's "TimeVal"

// Initialize the time
var start_time = new TimeVal ();
var time = start_time.tv_sec + (start_time.tv_usec * 0.000001);
// Do things here
...
// Figure out how long it took...
var end_time = new TimeVal ();
time = end_time.tv_sec + (end_time.tv_usec * 0.000001) - time;

// Print out our time
print ("Work took " + time.to_string () + " seconds");
// Or
printerr ("Work took %f seconds", time);
// Or
print (@"Work took $time seconds");


A Better Way with Timer

Timer is also built in and a lot more sensible when try to accomplish a stop watch. If you need to pause, continue and get the time between all of it then Timer is a much better choice. Timer is also apart of GLib. The output yield microseconds in a decimal format. For more information about Timer visit Valadoc's "Timer"

// Initialize the Timer
var time = new Timer();
time.start ();

// Do Work
...

time.stop ();
/ Print out our time
print ("Work took " + time.elapsed ().to_string () + " seconds");
// Or
printerr ("Work took %f seconds", time.elapsed ());

Some IRC people are just plain unhelpful

Yeah no surprise right? Well recently I've notice a lot of people who want to be the enlightener. So rather then answering your question, they tell you, "You're asking the wrong question" or even better "Why do you want to do that". Even after a more then justifiable answer, their response is anything but helpful. They want you to answer yourself in the form of a question. Making you understand that what you want is wrong. Whats even better is they couldn't even answer your question in the first place.

This really goes along the line of give a man a fish feed him for a day, or teach him to fish and feed him for life. The problem with that is its more like: You have a flat tire on your bicycle and just need to learn how to fix a flat so you can keep on going. You just need to get it fixed because your trying to write a solution to a problem. So instead of someone teaching you how to fix the flat, they are telling you: "You should never need to fix a flat. Instead your riding your bike wrong."

To those people you suck, for wasting my time and the bytes its taken for this rant. Get off your high horse and stop thinking everyone is at your level of understanding you. Everyone needs to start somewhere and sometimes it takes the wrong place to become better.

Then again maybe it does take worthless holes in this world to motivate people to push themselves. After all why would I even be writing this dump post?

Choosing a Language for High Performance Web Development

Performance

Haskell Snap - Snap can take on a high load, but its system limited. By default the max number of file descriptor on my linux system is 1024, which is the max number of concurrent connections Snap can handle. Once you go over Snap will crash. There are ways around this, the can edit the C files needed, recompile and have something like 60,000 connections. Given that I was extremely impress with its speed, and memory usage. I did run into weird delay issues, as in they would not happen when installing the development compile on the fly version of my apps.

Scala Lift - Its running on the JVM meaning it can take a pounding, and still accept connections, while serving 200 responses. It performed a lot slower then Snap, but it wouldn’t stop. However the memory usage kept climbing up and up and up. After the benchmark was done, it stayed at that memory level, which was every nook and cranny the system had. Other then that it could handle more then 1024 connections.

Ada Aws - This really depends on who you choose to program your application. If program your app like most web apps, take a request in, compute, server then you won’t get too far with performance when dealing with a high connection rate. However if you take in a request, and quickly return the connection as taken, then the high connection rate isn’t a problem anymore. However you then need to write the responses using Ada’s tasking system, which can take a little getting use to. The end result is it can be a lot faster then snap, but you have to put a lot more effort into it. Other then that I wasn’t able to go beyond 1016 concurrent connections, which is the same issue with Snap.

Can it Comet?

Haskell Snap - No, but by default it serves as chucked data, which is how comet data is served. Snap is still a very new library and its ability to comet can certainly happen, its just not built yet.

Scala Lift - Yup. It uses an actor model to work. Even better is how you get to write it. For the most part Lift will write the html, and javascript needed. All you need to do is write the scala code. It might seem like bliss but it takes a while to even get use to actors in scala. Its code is very condense so as soon as you want to do something different it takes a some creative thinking before executing.

Ada Aws - Yup. It uses Ada’s built in tasks and their Push package. Each Push object can have many subscribers, which is no different then Lift, but how you write them really is. The draw back with AWS is that you also have to write the html and javascript by hand.

Productivity

This will go to Snap right off the back. The time it takes with Lift, even with using JRebel on a quad core system is about 5-7 seconds. Snap reloads instantly and on the page load. Ada on the other hand, is about the same time to recompile and reload the webserver. The only different is your doing that by yourself. I am sure I could right a tool to make that automatic.you have to stop the server, and restart it. AWS is by far the least productive one.

Template Language

All of these let you use any other template language. Snap steals a lot of the ideas from Lift, while AWS is really off the wall. For the most part all of these have logic-less template languages, preventing templates from looking like tag soup (ermm php). AWS does have if / if else / else, but that’s it. From a designer’s standpoint Lift is probably the best to deal with.

Language Power

All three of these languages have a small community, yet are very powerful. This is really bias as my choice is in Ada, but Haskell and Scala are both amazing languages. Ada and Haskell has a fairly small library set. However they can use any C library by wrapping them with some Ada/Haskell code. Ada is the fastest and lowest memory footprint language of them all, but the amount of code you have to write is just ridiculous, its more then any other language out there.

Haskell - Its a functional language, it doesn’t have mutable types (values that change over time) minus IO which is a weird way to get around that issue. Its very condensed, every character has deep meaning. Over all its functional aspect isn’t what sold me. What did sell me was it rich data structures, amazing type inference, and pattern matching is just magical. You save so much time because your not writing useless characters like brackets or semicolons and because the resulting code base is very small, the error rate you’d hit would be a lot lower. Lastly the fact it can be interpreted or compiled to a binary file.

Scala - Its everything Haskell is and more. It can be like java if you wanted, but you’d be dumb to do that. It can also use every Java library out there. However it took me learning Haskell to really understand the power of Scala. Until your forced to write in a functional way your benefit from Scala will be limited. Scala’s community is sky rocketing and extremely reactive.

Ada - Ada is a blocks style language. Its extremely verbose making it about the most readable languages I know. Also Gnat the compiler is one of the best compilers I’ve used. I’ve yet had a reason used the debugger. Any crash that does happen actually tells you what went wrong. Sadly Ada has about the weakest community of them all. Really the best thing about Ada for me is its real time and concurrency features, as its built into the language.

My Decision

In the end I picked Ada AWS. Haskell Snap would be my next choice. Scala’s Lift is amazing and safe but it really got in my way. I don’t mean limited in the sense of features, but rather along the lines of Django. It’s a very very high level library, so wanting to start at a lower level means you have to understand the in’s and out’s of Lift’s libraries first. On top of that I’m using a server with a limited amount of memory. AWS and Snap both fit in that range, not Scala. If I had the time to learn Lift, I’d go with lift anyways. It feels a little like Google Web Toolkit, but much more leaned back and lot less push on using their GUI, right now Lift really only does the menu for you.

How the language Vala can speed up development time frames.

First off Vala is a language that is very much like C#. It does have some oddities and missing features, but other then that the syntax isn't so different. Vala is a language that compiles to C code, not to virtual machine byte code. This is not a new concept and there has been a few translation languages before, Haxe (ActionScript 3 like), ShedSkin (Python), Hiphop (Php). However they all push towards C++ and has a high level of abstraction to support the dynamic typing in those languages.

Vala does have a level of abstraction, however is in C code, not C++ and its based on gobject. GObject is a cross platform library to help C developers code in sane object oriented fashion. There are a lot projects that use gobject so its not some middle-ware that no one would be willing to used along side your c generated code. Given that, Vala's C code, can be used in any project that is okay with accessing the object with the Gobject interface. It can produces headers and libraries making a solid bridge between any language that supports Gobject. This includes, C++, Java, Ruby, Python, Php, Lisp, .Net/Mono .

What makes Vala so great?

Vala is fast. Object allocation is its weaker spot and this is due to Gobject, but its very close to a pure C implementation. It you are looking to get around the same speed, you'd need to write it "c-like", this is no different if in the event of using a language like C++.

Vala is safer then C. You can still get segment faults and crashes, but the likeness of getting memory corruption is very small.

Vala is cross-platform, the very basics of Vala works on Linux and Windows, I haven't tested Mac OSX, but there are reports it works on there as well. As long as you use cross platform libraries with it, then it can also work.

Vala can use C. Vala has what's called VAPI, a wrapper around c headers to make calling C functions "pretty" and "Like Vala!".

C can use Vala, like I said before the middle wear is gobject, but its a proven way to allow C developers gain the benefits of many features that are hard to implement in C code.

Vala is like C#, which is better then Java. Vala has much less boilerplate for certain language features compared to C#.

What makes Vala not so great?

Vala's toolset is lacking. IDE support kind of sucks, the most you get is auto-complete and syntax highlighting.

Vala's compiler is not great at forcing you to be safe. Because its tied so closely to C I don't know how close they can get.

Vala's debugger doesn't exist. You have to look at the c code it generates to find out where it might be happening. So in result you have to use a C debugger to find the bad C code. What Vala outputs as far as C is concern is still readable, so its not impossible or even that hard, just a pain when you manage to crash Vala.

Its a new look at old ways. Vala doesn’t invent anything new, items like concurrency, distributed system programming, these are things that C can do with the right libraries, but its not easy, and not any easier in Vala.

Conclusion

Support, there is the mailing list, but that really is only avenue to support. There isn’t 30 years of resource behind this language. Given that if you choose Vala, make sure you understand the languages and its limits on every platform, before picking it as the de facto language to program in. In short, Vala is a great tool to use. My productivity while using Vala, is alongside programming in PHP. Using it on the Linux/GNU Operating system is the best way to use this language. GUIs, Games, even Web Services are perfect examples of Vala, as long as your okay with staying on Linux/GNU. Given that I have been using Vala on windows as well, its still workable, but getting libraries to link is a seemingly impossible task. Once that huddle is done, its really not that bad.

Multidimensional Arrays in C++ for a tilemap in SFML

To understand this tutorial to must first know the basics of vectors in c++ and how to use SFML.

The Basics - Defining the Map

First lets invasion a 4x4 tile map. Each box will hold the tile ID, which is basically saying, "This box is grass", or "This box is water".

 _______
|_|_|_|_|
|_|_|_|_|
|_|_|_|_|
|_|_|_|_|


Now lets see how this works in C++. In C++ you can dynamically initialize the entire multidimensional array. However you cannot initialize each row dynamically unless you enable your compiler's support for c++0x. Not all compiler support "extended initializer lists".

int map[4][4] = {
    {0, 0, 0, 0}, // <-- There are 4 columns per row, and 4 rows
    {0, 0, 0, 0},
    {0, 0, 0, 0},
    {0, 0, 0, 0}
}; // This works

int map[4][4];
map[0] = {0, 0, 0, 0}; // Fails unless you use enable c++0x support in your C++ compiler


You can also used C++'s standard vector library. I feel the use of vectors are a bit more easier to deal with when you want to access your map indexes. C++ vectors give you better tools to know the limits of your map before accessing an index of the map. Hence less likely to have your application crash. To used multidimentional vectors, you have to use a very type heavy syntax.

// much like "int map[4][4];"
std::vector< std::vector<int> > map(4, std::vector<int>(4));
map[0][0] = 0;
map[0][1] = 0;
// ... 

// If you want to use the same initialization as the previous example 
// you will have to enable c++0x  

// !!! NOTE !!!
// Using the format below will fail because >> in C++ means something
// different
// std::vector<std::vector<int>> map(4, std::vector<int>(4));


How to Access Multidimensional Indexes - Ermm Map Tiles

So lets stick with vectors for now. They are a bit more complicate to initialize but doing this forces you to understand how arrays look in a programming language.

Remember our map?
 _______
|_|_|_|_|
|_|_|_|_|
|_|_|_|_|
|_|_|_|_|


Can you tell me where 2,3 is? Well look at the map, down 2, left 3.
 _______
|_|_|_|_|
|_|_|X|_|
|_|_|_|_|
|_|_|_|_|


Well how do you access that tile (2,3) in C++? Even more so while using vectors?
int tileId = map[1][2]; // This is not a typo it really is [1][2], read below!
// Or
int tileId = map.at(1).at(2);


Well that makes since right? Not really, this is because zero (0) has a size in C++. So zero (0) is really the first index, not one (1).

How to Iterate aka "Array Walk" your map

Because we are using vectors you'd be tempted to use the vector iterator, but because we are using a complex vector array, its much better off to not use them. So instead we will use a regular for loop for the X and Y based tiles in the map. Since the map uses vectors we can get the size of each vector dynamically.

    std::vector< std::vector<int> > map(4, std::vector<int>(4));
    // Define the map
    map[0][0] = 0;
    map[0][1] = 1;
    map[0][2] = 0;
    map[0][3] = 0;
    map[1][0] = 0;
    map[1][1] = 0;
    map[1][2] = 0;
    map[1][3] = 0;
    map[2][0] = 0;
    map[2][1] = 0;
    map[2][2] = 0;
    map[2][3] = 0;
    map[3][0] = 0;
    map[3][1] = 0;
    map[3][2] = 0;
    map[3][3] = 1;
    
    
    for (int x = 0; x < map.size(); x++) {
        for (int y = 0; y < map[x].size(); y++) {
            int tileId = map[x][y];
            std::cout << tileId << "\n";
        }
    }



Slapping SFML into the mix

Before we start I will have you use a startup file to have SFML setup with out basic map and a grass / water tile to be loaded.

Tutorial-01.zip

First lets load our images and setup sprites for them. Those zeros and ones will now have meaning to them. At these lines just below line 29 sf::RenderWindow App(sf::VideoMode(640, 480, 32), "SFML TileMap");
    sf::RenderWindow App(sf::VideoMode(640, 480, 32), "SFML TileMap");

    // Load the images from files
    std::vector<sf::Image> images(2); // Preset the vector to 2 images
    if (!images[0].LoadFromFile("grass.png")) {
        return EXIT_FAILURE;
    }
    if (!images[1].LoadFromFile("water.png")) {
        return EXIT_FAILURE;
    }

    // Create the sprite
    std::vector<sf::Sprite> tiles(2); // Preset the vector to 2 sprites
    tiles[0] = sf::Sprite(images[0]); // Grass
    tiles[1] = sf::Sprite(images[1]); // Water


Now if you notice tiles[0] and tiles[1], the 0 and 1 are what we used in the map! Next we take our map walk over it and associate it to these sprites. Locate App.Clear, just below that we have our array walk happening. Go ahead and compile the code below and see the what happens.

        for (int x = 0; x < map.size (); x++) {
            for (int y = 0; y < map[x].size (); y++) {
                int tileId = map[x][y];
                App.Draw(tiles[tileId]); // Add this like ... WE DRAW TILES YAY
                std::cout << tileId << "\n";
            }
        }




Uhh wait they are just showing up as one water tile, what gives? Well its because the position each tile needs to be set before drawing. So lets give it a try. Assign the x and y coordinates from the map as the position of the tile. Now compile again and see the result.

        for (int x = 0; x < map.size (); x++) {
            for (int y = 0; y < map[x].size (); y++) {
                int tileId = map[x][y];
                
                tiles[tileId].SetPosition(x, y);
                App.Draw(tiles[tileId]);
                std::cout << tileId << "\n";
            }
        }




Ok well you see some grass? I think... Well thats for good reason, we only push the tile over 1 pixel. Since the x and y variables are represented as 1 pixel, we will have to use the width and height of each sprite's image to get the right result.

So lets go back to or example of find out the coordinate (2,3).

 _______
|_|_|_|_|
|_|_|X|_|
|_|_|_|_|
|_|_|_|_|


To find the number of pixels we need to push the tile over to draw in the right spot we need a constant width and height. So if each tile is 32 pixels wide and 32 pixels tall, then when you get to the 2nd tile down whats your starting position? Think for a second, the 2nd tile was really "1" in the map index. map[1] = 2nd tile down, with that you know that its going to start at 32 pixels, not 64 pixels, on the x-axis. What about the y-axis? Well again that 3rd tile was really "2". So again map[1][2] = (2,3). So this time is 2 tiles down, 32 + 32 pixels = 64 pixel. So x = 32, y = 64... Now put on your thinking cap, if we start at zero, want to render the 3rd tile and its really 2 tiles over, then you get the formula y_pixels = 32 * y (the maps y in the for loop).

        for (int x = 0; x < map.size (); x++) {
            for (int y = 0; y < map[x].size (); y++) {
                int tileId = map[x][y];
                // Get the tile's image
                const sf::Image* image = tiles[tileId].GetImage();
                // Get the width and height of the image
                int width = image->GetWidth();
                int height = image->GetHeight();
                // Adjust the offset by using the width
                tiles[tileId].SetPosition(x * width, y * height);
                // Draw the tile
                App.Draw(tiles[tileId]);
            }
        }


So go ahead and compile the example see what you get!



If all else fails, then I have the entire tutorial source below:
sfml-tilemap2.zip

You can also view the source online:
https://gist.github.com/998540

Php on Windows is ...

From my last post I found that depending on Memcached for fast memory access across multiple processes was a bad idea. So then I began to moved my work towards the php module shmop. Using in-processor memory I was able to up to process 300,000 events, while Memcached let me process 1,000-3,000 events. So now what did shmop yield? Well Considering I had to move to a binary format, and then depending on deseralization using pack / unpack php calls I get about 35,000+ events per second. Its not the 300,000 I was hoping for but the bottle neck is now CPU bound. So what do you do when the cpu becomes an issue? Well use a CPU with multiple cores! Multiple processes means you can now use multiple cores. Also since its using shared memory, its not bound by a single process. So If I spawn more then one world simulator on a 4 core system and then I could process up to 140,000 events per second.

Issues with Php on Windows

This was a huge disappointment, all the speed you get from linux doesn't transfer over with Windows. This is also true for Php GTK and Shmop. Php GTK Fullscreen redraws where about 10 frames a second versus the 30 FPS I got on Linux. As for shmop, I tried on a Window laptop so this might be the reason for this, but I hit about 1,000 (versus 35,000) events before the CPU would max out. Considering most people will only be running the game clients on Windows this isn't too bad. However Php Gtk will have to have some hard core dirty rect calcutions. Dirty Rect is a term used in 2D games where you find what areas of the screen to redraw, rather then redrawing the entire screen. Anyways onto the last issue with PHP on Windows, pcntl DOESN'T WORK ON WINDOWS!!! Gosh this is a big blow I think... I can revert to using a windows shell script to run the processes by themselves. If I completely ignore windows as an OS to run the server on, then I can get away with using Php GTK to run the threads via Gtk::timeout_add

Php on Wine 1.3

Wine is a program used to run Windows applications on Linux. Its awesome stuff, even better when you can test PHP on there as to running back and forth between machines for Windows testing. However I will note shmop does not work on Wine, I get "fixme:msvcrt:MSVCRT__sopen_s : pmode 0x01b6 ignored" Which results in me unable to write to memory.

Php GTK Running on Php 5.3 and Windows

The last issue I ran into was finding a version of Php-GTK that worked on Php 5.3 for windows. There is just some random link http://php-gtk.eu/en/apps/php-gtk-installer-for-windows that has Php 5.3 and GTK working together, wasn't the easiest thing to come across.