【Cocos2d-Js实战教学(1)横版摇杆八方向移动】
本教程主要通过搭建一个横版摇杆八方向移动的实例,让大家如何用Cocos2dx-Js来做一款
游戏,从基础了解Cocos2dx-Js的基本实现原理,从创建工程,到各个知识点的梳理。
教程分为上下两讲:
上讲有2个小节:
1,工程的创建;
2,Cocos2dx-Js目录及Cocos2dx运行原理;
下讲有2个小节:
1,Cocos2dx-Js的事件处理机制;
2,摇杆的、八方向、精灵移动的实现;
Js环境搭载传送门:
轻松搭建完后,开始用JS写一个横版摇杆动作游戏的Demo,听起来貌似很高大上~~。
首先要做好几个准备:
1,角色精灵,我准备了一个骨骼动画精灵1个,cocosstiduo2.0.6制作的;
2,地图,也是用cocosstiduo2.0.6制作,生成出MainScene.csb 文件;
3,摇杆的PNG素材;
下面开始创建一个新的工程GoFighting,创建主场景MainLayer.js文件;
MainLayer继承BaseLayer.js,BaseLayer中处理这个层基本的页面处理,包括弹出的新层的遮罩处理;
BaseLayer.js:
var BaseLayer=cc.Layer.extend({
_bgFrame:null,
_notShowAnimation:null,
_directorSteps:null,
_showAnied:false,
init:function(notShowAnimation){
var bret=false;
if(this._super()){
//不可删除
var bgFrame = cc.LayerColor(cc.color(0,0,0,200));
this.addChild(bgFrame);
this._bgFrame=bgFrame;
this._notShowAnimation=notShowAnimation;
this.setAnchorPoint(cc.p(0.5,0.5));
this.ignoreAnchorPointForPosition(false);
if(!this._notShowAnimation){
this.setScale(0.8);
}
this.setContentSize(winSize);
this.setPosition(cc.p(winSize.width/2,winSize.height/2)); cc.eventManager.addListener({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
//onTouchMoved: this.onTouchMoved,
onTouchBegan: function(){return true;}
}, this); bret=true;
}
return bret;
},
setBgColor:function(color){
this._bgFrame.setColor(color);
}, onEnter:function(){
this._super();
if(!this._notShowAnimation&&!this._showAnied){
var sl=cc.EaseIn.create(cc.ScaleTo.create(0.15,1.1),2);
var sl2=cc.ScaleTo.create(0.15,1);
var seq=cc.Sequence.create(sl,sl2);
this.runAction(seq);
this._showAnied=true;
}
}, onExit:function(){
this._super();
MemoryManager.getInstance().releaseMeoryFromOther();
}
}); BaseLayer.OpenActionFs=function(obj){
obj.setScale(0.8);
if(obj!=null){
var sl=cc.EaseIn.create(cc.ScaleTo.create(0.15,1.1),2);
var sl2=cc.ScaleTo.create(0.15,1);
var seq=cc.Sequence.create(sl,sl2);
obj.runAction(seq);
}
};
首先我们加载主场景必须得背景图片,而主场景背景图片由cocosstiduo2.0.6制作,如何绑定呢?
在3.2引擎终目前还不支持直接使用widgetFromBinaryFile方法加载CSB,那么换成另外一种加载创建Node的方式:
ccs.csLoader.createNode(res.MainScene_CSB);
使用该方法需要自己去添加全路径
/*
cocostidio制作的CSB文件加载,注:
在3.2引擎终目前还不支持直接使用widgetFromBinaryFile方法加载CSB
*/
var baseroot = ccs.csLoader.createNode(res.MainScene_CSB);
baseroot.setAnchorPoint(cc.p(0.5,0.5));
baseroot.setPosition(this.getContentSize().width/2,this.getContentSize().height/2);
this.baseroot=baseroot;
this.addChild(baseroot,1,9001);
BaseLayer.OpenActionFs(baseroot);
然后Run看一下效果:
然后继续加载角色的骨骼动画
//角色骨骼动画加载
var charname = "Char_014_1";
var nowcharurl = resRole+charname+".ExportJson";
if(jsb.fileUtils.isFileExist(nowcharurl)==true) {
cc.log("nowcharurl =" + nowcharurl);
ccs.ArmatureDataManager.getInstance().addArmatureFileInfo(nowcharurl);
var hero = ccs.Armature.create(charname);
this._hero_donghua = hero;
hero.setPosition(cc.p(330, 260));
hero.getAnimation().play("stand");
hero.getAnimation().setMovementEventCallFunc(this.overStand, this);
baseroot.addChild(hero, 3,99999);
}
角色hero有回调,如跑动后停下来的回调:
//移动完后回调
overStand:function() {
if(this._hero_donghua.getAnimation().getCurrentMovementID()=="")
{
this._hero_donghua.getAnimation().play("stand");
}
},
单单一个角色植入场景是否显得逻辑太单调,我们可以拖动这个精灵岂不更好,加一个简单的事件,让精灵活一点吧!!
//主角监听
var listener_Role = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function (touch, event) {
var target = event.getCurrentTarget(); var locationInNode = target.convertToNodeSpace(touch.getLocation());
var s = target.getContentSize();
var rect = cc.rect(0, 0, s.width, s.height); if (cc.rectContainsPoint(rect, locationInNode)) {
cc.log("sprite began... x = " + locationInNode.x + ", y = " + locationInNode.y);
target.setOpacity(180);
target.getAnimation().play("move");
return true;
}
return false;
},
onTouchMoved: function (touch, event) {
var target = event.getCurrentTarget();
var delta = touch.getDelta();
target.x += delta.x;
target.y += delta.y; },
onTouchEnded: function (touch, event) {
var target = event.getCurrentTarget();
cc.log("sprite onTouchesEnded.. ");
target.setOpacity(255);
target.getAnimation().play("stand"); }
});
在ctor构造中添加角色事件的注册方法:
//人物
cc.eventManager.addListener(listener_Role, this._hero_donghua);
OK,我们再Run起来看看效果:
还可以拖动的呢!
然后,我们继续实现摇杆模式:
摇杆与事件有关,JS中摇杆须继承cc.EventListener去创建事件,事件类型cc.EventListener.TOUCH_ONE_BY_ONE(单点触摸方式);
看代码:
//摇杆监听
var listener_YaoGan = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
onTouchBegan: function (touch, event) {
var target = event.getCurrentTarget();
var locationInNode = target.convertToNodeSpace(touch.getLocation());
//创建摇杆
this.sprite_yaogan = new cc.Sprite(res.YaoGan_png);
this.sprite_yaogan.attr({
x: locationInNode.x,
y: locationInNode.y
});
target.addChild(this.sprite_yaogan, 4,90099); //创建摇杆点
this.sprite_yaogan_dian = new cc.Sprite(res.YaoGan_Dian_png);
this.sprite_yaogan_dian.attr({
x: locationInNode.x,
y: locationInNode.y
});
target.addChild(this.sprite_yaogan_dian, 4,90999); return true;
}, onTouchMoved: function (touch, event) {
//摇杆点
var target = event.getCurrentTarget();
var sp_dian = target.getChildByTag(90999);
var sp_yaoganbd = target.getChildByTag(90099);
var sp_hero = target.getChildByTag(99999); //摇起来
if(sp_dian!=null&&sp_yaoganbd!=null)
{
var p_dian = sp_yaoganbd.getPosition();
var bd_width =sp_yaoganbd.getContentSize().width*0.5;
cc.log("bd_width>>=="+bd_width);
var point = touch.getLocation();
var p_rad = this.getRad(p_dian,point);
cc.log("p_rad>>=="+p_rad);
//计算两个圆心之间距离
var juli =Math.sqrt(Math.pow((p_dian.x - point.x),2) + Math.pow((p_dian.y - point.y),2));
//距离不超过半径
if(juli>=bd_width)
{
cc.log("go111>>>");
sp_dian.setPosition(cc.pAdd(this.getAngelePosition(bd_width,p_rad),cc.p(p_dian.x,p_dian.y)));
}
else
{
cc.log("go2222>>>");
var delta = touch.getDelta();
sp_dian.x += delta.x;
sp_dian.y += delta.y;
} // //判断方向---四方向
// if(p_rad>=-PI/4&&p_rad<PI/4)
// {
// R_Direction="right";
// }
// else if(p_rad>=PI/4&&p_rad<3*PI/4)
// {
// R_Direction="up";
// }
// else if((p_rad>=3*PI/4&&p_rad<=PI)||(p_rad>=-PI&&p_rad<-3*PI/4))
// {
// R_Direction="left";
// }
// else if(p_rad>=-3*PI/4&&p_rad<-PI/4)
// {
// R_Direction="down";
// } //判断方向---八方向
var move_x = parseInt(p_dian.x -point.x);
var move_y = parseInt(p_dian.y -point.y); if(move_x>=10&&move_y<=-10)
{
//左上
R_Direction = "left_up";
}
else if(move_x>=10&&move_y>=10)
{
//左下
R_Direction = "left_down";
}
else if(move_x<=-10&&move_y<=-10)
{
//右上
R_Direction = "rigth_up";
}
else if(move_x<=-10&&move_y>=10)
{
//右下
R_Direction = "rigth_down";
}
else if(move_x>-10&&move_x<10&&move_y>0)
{
//下
R_Direction = "down";
}
else if(move_x>-10&&move_x<10&&move_y<0)
{
//上
R_Direction = "up";
}
else if(move_x>0&&move_y>-10&&move_y<10)
{
//左
R_Direction = "left";
}
else if(move_x<0&&move_y>-10&&move_y<10)
{
//右
R_Direction = "right";
} R_Action="move";
cc.log("R_Direction>>>"+R_Direction);
}
}, //获取半径坐标
getAngelePosition:function(r,angle){
return cc.p(r*Math.cos(angle),r*Math.sin(angle));
}, //判断两点之间夹角
getRad:function(pos1,pos2)
{
var px1 = pos1.x;
var py1 = pos1.y;
var px2 = pos2.x;
var py2 = pos2.y; //得到两点x的距离
var x = px2 - px1;
//得到两点y的距离
var y = py1 - py2;
//算出斜边长度
var xie = Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
//得到这个角度的余弦值(通过三角函数中的店里:角度余弦值=斜边/斜边)
var cosAngle = x / xie;
//通过反余弦定理获取到期角度的弧度
var rad = Math.acos(cosAngle);
//注意:当触屏的位置Y坐标<摇杆的Y坐标,我们要去反值-0~-180
if (py2 < py1)
{
rad = -rad;
}
return rad;
}, onTouchEnded: function (touch, event) {
var target = event.getCurrentTarget();
if(target.getChildByTag(90099)!=null)
{
target.removeChildByTag(90099);
}
if(target.getChildByTag(90999)!=null)
{
target.removeChildByTag(90999);
} R_Action="stand"; var sp_hero = target.getChildByTag(99999);
sp_hero.getAnimation().play("stand");
} });
在上面这个Js类中,包含了几个方法如,两点之间夹角的计算公式和最大半径坐标的计算公式;
因为我们需要在摇杆和摇杆点上面去做坐标处理,计算出夹角来对角色进行坐标位移操作,达到我们所需要的效果
跑起来的摇杆效果如下:
摇杆可以活动了,并且不能超过底下的背景半径,达到了我们需要的效果,下面就继续实现摇杆操控精灵移动的功能
可以继续在onTouchMoved: function (touch, event)事件终写方法获取一些判定参数:
//方向
var R_Direction = "";
//动作
var R_Action = "stand";
//移动速度
var R_speed = 4;
继续看listener_YaoGan类中的方向判断,我写了2种角色移动方法:
1,根据PI=3.1415 来计算 ,做了4方向的标识判断
2,根据坐标差值来计算,做了8方向的标识判断
OK,两种方法都可以行,可以自己拓展。
有了标识我们需要启动一个定时器来执行人物的操作
下面是定时器部分的代码:
//更新状态
runGame:function(){ if(R_Action=="move")
{
if(this._hero_donghua!=null)
{
if(this._hero_donghua.getAnimation().getCurrentMovementID()!="move")
{
this._hero_donghua.getAnimation().play("move");
} var p_hero_old = this._hero_donghua.getPosition();
if(R_Direction=="right")
{
this._hero_donghua.setScaleX(-1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x+R_speed,p_hero_old.y)); }
else if(R_Direction=="up")
{
this._hero_donghua.setPosition(cc.p(p_hero_old.x,p_hero_old.y+R_speed)); }
else if(R_Direction=="left")
{
this._hero_donghua.setScaleX(1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x-R_speed,p_hero_old.y)); }
else if(R_Direction=="down")
{
this._hero_donghua.setPosition(cc.p(p_hero_old.x,p_hero_old.y-R_speed)); }
else if(R_Direction=="left_up")
{
this._hero_donghua.setScaleX(1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x-R_speed,p_hero_old.y+R_speed)); }
else if(R_Direction=="left_down")
{
this._hero_donghua.setScaleX(1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x-R_speed,p_hero_old.y-R_speed)); }
else if(R_Direction=="rigth_up")
{
this._hero_donghua.setScaleX(-1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x+R_speed,p_hero_old.y+R_speed));
}
else if(R_Direction=="rigth_down")
{
this._hero_donghua.setScaleX(-1);
this._hero_donghua.setPosition(cc.p(p_hero_old.x+R_speed,p_hero_old.y-R_speed)); }
}
}
}
OK,人物可以根据摇杆八方向的跑动起来了,我们Run起来看看效果,应该很赞!
嗯,该Demo就开发完毕了,下面是整个DEMO的下载地址,希望能大家对大家起到帮助;
cocos2d-x 3.2 - JS -横版摇杆八方向移动DEMO下载地址
自己创建一个新的工程,将ZIP解压文件拷贝到工程根目录就可以Run起来,替换main.js和project.json;
【Cocos2d-Js实战教学(1)横版摇杆八方向移动】的更多相关文章
- unity3d easytouch计算摇杆旋转角度以及摇杆八方向控制角色
在写第三人称控制的时候,一开始在电脑测试是用WASD控制角色 后来需要发布到手机上,于是就加了一个摇杆 键盘控制角色的代码已经写好了,角色八方向移动 如果按照传统的大众思路来控制的话,是达不到我想要的 ...
- iKcamp团队制作|基于Koa2搭建Node.js实战项目教学(含视频)☞ 环境准备
安装搭建项目的开发环境 视频地址:https://www.cctalk.com/v/15114357764004 文章 Koa 起手 - 环境准备 由于 koa2 已经开始使用 async/await ...
- Linux实战教学笔记03:操作系统发展历程及系统版本选择
标签(空格分隔): Linux实战教学笔记-陈思齐 第1章 Linux简介 1.1 什么是操作系统? 简单讲:操作系统就是一个人与计算机硬件的中介. 操作系统,英文名称Operating System ...
- 轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)
轻量级Java EE企业应用实战(第4版):Struts 2+Spring 4+Hibernate整合开发(含CD光盘1张)(国家级奖项获奖作品升级版,四版累计印刷27次发行量超10万册的轻量级Jav ...
- 《Node.js实战(双色)》作者之一——吴中骅访谈录
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)
介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...
- 如何让格斗游戏的横版过关(2) Cocos2d-x 2.0.4
在第一章<如何使横版格戏>基础上.添加角色运动.碰撞.敌人.AI和音乐音效,原文<How To Make A Side-Scrolling Beat 'Em Up Game Like ...
- 微信小程序横版日历,tab栏
代码地址如下:http://www.demodashi.com/demo/14243.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...
- cocos2d js jsb XMLHttpRequest 中文乱码
1.首先讲下怎样使用XMLHttpRequest 下面所说的是在cocos2d-x 2.2.2 或者 2.3 版本号中. 首先要明确cocos2d js事实上分两个版本号,一个是html5的版本号,另 ...
随机推荐
- 文件Move操作
#coding=utf-8 import os import shutil stra = "G:/should/v3/a" strb = "G:/should/v3/b& ...
- Markdown的简单使用
markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式.(扩展名为.md) markdown语法 # 一级标题 ## 二级标题 ### ...
- 记录java版本不兼容的坑,(kafka运行报错)
启动kafka报错 错误原因是: 由较高版本的jdk编译的java class文件 试图在较低版本的jvm上运行的报错 解决办法是: 查看java版本 C:\Users\Administrator&g ...
- webkit开源项目
WebKitOpen Source Web Browser Engine Blog Downloads Feature Status Reporting Bugs Contribute Getting ...
- html转义字符对照表
常用的html转义字符 字符 描述 实体名称 实体编号 " quotation mark(双引号“半角”) " " ' apostrophe (单引号‘半角’) & ...
- Codeforces 607A 动态规划
A. Chain Reaction time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 品味性能之道<二>:性能工程师可以具备的专业素养
性能工程师可以具备的专业素养 程序语言原理,包括:C.C++.java及jvm.ASP,因为建站大部分外围应用和中间件都是JAVA编写,大部分的电商平台采用的ASP编写,底层核心系统是C/ ...
- eclipse 远程调试mapreduce
使用环境:centos6.5+eclipse(4.4.2)+hadoop2.7.0 1.下载eclipse hadoop 插件 hadoop-eclipse-plugin-2.7.0.jar 粘贴到 ...
- java Exception in thread "main" java.lang.NoClassDefFoundError: main (wrong name: pm/main)
javac main.java 编译后没有问题 java main 出现下面在问题: Exception in thread "main" java.lang.NoClassDef ...
- 2018.08.29 NOIP模拟 table(拓扑排序+建图优化)
[描述] 给出一个表格,N 行 M 列,每个格子有一个整数,有些格子是空的.现在需要你 来做出一些调整,使得每行都是非降序的.这个调整只能是整列的移动. [输入] 第一行两个正整数 N 和 M. 接下 ...