虚拟摇杆SneakyInput的多点触摸问题

SneakyJoystick和SneakyButton继承的都是CCTargetedTouchDelegate。

CCTargetedTouchDelegate并不是单点触摸,只是和CCStandardTouchDelegate多点触摸分发机制不同。

具体可以参考:

http://www.cnblogs.com/boliu  

所以开启多点触摸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");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值