这个错误如何修改

以下代码出现这个错误如何修改?错误如下:
“Assert failed: running scene should not null
Assertion failed!”
代码如下:
Director::getInstance()->purgeCachedData();
Scene* pScene=Scene::create();
auto layer1=Layer::create();
auto sprite1=Sprite::create(“yyy.png”);
sprite1->setPosition(Vec2(250,170));
sprite1->setAnchorPoint(Vec2(0,0));
layer1->addChild(sprite1);
pScene->addChild(layer1);
Director::getInstance()->pushScene(pScene);
Director::getInstance()->popScene();

Director::getInstance()->popScene();
这句代码注释掉,你再试一下,看报错是因为你的 Scene 是 NULL.

将这段Director::getInstance()->popScene();注释掉后虽然不再报错,但也少了这个功能,
我希望将最初的场景替换为pScene这个场景后,再将pScene这个场景弹出恢复为最初的场景。应该如何修改?

你应该确保你的代码:Director::getInstance()->popScene();
需要确保你的场景里面还有 Scene。popScene 只是移除了栈顶场景,你之前的场景还在,确保之前的场景还在,就不会报错了。

在AppDelegate.cpp文件中完整的代码是这样的,其中之前的场景scene也包含在其中,要确保之前的场景还在应该如何修改?
代码如下:
#include “AppDelegate.h”
#include “HelloWorldScene.h”

USING_NS_CC;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate()
{
}

//if you want a different context,just modify the value of glContextAttrs
//it will takes effect on all platforms
void AppDelegate::initGLContextAttrs()
{
//set OpenGL context attributions,now can only set six attributions:
//red,green,blue,alpha,depth,stencil
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};

GLView::setGLContextAttrs(glContextAttrs);

}

// If you want to use packages manager to install more packages,
// don’t modify or remove this function
static int register_all_packages()
{
return 0; //flag for packages manager
}

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::create(“My Game”);
director->setOpenGLView(glview);
}

// turn on display FPS
director->setDisplayStats(true);

// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);

register_all_packages();

// create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();

// run
director->runWithScene(scene);



//使用pushScene()和popScene()切换场景
Director::getInstance()->purgeCachedData();
Scene* pScene=Scene::create();
auto layer1=Layer::create();
auto sprite1=Sprite::create("yyy.png");
sprite1->setPosition(Vec2(250,170));
sprite1->setAnchorPoint(Vec2(0,0));
layer1->addChild(sprite1);
pScene->addChild(layer1);
Director::getInstance()->pushScene(pScene);
Director::getInstance()->popScene();






return true;

}

// This function will be called when the app is inactive. When comes a phone call,it’s be invoked too
void AppDelegate::applicationDidEnterBackground() {
Director::getInstance()->stopAnimation();

// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

}

// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
Director::getInstance()->startAnimation();

// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

没看明白你这一块的代码 感觉有点奇怪,这一块代码

//使用pushScene()和popScene()切换场景
Director::getInstance()->purgeCachedData();  //清除缓存数据
Scene* pScene=Scene::create();               //创建pScene场景对象
auto layer1=Layer::create();                 //创建layer1层
auto sprite1=Sprite::create("yyy.png");      //添加图片
sprite1->setPosition(Vec2(250,170));         //设置图片位置
sprite1->setAnchorPoint(Vec2(0,0));          //设置图片锚点
layer1->addChild(sprite1);                   //将图片精灵作为节点添加到层中
pScene->addChild(layer1);                    //将层作为节点添加到场景中
Director::getInstance()->pushScene(pScene);  //将场景scene切换为场景pScene
Director::getInstance()->popScene();         //将场景pScene切换为场景scene

push和pop之间加个延时看看,个人感觉你这样写场景还未加载完成就被删除就导致了这个问题。你可以试下把sprite1改成button,button给个点击事件,点击后弹出pscene

延时的代码要怎么写?能否给出?

Director::getInstance()->purgeCachedData();  //清除缓存数据
Scene* pScene = SecondScene::create();
Layer* layer1 = Layer::create();                 //创建layer1层
Sprite* sprite1 = Sprite::create("test.png"); //添加图片
sprite1->setPosition(Vec2(250, 170));         //设置图片位置
sprite1->setAnchorPoint(Vec2(0, 0));          //设置图片锚点
layer1->addChild(sprite1);                   //将图片精灵作为节点添加到层中
pScene->addChild(layer1);                    //将层作为节点添加到场景中
Director::getInstance()->pushScene(pScene);
Director::getInstance()->popScene();

按照你的写的,不会有问题,这样写看不到场景添加,因为你立马移除了,看不到。你用的什么版本 cocos 。

