Introduction to Moscrif SDK – A cross-platform development tool for mobile developers

Mobile devices have become extremely popular over the last couple of years. The popularity is still rising and mobile devices are clearly pushing old-school PCs and notebooks out of the market. Even though iOS and Android are by far the most popular mobile platforms, the number of newer platforms is also increasing, thereby making it difficult for the developer to reach the desired and widespread audience.

As a result, it has become impossible to develop an app/game for every platform separately, simply because it is just too costly and time-consuming. Instead, many developers have now started using cross-platform solutions which allow them to develop their mobile app just once and easily port it to multiple mobile devices. Moscrif SDK is one such tool.

Moscrif SDK

Moscrif is a cross-platform development tool suited for modern mobile developers. Currently, it supports 80% of devices and this number is rising with every new release of the SDK. Besides the well-known iOS and Android platforms, Moscrif supports Kindle, Bada and Nook. Support for the newly-released Windows Phone is scheduled for mid-2013.

Key advantages over other similar solutions:

  • Free licence – Moscrif offers free licence making it ideal for all developers.
  • JavaScript – Moscrif is based on JavaScript, so there is no need to learn any advanced programming language. Most developers are already familiar with this language and because JavaScript is extremely easy to learn, it is ideal for beginners as well.
  • High performance – Moscrif is the only cross-platform development tool offering amazing 50fps for mobile games allowing them to run smoothly even with the most complex graphics.

android smatphone market share 2012
[Data Source]

Before We Begin

Before we can start developing, we need to prepare the environment. Moscrif comes with its own IDE that is included in the SDK download. Preparing the complete environment takes only 9 minutes, so you can start typing your first lines of code very quickly!

Moscrif sdk comes with its own IDE that is included in the SDK download

Moscrif is available for free on its home page: http://moscrif.com/get-started.

Building a Billiard Game App with Moscrif

For the sake of this introduction, we will create a simple Billiard game demo using the Moscrif SDK.

Physical Engine

Simulating the real world’s behaviour can be a difficult task. Therefore, Moscrif relies on the well-known Box2x physical engine that, besides being open-source, is used by many major platforms such as Nintendo DS and the Wii. Even the popular Angry Birds game relies on this engine.

A typical Box2x simulation consists of several key elements such as world, bodies and joints. All these cooperate together and provide trustworthy simulation of a real world. The world element itself defines gravity force that affects all the bodies within it and offers several events that are called as and when any of these bodies collide together.

There are basically two types of bodies that affect the final behaviour – static and dynamic. Static bodies (like barriers in this demo) never move. On the other hand, dynamic bodies are fully simulated and move according to the forces in the world (gravity, etc.). Billiard balls are objects, or bodies, contain some other important properties that affect their behaviour. According to Moscrif’s API, these are:

  • Density: Density of the body.
  • Friction: Friction of the body affects the body adhesion.
  • Bounce: The bounce value is usually set between 0 and 1. Consider dropping a ball on a table. A value of zero means the ball won’t bounce. This is called an inelastic collision. A value of one means the ball’s velocity will be exactly reflected. This is called a perfectly elastic collision. If we collide two bodies with different bounce, box2d uses the one with the larger value to simulate the bounce.

PhysicsScene

In Moscrif, the Box2d world is represented by PhysicsScene class. In our demo, this class is responsible for drawing objects like table, borders around it, holes, balls and the cue. The scene also contains ForceBar layers that draw the bar responsible for controlling the hit force.

In Moscrif sdk the Box2d world is represented by PhysicsScene class

To redraw the scene, overwritten Draw method is called drawing the desired objects. The cue is drawn only when the ball is not moving.

Example: Drawing the Table and the Cue

