Sunday, December 1, 2013

Fruit Dating is out!


Get it on Google Play

 As I wrote in previous post, this week was really busy. We released two new games: FRUIT DATING and SHARDS!

 This post is on Fruit Dating. You can read about Shards here.

 Fruit Dating is original puzzle game in which you match pairs of fruit of the same color simply by swiping with your finger. The finger motion matches the tilting of the board in any given direction. So, while trying to fulfill your goal, various obstacles like stones, cars or other fruit, hinder the way.

With advanced levels the date-lusty fruit are encountering various other pitfalls such as: one-way tiles, puddles of mud or animal kingdom representatives looking forward to enliven their diet with juicy fruit!

 This time SBC Games joined their forces with LittleColor and with great music composer Matúš Široký. The result is very nice game featuring:

·       three unique worlds,
·       challenge in each of 60+ levels,
·       addictive game play and graphics,
·       new game elements to diversify the game and bring new challenges,
·       25 achievements to fulfill,
·       original music soundtrack.

 We took it really seriously so we have web page. We have presskit. And we have great promo graphics:
 

 The game is currently available for Android, but bada and Tizen version will come closely. In future I would like add iOS as well.

 During development we had to solve basic problem of all logic puzzles ... where to get levels? In the end we made tool that is generating them procedurally for us. Of course we had to carefully select from the generator output but plenty of levels were interesting or required only small adjustments (while other were total trash). In future I will probably post an article about making the tool on this blog.










Shards is out!


Get it on Google Play Appstore-badge-black


This week was really busy. We released two new games SHARDS and FRUIT DATING!

 In this post I will introduce Shards and Fruit Dating will be introduced in this post.

 Shards is clone of  Arkanoid / Breakout games. It is a modern approach to the classic brick breaking game. Each of the 50 levels has its own fractal background, uniquely arranged as well as arbitrary scaled and rotated glass bricks for you to destroy.
 The game features about ten various power-ups and a great original soundtrack.

 To manage the physics we employed well known physics library Box2D.

 The game is currently available for Android but Samsung bada version is already in approval process and Tizen version is just a matter of upcoming weeks. The game is made using our small cross platform engine. On this blog I am posting on topics I came accross when building it.

Form game features:
 - enter a world of 50 levels full of glass:
 - each level has its own original stunning fractal background,
 - glassy bricks are of arbitrary sizes and rotate to bring you interesting patterns to destroy,
 - ten power-ups will help you to clean the board,
 - listen to an original soundtrack,
 - play through three difficulty levels




 



Sunday, October 27, 2013

Fruit Dating - upcoming puzzle game


 One more post today. Beside Shards I am also working on another game. The name is Fruit Dating and my role in the project is programmer. Bellow you can see some screenshots from the game. Very nice and neat graphics is work of Tomáš Kopecký from LittleColor.com.


 The game is logical puzzle and target platforms are Android, bada and new Linux based OS Tizen. The screenshots are taken from working desktop Windows version (through OpenGL ES emulation libraries).


 If you ever tried to make puzzle game you will agree that most of the work is in design of puzzles. It is also valid for our game, but thanks to small trick we saved lot of work. The name of this trick is: procedural generation.


 To create interesting puzzles we created generator/editor. It is written in Java and it can not only generate puzzles, but also solve them. The generator is also focused on aesthetic side of puzzle - it tires to generate more or less symmetric walls. With drag and drop features you can adjust positions of fruit and stones and then resolve the level to check whether it is still solvable.


The second part of the tool is editor where we can decorate the level with trees, ...


 The game will be finished this year and we hope you will enjoy it!


Shards - Work In Progress II



 Here comes our second and last work in progress video. The last one as we are almost finished. The game currently runs on Android, bada and even Tizen - new upcoming Linux based mobile OS.


 Compare our progress with previous WIP video here.

 The game uses our own small cross-platform engine. Beside above mentioned mobile platforms it also runs on desktop Windows thanks to OpenGL ES simulation libraries from Imagination Technologies. For physics simulation it uses great Box2D library.

 And yes ...! That great music is also from Shards.





Saturday, October 19, 2013

Building mobile game engine with Android NDK: 4 - timing service



