SneakyJoystick和SneakyButton继承的都是CCTargetedTouchDelegate。
CCTargetedTouchDelegate并不是单点触摸,只是和CCStandardTouchDelegate多点触摸分发机制不同。
具体可以参考:
所以开启多点触摸setTouchEnabled(true)就可以了。
但是做一个射击类的游戏,摇杆决定枪方向,同时移动屏幕能移动枪的准星,该怎么实现。如果按上述做法,
则会出现move摇杆的时候,方向改变了同时准星也改变了。如果两个手指一起摁下并move,那么两个手指
都能控制准星的移动。解决方案是根据touchID,进行不同的操作。如果某个touchID在摇杆的范围内在move
的时候就过滤掉这个touchID。以前是继承了CCStandardTouchDelegate,但是手指按下的先后顺序不一样,
处理起来会很麻烦。事实上,CCStandardTouchDelegate的是CCSet存放的就是CCTouch。
CCTouch.h
class CC_DLL CCTouch : public CCObject
{
public:
/**
* @js ctor
*/
CCTouch()
: m_nId(0),
m_startPointCaptured(false)
{}
/** returns the current touch location in OpenGL coordinates */
CCPoint getLocation() const;
/** returns the previous touch location in OpenGL coordinates */
CCPoint getPreviousLocation() const;
/** returns the start touch location in OpenGL coordinates */
CCPoint getStartLocation() const;
/** returns the delta of 2 current touches locations in screen coordinates */
CCPoint getDelta() const;
/** returns the current touch location in screen coordinates */
CCPoint getLocationInView() const;
/** returns the previous touch location in screen coordinates */
CCPoint getPreviousLocationInView() const;
/** returns the start touch location in screen coordinates */
CCPoint getStartLocationInView() const;
void setTouchInfo(int id, float x, float y)
{
m_nId = id;
m_prevPoint = m_point;
m_point.x = x;
m_point.y = y;
if (!m_startPointCaptured)
{
m_startPoint = m_point;
m_startPointCaptured = true;
}
}
/**
* @js getId
*/
int getID() const
{
return m_nId;
}
private:
int m_nId;
bool m_startPointCaptured;
CCPoint m_startPoint;
CCPoint m_point;
CCPoint m_prevPoint;
};
可以直接继承CCTargetedTouchDelegate,获取移动准星是的touchID。因为CCTargetedTouchDelegate中的began,
move,end都是同一个对象。
SneakyJoystick.cpp和SneakyButton.cpp中响应ccTouchBegan直接在里面判断的事件,如果在所在层中调用SneakyJoystick
和SneakyButton会改变对象的数据,我分离出来了一个函数isIntouch。
ItemLayer.h
//
// ItemLayer.h
// BWBattle
//
// Created by Fuatnow on 14-8-15.
//
//
#ifndef __BWBattle__ItemLayer__
#define __BWBattle__ItemLayer__
#include <iostream>
#include "BasicLayer.h"
#include "SneakyInput/SneakyJoystick.h"
#include "SneakyInput/SneakyJoystickSkinnedBase.h"
#include "SneakyInput/SneakyButton.h"
#include "SneakyInput/SneakyButtonSkinnedBase.h"
class GameLayer;
class ItemLayer : public BasicLayer
{
public:
ItemLayer(GameLayer* game);
~ItemLayer();
static ItemLayer* create(GameLayer* game);
virtual bool init();
void initData();
void initView();
void update(float dt);
void rocket_callBack();
void onEnter();
void onExit();
virtual bool ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent);
virtual void ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent);
virtual void ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent);
protected:
GameLayer* _game;
SneakyButton* sneakButton;
SneakyJoystick* heroJoystick;
CC_SYNTHESIZE(CCSprite*, sight, Sight);
bool hasRoctetPress;
CCTouch* sightTouch;
CCPoint sumDis ;
};
#endif /* defined(__BWBattle__ItemLayer__) */
ItemLayer.cpp
//
// ItemLayer.cpp
// BWBattle
//
// Created by Fuatnow on 14-8-15.
//
//
#include "ItemLayer.h"
#include "GameLayer.h"
#define VELMU 150
ItemLayer::ItemLayer(GameLayer* game)
{
_game = game;
}
ItemLayer::~ItemLayer()
{
}
ItemLayer* ItemLayer::create(GameLayer *game)
{
ItemLayer* item = new ItemLayer(game);
if(item && item->init())
{
item->autorelease();
return item;
}
CC_SAFE_DELETE(item);
return NULL;
}
bool ItemLayer::init()
{
if(!BasicLayer::init()) return false;
initData();
initView();
return true;
}
void ItemLayer::initData()
{
hasRoctetPress = false;
setTouchEnabled(true);
sightTouch = NULL;
sumDis = CCPointZero;
}
void ItemLayer::initView()
{
sight = CCSprite::createWithSpriteFrameName("zhunxing.png");
sight->setPosition(ccp(320,1100));
sight->setScale(1.2f);
CCScaleTo* scaleTo1 = CCScaleTo::create(0.5f, 1.8f);
CCScaleTo* scaleTo2 = CCScaleTo::create(0.25f, 2.0f);
CCScaleTo* scaleTo3 = CCScaleTo::create(0.25f, 1.8f);
CCScaleTo* scaleTo4 = CCScaleTo::create(0.5f, 1.2f);
CCRotateBy* rotate = CCRotateBy::create(2.5f, 90);
CCSequence* seq = CCSequence::create(scaleTo1,scaleTo2,scaleTo3,scaleTo4,NULL);
CCRepeatForever* _action1 = CCRepeatForever::create(rotate);
CCRepeatForever* _action2 = CCRepeatForever::create(seq);
sight->runAction(_action1);
sight->runAction(_action2);
addChild(sight);
float joystickRadius = 80;
heroJoystick=new SneakyJoystick();
heroJoystick->autorelease();
heroJoystick->initWithRect(CCRectZero);
//
heroJoystick->setJoystickRadius(joystickRadius);
//是否自动回到中心
heroJoystick->setAutoCenter(true);
//是否支持死亡区域,该区域不会触发
heroJoystick->setHasDeadzone(true);
//死亡区域半径
heroJoystick->setDeadRadius(10);
SneakyJoystickSkinnedBase *joystickSkin = SneakyJoystickSkinnedBase::create();
joystickSkin->init();
//背景
joystickSkin->setBackgroundSprite(CCSprite::create("controlBg.png"));
//中心点
joystickSkin->setThumbSprite(CCSprite::create("cen.png"));
joystickSkin->getThumbSprite()->setScale(1.0f);
//joystickSkin->setPosition(CCPointMake(joystickRadius,joystickRadius));
joystickSkin->setPosition(ccp(0.25f*winWidth,0.25f*winHeight));
joystickSkin->setJoystick(heroJoystick);
addChild(joystickSkin);
SneakyButtonSkinnedBase *buttonBase = SneakyButtonSkinnedBase::create();
buttonBase->setDefaultSprite(CCSprite::create("controlBg.png"));
buttonBase->setActivatedSprite(CCSprite::create("cen.png"));
buttonBase->setPressSprite(CCSprite::create("controlBg.png"));
buttonBase->setPosition(CCPointMake(480-48, 98));
//按钮
sneakButton = new SneakyButton();
sneakButton->autorelease();
sneakButton->initWithRect(CCRectMake(0,0,32,32));
//sneakButton->setIsToggleable(false);
//设置在按下时,是否保持按下状态
sneakButton->setIsHoldable(true);
buttonBase->setButton(sneakButton);
addChild(buttonBase);
}
void ItemLayer::onEnter()
{
BasicLayer::onEnter();
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0,false);
}
void ItemLayer::onExit()
{
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
BasicLayer::onExit();
}
bool ItemLayer::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent)
{
if(heroJoystick->isInTouch(pTouch, pEvent) == false &&
sneakButton->isInTouch(pTouch, pEvent) == false)
{
CCLOG("began sightTouch");
sightTouch = pTouch;
}
return true;
}
void ItemLayer::ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent)
{
if(pTouch == sightTouch)
{
CCLOG("move sightTouch");
CCPoint dis = sightTouch->getLocation() - sightTouch->getPreviousLocation();
sumDis = sumDis + dis;
sight->setPosition(sight->getPosition() + dis);
}
}
void ItemLayer::ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent)
{
if(sightTouch == pTouch)
{
CCLOG("end sightTouch");
sightTouch = NULL;
sumDis = CCPointZero;
}
}
void ItemLayer::update(float dt)
{
//CCLOG("%f %f",VELMU*dt,dt);
CCPoint poi = ccpMult(heroJoystick->getVelocity(), VELMU*dt);
CCPoint heroPoint = _game->hero->getPosition();
_game->hero->setPosition(heroPoint + poi);
if (sneakButton->getIsActive())
{
if(!hasRoctetPress)rocket_callBack();
}
else
{
hasRoctetPress = false;
}
}
void ItemLayer::rocket_callBack()
{
hasRoctetPress = true;
CCLOG("rocket_callBack");
}