Hello,
I have a problem with the implement of the touch on a sprite.
I have this code on my sprite :
character.h :
typedef enum tagCharacterState
{
kCharacterStateGrabbed,
kCharacterStateUngrabbed
} CharacterState;
class Character : public Sprite, public Clonable
{
CharacterState _state;
public:
Character(void);
virtual ~Character(void);
Rect getRect();
bool initWithTexture(Texture2D* aTexture);
virtual void onEnter() override;
virtual void onExit() override;
bool containsTouchLocation(Touch* touch);
bool onTouchBegan(Touch* touch, Event* event);
void onTouchMoved(Touch* touch, Event* event);
void onTouchEnded(Touch* touch, Event* event);
virtual Character* clone() const;
static Character* createWithTexture(Texture2D* aTexture);
};
character.m
Rect Character::getRect()
{
auto s = getTexture()->getContentSize();
return Rect(-s.width / 2, -s.height / 2, s.width, s.height);
}
Character* Character::createWithTexture(Texture2D* aTexture)
{
Character* pCharacter = new (std::nothrow) Character();
pCharacter->initWithTexture(aTexture);
pCharacter->autorelease();
return pCharacter;
}
bool Character::initWithTexture(Texture2D* aTexture)
{
if( Sprite::initWithTexture(aTexture) )
{
_state = kCharacterStateUngrabbed;
}
return true;
}
void Character::onEnter()
{
Sprite::onEnter();
// Register Touch Event
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(Character::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(Character::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(Character::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}
void Character::onExit()
{
// auto director = Director::getInstance();
// director->getTouchDispatcher()->removeDelegate(this);
Sprite::onExit();
}
bool Character::containsTouchLocation(Touch* touch)
{
return getRect().containsPoint(convertTouchToNodeSpaceAR(touch));
}
bool Character::onTouchBegan(Touch* touch, Event* event)
{
CCLOG("Character::onTouchBegan id = %d, x = %f, y = %f", touch->getID(), touch->getLocation().x, touch->getLocation().y);
if (_state != kCharacterStateUngrabbed) return false;
if ( !containsTouchLocation(touch) ) return false;
_state = kCharacterStateGrabbed;
CCLOG("return true");
return true;
}
void Character::onTouchMoved(Touch* touch, Event* event)
{
// If it weren't for the TouchDispatcher, you would need to keep a reference
// to the touch from touchBegan and check that the current touch is the same
// as that one.
// Actually, it would be even more complicated since in the Cocos dispatcher
// you get Sets instead of 1 UITouch, so you'd need to loop through the set
// in each touchXXX method.
CCLOG("Character::onTouchMoved id = %d, x = %f, y = %f", touch->getID(), touch->getLocation().x, touch->getLocation().y);
CCASSERT(_state == kCharacterStateGrabbed, "Character - Unexpected state!");
auto touchPoint = touch->getLocation();
setPosition( Vec2(touchPoint.x, getPosition().y) );
}
Character* Character::clone() const
{
Character* ret = Character::createWithTexture(_texture);
ret->_state = _state;
ret->setPosition(getPosition());
ret->setAnchorPoint(getAnchorPoint());
return ret;
}
void Character::onTouchEnded(Touch* touch, Event* event)
{
CCASSERT(_state == kCharacterStateGrabbed, "Character - Unexpected state!");
_state = kCharacterStateUngrabbed;
}
And I insert my characters on my layer with :
char s_Character[] = "monkey.png";
auto characterTexture = Director::getInstance()->getTextureCache()->addImage(s_Character);
Vector<Character*> charactersM(4);
Character* character = Character::createWithTexture(characterTexture);
character->setPosition( Vec2(100 , 100) );
charactersM.pushBack( character );
Character* character1 = Character::createWithTexture( characterTexture );
character1->setPosition( Vec2(400, 400) );
charactersM.pushBack( character1 );
_characters = charactersM;
for (auto& character : _characters)
{
addChild(character);
}
I don’t understand why, but when I run and I touch my character, the method “onTouchBegan” is called twice (for each character I think, I have read a lot of examples and topic but I don’t resolve my problem
Thanks for help