cocos2dx—游戏摇杆类(观察者模式控制英雄移动)
1:摇杆类:JoyStick
+ 共有继承 public cocos2d::ui::Widget+ 观察者模式
2:成员函数
//头文件#include "ui/CocosGUI.h"#include"cocos2d.h"//成员cocos2d::ui::ImageView* stick;float radius;//半径cocos2d::Vec2 originPos;//摇杆起始坐标bool isTouch;//是否触摸cocos2d::Vec2 touchAxis;//触摸方向
:3:create 函数:1:背景图片,2摇杆图片
JoyStick* JoyStick::create(const std::string& bgImage, const std::string& stickImage){JoyStick* ret = new (std::nothrow)JoyStick();if (ret&&ret->init(bgImage, stickImage)){ret->autorelease();}else{delete ret;ret = nullptr;}return ret;}
4:init()函数
bool JoyStick::init(const std::string& bgImage, const std::string& stickImage){if (!Widget::init()){return false;}//创建背景图片:ImageView可以直接添加触摸/监听事件ImageView* bg = ImageView::create(bgImage);this->addChild(bg);//创建摇杆图片,可以拖动,必须先开启触摸stick = ImageView::create(stickImage);stick->setTouchEnabled(true);//开启触摸this->addChild(stick);//给Stick添加触摸监听事件stick->addTouchEventListener(CC_CALLBACK_2(JoyStick::onJoyStickTouch,this));//初始化半径,坐标radius = bg->getContentSize().width / 2 * bg->getScale();//半径=图片的宽度一半*缩放比例(缩放的时候依然你能使用)originPos = stick->getPosition();//开启默认调度器scheduleUpdate();return true;}
5:默认调度器update()
//默认调度器void JoyStick::update(float dt){//判断是否触摸if (isTouch&&onJoyStickMoved != nullptr){onJoyStickMoved(touchAxis);}}
6:摇杆触摸监听事件函数:摇杆拖动时调用
void JoyStick::onJoyStickTouch(Ref* pSender, Widget::TouchEventType type){Vec2 touchPoint = Vec2::ZERO;Vec2 pos;switch (type){//触摸开始case cocos2d::ui::Widget::TouchEventType::BEGAN:{isTouch = true;if (onJoyStickBegan != nullptr)//观察者模式调用{onJoyStickBegan();}touchPoint= stick->getTouchBeganPosition();//获取触摸点的坐标pos=this->convertToNodeSpaceAR(touchPoint); //转换坐标系:将touchPoint从世界转到JoyStick坐标系下stick->setPosition(pos);//stick用触摸点坐标赋值break;}//触摸移动case cocos2d::ui::Widget::TouchEventType::MOVED:{touchPoint=stick->getTouchMovePosition();//获取触摸点的位置pos = this->convertToNodeSpaceAR(touchPoint); //转换坐标系:将touchPoint从世界转到JoyStick坐标系下stick->setPosition(pos);//stick用触摸点坐标赋值Vec2 offset;//将摇杆限制在半径内offset = pos - originPos;//获得向量if (offset.getLength() > radius)//判断是否大于半径{offset = offset.getNormalized()*radius;//getNormailzed:获得单位向量 长度为1的向量pos = offset + originPos;}stick->setPosition(pos); //stick用触摸点赋值touchAxis = offset.getNormalized();if (onJoyStickMoved != nullptr)//观察者模式调用{onJoyStickMoved(touchAxis);}break;}case cocos2d::ui::Widget::TouchEventType::ENDED:case cocos2d::ui::Widget::TouchEventType::CANCELED://触摸结束/取消default:{isTouch = false;//摇杆回到原点//stick->setPosition(originPos);auto move = MoveTo::create(0.3f, originPos);stick->runAction(move);//stick->getTouchEndPosition();if (onJoyStickEnded != nullptr)//观察者模式调用{onJoyStickEnded();}break;}}}
7:观察者模式类外调用
//function<返回值类型 (形参表类型)> 变量名typedef std::function<void()> ccJoyStickBeganCallback;typedef std::function<void(cocos2d::Vec2)> ccJoyStickMovedCallback;typedef std::function<void()> ccJoyStickEndedCallback;ccJoyStickBeganCallback onJoyStickBegan;//摇杆开始拖动时ccJoyStickMovedCallback onJoyStickMoved;//摇杆拖动时ccJoyStickEndedCallback onJoyStickEnded;//摇杆结束拖动时
7.1默认构造函数初始化nullptr
JoyStick():onJoyStickBegan(nullptr), onJoyStickMoved(nullptr), onJoyStickEnded(nullptr),isTouch(false), touchAxis(cocos2d::Vec2(0,0)){}
8:主函数中创建摇杆
void HelloWorld::addJoyStick(){JoyStick* joy = JoyStick::create("image3/JoyStick_Bg.png", "image3/JoyStick.png");//joy->onJoyStickMoved = CC_CALLBACK_1(Hero::move, hero);//摇杆控制英雄移动joy->setPosition(Vec2(200, 200));this->addChild(joy);}