Cannot get update with my highscore

  • MoseHas
    Likes 0

    Problem Description

    Hi there. It is me again.

    After I watched the episode “Saving The Score”of Creating Flappy Bird Cocos2d-x Course, I tried to implement this pretty cool function in my code.

    Unforetunately, I failed and did not know why, so I tried to copy and paste the partial lesson source code which was modified in the lesson.

    Surprisingly, it still did not work. My highscore never got updated. It just followed what I have scored in current game.

    Would you mind checking my code and see what is going on? Thanks.

    Here is my code below.

    #include "GameOverScene.h"
    #include "GameScene.h"
    #include "MainMenuScene.h" 
    #include "Definitions.h"
    
    USING_NS_CC;
    
    unsigned int score;
    
    Scene* GameOverScene::createScene(unsigned int tempscore)
    {	
    	score = tempscore;
        // 'scene' is an autorelease object
        auto scene = Scene::create();
        
        // 'layer' is an autorelease object
        auto layer = GameOverScene::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 GameOverScene::init()
    {
        //////////////////////////////
        // 1. super init first
        if ( !Layer::init() )
        {
            return false;
        }
        
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    	auto backgroundSprite = Sprite::create("background.jpg");
    	backgroundSprite->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
    
    	this->addChild(backgroundSprite);
    
    	auto retryItem = MenuItemImage::create("RetryButton.png", "RetryButtonClicked.png", CC_CALLBACK_1( GameOverScene::GoToGameScene,this));
    	retryItem->setPosition(Point((visibleSize.width + origin.x) / 3 * 1, visibleSize.height / 2 + origin.y));
    	auto mainMenuItem = MenuItemImage::create("MenuButton.png", "MenuButtonClicked.png", CC_CALLBACK_1(GameOverScene::GoToMainMenuScene, this));
    	mainMenuItem->setPosition(Point((visibleSize.width + origin.x) / 3 * 2, visibleSize.height / 2 + origin.y));
    
    	auto menu = Menu::create(retryItem, mainMenuItem, NULL);
    	menu->setPosition(Point::ZERO);
    	this->addChild(menu);	
    
    	UserDefault *def = UserDefault::getInstance();
    	auto highScore = def->getIntegerForKey("HIGHSCORE FLAPPY", 0);
    	if (score>highScore)
    	{
    		highScore = score;
    		def->setIntegerForKey("HIGHSCORE FLAPPY", highScore);
    	}
    	def->flush();
    	
    	__String *tempScore = __String::createWithFormat("Your Score: %i", score);
    	auto currentScore = Label::createWithTTF (tempScore->getCString(), "fonts/Marker Felt.ttf", visibleSize.height * SCORE_FONT_SIZE);
    	currentScore->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height * 0.7 + origin.y));
    	this->addChild(currentScore);
    
    	__String *tempHighScore = __String::createWithFormat("HighScore: %i", highScore);
    
    	auto highScoreLabel = Label::createWithTTF(tempHighScore->getCString(), "fonts/Marker Felt.ttf", visibleSize.height * SCORE_FONT_SIZE);
    	highScoreLabel->setPosition(Point((visibleSize.width + origin.x) / 2 , visibleSize.height + origin.y - highScoreLabel->getContentSize().height));
    	highScoreLabel->setColor(Color3B::RED);
    	highScoreLabel->enableShadow();
    	this->addChild(highScoreLabel);
    
        return true;
    }
    
    void GameOverScene::GoToMainMenuScene(cocos2d::Ref *sender)
    {
    	auto scene = MainMenuScene::createScene();
    	Director::getInstance()->replaceScene(TransitionFade::create(TRANSITION_TIME, scene));
    }
    
    void GameOverScene::GoToGameScene(cocos2d::Ref *sender)
    {
    	auto scene = GameScene::createScene();
    	Director::getInstance()->replaceScene(TransitionFade::create(TRANSITION_TIME, scene));
    }

     

    ps. this is my original code, so the position of labels and buttons will be a little bit different from the source code. Thanks.


  • MoseHas
    Likes 0

    Will scene replacement erase my highscore? I recall that I use replaceScene to implement retry function.

    But I have looked into the source code, it used replaceScene as well.

    I assume my def->setIntegerForKey did not work.


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    As long as you flush the UserDefault it should save, so isn’t it saving?


    This reply has been verified.
  • MoseHas
    Likes 0

    I tried to check it out if it is saving or not but I have no idea how to. 

    Would you teach me how to debug it?

    Thanks.


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    just use the getinteger line

    def->getIntegerForKey("HIGHSCORE FLAPPY", 0);

    This reply has been verified.
  • MoseHas
    Likes 0

    Sorry I cannot fully understand.

    auto highScore = def->getIntegerForKey("HIGHSCORE FLAPPY", 0);

    Is that correct?


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    yh, the highScore variable should have your saved value now

     

    Also check out this video for more info on UserDefaults

    https://www.youtube.com/watch?v=_FYsuSFKCZU&list=PLRtjMdoYXLf4vzkg0wdBrp7YoOThOLf4H&index=15


    This reply has been verified.
  • MoseHas
    Likes 0

    Oops.

    They did save in my newly created project but could not work on the old one.

    Let me try more and report it.

  • MoseHas
    Likes 0

    UserDefault *def = UserDefault::getInstance();
    	auto highScore = def->getIntegerForKey("HIGHSCORE FLAPPY", 0);
    	if (highScoresetIntegerForKey("HIGHSCORE FLAPPY", highScore);
    	}
    	def->flush();

    The partial code should get a default integer from HIGHSCORE FLAPPY, which is 0 in the very first beginning.

    After the game is proceeding, score has been modified and should go into the if decision because the score is now larger than highScore.

    Now we assign score value into highScore in order to replace the lower grade, and use setIntegerForKey to save new value into HIGHSCORE FLAPPY.

    If my thought is correct, this should be what my code is doing. However, it is not.

    Do I have any other method to implement this function? It is really strange.


  • MoseHas
    Likes 0

    I have tried to debug it and I discovered that no matter what the last game score was, highScore was always 0.

    Officially give up. I have created an another brand new project, pasted all the code downloaded from GitHub and it still did not work.

    But I did succeed ONLY using UserDefault to perserve the value.

    Another frustrating day.


  • Sonar Systems admin
    Likes 0

    What do you mean by this

     

    But I did succeed ONLY using UserDefault to perserve the value.

  • MoseHas
    Likes 0

    Apology for my poor English.

    What I mean is, I created a new project, and tested UserDefault. Turns out it worked properly. It did save the value after setIntegerForKey();

    But I still don’t know why it could not use UserDefault on my flappy bird project.

    Does this often occur? Same code lines work different in different project.

    Or just because of my pathetic coding ability? 

    Stuck for two days.

  • Sonar Systems admin
    Likes 0

    This shoulnd’t be an issue, have you tried getting the entire code from Github and testing that without any modifications?


    This reply has been verified.
  • MoseHas
    Likes 0

    Yes, I have tried. And it did not work as well.

    Only will I succeed if I create a new project and do nothing but UserDefault function.

  • Sonar Systems admin
    Likes 0

    What version of Cocos are you using?


    This reply has been verified.
  • MoseHas
    Likes 0

    cocos2d-x-3.6, downloaded last Monday.


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Try an older version but that shouldn’t be a problem.


    This reply has been verified.
  • MoseHas
    Likes 0

    I have just discovered that there was a error message displayed after it created the gameoverscene.

    I assume it is why the score could not be stored.

    read root node error

    Is that possible the program tried to access the path but failed?

    Thanks.


    This reply has been verified.
  • MoseHas
    Likes 0

    Problem Solved!! Thanks to Google.

    1. DO NOT use space character as your key name.
    2. delete the UserDefault.xml from your computer.
    3. rebuild and run your program.

    This is weird because I saw the tutorial use “HIGHSCORE FLAPPY”as the key, and it worked.

    However, I saw others have the same issue, and they provided the solution.

    The path of UserDefault.xml is “C:\Users\(USERNAME)\AppData\Local\(PROJECT_NAME)

     

    Thank you!

    reference: https://github.com/cocos2d/cocos2d-x/issues/10414


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Maybe because i was on Mac, good to know for the future :D

     

    Glad it’s now solved :D


    This reply has been verified.
  • MoseHas
    Likes 0

    Thank you!

    I have never been so eager to buy a Mac.  This is insane. Stable environment is the top priority for developers.


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    I prefer Windows overall but I do prefer Mac for development as I just find it’s less hassle to perform mundane tasks.


    This reply has been verified.

Login to reply