all parts:
1 - installing the tools and running samples
2 - calling C++ library from Java
3 - abstracting types and logging
4 - timing service

 today we will create first from the set of services. It will be timing service. Service is here some class or set of classes that enclose some functionality and is fully reusable in future projects.

 Until now our engine run as fast as possible calling engine_tick method. In this method we set background color but so far we do not know how much time elapsed form previous call. So we have no information that would be handy in whatever you can imagine - timing animation, showing the player time spent in level, timing bombs explosion, etc.

Project structure

 On the image bellow you can see project structure. New files we are going to create today are highlighted with green. Beside this we will make changes into Main.cpp. As the timing service is the first one from set off services we will create in future we are also going to create Context class. This class works as a bag full of services which is easy to reference and handle inside game.


 As with the logging class we are preparing ourselves for future when we want to go cross-platform. ITimeService.h is abstract interface class that defines interface that will be common for all supported systems -  only Android now. TimeServiceBase is class that implements those parts of the ITimeService, that are the same for all systems. Finally, AndroidTimeService implements rest of the methods.

Implementation

 Listing for ITimeService.h is simple:
#ifndef ITIMESERVICE_H_
#define ITIMESERVICE_H_

#include "Types.h"
#include "Log.h"

namespace SBC
{
namespace System
{

class ITimeService
{
public:
 virtual ~ITimeService() {};

 virtual void reset() = 0;
 virtual void update() = 0;

 virtual f64 now() = 0;
 virtual f32 elapsed() = 0;
};

} /* namespace System */
} /* namespace SBC */
#endif /* ITIMESERVICE_H_ */

 The common base for all systems looks like this:
#ifndef TIMESERVICEBASE_H_
#define TIMESERVICEBASE_H_

#include "ITimeService.h"

namespace SBC
{
namespace System
{

class TimeServiceBase : public ITimeService
{
public:
 TimeServiceBase();
 virtual ~TimeServiceBase();
 void construct();

 void reset();
 void update();

 f64 now();
 f32 elapsed();

 static unsigned long getTickCount();

private:
 f32 mElapsed;
 f64 mLastTime;
};

} // namespace System
} // namespace SBC

#endif // TIMESERVICEBASE_H_

 We added some member variables to store elapsed time from last update of timer and also previous time. This base class also has construct method. This method is part of construction of the object. First the constructor is called and then construct method is called. It is called two-phase construction. Imagine that you are creating new object that needs to create several other objects on the heap. Next imagine that first of these objects is successfully created but you get out of memory error when constructing the second one. In such a case the original object is not constructed and thus its destructor is not called. But you already successfully created on of its child objects in constructor. Who will destruct it? Answer is no one - you will get memory leak.
 Opposite to this you can do two phase construction. First allocate the object and just initialize its member variables that do not need additional memory allocations or do thing that can not fail. Then call construct method that will do the rest. Good explanation and example of this can be found here.
 We are not allocating any memory for time service now. But what if there was system that would need it in future...

 Implementation of TimeServiceBase is here:
#include "TimeServiceBase.h"

#undef LOG_TAG
#define LOG_TAG "TimeServiceBase"

namespace SBC
{
namespace System
{

//------------------------------------------------------------------------
TimeServiceBase::TimeServiceBase() :
  mElapsed(0.0f), mLastTime(0.0f)
{
}

//------------------------------------------------------------------------
TimeServiceBase::~TimeServiceBase()
{
}

//------------------------------------------------------------------------
void TimeServiceBase::construct()
{
 LOGI("TimeService constructed");
}

//------------------------------------------------------------------------
void TimeServiceBase::reset()
{
 LOGI("TimeService reseted");
 mElapsed = 0.0f;
 mLastTime = now();
}

//------------------------------------------------------------------------
void TimeServiceBase::update()
{
 // Checks elapsed time since last frame. It is important to
 // work on double with current time to avoid losing accuracy
 // Then we can go back to float for elapsed time.
 double lCurrentTime = now();
 mElapsed = (f32)(lCurrentTime - mLastTime);
 mLastTime = lCurrentTime;
}

//------------------------------------------------------------------------
f64 TimeServiceBase::now()
{
 LOGE("Feature not implemented for current system");
 return 0;
}

//------------------------------------------------------------------------
f32 TimeServiceBase::elapsed()
{
 return mElapsed;
}

//------------------------------------------------------------------------
unsigned long TimeServiceBase::getTickCount()
{
 LOGE("Feature not implemented for current system");
 return 0;
}

} // namespace System
} // namespace SBC

 As you can see some methods just say "Feature not implemented for current system". I found this very useful when I was adding new Tizen system into my cross platform engine. As I was writing Tizen implementation of the all the services one by one I was able to run it and when I came across some that was not implemented yet I got log message about it but there was minimum of crashes. Also when see this you know there is needed some system specific implementation.

