cocos2d-x-3.3-018-游戏摇杆joystick源码分享

来源:未知 责任编辑:责任编辑 发表时间:2015-09-16 20:03 点击:

 

 


  • 核心思想

    • 解耦,采用事件机制将joystick的事件和目标对象之间的关联进行解耦

      实现思路

      • 1.继承自layer并注册监听touch event
      • 2.若touch事件在joystick的中心点触发的,则继续下面的逻辑
      • 3.更新joystick中心点的位置
      • 4.计算touch点joystick中心点的角度(角度范围,第一象限[0, 90], 第二象限[90, 180], 第三象限[-180, -90], 第四象限[-90, 0])
      • 5.发布自定义的joystick event,目前事件仅包含上面计算的角度值,可根据需要进行增改
      • 6.注册joystick event的事件监听器,并在回调函数里实现你的业务逻辑
      • 7.joystick event中的userdata的内存释放,交给auto-release-pool了, 具体见JoystickEvent的实现

        核心代码

        • JoystickEvent主要是规范内存管理,严格按照cocos的'风俗'进行: 两段构造方式create+Ref+pool,使create出的对象像个栈上的局部变量。(mainLoop下次清理pool时自动删除)。
        • Joystick的核心代码
          
          bool Joystick::init() {
              bool result = false;
              do {
                  // 父类初始化
                  if (!Layer::init()) {
                      break;
                  }
                  // joystick的背景
                  mJsBg = Sprite::create(joystick_bg.png);
                  if (nullptr == mJsBg) {
                      break;
                  }
                  mJsBg->setPosition(mJsPos);
                  addChild(mJsBg);
          
                  // joystick的中心点
                  mJsCenter = Sprite::create(joystick_center.png);
                  if (nullptr == mJsCenter) {
                      break;
                  }
                  mJsCenter->setPosition(mJsPos);
                  addChild(mJsCenter);
          
                  // touch event监听
                  auto touchListener = EventListenerTouchOneByOne::create();
                  if (nullptr == touchListener) {
                      break;
                  }
                  touchListener->setSwallowTouches(true);
                  touchListener->onTouchBegan =
                          CC_CALLBACK_2(Joystick::onTouchBegan, this);
                  touchListener->onTouchMoved =
                          CC_CALLBACK_2(Joystick::onTouchMoved, this);
                  touchListener->onTouchEnded =
                          CC_CALLBACK_2(Joystick::onTouchEnded, this);
                  _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,
                          this);
          
                  result = true;
              } while (0);
          
              return result;
          }
          
          bool Joystick::onTouchBegan(Touch *touch, Event *unused_event) {
              log(onTouchBegan);
              auto point = touch->getLocation();
              if (mJsCenter->getBoundingBox().containsPoint(point)) {
                  // 若触摸点在joystick的中心点,则继续接受事件
                  return true;
              }
              // 否则不接受后续事件
              return false;
          }
          
          void Joystick::onTouchMoved(Touch *touch, Event *unused_event) {
              log(onTouchMoved);
          
              // 1. 获得角度,
              //第一象限是0,90度
              //第二象限是90,180度
              //第三象限是-90,-180度
              //第四象限是-90,0度
              Vec2 point = touch->getLocation();
              double y = point.y - mJsPos.y;
              double x = point.x - mJsPos.x;
              double angle = atan2(y, x) * 180 / PI;
              log(------------------------------------          %f, angle);
          
              // 2. 更新joystick中心点位置,目的是想让中心点始终在它的背景图范围
              // joystick背景图半径
              double jsBgRadis = mJsBg->getContentSize().width * 0.5;
              //触摸点到中心点的实际距离
              double distanceOfTouchPointToCenter = sqrt(
                      pow(mJsPos.x - point.x, 2) + pow(mJsPos.y - point.y, 2));
              if (distanceOfTouchPointToCenter >= jsBgRadis) {
                  //利用等比关系计算delta x y
                  double deltX = x * (jsBgRadis / distanceOfTouchPointToCenter);
                  double deltY = y * (jsBgRadis / distanceOfTouchPointToCenter);
                  mJsCenter->setPosition(Vec2(mJsPos.x + deltX, mJsPos.y + deltY));
              } else {
                  mJsCenter->setPosition(point);
              }
          
              //   3. 分发joystick event
              JoystickEvent* jsEvent = JoystickEvent::create();
              jsEvent->mAnagle = angle;
              Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(
                      JoystickEvent::EVENT_JOYSTICK, jsEvent);
          }
          
          void Joystick::onTouchEnded(Touch *touch, Event *unused_event) {
              log(onTouchEnded);
              // 事件结束,还原joystick中心点位置
              mJsCenter->setPosition(mJsPos);
          }
          
          	
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:点击我更换图片
最新评论 更多>>

推荐热点

  • cocos2d-x学习笔记(19)--label 、label atlas
  • cocos2d-x学习笔记(23)--地图的使用3--CCTMXLayer
  • Cocos2d-x 2.0 之 Actions “三板斧” 之一
  • Cocos2d-x学习(一):HelloWorld
  • cocos2d-x学习笔记(18)--游戏打包(windows平台)
  • cocos2d 设置屏幕默认方向
  • cocos2d-x学习笔记(16)--spritesheet(精灵表单)
  • cocos2d-x学习笔记(15)--地图的使用(TMX)
  • cocos2dx在xcode下开发,编译到android上(2)
网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
Copyright © 2008-2015 计算机技术学习交流网. 版权所有

豫ICP备11007008号-1