Cocos2d is a popular native game framework which is out there for many years. There are several version of Cocos2d like Cocos2d-x or Cocos2d-html5. Cocos2d also supports different coding languages, such as lua, C++ and Javascript. This features makes Cocos2d a really powerful tool when it comes to real cross device solutions, code once and deploy it everywhere immediately.
I assume you already have set up your Cocos2d environment, and you know how to create an empty project. We will start of with the basic project template provided by CocosStudio and use javascript as coding language. After some basic coding we will end up with a customizable D-pad which will work on every platform supported by Cocos2d.
New to cocos2d? Here some helpful links:
D-pad script
Starting off with extending a cc.Laye class, which will handle our touch inputs and draw the sprites. We can easily add all the touch events we need to this layer. Since we have multi touch response, we need to check each touch coordinate with the position of our input elements. Once the positions overlaps the input element will be activated. While a button element has just a pressed state, the analog stick will return an x and y value between -1 and 1.
The analog stick gets updated each time the touch-move event occurs. Once the touch-end event is fired, the input element state will fall back to deactivated.
Once the script is included into your cocos2d project you can add a analog-stick or a button by a simple command. You should definitely customize your input script to perfectly fit into your theme.
ctor:function () {
this._super();
//ARRAY WHICH HOLDS ALL CONTROLL ELEMENTS
this.controls = [];
//HANDLE INPUT EVENTS
cc.eventManager.addListener(cc.EventListener.create({
event: cc.EventListener.TOUCH_ALL_AT_ONCE,
swallowTouches: true,
onTouchesBegan: function (touches, event) {
var controls = event.getCurrentTarget().controls;
//FOR EACH TOUCH
for (var i = 0; i < touches.length; i++)
{
var touch = touches[i]; //CURRENT TOUCH EVENT
var pos = touch.getLocation(); //TOUCH POSITION
//CHECK TOUCH POSITION AGAINST EACH CONTROLL ELEMENT
for (var j = 0; j < controls.length; j++)
{
var dist = Math.sqrt((pos.x-controls[j].pos.x)*(pos.x-controls[j].pos.x) + (pos.y-controls[j].pos.y)*(pos.y-controls[j].pos.y));
//ON A INPUT ELEMENT
if(dist < controls[j].size)
{
controls[j].touchStart(touch);
};
};
};
},
onTouchesMoved:function (touches, event) {
var controls = event.getCurrentTarget().controls;
//FOR EACH TOUCH
for (var i = 0; i < touches.length; i++)
{
var touch = touches[i]; //CURRENT TOUCH EVENT
//FOR EACH CONTROLL ELEMENT
for (var j = 0; j < controls.length; j++)
{
//IF TOUCH ID == CONTROLL ELEMENT TOUCH ID
if(touch.getID() == controls[j].touchID)
{
//MOVE EMLEMENT
controls[j].touchMove(touch);
};
};
};
},
onTouchesEnded:function (touches, event) {
var controls = event.getCurrentTarget().controls;
//FOR EACH TOUCH
for (var i = 0; i < touches.length; i++)
{
var touch = touches[i]; //CURRENT TOUCH EVENT
//FOR EACH CONTROLL ELEMENT
for (var j = 0; j < controls.length; j++)
{
//IF TOUCH ID == CONTROLL ELEMENT TOUCH ID
if(touch.getID() == controls[j].touchID)
{
controls[j].touchEnd();
};
};
};
}
}), this);
},
//ADD A NEW ANALOG STICK
addStick:function(posX,posY)
{
//ADD ANALOG STICK BASE SPRITE
var base = cc.Sprite.create("res/input/StickBase.png");
base.setPosition(cc.p(posX,posY));
this.addChild(base);
//ADD ANALOG STICK SPRITE
var stick = cc.Sprite.create("res/input/Stick.png"); // SET SPRITE
stick.setPosition(cc.p(posX,posY)); // SET POSITION
stick.pos = {x:posX,y:posY}; // SAVE START POSITION
stick.size = 40; // TOUCH SIZE / MOVABLE RADIUS SIZE
stick.startPos = {x:0,y:0}; // TOUCH START POSITION
stick.input = {x:0,y:0}; // CURRENT INPUT VALUE
stick.touchID = -1; // TOUCH ID
stick.opacity = 150; // LOW OPACITY 0-255
this.addChild(stick); //ADD STICK TO SCENE
// ON TOUCH START
stick.touchStart = function(touch)
{
this.startPos = {x:touch.getLocation().x,y:touch.getLocation().y}; //GET TOUCH START POSITION
this.opacity = 255; //SET FULL OPACITY
this.touchID = touch.getID(); //GET TOUCH ID
};
// ON TOUCH MOVE
stick.touchMove = function(touch)
{
var pos = touch.getLocation(); //CURRENT LOCATION
var dx = touch.getLocation().x - this.startPos.x; //MOVED IN X DIRECTION
var dy = touch.getLocation().y - this.startPos.y; //MOVED IN Y DIRECTION
var r = Math.sqrt(dx * dx + dy * dy); //GET MOVE DISTANCE
var _r = Math.min(r, this.size); //KEEP DISTANCE BETWEEN 0 - SIZE
dx = dx * _r / r;
//RECALCULATE dx based on _r
if (isNaN(dx) === true) {
dx = 0.0;
}
//RECALCULATE dy based on _r
dy = dy * _r / r;
if (isNaN(dy) === true) {
dy = 0.0;
}
//UPDATE STICK POSITION
this.setPosition(cc.p(this.pos.x+dx,this.pos.y+dy));
//UPDATE INPUT VALUE TO STAY BETWEEN 0-1;
this.input = {x:dx/this.size,y:dy/this.size};
};
// ON TOUCH END
stick.touchEnd = function()
{
this.setPosition(cc.p(this.pos.x,this.pos.y)); // SET POSITION TO 0,0
this.opacity = 150; // SET OPACITY
this.touchID = -1; // REMOVE TOUCH ID
this.input = {x:0,y:0}; //RESET INPUT VALUE
};
//GET ANGLE FROM STICK
stick.getAngle = function()
{
return Math.atan2(this.input.x, this.input.y)* 180/Math.PI;
}
this.controls.push(stick); //ADD STICK TO CONTROLL ARRAY
return stick; //RETURN STICK FOR EASY ACCESS
},
//ADD A NEW BUTTON
addButton:function(posX,posY)
{
var button = cc.Sprite.create("res/input/button.png"); // SET SPRITE
button.setPosition(cc.p(posX,posY)); //SET POSITION
button.pos = {x:posX,y:posY}; // SAVE START POSITION
button.opacity = 150; //SET OPACITY
button.size = 40; // TOUCH SIZE
button.input = false; // CURRENT INPUT VALUE
button.touchID = -1; // TOUCH ID
this.addChild(button); //ADD BUTTON TO SCENE
// ON TOUCH START
button.touchStart = function(touch)
{
this.input = true; //SET INPUT TO TRUE
this.opacity = 255; //SET FULL OPACITY
this.touchID = touch.getID(); //GET TOUCH ID
};
button.touchMove = function(touch,target)
{
};
button.touchEnd = function()
{
this.input = false; //SET INPUT TO FALSE
this.opacity = 150; //SET LOW OPACITY
this.touchID = -1; //REMOVE TOUCH ID
};
this.controls.push(button); //ADD STICK TO CONTROLL ARRAY
return button; //RETURN STICK FOR EASY ACCESS
}
})
how to use
Make sure you have copied or changed the necessarily graphic assets. Simply add a new touch controller layer to the scene. Add buttons and analog sticks as required.
I highly encourage you to check an manipulate the touchController.js script to fit your needs perfectly.
var touchInput = new touchController();
this.addChild(touchInput);
this.lStick = touchInput.addStick(x,y);
this.rStick = touchInput.addStick(x,y);
this.button_1 = touchInput.addButton(x,y)
conclusion
Cocos2d is a great cross device game engine, unfortunately it will take a lot of time to fully understand how cocos2d works and how to use the javascript version of it. Once you feel comfortable with cocos2d you can easily build 2d games for any target device natively and in html5.
Having a D-pad is a good starting point, you have to control the player somehow. Even better, this D-pad will work on Android, iOs, html5 and most desktop operating systems without any customization.