0

I'm trying to create a button that is derived from the base class CCMenuItemImage. I want this button to be able to call it's function when it's first touched instead of after the touch ends. However, trying to subclass, I get an error saying it's an invald conversion.

button.ccp:

#include "button.h"

void Button::selected(){
CCLOG("SELECTED");
}

void Button::unselected(){
CCLOG("UNSELECTED");
}

Button* Button::create(const char *normalImage, const char *selectedImage, const char     *disabledImage, CCObject* target, SEL_MenuHandler selector) {
Button *button = new Button();
    if (button && button->initWithNormalImage(normalImage, selectedImage,     disabledImage, NULL, NULL))
    {
        button->autorelease();
        return button;
    }
    CC_SAFE_DELETE(button);
    return NULL;

}

button.h:

#ifndef BUTTON_H
#define BUTTON_H
#include "cocos2d.h"

class Button : public cocos2d::CCMenuItemImage{
public:
virtual void selected();

virtual void unselected();

};

#endif

SinglePlayer.ccp piece:

Button *left1 = Button::create("turncircle.png","turncircle.png", this, menu_selector(SinglePlayer::turning));
David Small
  • 581
  • 1
  • 10
  • 25
  • 1
    did you define this create() function in .h file ? if not, you should put `Button* Button::create(const char *normalImage, const char *selectedImage, const char *disabledImage, CCObject* target, SEL_MenuHandler selector);` there. – m.ding Dec 19 '12 at 03:26
  • @m.ding It says 'SEL_MenuHandler' has not been declared. – David Small Dec 19 '12 at 17:21
  • 1
    did you put `using namespace cocos2d;` in your h file? – m.ding Dec 19 '12 at 22:16
  • After adding it, the remaining error is extra qualification 'Button::' on member 'create' – David Small Dec 19 '12 at 22:26
  • 1
    Sorry it's my fault, you should remove the `Button::` in h file – m.ding Dec 19 '12 at 22:36
  • @m.ding cannot call member function 'Button* Button::create(char const*, char const*, char const*, cocos2d::CCObject*, cocos2d::SEL_MenuHandler)' without object. How do I go about this? – David Small Dec 20 '12 at 22:57
  • 1
    make it static. in h file. `static Button*...` – m.ding Dec 20 '12 at 23:02
  • make: *** No rule to make target `/CCMenu.cpp', needed by CCMenu.o'. – David Small Dec 21 '12 at 03:00
  • 1
    delete everything in the proj.android/libs and proj.android/objs. But I do think you need to read some books about c++ and ndk before you jumping straight in to cocos2d-x. – m.ding Dec 21 '12 at 03:25
  • I would still like to get this problem figured out if you're still out there. I deleted the folders and it still didn't work. Any other ideas? – David Small Jan 02 '13 at 05:49
  • Looks like a file was deleted so all is working now. I have one final question. I'm using selected() to run the activate() method. However, once I end the touch, it runs activates() again. How can I stop this from happening? – David Small Jan 06 '13 at 04:33
  • 1
    overwrite the CCTouchEnded – m.ding Jan 08 '13 at 00:13
  • That's what I'm trying to do. I added the ccTouchBegan and ccTouchEnded methods and their virtual prototypes, but it still doesn't behave like I want. – David Small Jan 08 '13 at 06:18
  • 1
    are they virtual in CCMenuItemImage? if not, you cannot overwrite them. – m.ding Jan 09 '13 at 00:01

2 Answers2

2

MenuItem select() is triggered on touch finished by default.

You need to subclass CCSprite with Touch registered with dispatcher and overwrite the ccTouchBegan

m.ding
  • 3,172
  • 19
  • 27
1

What I can understand is that you are trying to do manual control with the touches of your CCMenuItemImage. Actually all the touches are being handled in CCMenu not in MenuItem so you have to inherit CCMenu rather CCMenuItemImage to override the touches.

In my game I had this problem with CCTableView and CCMenuItem where MenuItem was a prioritised in taking gestures. So I tweaked it with inheriting CCMenu.

It also contain some extra code but just to make everything gets intact I am pasting everything.

ScrollMenu.h Class

class ScrollMenu:public CCMenu
{
public:
ScrollMenu();
virtual ~ScrollMenu(){};

bool isMovedGesture_;
bool istabBar_;
CCMenuItem * previousSelectedItem_;
static ScrollMenu* create(CCMenuItem* item,...);
virtual void registerWithTouchDispatcher();

virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch *touch, CCEvent* event);
CREATE_FUNC(ScrollMenu);
};

class ScrollMenuLoader : public cocos2d::extension::CCNodeLoader
{
public:
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(ScrollMenuLoader, loader);

protected:
    CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(ScrollMenu);
};

ScrollMenu.cpp Class

#include "ScrollMenu.h"

ScrollMenu* ScrollMenu::create(CCMenuItem* item, ...)
{
    va_list args;
    va_start(args, item);
    ScrollMenu *pRet = new ScrollMenu();
    if (pRet && pRet->initWithItems(item,args))
    {
        pRet->autorelease();
        va_end(args);
        return pRet;
    }
    va_end(args);
    CC_SAFE_DELETE(pRet);
    return NULL;
}
ScrollMenu::ScrollMenu()
{
    isMovedGesture_ = false;
}

void ScrollMenu::registerWithTouchDispatcher()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
}

bool ScrollMenu::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    return CCMenu::ccTouchBegan(touch, event);
}

void ScrollMenu::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
    CC_UNUSED_PARAM(event);
    CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchMoved] -- invalid state");
    isMovedGesture_ = true;
}

void ScrollMenu::ccTouchEnded(CCTouch *touch, CCEvent* event)
{
    CC_UNUSED_PARAM(touch);
    CC_UNUSED_PARAM(event);
    CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state");

    CCMenuItem * currentItem = this->itemForTouch(touch);
    if(!currentItem && isMovedGesture_ && m_pSelectedItem)
    {

        if(!istabBar_ || (previousSelectedItem_ && previousSelectedItem_ != m_pSelectedItem))
        {
            m_pSelectedItem->unselected();
        }
    }
    else if(currentItem)
    {
        if(currentItem == m_pSelectedItem)
        {
            if(!isMovedGesture_)
            {
                m_pSelectedItem->activate();
                previousSelectedItem_ = m_pSelectedItem;
            }
            else{
                if(previousSelectedItem_ != m_pSelectedItem)
                {
                    m_pSelectedItem->unselected();
                }
            }

        }
        else
        {
            if(isMovedGesture_)
            {
                m_pSelectedItem->unselected();
                m_pSelectedItem = currentItem;
                m_pSelectedItem->activate();
                previousSelectedItem_ = m_pSelectedItem;
            }

        }
        if (!istabBar_) {
            currentItem->unselected();
        }
    }

    m_eState = kCCMenuStateWaiting;
    isMovedGesture_ = false;

}
Ahsan.Amin
  • 736
  • 6
  • 14