【cocos2d-x 3.2 - JS -横版摇杆八方向移动】

花了少许时间利用了一下cocos2dx 3.2Js版本+cocosstiduo2.0.6做了一个横版摇杆八方向的demo;

目前到今天为止,Js版本为3.2稳定版本,官网下载传送门:

http://www.cocos2d-x.org/filedown/cocos2d-js-v3.2.zip

Js环境搭载传送门:

【cocos2d-x 3.0 - 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 };

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

时间: 2024-08-26 13:08:36

【cocos2d-x 3.2 - JS -横版摇杆八方向移动】的相关文章

unity3d easytouch计算摇杆旋转角度以及摇杆八方向控制角色

在写第三人称控制的时候,一开始在电脑测试是用WASD控制角色 后来需要发布到手机上,于是就加了一个摇杆 键盘控制角色的代码已经写好了,角色八方向移动 如果按照传统的大众思路来控制的话,是达不到我想要的效果的,传统控制思路代码如下: 1 //当摇杆处于移动状态时,角色开始奔跑 2 void OnJoystickMove(MovingJoystick move) 3 { 4 if (move.joystickName != "EasyJoystick") 5 { 6 return; 7 }

cocos2d横版游戏之摇杆控制

以上是一个控制摇杆,分为一个底座和摇杆小圈圈,我们的目的是通过算出摇杆小圈跟底座中心的偏移来控制任务的走向,我们计算出一个偏移量来,然后在场景update(foat dt)...每一帧的位置上加上这个偏移量,不停的播放行走动画(当然人物的朝向要对),就可以达到控制任务行走的效果了,这一点你可能一下子就会想到高中学过的向量的加减处理了......坐标象限....之类的. void DirectionControlButton::controlTargetMove(CCTouch *pTouch){

cocos2d-x 如何制作一个类马里奥的横版平台动作游戏 1 献给所有对动作游戏有爱的朋友

本文翻译自国外著名IOS源码教学商业网站raywenderlich 的IOS Game Start Kits三件套之一的Platformer Game/平台动作游戏的前奏曲,另一个是Beat'Em up Game/横版格斗游戏,作者是国外著名游戏开发专家Jake Gundersen,曾参与开发过SFC时代的洛克人X系列. 原文网址: http://www.raywenderlich.com/15230/how-to-make-a-platform-game-like-super-mario-br

如何制作一个类马里奥的横版平台动作游戏 续

欢迎回来,上篇我们讲到了物理引擎中重力环境模拟以及主角考拉与地面墙壁的碰撞,相信大家已经对2D世界的物理模拟有了一定的了解,现在我们接着讲如何让考拉动起来吧! 让考拉动起来! 这里控制考拉移动变得非常简单,它只有向前和跳两个能力(源码中我加了考拉向后走功能,建议大家自己加几个虚拟按键来实现更非富的功能)如果你按着屏幕左半部考拉会向前走,按住右半部考拉会跳起来(原文设定考拉不会后退-_-). 我们需要在Player.h里加两个成员变量: bool _forwardMarch;  //是否向前走 b

cocos2dx实战篇——Demo《横版拳击》学习心得

[唠叨] 源码教程请移步:http://blog.csdn.net/iamlazybone/article/details/19612941 感谢懒骨头提供了这么多的Demo教程,对于初学者的我而言,帮助真的十分大. 注:本节仅仅记录博主自身学习<横版拳击>的心得体会. [游戏截图] [学习心得] 0.编码步骤 (1)实现摇杆SneakyInput (2)实现ActionSprite (3)实现Hero,走动+攻击+受伤+死亡 (4)实现Enemy和EnemyManager,走动+攻击+受伤+

cocos2d-x 如何制作一个类马里奥的横版平台动作游戏续 2

     欢迎回来,上篇我们讲到了物理引擎中重力环境模拟以及主角考拉与地面墙壁的碰撞,相信大家已经对2D世界的物理模拟有了一定的了解,现在我们接着讲如何让考拉动起来吧! 让考拉动起来!    这里控制考拉移动变得非常简单,它只有向前和跳两个能力(源码中我加了考拉向后走功能,建议大家自己加几个虚拟按键来实现更非富的功能)如果你按着屏幕左半部考拉会向前走,按住右半部考拉会跳起来(原文设定考拉不会后退-_-).    我们需要在Player.h里加两个成员变量:    bool _forwardMar

如何制作一个类马里奥的横版平台动作游戏 献给对动作游戏有爱的朋友

本文翻译自国外著名IOS源码教学商业网站raywenderlich 的IOS Game Start Kits三件套之一的Platformer Game/平台动作游戏的前奏曲,另一个是Beat'Em up Game/横版格斗游戏,作者是国外著名游戏开发专家Jake Gundersen,曾参与开发过SFC时代的洛克人X系列. 原文网址: http://www.raywenderlich.com/15230/how-to-make-a-platform-game-like-super-mario-br

css 下拉列表,图片背景,竖版,取消注释为横版

<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link href="style/style.css" rel="stylesheet" type="text

横版游戏制作之英雄技能CD遮罩,人物头像血条属性

上图就是技能CD的一个效果,在此我需要给介绍下,cocosStuido这个工具中的UI Eidtor功能,编辑UI真的是很方便,至于怎么使用它,我相信您可以随便看看网上的东西,自己摸索,参考接下来的代码就知道了 在UI编辑器中,我们的技能是没有CD遮罩效果的,那怎么实现的呢? 答案就是:在点击触摸技能时,我们在技能的上方覆盖一张灰色的图片(这个你可以用PS去制作一张),大小与技能图标相同,然后根据每个技能的CD时间,产生一个扇形进度动画,动画结束后取消定时器跟这个遮罩对象就可以了 至于人物头像的