Android implementation

 Now we can implement Android specific parts. AndroidTimeService.h has this listing:
#ifndef TIMESERVICE_H_
#define TIMESERVICE_H_

#include "../TimeServiceBase.h"
#if (PLATFORM_ID == PLATFORM_ANDROID)

namespace SBC
{
namespace System
{

class TimeService: public TimeServiceBase
{
public:
 TimeService();
 virtual ~TimeService();

 f64 now();

 static unsigned long getTickCount();
};

} /* namespace System */
} /* namespace SBC */
#endif // PLATFORM_ANDROID

#endif /* TIMESERVICE_H_ */

and implementation is like this:
#include "AndroidTimeService.h"
#if (PLATFORM_ID == PLATFORM_ANDROID)

#undef LOG_TAG
#define LOG_TAG "TimeService"

#include <time.h>

namespace SBC
{
namespace System
{

//------------------------------------------------------------------------
TimeService::TimeService()
{
}

//------------------------------------------------------------------------
TimeService::~TimeService()
{
}

//------------------------------------------------------------------------
f64 TimeService::now()
{
 timespec lTimeVal;
 clock_gettime(CLOCK_MONOTONIC, &lTimeVal);
 return lTimeVal.tv_sec + (lTimeVal.tv_nsec * 1.0e-9);
}

//------------------------------------------------------------------------
unsigned long TimeService::getTickCount()
{
 timespec lTimeVal;
 clock_gettime(CLOCK_MONOTONIC, &lTimeVal);
 return lTimeVal.tv_sec * 1000 + (lTimeVal.tv_nsec * 1.0e-6);
}

} /* namespace System */
} /* namespace SBC */

#endif // PLATFORM_ANDROID

 In now method we are reading current time for monotonic clock. But, what is current time? According for example to this documentation you can read that it is "Clock that cannot be set and represents monotonic time since some unspecified starting point.". The starting point is often system boot. Fortunately it is not interested for us. We need it just to measure time leaps from one call to another and to calculate the elapsed time. Last time as well as elapsed time are in seconds.

Creating context class

 Our first service is created so let's put it into bag for services - into the context. But first we have to create this bag. This is the header for Context class. It is first class that is created in Engine directory of our engine structure:
#ifndef CONTEXT_H_
#define CONTEXT_H_

#include "../System/system.h"

namespace SBC
{
namespace Engine
{

class Context
{
public:
 Context();
 ~Context();

public:
 // application
 void setApplication(SBC::System::Application* aApplication);
 SBC::System::Application* getApplication();

 //time service
 void setTimeService(SBC::System::TimeService* aTimeService);
 SBC::System::TimeService* getTimeService();

private:
 SBC::System::Application* mApplication;
 SBC::System::TimeService* mTimeService;
};

} // namespace Context
} // namespace SBC

#endif // CONTEXT_H_

 As can be seen it is just set of getters and setters. Only interesting is destructor because ownership of all created services is handeled to context and it is then responsible for destructing them (except for application). In implementation you can see it:
#include "Context.h"

#undef LOG_TAG
#define LOG_TAG  "Context"

