查看原文或更新请移步到我的wiki: https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3-018-joystick4cocos3.3
joystick
- joystick for cocos2d-x v3.3
- 完整代码和资源https://github.com/cheyiliu/joystick
核心思想
- 解耦,采用事件机制将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);
- }
集成到项目
- 我以proj.linx为例
- 拷贝相关cpp .h到工程并在CMakeLists.txt中增加cpp
- set(GAME_SRC
- Classes/AppDelegate.cpp
- Classes/HelloWorldScene.cpp
- Classes/Joystick.cpp #新增
- ${PLATFORM_SPECIFIC_SRC}
- )
- 添加joystick到场景
- auto joystick = Joystick::create();
- scene->addChild(joystick);
- 注册监听joystick event
- #include "Joystick.h"
- auto _listener = EventListenerCustom::create(JoystickEvent::EVENT_JOYSTICK,[=](EventCustom* event){
- JoystickEvent* jsevent = static_cast<JoystickEvent*>(event->getUserData());
- log("--------------got joystick event,%p,angle=%f",jsevent,jsevent->mAnagle);
- // do you business you'd like to
- });
- _eventDispatcher->addEventListenerWithFixedPriority(_listener,1);
效果图
参考资料
- https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3rc2-005-cocos%E4%B8%AD%E7%9A%84%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88#%E5%B0%8F%E7%BB%93
- https://github.com/cheyiliu/All-in-One/wiki/cocos2d-x-3.3-012-%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%E6%9C%BA%E5%88%B6
- http://www.jb51.cc/article/p-getkrcwn-kh.html