lunes, 21 de abril de 2014

Events, delegates and functions as arguments in C#

Last year I learnt a bit of Scala and I realized that functional languages have, I have to admit, a lot of pros. I am not saying that the functional paradigm is one of my favorites; it is not, in fact I think that it is one of the most difficult to interiorize. However, some of the ideas of this paradigm are really useful and they would be very useful in other languages.

And suddenly, learning C# I discovered the delegates and how to pass functions as arguments in other functions. So simple, so easy, so clean, so beautiful that I had to share it with you.

Example of delegates in C#:
You can also use an anonymous method or a lambda expression instead of an actual method:
In this example with multiple classes subscribing to a delegate, we have a class that allows the user to make movements with the arrow keys (for example, to escape from a maze) and another class that constraints the number of movements to escape:
Instead of defining a new delegate each time, you can take advantage of the delegates that come with the .Net library which are Action and Func. The first one is used when the delegate returns void and the other when a value is returned (thus not common with events). Both are overloaded for different number of arguments, from 0 up to 16 (I think it's enough), with the form: Action(T1 arg1, T2 arg2, ...).
Passing function as arguments to other functions is also very easy. Here I modify the example to prompt the user to retry the game when the max movements are reached: Note that when you use delegates in Unity3D and you apply them to a MonoBehaviour, you must be careful with their lifetime and prevent the delegate from calling methods that are not anymore available. Be aware that changing the scene or removing the component from the game object, removes the script from memory but doesn't deallocate the callback, so you should remove it explicitly in the onDestroy method.

Enjoy!

jueves, 17 de abril de 2014

New challenges

New job, new developing tools, new projects, new versions of frameworks, ... What does it mean? More fun... well, sometimes ;-)

Since November I am working in a game company where we work with Unity3D, C# and all the surrounding tools and languages around such big project. It was completely new for me to change to a three dimensional world, but it's really worth it and I discovered that C# is a great language. I will definitely write about it.

In addition, I decided to start my own project with my sister, a 2d casual game. However, the new 2d Unity implementation does not suit all my needs and it only gives me headaches. Thus, I decided to start the project using Cocos2d v3.
I haven't progressed too much with the project but up to this point I am very happy with the improvements I've already seen in the framework. But it is quite recent, which means no documentation, no questions in stackoverflow, not many places to look at when problems arise... but this is an interesting challenge and I hope I can contribute with my findings in this blog.

This is plainly an update post, and a way to push myself into writing about these new topics.

miércoles, 4 de septiembre de 2013

Resources framework for "universal" apps

When I started programming for iOS, the projects I were involved in were all for iPad devices only (only a pack of image resources), but when I started coding I did it in such a way that with the same code it was valid for iPad and iPhone. It was a great idea because later on the iPad apps were turned into universal apps and the changes in the code were just a few details. The idea is the following:
  1. Initialize the scale of the background with respect to the current screen size and the resources dimensions and save this ratio.
  2. Scale the background and images with the previously calculated ratio. As the iPhone has not the same dimensions of the iPad, it uses scaleX and scaleY, and the images get a bit stretched.
  3. Never use points for positions, but use logic of dynamic positions with respect to the screen: top-left corner of the screen is (size.width*0, size.height*1) and the center-right point is (size.width*1, size.height*0.5).
One of the problems I found in my way was the memory constraint, the iPad 1 couldn't load big files of images. I had to change the resources target from iPad retina to iPad non-retina screen. Enabling retina display but without the -hd resources makes the graphics on iPad retina not blurred nor with pixels, so it was a good solution and saved a lot of mega bytes.

Here you have the framework and an example of the usage:

When the iPhone 5 ready apps were mandatory for new submissions (and updates), it was also possible to keep stretching the backgrounds and sprites, but now our characters have got too much fat. I had to think a new way of using only a pack of images and taking advance of all screen sizes. Pen and paper and a calculator for operations, I draw something like this:


The small rectangle should have all the important information for the app (buttons, information, ...) but the background have to fill all the space, in order to take advance of the iPhone screens. The reference size is the dimension of this rectangle in the different devices: in the iPad is the same as its size, while in the iphone will fulfill that 4*iphoneHeight = 3*iphoneWidth. Thus, the left reference point is the (screen size - reference size) / 2 and the point most on the right would be refLeft+refWidht*1.0.

Here there is the new framework and an example of how to use it:

jueves, 6 de junio de 2013

Adding sound to your game with Cocos2D

If you are developing a game probably you need to add sound to your app.

As many other things, although Apple offers you a library to manage the audio, Cocos2D has it's own class: SimpleAudioEngine. It makes you really easy to insert background music and sound effects. It also allows you to modify basic properties such as pitch, pan and gain, and the possibility of looping a sound.

You can preload the sound (if you have a lot and heavy sounds). For loopings you need a CDSoundsource class:
Playing effects and background is very easy:
Setting other properties is also easy:
Playing around with looping sounds:

lunes, 6 de mayo de 2013

I thought I removed the file...

Sometimes, when you are sure that everything is alright because the app runs perfectly on all your devices, one of your testers report a bug saying that the app shuts down while loading in some scene (well, they just say something like "yeah.. I select all the items and then, it closes and I cannot continue"). You have very few information, so you start summarizing:
  1. It cannot be memory warning (always first guess, but you test with an iPad 1, the iPad 3 cannot raise this problem)
  2. It cannot be a weird behavior of the inner logic because it is just a background and some sprites...
  3. This scene had previously worked, and then I changed the background...
  4. If the background is not found?
  5. (After look in the project) But the background is not in the project... Why is it working in my devices if there is no image?!