[js]
function draw(canvas)
{
canvas.clear(0xffaaaaaa);
canvas.drawBitmapRect(res.image.table, 0, 0, res.image.table.width, res.image.table.height, res.number.tableLeft, res.number.tableTop, res.number.tableLeft + res.number.tableWidth, res.number.tableTop + res.number.tableHeight);
var (x, y);
if (!this.ballsMoving) {
// save canvas without transalation
canvas.save();
// restirct the drawing area
canvas.clipRect(res.number.tableLeft + res.number.mantinel, res.number.tableTop + res.number.mantinel, res.number.tableLeft + res.number.tableWidth – res.number.mantinel, res.number.tableTop + res.number.tableHeight-res.number.mantinel, #intersect );
(x, y) = this.whiteBall.getPosition();
x = x.toInteger();
y = y.toInteger();
canvas.translate(x, y);
canvas.rotate(this.angle*180.0/Math.PI – 90);
canvas.drawLine(0, 0, 0, res.number.lineLength, res.paint.line);
// restore saved canvas
canvas.restore();
}
// draw box2d world
super.draw(canvas);

if (!this.ballsMoving) {
(x, y) = this.whiteBall.getPosition();
x = x.toInteger();
y = y.toInteger();
// save canvas without transalation

canvas.save();
// move and rotate canvas

canvas.translate(x, y);
canvas.rotate(this.angle*180.0/Math.PI);
// draw cue
canvas.drawBitmap(res.image.cue, -1*res.image.cue.width – this._cuePosition, res.image.cue.height / -2);
// restore saved canvas
canvas.restore();
}
// draw FPS
canvas.drawText(String.printf("FPS: %2.f", System.avgFPS), 50, 50, res.paint.textPaint);
}
[/js]

Creating the Border

The table’s borders are made of 6 static bodies, placed around the table’s playground. Because their bounce property is set to 1.0, once the ball hits the border it will bounce back with the same force. The barriers are represented by polygon bodies and created by createPolygonBody method. An array of all bodies vertexes is provided as an argument. These vertexes are set by x and y coordinates in pixels from the centre of bodies’ shape.

The barriers are represented by polygon bodies and created by createPolygonBody

Example:: Creating the Table’s Border

[js]
function _createBarriers()
{
// top
var shape = [
{x: res.number.tableWidth / -4 + res.number.holeRadius, y : res.number.mantinel / 2 },
{x: res.number.tableWidth / -4 + res.number.holeRadius + res.number.mantinel, y : res.number.mantinel / -2 },
{x: res.number.tableWidth / 4 - res.number.holeRadius, y : res.number.mantinel / -2 },
{x: res.number.tableWidth / 4, y : res.number.mantinel / 2},
];

this.addPolygonBody(null, #static, 1.0, 0.0, 1.0, shape).setPosition(res.number.tableLeft + res.number.tableWidth / 4, res.number.tableTop + res.number.mantinel / 2);

shape = [
{x: res.number.tableWidth / -4, y : res.number.mantinel / 2 },
{x: res.number.tableWidth / -4 + res.number.holeRadius, y : res.number.mantinel / -2 },
{x: res.number.tableWidth / 4 - res.number.mantinel - res.number.holeRadius, y : res.number.mantinel / -2 },
{x: res.number.tableWidth / 4 - res.number.holeRadius, y : res.number.mantinel / 2},
];

this.addPolygonBody(null, #static, 1.0, 0.0, 1.0, shape).setPosition(res.number.tableLeft + 3*res.number.tableWidth / 4, res.number.tableTop + res.number.mantinel / 2);


}
[/js]

Ball Distribution

The balls are distributed into equilateral triangles on the right half of the table alternately full and half ball.

Example: : Distributing the Balls

[js]
function _createBalls()
{
this.balls = new Array();
var gap = Math.sqrt((res.number.ballRadius*res.number.ballRadius)/2);
var shape = new b2CircleShape(res.number.ballRadius / this.scale);
var ball = 0;
var number = 0;
for (var i = 0; i < 5; i++)
for (var q = 0; q < i+1; q++) {
ball = PhysicsSprite.create(this, res.images.sonicRoll, shape, #dynamic, 1.0, 0.0, 1.0, Ball);
ball.setPosition(res.number.ballX + 2*i*gap, res.number.ballY + i*gap – 2*q*gap);
ball.bullet = true;
ball.setLinearDamping(res.number.tableDamping);
ball.color = res.ballColor[number];
ball.ballType = res.ballType[number];
ball.id = #ball;
number++;
this.balls.push(ball);
}
this.balls[4].color = 0xff000000;
this.balls[4].ballType = #full;
}
[/js]

Controlling the Cue

The cue and its hit force are controlled by the user’s touch. When the user taps the screen, the pointerPressed method is called and the first angle of the cue is calculated.

Example: : Managing Pointer Pressed Event

[js]
function pointerPressed(x, y)
{
super.pointerPressed(x, y);
// if some ball is moving do nothing
if(this.ballsMoving)
return;

if (x<System.width – res.number.barWidth) {
// compute actual distance from the white ball
var (ballX, ballY) = this.whiteBall.getPosition();
var distanceX = x – ballX;
var distanceY = y – ballY;
// calculate angle
this.angle=Math.atan2(distanceY, distanceX);

this._control = #angle;
}
}
[/js]

When the user’s touch is moving on the screen, the pointerDragged method is called and a new angle of the cue is calculated.

Example: : Managing Pointer Dragged Event

[js]
function pointerDragged(x, y)
{
super.pointerDragged(x, y);
if(this.ballsMoving)
return;
if (this._control == #angle) {
// compute actual distance from start position
var (ballX, ballY) = this.whiteBall.getPosition();
var distanceX = x – ballX;
var distanceY = y – ballY;

this.angle=Math.atan2(distanceY, distanceX);
this._direction = {
x : x,
y : y,
}
}
}
[/js]

Force Control

The hitting force is controlled by the bar to the right ofm the table. This bar is created in a separate layer and responds to the user’s tap, very similar to the cue. Beside pointerPressed and pointerDragged events, it also responds to the pointerReleased event that is called when the user releases their finger from the screen.

Example: : Applying Impulse to the White Ball>

[js]
function pointerReleased(x, y)
{
if (this._control == #power) {
// this.force -> from 0.0 to 1.0
var force = this.force * res.number.maxForce;
// linear velocity on x and y axis
var velox = force*Math.cos(game.table.angle)/this.scale;
var veloy =-force*Math.sin(game.table.angle)/this.scale;

// set linear velocity to the ball
game.table.whiteBall.setLinearVelocity(velox, veloy);
game.table.ballsMoving = true;
this._control = #nothing;
this.force = 0.0;
}
}
[/js]

Source Code

Final source code can be downloaded from the attached ZIP file. The project is a fully working Billiard (pool) game for three mobile platforms: iOS, Android and Bada. With only a few adjustments, this demo can be easily transformed into a full game ready for app stores.

Summary

The aim of this article was to introduce you to Moscrif SDK as an easy to use cross-platform tool for developing mobile games for the most common platforms.

Author: (928 Posts)

This post has been written by the team here at Speckyboy Design Magazine.

Comments