Demo.zip (526.4 KB)

这是代码,你去试一下。

用cocos2d-x 3.5版本的

嗯嗯,你去用 Demo 去试一下,看看会不会有问题。

我将你的demo文件夹中的Classes文件和Resources文件与项目中的Classes文件和Resources文件进行替换。然后重新生成解决方案,但结果失败了。
appdelegate.cpp文件中的这行:
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8, 0};
出现以下错误:
“初始值设定项太多”

3.5 版本没接触过,但是知道大概问题出在了哪里,Director::getInstance()->popScene(); 你的版本不支持场景栈里面还剩一个场景然后执行出栈,3.17 支持,如果场景栈里面只有一个场景,当执行Director::getInstance()->popScene(); 就会退出游戏,你的就报了一个断言,你的逻辑没有错,就是容错率的问题。Director::getInstance()->pushScene(pScene); 这个估计就是没有 push 到场景栈里面,然后你就下面的代码就执行了,所以就出问题了。

那是否可以在Director::getInstance()->pushScene(pScene);的后面添加一段延时的代码,等待pScene场景push到栈中之后,这时栈中就存在scene和pScene两个场景,然后再用Director::getInstance()->popScene();就可以将pScene场景pop出栈?
如果可以,那延时代码要怎么写?

// 头文件定义
void popScene(float t);

// cpp 文件实现
void HelloWorld::popScene(float t)
{
Director::getInstance()->popScene(); //将场景pScene切换为场景scene
}

// 调用代码:
// 这个定时器只会执行一次,延迟 30 秒之后执行代码,也就是
this->scheduleOnce(CC_SCHEDULE_SELECTOR(HelloWorld::popScene), 30);

逻辑需要你自己组合一下。

由于最初我将代码添加在AppDelegate.cpp文件中,而并没有添加在HelloWorldScene.cpp文件中。

因此是否应该放在AppDelegate.h头文件中定义:
void popScene(float t);

是否在AppDelegate.cpp文件中实现:
this->scheduleOnce(CC_SCHEDULE_SELECTOR(HelloWorld::popScene), 30);
void AppDelegate::popScene(float t) //由于在AppDelegate.h头文件中定义了void popScene(float t);所以将HelloWorld改为AppDelegate
{
Director::getInstance()->popScene(); //将场景pScene切换为场景scene
}

这时修改后VS提示这行错误:
void AppDelegate::popScene(float t)
错误如下:
不能在成员函数AppDelegate::popScene的类外部重新声明该函数,

因此在文件AppDelegate.cpp文件中最后的修改如下:
//使用pushScene()和popScene()切换场景
Director::getInstance()->purgeCachedData();
Scene* pScene=Scene::create();
auto layer1=Layer::create();
auto sprite1=Sprite::create(“yyy.png”);
sprite1->setPosition(Vec2(250,170));
sprite1->setAnchorPoint(Vec2(0,0));
layer1->addChild(sprite1);
pScene->addChild(layer1);
Director::getInstance()->pushScene(pScene);
this->scheduleOnce(CC_SCHEDULE_SELECTOR(AppDelegate::popScene), 30);
Director::getInstance()->popScene(); //将场景pScene切换为场景scene

但调试后依然报错,错误如下:
2>d:\cocos2d-x-3.5\tests\mygame\classes\appdelegate.cpp(97): error C2039: “scheduleOnce”: 不是“AppDelegate”的成员
2> d:\cocos2d-x-3.5\tests\mygame\classes\appdelegate.h(11) : 参见“AppDelegate”的声明
2>d:\cocos2d-x-3.5\tests\mygame\classes\appdelegate.cpp(97): error C2440: “static_cast”: 无法从“void (__thiscall AppDelegate::* )(float)”转换为“cocos2d::SEL_SCHEDULE”
2> 与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换

建议你放在场景里面,或者如果可以你把你的 classes 和 resource 发我一份,可以帮你看看。这个scheduleOnce是节点特有的。

之前的文件有误,现在重新上传:
https://590m.com/f/29330416-501535235-d9baad
(访问密码:7800)

scheduleOnce是哪个节点特有的?为什么一定要放在HelloWorldScene.cpp中?

另外放在HelloWorldScene.cpp中调试后出现以下错误:
2>d:\cocos2d-x-3.5\tests\mygame\classes\helloworldscene.cpp(124): error C2601: “HelloWorld::popScene”: 本地函数定义是非法的
2> d:\cocos2d-x-3.5\tests\mygame\classes\helloworldscene.cpp(22): 此行有一个“{”没有匹配项