【Cocos2d-Js实战教学(1)横版摇杆八方向移动】

本教程主要通过搭建一个横版摇杆八方向移动的实例,让大家如何用Cocos2dx-Js来做一款
游戏,从基础了解Cocos2dx-Js的基本实现原理,从创建工程,到各个知识点的梳理。

教程分为上下两讲:

上讲有2个小节:

1,工程的创建;

2,Cocos2dx-Js目录及Cocos2dx运行原理;

下讲有2个小节:

1,Cocos2dx-Js的事件处理机制;

2,摇杆的、八方向、精灵移动的实现;

 

Js环境搭载传送门:

【Cocos2d-Js基础教学(1)JS -Mac配置篇】

 

轻松搭建完后,开始用JS写一个横版摇杆动作游戏的Demo,听起来貌似很高大上~~。

首先要做好几个准备:

1,角色精灵,我准备了一个骨骼动画精灵1个,cocosstiduo2.0.6制作的;

2,地图,也是用cocosstiduo2.0.6制作,生成出MainScene.csb 文件;

3,摇杆的PNG素材;

 

 

下面开始创建一个新的工程GoFighting,创建主场景MainLayer.js文件;

MainLayer继承BaseLayer.js,BaseLayer中处理这个层基本的页面处理,包括弹出的新层的遮罩处理;

 

BaseLayer.js:

 1 var BaseLayer=cc.Layer.extend({
 2     _bgFrame:null,
 3     _notShowAnimation:null,
 4     _directorSteps:null,
 5     _showAnied:false,
 6     init:function(notShowAnimation){
 7         var bret=false;
 8         if(this._super()){
 9             //不可删除
10             var bgFrame = cc.LayerColor(cc.color(0,0,0,200));
11             this.addChild(bgFrame);
12             this._bgFrame=bgFrame;
13             this._notShowAnimation=notShowAnimation;
14             this.setAnchorPoint(cc.p(0.5,0.5));
15             this.ignoreAnchorPointForPosition(false);
16             if(!this._notShowAnimation){
17                 this.setScale(0.8);
18             }
19             this.setContentSize(winSize);
20             this.setPosition(cc.p(winSize.width/2,winSize.height/2));
21 
22             cc.eventManager.addListener({
23                 event: cc.EventListener.TOUCH_ONE_BY_ONE,
24                 swallowTouches: true,
25                 //onTouchMoved: this.onTouchMoved,
26                 onTouchBegan: function(){return true;}
27             }, this);
28 
29             bret=true;
30         }
31         return bret;
32     },
33     setBgColor:function(color){
34         this._bgFrame.setColor(color);
35     },
36 
37     onEnter:function(){
38         this._super();
39         if(!this._notShowAnimation&&!this._showAnied){
40             var sl=cc.EaseIn.create(cc.ScaleTo.create(0.15,1.1),2);
41             var sl2=cc.ScaleTo.create(0.15,1);
42             var seq=cc.Sequence.create(sl,sl2);
43             this.runAction(seq);
44             this._showAnied=true;
45         }
46     },
47 
48     onExit:function(){
49         this._super();
50         MemoryManager.getInstance().releaseMeoryFromOther();
51     }
52 });
53 
54 BaseLayer.OpenActionFs=function(obj){
55     obj.setScale(0.8);
56     if(obj!=null){
57         var sl=cc.EaseIn.create(cc.ScaleTo.create(0.15,1.1),2);
58         var sl2=cc.ScaleTo.create(0.15,1);
59         var seq=cc.Sequence.create(sl,sl2);
60         obj.runAction(seq);
61     }
62 };
View Code

 