namespace SBC
{
namespace Engine
{

//------------------------------------------------------------------------
Context::Context()
{
 mApplication = NULL;
 mTimeService = NULL;
}

//------------------------------------------------------------------------
Context::~Context()
{
 LOGI("Deleting TimeService");
 if (mTimeService != NULL)
 {
  delete mTimeService;
  mTimeService = NULL;
 }
}

//------------------------------------------------------------------------
void Context::setApplication(SBC::System::Application* aApplication)
{
 mApplication = aApplication;
}

//------------------------------------------------------------------------
SBC::System::Application* Context::getApplication()
{
 return mApplication;
}

//------------------------------------------------------------------------
void Context::setTimeService(SBC::System::TimeService* aTimeService)
{
 mTimeService = aTimeService;
}

//------------------------------------------------------------------------
SBC::System::TimeService* Context::getTimeService()
{
 return mTimeService;
}

} // namespace Context
} // namespace SBC

 Maybe you noticed that in all .cpp files, there is defined LOG_TAG in the very top. This tag helps in debugging as all log messages from the same .cpp file are tagged with it.

 As a last step change system.h file - add TimeService to it:
// Android platform
#if (PLATFORM_ID == PLATFORM_ANDROID)
 // system
 #include "Android/AndroidSystem.h"
 // time service
 #include "Android/AndroidTimeService.h"

 As we have now also the context we can wire it into Main.cpp. We will initialize the services when the engine starts and destroy the context (and all services in it) when the engine is to be destroyed.

Wiring context

 Change top of the Main.cpp to this:
//BEGIN_INCLUDE(all)
#include "src/System/system.h"
#include "src/Engine/Context.h"

#undef LOG_TAG
#define LOG_TAG "Main"

using namespace SBC::System;
using namespace SBC::Engine;

Context* gContext = NULL;

 Adjust engine_start and engine_stop methods:
//------------------------------------------------------------------------
static void engine_start(JNIEnv* aEnv, jobject aObj, jobject aAssetManager)
{
 LOGD("Starting engine ...");

 AAssetManager* assetManager = AAssetManager_fromJava(aEnv, aAssetManager);
 
 // create context that holds particular system services
 LOGI("Creating game context");
 gContext = new Context();
 
 // SERVICES
 // time service
 LOGI("Creating and initializing TimeService");
 TimeService* tm = new TimeService();
 tm->construct();
 gContext->setTimeService(tm);

}

//------------------------------------------------------------------------
static void engine_stop(JNIEnv* aEnv, jobject aObj, jboolean aTerminating)
{
 LOGD("Stopping engine ...");
 
 LOGI ("Deleting game Context");
 if (gContext != NULL)
 {
  delete gContext;
  gContext = NULL;
 }
}

and also adjust resume_engine method. We will reset the time service in it:
//------------------------------------------------------------------------
static void engine_resume(JNIEnv* aEnv, jobject aObj)
{
 LOGI("Resuming engine - resetting time");
 gContext->getTimeService()->reset();
}

 Finally, to see some effect change engine_tick method to this:
//------------------------------------------------------------------------
static void engine_tick(JNIEnv* aEnv, jobject aObj)
{
 TimeService* time = gContext->getTimeService();
 time->update();


 // do something
 static f32 counter = 0.0f;
 f32 elapsedTime = time->elapsed();
 counter += elapsedTime;
 if (counter > 1.0f)
  counter = 0.0f;

 // Just fill the screen with a color.
 glClearColor(1.0f - counter, 1.0f, counter, 0.0f);
 glClear(GL_COLOR_BUFFER_BIT);
}

 the counter variable is based on value of counter and the screen is blinking from yellow to light blue. The complete change of color takes 1 second.

Conclusion

 Today we created first of engine services - the TimeService. It tells us how much time elapsed from last tick and we can use this information to adjust whatever is based on real time in the game. Thanks to this we can base for example our animations on real time and not on frame rate which may differ from device to device.

 Download TutGame-04.zip




Tuesday, September 10, 2013

Building mobile game engine with Android NDK: 3 - abstracting types and logging



all parts:
1 - installing the tools and running samples
2 - calling C++ library from Java
3 - abstracting types and logging
4 - timing service


 Last time we ended with displaying green screen. We set all the needed things on java side and we created Main.cpp on C++ side. Today we will do things that will prepare our engine for going multiplatform. So, there will not be to much fun but it will pay soon in next parts of this series.


