【问题标题】:Cocos 2dx game increasing in memory every time a scene transition occurs每次发生场景转换时,Cocos2d 游戏的内存都会增加
【发布时间】:2016-02-04 04:03:09
【问题描述】:

我正在制作一个 cocos 2dx 游戏。但是每次内存随着每个级别的转换而增加。出于调试目的,我在触摸事件中一次又一次地调用同一个场景。每个级别都是通过更改以下代码的参数生成的。一开始我以为内存在增加是因为更高级别的对象更多,但是即使调用相同的级别,占用的内存也在增加。

#include "GameScene.h"
#include "MainMenuScene.h"
#include "GameOverScene.h"
#include "Levels.h"
#define COCOS2D_DEBUG 1

USING_NS_CC;

float theta=0;
int r=0;
int levelNo=0;
int controlable=0;      // flag to check if user can controll the ball or not
int rMax=0;             // max radius of circle
float objectTime;     // stores the inverse of speed
int secondCount=0;    // second han value in the timer
int minuteCount=0;   //minute hand clock in the timer
float obstacleSpeed=0;
Label *timer;

GameScene::~GameScene()
{


    rotationPoint->removeAllChildrenWithCleanup(true);
    obstacleRotationPoint->removeAllChildrenWithCleanup(true);
       this->removeAllChildrenWithCleanup(true);

}

Scene* GameScene::createScene(int level)
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    controlable=0;
    r=0;
    theta=0;
    // 'layer' is an autorelease object
    levelNo=level;
    rMax=levels[levelNo].ringCount * 15;    //setting various parameters
    obstacleSpeed =levels[levelNo].obstacleSpeed;
    objectTime=1.0/levels[levelNo].speed;
    secondCount=0; minuteCount=0;
    auto layer = GameScene::create();

    // add layer as a child to scene
    scene->addChild(layer);


    // return the scene
    return scene;
}

// on "init" you need to initialize your instance

bool GameScene::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    controlable=0;
    distance=rMax;
    visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

#if COMPILE_FOR_MOBILE == 1
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);

    listener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

#endif

    goal = DrawNode::create();
    goal->drawDot(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y), 5, Color4F(100,0,0,1));
    this->addChild(goal,1);          // drawing the goal


    rotationPoint = Node::create();
    rotationPoint->setPosition(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y);
    this->addChild(rotationPoint, 2);


    //Setting the exit button
    auto exitLabel = Label::createWithTTF("Exit","fonts/Marker Felt.ttf",10);
    exitButtonWidth=exitLabel->getContentSize().width;
    exitButtonHeight=exitLabel->getContentSize().height;
    exitLabel->setPosition(Point(visibleSize.width-exitButtonWidth,visibleSize.height-exitButtonHeight));
    this->addChild(exitLabel);


    //setting the clock
    timer = Label::createWithTTF("00:00","fonts/Marker Felt.ttf",10);
    timer->setPosition(Point(timer->getContentSize().width,visibleSize.height-timer->getContentSize().height));
    this->schedule(schedule_selector(GameScene::updateClock),1.0f);  //scedule to call upDateClock function every 1.0 sec
    this->addChild(timer);

    obstacleRotationPoint = Node::create();
    obstacleRotationPoint->setPosition(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y);
    this->addChild(obstacleRotationPoint, 3);


    float theta=0;

    snake[0] = DrawNode::create();
    snake[0]->drawDot(Vec2(0,0),3,Color4F(100,110,0,1));
    theta+=2*M_PI/150;
    //this->addChild(snake[0],2);

    rotationPoint->addChild(snake[0]);
      // fixedPoint->addChild(snake[0]);


   //loop to draw the concentric circles

   for(r=15;r<=rMax;r+=15)
    {
      for(theta=0;theta<=2*M_PI;theta+=2*M_PI/r){
          pathNode = DrawNode::create();
          pathNode->drawDot(Vec2(r*cos(theta)+origin.x+visibleSize.width/2,r*sin(theta)+origin.y+visibleSize.height/2),1,Color4F(0,0,10,1));
          //pathNode->autorelease();
           this->addChild(pathNode,1);
          //this->removeChild(pathNode);
        }
    }

    controlable=0;
    this->scheduleUpdate();
    return true;
}

bool GameScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event)
{   // check if exit button region was clicked
    _eventDispatcher->removeAllEventListeners();
    auto scene = GameScene::createScene(levelNo);
    Director::getInstance()->replaceScene(scene);
    return true;
}



//function updates every frame
void GameScene::update(float dt){
}

我需要添加 pathNode 的 init 函数的最后一部分是每次转换场景时都会增加内存需求。我相信我正在释放我的析构函数中的所有内容。

【问题讨论】:

    标签: c++ cocos2d-x cocos2d-x-3.0


    【解决方案1】:

    首先,我不建议使用文件顶部的全局变量(尤其是计时器标签)。你应该把所有东西都放在课堂上。

    其次,您应该首先检查是否调用了析构函数。

    第三,您还可以尝试在两个级别之间使用一些“加载”屏幕,并像这样清除所有未使用的纹理:

    setOnExitCallback([&](){
        Director::getInstance()->getTextureCache()->removeUnusedTextures();
    });
    

    第四,我建议不要重新创建 GameScene,而是创建像 restartLevel() 和 loadLevel() 这样的函数,然后删除那里不必要的东西并加载新的。

    【讨论】:

    • 我会尝试这些方法。析构函数被调用。我确实检查了
    • 我也会实现加载级别
    • 我会尝试重新加载我需要的精灵。谢谢
    • 谢谢我实现了你所说的一切,内存泄漏已经停止。
    • 很高兴听到这个消息:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多