Contents
Introduction
Puzzle is a simple game suitable for all ages. The goal of the game is to put the right pieces into correct shapes.
Everyone has had a chance to play a puzzle game in real life but there are not that many puzzle games for mobiles. Nevertheless,
this game is suitable as a stand-alone game for children but it can be also used as a great marketing tool.
In this article, we would like to show you how to create this game for multiple mobile platforms using only one code.
Background
To overcome platform differences, we will use Moscrif SDK (available free for Open Source projects). This SDK comes with object-oriented JavaScript and an open-source framework which is easy to learn. The SDK also contains
publishing tools that generate native installation files.
About the game
Our game is made for Tablets and other devices which run iOS and Android, with a screen resolution larger than 600x900px. I have tested it on Amazon Kindle Fire, Galaxy Tab, Nook Color, iPad 2, and iPhone 4.
In this case, we designed a crocodile to be the puzzle objective so every piece has to be put in the correct shape in order for the picture of the crocodile to appear. This puzzle game can be implemented in many ways. For
marketing purposes, you can use your company logo, product photo, etc.
When making an app, our goal is to make a simple user interface, which gives the user the best experience possible.
Image 1: User interface
User experience
Recently, the mobile industry has been putting a lot of emphasis on user experience because programmers are finding out that only applications with a user-friendly interface can succeed. It means that applications have to do what the user’s intuition expects to do, while being responsive and smooth. To achieve this experience, parts can be moved smoothly according to finger movement and when a particular part is close to the position where it belongs, the part automatically snaps to it.
Development process
Using Moscrif SDK saves a lot of time, because we do not need to create three separate code for every platform.
We will create only one code and publish it for all target platforms.
There are three tasks that need to be addressed in order to create this game. The first one is the part distribution algorithm
which needs to take place right at the beginning of the game. During the game, there are two other tasks that need to be accomplished to make this a good puzzle game:
part dragging and snapping.
Parts distribution
Restart function
When the user taps onto the screen or every time the user hits the Refresh button, all puzzle parts are placed
randomly on the playing field. The position for every part is found separately.
Code Example 1: Restart function - calls
_findPosition
for every puzzle part
function restart()
{
for (var part in this._parts) {
part.isOnPlace = false;
this._findPosition(part);
}
this._onPlace = 0;
this._pulseButtons();
}
Function _findPosition
Function _findPosition
is even more interesting because it runs in a cycle until the right position for that particular part is found. Every run of this cycle generates a new
random position and then checks if it doesn’t overlays another, already placed, part.
However, in some cases, a cycle as we described can run forever. To prevent this critical mistake, we added a counter property and a max number of cycle repetitions.
Image 2: flow chart - _findPosition
Example code 2: Function _findPosition
finds a suitable position for the puzzle part
function _findPosition(part)
{
function random(from, to) { return from + rand(to-from+1); }
var counter = 0;
while (counter < 100 ) {
counter ++;
part.y = random(part.height/2,System.height-part.height/2);
if (part.y+part.height/2 < this._finalTop)
part.x = random(part.width/2, System.width - part.width/2);
else {
var area = rand(2);
if (area == 0)
part.x = random(part.width/2, this._finalLeft-part.width/2);
else
part.x = random(this._finalLeft + this._final.width,
System.width-part.width/2);
}
var collision = false;
for (var p in this._parts) {
if (part.intersectsBounds(p)) {
collision = true;
break;
}
}
if (!collision)
break;
}
}
Parts dragging
Smooth part dragging is important to provide an enjoyable user experience. When the user taps on a puzzle part,
finger movement will change the position of the part.
Example code 3: Function
_getPart
- finds the puzzle part under the tap position.
function _getPart(x, y)
{
var searchPart = #nothing;
for (var part in this._parts) {
if (part.intersectsPoint(x, y))
searchPart = part;
}
if (searchPart != #nothing) {
searchPart.relX = searchPart.x - x;
searchPart.relY = searchPart.y - y;
this._moveUp(searchPart);
}
return searchPart;
}
Example code 4: Function pointerDragged
- changes the part position in the pointer-dragged event
function pointerDragged(x, y)
{
super.pointerDragged(x, y);
if (this._catchImage != #nothing) {
this._catchImage.x = x;
this._catchImage.y = y;
this._catchImage.push(this);
}
}
Parts snapping
Snapping is another feature that provides a good user experience. While the user is dragging a part, the application calculates its distance from the position where it belongs.
If the distance is less than System.width
/ 38, it automatically snaps to its place.
Example code 5: Function push
- calculates the distance from the position where it belongs
function push(sender)
{
var sizeX = Math.pow((this.locX + this.width/2) - this.x,2);
var sizeY = Math.pow((this.locY + this.height/2) - this.y,2);
var size = Math.sqrt(sizeX + sizeY);
if (size < System.width / 38) {
this.x = this.locX + this.width/2 - this.relX;
this.y = this.locY + this.height/2 - this.relY;
if (!this.isOnPlace) {
sender._onPlace++;
this.isOnPlace = true;
}
} else if (this.isOnPlace) {
sender._onPlace--;
this.isOnPlace = false;
}
}
Image 3: Snapping area
As you can see in the previous example, if a part is snapped on its position, the
_onPlace
variable is increased.
The _victory
method checks if all parts are snapped on their position (_onPlace
== number of parts). If the _victory
method returns true
, the bitmap of the final image is drawn.
Summary
Now you know how to create your own puzzle game and what features are required to make the game enjoyable while providing a more user-friendly experience.
Yes, yes, we know the game is very basic but it was made for learning purposes and it should serve as a base ground for your next awesome app.
As we mentioned before, implementing such a game into your already existing business app will increase brand awareness and customer engagement.
And in addition to all of this amazing stuff, let’s not forget that this game was made in object-oriented JavaScript, can be run on
three platforms (iOS, Android, and Bada),
as well as on Tablets and SmartPhones. Happy coding!
More resources
More samples, demos, and information about Moscrif can be found on its homepage:
www.moscrif.com.