Project structure

 After the last article we ended with jni folder in our project with structure like this:


 When we finish today the structure will look like this:


 So, first go into jni folder and create all new subfolders: src, Engine, Game, System and under System also the Android folder. In future there will be some common system files in System folder. Usually some abstraction of some feature like touch input and in folder with concrete system name there will be implementation of this feature.


Adjusting Main.cpp

 Go to Main.cpp and in the top remove these lines:

#include <jni.h>
#include <errno.h>
#include <stdio.h>
#include <android/sensor.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

 and replace it with these lines:

//BEGIN_INCLUDE(all)
#include "src/System/system.h"

#undef LOG_TAG
#define LOG_TAG "Main"

using namespace SBC::System;

 The purpose of the LOG_TAG will be clear soon. You can also see that we will structure our engine with namespaces to keep it clean.


Parameters

  As the engine will grow and support more platforms and features, we will need some way how to parametrize it. So in the same folder as Main.cpp resides, create file params.h with the following content:

#ifndef PARAMS_H
#define PARAMS_H

//---------------- TARGET -----------------------------
// define target platforms
#define PLATFORM_ANDROID 1
#define PLATFORM_BADA  2
#define PLATFORM_WIN  3
#define PLATFORM_TIZEN  4
// choose target platform
#define PLATFORM_ID   PLATFORM_ANDROID

//---------------- OPEN GL ----------------------------
// define parameters for other sources
#define SBC_USE_OPENGL
// use values 1 or 2
#define SBC_USE_OPENGL_VERSION 2

//---------------- RESOLUTION -------------------------
// resolution
#define FRAMEBUFFER_WIDTH 1280
#define FRAMEBUFFER_HEIGHT 800

#endif /* PARAMS_H */

 In this file additional parameters will be added in future. From here I am switching various debugging features on and off.
 What we set now is that we say we are using Android (PLATFORM_ID = PLATFORM_ANDROID). We plan to use OpenGL in its version 2.0 and the target resolution for our game is 1280 x 800. The target resolution is not size of your device screen but buffer the OpenGL draws in. It is than scaled to your device screen.

 Now go to System folder and create file _parameters.h in it. The only purpose is to suck content of params.h into engine. As the params.h can be different for different platforms and we do not want to change or set up anything in System folder in future we are doing it in this way. The file looks like this:

#ifndef PARAMETERS_H_
#define PARAMETERS_H_

#include "params.h"

#endif /* PARAMETERS_H_ */


Abstract system

 In System folder create file system.h. If you later in your engine or game will need some system features like logging you will call it every time in the same way regardless of the actual system. Put these lines into the file:

#ifndef SYSTEM_H_
#define SYSTEM_H_

#include "_parameters.h"

/*
 *  define some common constants, typedefs, etc.
 */

#include "Types.h"
#include "Log.h"

// Android platform
#if (PLATFORM_ID == PLATFORM_ANDROID)
 // system
 #include "Android/AndroidSystem.h"

// Bada platform
#elif (PLATFORM_ID == PLATFORM_BADA)
 // system
 #include "bada/badaSystem.h"

// Win platform
#elif (PLATFORM_ID == PLATFORM_WIN)
 // system
 #include "Win/WinSystem.h"

// Tizen platform
#elif (PLATFORM_ID == PLATFORM_TIZEN)
 // system
 #include "Tizen/TizenSystem.h"
#endif

#endif /* SYSTEM_H_ */

 As you can see, while we are working with Android today I left also other systems there. In Eclipse it will be grayed out to mark that preprocessor is skipping it.

 Next create Log.h and Types.h that have similar structure.

 Log.h:
#ifndef LOG_H_
#define LOG_H_

#include "_parameters.h"

/*
 * define platform specific things
 */

// Android platform
#if (PLATFORM_ID == PLATFORM_ANDROID)
 // basic system
 #include "Android/AndroidLog.h"

// Bada platform
#elif (PLATFORM_ID == PLATFORM_BADA)
 #include "bada/badaLog.h"

#elif (PLATFORM_ID == PLATFORM_WIN)
 // basic system
 #include "Win/WinLog.h"

#elif (PLATFORM_ID == PLATFORM_TIZEN)
 // basic system
 #include "Tizen/TizenLog.h"

#endif

#endif /* LOG_H_ */

Types.h:
#ifndef TYPES_H_
#define TYPES_H_