首先我们加载主场景必须得背景图片,而主场景背景图片由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~-180if (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;

 

转载于:https://www.cnblogs.com/zisou/p/cocos2dx-js_sz1.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在单文档中显示我的第一个对话框

在单文档中显示我的第一个对话框 (2010-04-19 21:19:50) 转载▼标签&#xff1a; it 今天编写了在单文档中创建对话框以及调用对话框的代码&#xff0c;收获很多&#xff1b; 1&#xff1a;OnInitDialog函数的加载问题尤其是在VS上的加载&#xff1b;&#xff08;这一点花了…

主机Window不能访问该虚拟机Linux Samba文件服务提供了一个文件夹

我最近遇到一个问题。虚拟机Linux中间Samba服务常开。主办“\\192.168.229.200” (我的虚拟机Linux址)訪问不了Share文件夹&#xff08;/var/test&#xff09;&#xff0c;并且经过数次的重新启动&#xff0c;检查配置。再重新启动&#xff0c;都没法解决。后来突然想到了主机管…

Linux进程间通信(四) - 共享内存

共享内存的优势 采用共享内存通信的一个显而易见的好处是效率高&#xff0c;因为进程可以直接读写内存&#xff0c;而不需要任何数据的拷贝。对于像管道和消息队列等通信方式&#xff0c;则需要在内核和用户空间进行四次的数据拷贝&#xff0c;而共享内存则只拷贝两次数据&…

jQuery EasyUI使用教程之基本的拖放

2019独角兽企业重金招聘Python工程师标准>>> <jQuery EasyUI最新版下载> 本教程将为你展示如何使HTML元素可拖动。在这个示例中我们将创建3个DIV元素&#xff0c;然后使它们能够被拖动。 查看演示 首先&#xff0c;我们创建3个div元素&#xff1a; < div i…

在Linux中head命令,Linux 中 head 命令实例

原标题&#xff1a;Linux 中 head 命令实例head命令将每个文件的前10行打印到标准输出。对于多个文件&#xff0c;在每个文件前面加上一个给出文件名的头。如果没有文件&#xff0c;或者文件为-&#xff0c;则读取标准输入。如何使用head命令使用head显示/etc/passwd前十行内容…

【原创】Git删除暂存区或版本库中的文件

0 基础 我们知道Git有三大区&#xff08;工作区、暂存区、版本库&#xff09;以及几个状态&#xff08;untracked、unstaged、uncommited&#xff09;&#xff0c;下面只是简述下Git的大概工作流程&#xff0c;详细的可以参见本博客的其他有关Git的文章【链接】。&#xff08;1…

JMS

JMS即Java消息服务&#xff08;Java Message Service&#xff09;应用程序接口是一个Java平台中关于面向消息中间件&#xff08;MOM&#xff09;的API&#xff0c;用于在两个应用程序之间&#xff0c;或分布式系统中发送消息&#xff0c;进行异步通信。Java消息服务是一个与具体…

Android学习四、Android中的Adapter

一、Adapter的介绍 An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set. 一个Adapter是…

linux select shell,linux之shell编程select和case用法

shell里的select用法&#xff1a;语法&#xff1a;#i/bin/bashselect 变量 in 列表do要执行的语句done举例&#xff1a;#!/bin/bashecho "What is your favourite OS?"select var in "windows" "Linux" "Gnu Hurd" "Free BSD&qu…

Andorid获取状态栏高度

在应用开发中&#xff0c;有时我们需要用代码计算布局的高度&#xff0c;可能需要减去状态栏(status bar)的高度。状态栏高度定义在Android系统尺寸资源中status_bar_height,但这并不是公开可直接使用的&#xff0c;例如像通常使用系统资源那样android.R.dimen.status_bar_heig…

linux 检测蓝牙 rssi,树莓派开发笔记(十一):蓝牙的使用,BlueZ协议(双树莓探测rssi并通过蓝牙互传获取的rssi信号强度)...

若该文为原创文章&#xff0c;转载请注明原文出处长期持续带来更多项目与技术分享&#xff0c;咨询请加QQ:21497936、微信&#xff1a;yangsir198808下一篇&#xff1a;敬请期待…接下来介绍树莓派蓝牙模块的开发&#xff0c;使用的协议为bluez。客户端bob&#xff0c;服务器al…

Android Studio项目整合PullToRefresh的问题记录

PullToRefresh下拉刷新在App中应用非常频繁&#xff0c;然而PullToRefresh是在ADT下开发完成的。如果要将其整合到Android Studio目录下的话颇费周折。前面的文章“Android Studio项目引入外部库注意事项(PullToRefresh)”介绍了如何将PullToRefresh的library引入到项目中。如果…

第 三 十 八 天:Linux 的 LVM 逻 辑 卷 管 理

小Q&#xff1a;书籍是全世界的营养品。生活里没有书籍&#xff0c;就好像没有阳光&#xff1b;智慧里没有书籍&#xff0c;就好像鸟儿没有翅膀。 —— 莎士比亚简介LVM&#xff1a;Logical Volume Manager&#xff08;逻辑卷管理&#xff09;&#xff…

Camera Calibration 相机标定:原理简介(三)

3 绝对圆锥曲线 在进一步了解相机标定前&#xff0c;有必要了解绝对圆锥曲线&#xff08;Absolute Conic&#xff09;这一概念。 对于一个3D空间的点x&#xff0c;其投影空间的坐标为&#xff1a;x~[x1,x2,x3,x4]T。我们定义无穷远处的平面用符号Π∞表示&#xff0c;该平面内的…

C语言判断两字符串同构,c语言实现判断两颗树是否同构

在本题中认为如果两个树左右子树交换可以相同&#xff0c;也被认为是同构树。对应输入格式为&#xff1a;4(总结点数)A - 1B 2 3C - -D - -#include #define Tree int#define Null -1#define MAXSIZE 10struct Node{char Element;Tree Left;Tree Right;}T1[MAXSIZE], T2[MAXSIZ…

C语言常量类型及名称,菜鸟带你入门C语言|基本数据类型之常量

常量在程序中&#xff0c;有些数据是不需要改变的&#xff0c;也是不能改变的&#xff0c;因此&#xff0c;我们把这些不能改变的固定值称为常量。如下图中的“5”、“A”、“Good”&#xff0c;这些在程序执行过程中是一直保持不变的&#xff0c;他们就是常量。printf的作用是…

Android TabHost中实现标签的滚动以及一些TabHost开发的奇怪问题

最近在使用TabHost的时候遇到了一些奇怪的问题&#xff0c;在这里总结分享备忘一下。 首先说一点TabActivity将会被FragmentActivity所替代&#xff0c;但是本文中却是使用的TabActivity。 下面说说本程序能够实现的功能&#xff1a; 实现TabHost中的标题栏能够横向滚动&#x…

tl wn322g linux驱动下载,怎样才能装好tl_wn322G+V2.0版USB无线网卡的Linux驱动

怎样才能装好tl_wn322GV2.0版USB无线网卡的Linux驱动tl_wn322G 2.0版无线网卡采用的是Atheros 的AR9271方案&#xff0c;我尝试了用ndiswrapper-1.55在linux下安装该无线网卡的Windows驱动&#xff0c;安装windows版的驱动时&#xff0c;用ndiswrapper -l &#xff0c;显示为错…

Spring + Dubbo + zookeeper (linux) 框架搭建

2019独角兽企业重金招聘Python工程师标准>>> dubbo简介 节点角色说明&#xff1a; Provider: 暴露服务的服务提供方。 Consumer: 调用远程服务的服务消费方。 Registry: 服务注册与发现的注册中心。 Monitor: 统计服务的调用次调和调用时间的监控中心。 Container: …

c语言 函数编程四个数相加,C语言第四章课后编程题

1.编写程序&#xff0c;从键盘上输入4个整数&#xff0c;输出最小值。此题较为简单&#xff0c;只需定义一个桥梁最小值min就可以来着次比较他们的大小。2.编写一个程序&#xff0c;从键盘输入一个四位整数n&#xff0c;输出它的各位数字之和。例如n1308&#xff0c;则输出12&a…