Error: The name followed by "::" must be a class name or a namespace name

this code shows the error:
error: The name followed by “::” must be a class name or a namespace name.

the code as follows:

auto btn = Button::create("start.png","start_1.png");

Probably missing using directive? (or you could fully qualify it instead)

using cocos2d::ui::Button;
// or qualify
auto btn = cocos2d::ui::Button::create("start.png","start_1.png");

It has been modified in accordance with this, but the original error is still displayed.

Is it related to cocos2d-x 3.5 version?

Another way, I use Menu to create buttons,
But there is a problem, I want to resize the node size of the menu, I added the following line of code:

menu->setContentSize(Size(200,200));

But the size of the button node cannot be adjusted, the complete code is as follows:

    auto closeItem = MenuItemImage::create(
                                           "start.png",
                                           "start_1.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	closeItem->setPosition(Vec2(400,200));
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
	menu->setContentSize(Size(200,200));
    this->addChild(menu, 1);

Oh, probably, the cocos2d::ui namespace may be post v3.9?

Regardless, any information on these forums is potentially not useful for any versions that aren’t v3.17+ or v4. (not always, but just FYI)

Not sure what you’re trying to do here, but you’d probably need to create two separate Menus one for each size? Menu/MenuItem is meant to be a “list” of same sized menu items (though I believe each item could have a sprite/image that is smaller than the default menu item size?

Anyway, it’s been a long while since I’ve used Menu now that cocos2d::ui::Button is available.

You could potentially back-port to an earlier version by grabbing the source from v3.17, but instead I’d just consider upgrading your project to v3.17 (or even v4 if you want to try it).

Especially if this is not an existing project you’re just maintaining?

I have replaced with cocos2d-x version 3.17, but the problem still exists, the previous modification did not work.

In the HelloWorldScene.cpp file,
This line shows the error:

auto btn = Button::create("start.png", "start_1.png");

The error displayed is as follows:
1>D:\cocos2d-x-3.17\tests\game3\Classes\HelloWorldScene.cpp(119,16): error C2653:‘Button’: not a class or namespace name

1>D:\cocos2d-x-3.17\tests\game3\Classes\HelloWorldScene.cpp(119,57): error C2660:“HelloWorld::create”: function does not accept 2 arguments

In the HelloWorldScene.h file, this line shows the error:

CREATE_FUNC(HelloWorld);

The error is as follows:
1>D:\cocos2d-x-3.17\tests\game3\Classes\HelloWorldScene.h(41,5):message : see the declaration of “HelloWorld::create”

This is the demo file:
demo.zip (504.3 KB)

You probably just need to include the GUI stuff, since it’s not included by default.

#include "cocos2d.h" // doesn't include GUI
#include "ui/CocosGUI.h"

The button creation code would be something like this:

    auto btn = ui::Button::create("start.png", "start_1.png");
    btn->setScale9Enabled(true);
    btn->setTitleText("Jump");
    btn->setTitleFontSize(35);
    btn->setContentSize(Size(100, 50));
    btn->setPosition(Vec2(visibleSize.width - 100, 50));

    // this is the old way of doing callbacks, I think you can still use 
    // this model, but the preferred way now is to use lambdas.
    //btn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::menuCloseCallback, this));
    btn->addTouchEventListener([](Ref* senderButton, ui::Widget::TouchEventType eventType){
        auto button = static_cast<ui::Button*>(senderButton);
        switch(eventType) {
            case ui::Widget::TouchEventType::BEGAN: { CCLOG("Button Touch Began"); break; }
            case ui::Widget::TouchEventType::MOVED: { CCLOG("Button Touch Moved"); break; }
            case ui::Widget::TouchEventType::CANCELED: { CCLOG("Button Touch Cancelled"); break; }
            case ui::Widget::TouchEventType::ENDED: {
                CCLOG("Button Touch Ended");
                // here's the normal path for doing action based on button.
                CCLOG("do action:");
                auto actionGrow = ScaleTo::create(.1f, 2.f);
                auto actionShrink = ScaleTo::create(.1f, 1.f);
                button->runAction(Sequence::createWithTwoActions(actionGrow, actionShrink));
                break;
            }
        }
    });
    this->addChild(btn, 4);

Now i added include the GUI stuff .And added the node7 node to scene in the callbacks function of lambdas.
But this line shows a error:

this->addChild(node7);

The errors as follows:
Cannot capture ‘this’ implicitly because the default capture mode has not been specified

The code as follows:

#include "cocos2d.h"
#include "ui/CocosGUI.h"
bool HelloWorld::init()
{
    auto btn = Button::create("start.png", "start_1.png");
    btn->setScale9Enabled(true);
    btn->setTitleText("Jump");
    btn->setTitleFontSize(100);
    btn->setContentSize(Size(200, 100));
    btn->setPosition(Vec2(visibleSize.width - 200, 100));
    //btn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::menuCloseCallback, this));
    btn->addTouchEventListener([](Ref* senderButton, ui::Widget::TouchEventType eventType) {
        auto button = static_cast<ui::Button*>(senderButton);
        switch (eventType) {
        case ui::Widget::TouchEventType::BEGAN: { CCLOG("Button Touch Began"); break; }
        case ui::Widget::TouchEventType::MOVED: { CCLOG("Button Touch Moved"); break; }
        case ui::Widget::TouchEventType::CANCELED: { CCLOG("Button Touch Cancelled"); break; }
        case ui::Widget::TouchEventType::ENDED: {
            CCLOG("Button Touch Ended");
            // here's the normal path for doing action based on button.
            CCLOG("do action:");
            auto actionGrow = ScaleTo::create(.1f, 1.2f);
            auto actionShrink = ScaleTo::create(.1f, 1.f);

            auto node7 = Sprite::create("ty.png");
            node7->setPosition(Vec2(200, 200));
            this->addChild(node7);
            auto moveTo = MoveTo::create(8, Vec2(1555, 160));
            node7->runAction(moveTo);

            button->runAction(Sequence::create(actionGrow, actionShrink, moveTo));

            break;
        }
        }
        });
    this->addChild(btn, 4);
}

How to modify?

tl:dr; - add the variable this inside the capture []

e.g.

// replace the first part of the lambda from
[](Ref* senderButton, ui::Widget::TouchEventType eventType) {
// ...to...
[this](Ref* senderButton, ui::Widget::TouchEventType eventType) {

Further advice:

You’re going to need to learn c++11 (or c++17 or even more recent) if you want to use the Cocos2d-X engine. You don’t need a lot of the features of c++, but you should understand basics of classes, templates, and lambdas.

Maybe you know c++ reasonably well, and just haven’t used lambda functions much yet?
(hence my first sentence)

NOTE (for you or others reading this): You can still write your game with a more C99 (C-like) programming, like a lot of game developers prefer, but since cocos2d-x if fundamentally a c++11 game engine it’s probably a bit obvious that you need to understand c++11 itself to some level of expertise.

After the modification, although it can be compiled and passed, but at runtime, this error occurs when I click the button,
the error is as follows:
An exception was thrown: Read access violation.
this is 0xB444A8EF。

the code as follows:

auto btn = Button::create("start.png", "start_1.png");
    btn->setScale9Enabled(true);
    btn->setTitleText("Jump");
    btn->setTitleFontSize(100);
    btn->setContentSize(Size(200, 100));
    btn->setPosition(Vec2(visibleSize.width - 200, 100));
    //btn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::menuCloseCallback, this));
    btn->addTouchEventListener([this, visibleSize](Ref* senderButton, ui::Widget::TouchEventType eventType) {
        auto button = static_cast<ui::Button*>(senderButton);
        switch (eventType) {
        case ui::Widget::TouchEventType::BEGAN: { CCLOG("Button Touch Began"); break; }
        case ui::Widget::TouchEventType::MOVED: { CCLOG("Button Touch Moved"); break; }
        case ui::Widget::TouchEventType::CANCELED: { CCLOG("Button Touch Cancelled"); break; }
        case ui::Widget::TouchEventType::ENDED: {
            CCLOG("Button Touch Ended");
            // here's the normal path for doing action based on button.
            CCLOG("do action:");
            auto actionGrow = ScaleTo::create(.1f, 1.2f);
            auto actionShrink = ScaleTo::create(.1f, 1.f);

            auto node7 = Sprite::create("ty.png");
            node7->setPosition(Vec2(visibleSize.width - 230, 100));
            this->addChild(node7);
            auto moveTo = MoveTo::create(8, Vec2(visibleSize.width - 200, 100));
            node7->runAction(moveTo);

            button->runAction(Sequence::create(actionGrow, actionShrink, moveTo));

            break;
        }
        }
        });
    this->addChild(btn, 4);

I don’t know the C++11 standard, I want C++ to be as concise as C. It seems that if I want to continue using the cocos2d-x engine, I have to learn some features of C++11.

And this line of statement should be modified:

button->runAction(Sequence::create(actionGrow, actionShrink, moveTo));

modified as follows:

button->runAction(Sequence::create(actionGrow, actionShrink, moveTo,nullptr));

The complete code is as follows:

auto btn = Button::create("start.png", "start_1.png");
    btn->setScale9Enabled(true);
    btn->setTitleText("Jump");
    btn->setTitleFontSize(100);
    btn->setContentSize(Size(200, 100));
    btn->setPosition(Vec2(visibleSize.width - 200, 100));
    //btn->addTouchEventListener(CC_CALLBACK_2(HelloWorld::menuCloseCallback, this));
    btn->addTouchEventListener([this, visibleSize](Ref* senderButton, ui::Widget::TouchEventType eventType) {
        auto button = static_cast<ui::Button*>(senderButton);
        switch (eventType) {
        case ui::Widget::TouchEventType::BEGAN: { CCLOG("Button Touch Began"); break; }
        case ui::Widget::TouchEventType::MOVED: { CCLOG("Button Touch Moved"); break; }
        case ui::Widget::TouchEventType::CANCELED: { CCLOG("Button Touch Cancelled"); break; }
        case ui::Widget::TouchEventType::ENDED: {
            CCLOG("Button Touch Ended");
            // here's the normal path for doing action based on button.
            CCLOG("do action:");
            auto actionGrow = ScaleTo::create(.1f, 1.2f);
            auto actionShrink = ScaleTo::create(.1f, 1.f);

            auto node7 = Sprite::create("ty.png");
            node7->setPosition(Vec2(visibleSize.width - 230, 100));
            this->addChild(node7);
            auto moveTo = MoveTo::create(8, Vec2(visibleSize.width - 200, 100));
            node7->runAction(moveTo);

            button->runAction(Sequence::create(actionGrow, actionShrink, moveTo,nullptr));

            break;
        }
        }
        });
    this->addChild(btn, 4);

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Yeah, I posted the 2 (two) action version where you use the longer method name, createWithTwoActions, to avoid having to pass in the sentinel (nullptr), but if you use sequence with more than one action the way the API is set up requires passing a nullptr sentinel value (I think this is an artifact of the transition/port from Objective-C iphone only version to the c++ version that happened a while ago).


Glad you figured it out, at least this example. You probably don’t need to know or use a lot of the ‘modern’ c++11 feature set to use cocos2d-x, but it probably helps in understanding the engine source itself as well as interfacing with the parts of the API that uses lambdas, templates, virtual/override methods [1], and method overloading.

[1] composition is preferred by many C++ developers, especially in game dev, but if you choose to inherit from Sprite/Node/Ref/etc then you’ll need to use virtual/override or if you want to read and understand the engine source you’ll definitely find a lot of shallow inheritance and use of virtual/override.

You’ll also need to understand at a basic level how the engine uses reference counting for memory management, which is another artifact of the port from the Objective-C iOS engine. Basically when you ::create(…) and object you have to add it as a child to a Ref-derived class (Node, Sprite, et al) to keep it alive and in many ways that’s the extent of what you need to know.

However, if you want to keep the object/instance alive beyond the scope where ::Create() is called without adding it as a child (which does the retain/release for you), then you have to manually ->retain() and then ‘release’ it CC_SAFE_RELEASE(mynode).

2c