#include "_parameters.h"

// Android platform
#if (PLATFORM_ID == PLATFORM_ANDROID)
 // types
 #include "Android/AndroidTypes.h"

// Bada platform
#elif (PLATFORM_ID == PLATFORM_BADA)
 // types
 #include "bada/badaTypes.h"

// Win platform
#elif (PLATFORM_ID == PLATFORM_WIN)
 // types
 #include "Win/WinTypes.h"

// Tizen platform
#elif (PLATFORM_ID == PLATFORM_TIZEN)
 // types
 #include "Tizen/TizenTypes.h"

#endif

#endif /* TYPES_H_ */

 You see that its purpose is again just to load concrete implementation from selected system folder. Now we can go into Android folder and implement it.


Android implementation

 We have selected Android in parameters and our engine now awaits concrete implementation for system, logging and types. Let's make it happy.

 First create file AndroidTypes.h in Android folder and fill it like this:

#ifndef ANDROIDTYPES_H_
#define ANDROIDTYPES_H_

#include "../_parameters.h"

#if (PLATFORM_ID == PLATFORM_ANDROID)

// typedefs for safe datatypes
typedef unsigned char   u8;
typedef signed char   s8;
typedef char     c8;
typedef unsigned short  u16;
typedef signed short  s16;
typedef unsigned int  u32;
typedef signed int  s32;
typedef float   f32;
typedef double   f64;

#endif // PLATFORM_ANDROID

#endif /* ANDROIDTYPES_H_ */

 You see that we abstracted C++ types with our own. In the rest of the engine we will use s32 instead of int or u16 instead of unsigned short. In this way we can construct 32 signed integer needed by engine from int on most of today platforms but in case int was only 16bits on some platform we can construct it from long which will probably be 32bit. But our engine will use s32 and will not be interested what is behind.

 Now to logging. It is nice that Android has __android_log_print function in log.h file. But again it is not general enough for multiplatform engine. So, we will abstract it in file AndroidLog.h like this:

#ifndef ANDROIDLOG_H_
#define ANDROIDLOG_H_

#include "../_parameters.h"

#if (PLATFORM_ID == PLATFORM_ANDROID)
#include <android/log.h>

// logging functions with fixed tag
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

#endif

#endif /* ANDROIDLOG_H_ */

 We defined four macros and in the rest of the engine we will use it just like: LOGD("Hello");
 Here comes into play the LOG_TAG we defined in the top of the Main.cpp. We will define it in every source file so logging will always say us where we used it.

 Finally create file AndroidSystem.h with this content:

#ifndef ANDROIDSYSTEM_H_
#define ANDROIDSYSTEM_H_

#include "../_parameters.h"

#if (PLATFORM_ID == PLATFORM_ANDROID)

#include <jni.h>
#include <errno.h>
#include <stdio.h>
#include <android/sensor.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

// include openGL headers
#ifdef SBC_USE_OPENGL
 #include <EGL/egl.h>

 #if (SBC_USE_OPENGL_VERSION == 1)
  #include <GLES/gl.h>
 #elif (SBC_USE_OPENGL_VERSION == 2)
  #include <GLES2/gl2.h>
  #include <GLES2/gl2ext.h>
 #endif
#endif

namespace SBC
{
namespace System
{
typedef struct android_app Application;
} // System
} // SBC

 You can see that we are benefiting from our parameter file params.h where we set OpenGL version 2. Without any further settings it is processed inside system files and the system is parametrized from one place.


Let's try it

 Today there will not be any wow effect when running the engine. But we can at least prove that what we did is working. Go to Main.cpp and add these lines to our native methods:

//------------------------------------------------------------------------
static void engine_start(JNIEnv* aEnv, jobject aObj, jobject aAssetManager)
{
 LOGD("Starting engine ...");
}

//------------------------------------------------------------------------
static void engine_stop(JNIEnv* aEnv, jobject aObj, jboolean aTerminating)
{
 LOGD("Stopping engine ...");
}

 With this you should see log messages in the the LogCat.


Conclusion

 Today we put base for spreading our engine to more platforms in future. Next time we will focus on measuring time.

Download TutGame-03.zip