It has happened to me to many times so I decided to write this post.
The first time I saw this issue was when refactoring my code and stop using retina resources, so it turned from having background-hd.jpg and background.jpg to just background.jpg. I removed the file from the project, clean the cache and made sure it wasn't the old file there anymore. But, somehow, XCode seemed to remember it, so when I asked for this file in my devices was ok but my testers iPad hadn't that resource and crashed.
I was very crossed, because I didn't want to rename all files to solved the problem. So, I asked the Almighty and found some solutions on Stackoverflow. The problem relied on XCode's derived cache, and there were offered some solutions:
  1. Clean via XCode (source)
    • The problem remained
  2. Going to the folder in your laptop and cleaning the data manually: ~/Library/Developer/Xcode/DerivedData/ (source)
    • It didn't worked for me, my corresponding folder was empty
  3. Delete app, clean everything, empty caches (source)
    • Still there
How did I solved the problem? I did not solve it :( I solved my concrete bug manually, by renaming the files and the path names in the code.
Why did I write this post? To show you potential problems you may have with XCode and the resources, and a non-perfect solution for it. Also, if you find a good way to get rid of this ridiculous issue that makes stupid names of our resources, feel free to share it with a comment.




viernes, 5 de abril de 2013

'Kamcording' your app

When you are a programmer, you get used to searching for new tools, fighting with poorly documented frameworks, and searching for solutions of problems that come with new staff. You also end up learning when to discard a tool. Tools may be bad, may not adjust to your problem, may give you more problems than solutions... or may be exactly what you are looking for... But what makes a tool great is the people behind it, a technical support that turns problems into solutions. And that's exactly how I would describe Kamcord.

The moment I saw this tool I knew it could be perfect for the new game we are designing, so I decided to make a project to test it. I had two problems: one with the rotation and the other was causing a crash with certain iOS version. Thus, I wrote to the supporting team. The answer was really fast and solved the orientation issue. They needed more information about my devices and project in order to solve the crashing problem so we exchanged several mails, projects, framework's updates... In just 5 days I had the whole project perfectly working. I didn't have to insist, but they were working on my problem till they got to the solution. And every mail was really polite. I'm very happy with the support I've received :)

Kamcord, this amazing tool, is a framework that allows your app's users to record the flow of the app and share it with friends. Easy and well documented.

Available for Cocos2d and Unity. Download from the web and follow the tutorial, it's well explained.
  1. Copy the Kamcord folder into your project.
  2. Add the framework and other supporting frameworks (twitter, mediaplayer, ... ).
  3. Adjust the settings for iOS < 4 (turn to optional some of the just added frameworks).
  4. Add to 'other linker flags': -ObjC -all_load -lxml2

At this point, it should compile, if not, check all the steps. At my first attempt it failed but I realized I  had skipped the third step.

On the other hand, Kamcord uses their own glview, therefore you have to do some changes in your AppDelegate.
  1. Make the root view controller extend from KCViewController
  2. Instantiate the glview as a KCGLView instead of an eaglview
  3. Set the root view controller to the window
  4. Configure Kamcord and set your developer key, secret and app name.
Notation for the comments:
Indented // comments: cocos2d autogenerated;
Non-indented // comments: code not anymore needed;
Indented //* comments: Kamcord explanations;
Non-indented //* comments: mine

Now, adding the functionality is really easy:
  1. Import the Kamcord framework on each scene you want.
  2. Call startRecording when you want to start the video
  3. Call stopRecording when you want to stop the recording
  4. Call showView (normally after you have record) to show the replay and share options of Kamcord

It will look like this









And you can see the video here :)


viernes, 8 de marzo de 2013

Arabic, a language written from right to left 

Lately I had to face inserting text in my app in different languages: English, Spanish, German, Chinese, Arabic, ...

What I first thought was how wonderful it would be to have all the texts in a string and change the label content depending on the selected language. Now, how intelligent labels are? Can they "understand odd symbols"? Actually, I was surprised of how simple was with the chinese: copy and paste the symbols. Tip: if you just want to insert Chinese symbols (for example, if you don't have yet the text and just want to try), don't search for "chinese symbols", instead use the google translator ;)
It doesn't depend on the font, it works with all I have tried (in this site)

So, if it's so simple, why did I write a post? Because after that I realized that the Arabic was a bit more complicated than Chinese or Japanese. It's written from right to left!

As the Arabic is written in this different direction, the label must be aligned on the right. In addition, it's not possible to change the property once the label is initialized. For this reason, I had to change the structure of the labels because before I had one label and I changed the text (which, actually, wasn't performing better than creating a new label).

But it wasn't working yet, the text was written backwards, so there was still something I was missing. There was no possibility of changing it in the label. I was surprised I couldn't find in internet any solution for this, what, in my opinion, should be a common problem. Maybe I'm loosing my ability of search in google and find an answer in Stackoverflow.

The solution was given to me by my good fairy, Alejandro, with a Wikipedia article about RLM and the wonderful unicode codes. It was like magic, just inserting \u200f at the beginning of the Arabic text and the problem was fixed. Checking whether a text is correct or not is king of fun when you don't even know the language.

For short, what did I do to insert text in Arabic in Cocos2D?

  1. Write in a string the text starting with the rlm unicode mark at the beginning.
  2. Create a label with the correct align.
  3. Add the label to the corresponding layer



Only three steps and very easy, isn't it? I hope this helps anyone with the same problem