VioletaBabel
16일 : 파일 입출력 - 바이너리 저장, JSON 본문
바이너리 저장 방식
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //c에서 제공하는 파일 출력 FILE* pFile = NULL; // 1번째 인수로 2중 포인터를 받는다. 하드디스크에 있는 주소를 가진 포인터를 인수로 받는다는 말 fopen_s(&pFile, "a.dat", "wb"); //주소를 가진 포인터의 주소를 넣어주는 것. //2번째 인수는 파일 이름, 뒤에는 wt, wb, rt, rb가 들어가는데, //w는 write, r은 read, t는 text, b는 binary이다. if (pFile != NULL) {//pFile을 못 열었을 때의 에러 방지책 int data = 100; //첫 인수는 주소인데 보이드의 포인터를 넣어줬음. 뭐든지 받을 수 있게 보이드. fwrite((void*)&data, sizeof(int), 1, pFile); //두번째 인수는 사이즈, 세번째 인수는 쓸 데이터 수, 네번째 인수는 스트림 fclose(pFile); } //생긴 경로는 게임프로젝트 폴더 안의 proj.win32 안의 Debug.win32 안에 생김 | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //구조체 이용 struct ddd { int a; int b; int c; }; //... FILE* pFile = NULL; fopen_s(&pFile, "a.dat", "wb"); if (pFile != NULL) { ddd data; fwrite((void*)&data, sizeof(ddd), 1, pFile); fclose(pFile); } | cs |
1 2 3 4 5 6 7 8 9 10 11 | //c에서 제공하는 파일 입력 FILE* pFile = NULL; fopen_s(&pFile, "a.dat", "rb"); if (pFile) { int data = 0; fread_s(&data, sizeof(int), sizeof(int), 1, pFile); std::string out = StringUtils::format("%d", data); MessageBox(out.c_str(), out.c_str());//아까 위에서 100을 넣었으니 100이 출력 fclose(pFile); } | cs |
-----
1 2 3 4 5 6 7 | //코코스 제공 클래스를 이용한 파일 입력 Data data; //코코스에서 파일 입출력을 위해 지원하는 클래스 data = FileUtils::getInstance()->getDataFromFile("a.dat"); unsigned char* pBytes = data.getBytes(); int nData = (int)*pBytes; std::string re = StringUtils::format("%d", nData); MessageBox(re.c_str(), re.c_str()); | cs |
-----
XML을 대체하기 위해 JSON이 등장.(XML은 폰게임에서 속도가 많이 더디기에 게임에선 잘 쓰지 않음)
나중에 배울 XAML도 많이 쓰임.
Json 종류마다 조금씩 다르니 다른 Json을 쓸 때는 잘 찾아볼 것.
우리가 쓸 것은 libJson이다.
libjson 폴더 내용을 proj.win32 폴더에 넣고, json_reader.cpp와 json_value.cpp, json_writer.cpp를 솔루션 탐색기에 드래그하여 넣어준다.
Json을 이용해 파일 출력
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include "json/json.h" //... Json::Value root; root["userName"] = "알랭드보통"; root["BookName"] = "뉴스의시대"; root["popular"] = 100; Json::StyledWriter sw; // 사람이 알아보기 쉽게 스타일을 적용하여 문자열을 만듦 std::string jsonString = sw.write(root); FILE* pFile = NULL; // 앱에 허락된 공간의 경로를 달라(os의 보안을 건드리지 않을 경로) std::string fileName = FileUtils::getInstance()->getWritablePath()+"data.json"; fopen_s(&pFile, fileName.c_str(), "wt"); fwrite(jsonString.c_str(), jsonString.length(), 1, pFile); fclose(pFile); //C:\Users\user\AppData\Local\프로젝트명 에 가면 data.json파일이 있음 | cs |
ㅓ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include "json/json.h" //... Json::Value root; FILE* pFile = NULL; // 앱에 허락된 공간의 경로를 달라(os의 보안을 건드리지 않을 경로) std::string fileName = FileUtils::getInstance()->getWritablePath()+"data.json"; //읽어오는건 제이슨으로 하기 귀찮으니까 코코스에서 지원하는걸로 해버리기 Data data; data = FileUtils::getInstance()->getDataFromFile(fileName); char* pBuffer = (char*)data.getBytes(); std::string strJson = pBuffer; Json::Reader reader; reader.parse(strJson.c_str(), root); std::string book = root["BookName"].asString(); int pop = root["popular"].asInt(); MessageBoxA(NULL, book.c_str(), "Name!!!", MB_OK); | cs |
--
전에 했던 러닝게임의 하이 스코어를 JSON으로 바꿔보자!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | //ScoreLayer.cpp #include "ScoreLayer.h" #include "json/json.h" ScoreLayer::ScoreLayer() { po = 0; } ScoreLayer::~ScoreLayer() { } bool ScoreLayer::init() { /*Data d = FileUtils::getInstance()->getDataFromFile(fileName); unsigned char* highpoString = d.getBytes(); highpo = (int)*highpoString;*/ Json::Value Json_HighScore; std::string fileName = FileUtils::getInstance()->getWritablePath() + "data.json"; Data data = FileUtils::getInstance()->getDataFromFile(fileName); bool a = data.isNull(); if (a) { Json_HighScore["highpo"] = 0; Json::StyledWriter sw; std::string jsonString = sw.write(Json_HighScore); FILE* pFile = NULL; std::string fileName = FileUtils::getInstance()->getWritablePath() + "data.json"; fopen_s(&pFile, fileName.c_str(), "wt"); fwrite(jsonString.c_str(), jsonString.length(), 1, pFile); fclose(pFile); } data = FileUtils::getInstance()->getDataFromFile(fileName); char* pBuffer = (char*)data.getBytes(); std::string strJson = pBuffer; Json::Reader reader; reader.parse(strJson.c_str(), Json_HighScore); highpo = Json_HighScore["highpo"].asInt(); Sprite *pHighScoreString1 = Sprite::create("res/high.png"); Sprite *pHighScoreString2 = Sprite::create("res/score.png"); Sprite *pScoreString = Sprite::create("res/score.png"); addChild(pHighScoreString1, 60, "Score_HighScoreString1"); addChild(pHighScoreString2, 60, "Score_HighScoreString2"); addChild(pScoreString, 60, "Score_ScoreString"); pHighScoreString1->setPosition(50, 695); pHighScoreString1->setScale(0.8f); pHighScoreString2->setPosition(165, 695); pHighScoreString2->setScale(0.8f); pScoreString->setPosition(1100, 695); pScoreString->setScale(0.8f); highScore(); Score(); return true; } void ScoreLayer::update() { } void ScoreLayer::highScore() { for (int i = 0, copyH = highpo, hun = 100; i < 3; ++i, hun/=10, ++highpoCount) { if (highpoCount > 2) pHighScore[i]->removeFromParent(); high[i] = copyH / hun; copyH %= hun; std::string highScoreName = StringUtils::format("res/%d.png", high[i]); pHighScore[i] = Sprite::create(highScoreName); std::string name = StringUtils::format("Score_HighScore%d", i + 1); addChild(pHighScore[i], 60, name); pHighScore[i]->setPosition(255 + (i * 35), 689); pHighScore[i]->setScale(0.5f); } } void ScoreLayer::Score() { for (int i = 0, copyS = po, hun = 100; i < 3; ++i, hun/=10, ++poCount) { if(poCount > 2) pScore[i]->removeFromParent(); sc[i] = copyS / hun; copyS %= hun; std::string scoreName = StringUtils::format("res/%d.png", sc[i]); pScore[i] = Sprite::create(scoreName); std::string name = StringUtils::format("Score_Score%d", i + 1); addChild(pScore[i], 60, name); pScore[i]->setPosition(1190 + (i * 35), 689); pScore[i]->setScale(0.5f); } } int ScoreLayer::getPo() { return po; } int ScoreLayer::getHignPo() { return highpo; } void ScoreLayer::poPlus() { ++po; Score(); if (po > highpo) { highPlus(); } } void ScoreLayer::highPlus() { ++highpo; highScore(); } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | //GameLayer.cpp #include "GameLayer.h" #include "GroundLayer.h" #include "CharacterAni.h" #include "StartGround.h" #include "GameScene.h" #include "ScoreLayer.h" #include "json/json.h" GameLayer::GameLayer() { jump = 1; jumpcount = 0; t = 1; move = 0; srand(time(NULL)); } GameLayer::~GameLayer() { } bool GameLayer::init() { makePlayer(); auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); StartGround *SG = StartGround::create(); addChild(SG, 15, "Game_StartGround"); ScoreLayer *SL = ScoreLayer::create(); addChild(SL, 2000, "Game_ScoreBoard"); scheduleUpdate(); return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unuserd_event) { if (jumpcount++ < 2) { MGOff(); jump = -30; } return false; } void GameLayer::RestartGame(Object * sender) { gameover = 0; auto a = (GameScene*)getParent(); a->StartP(); removeFromParent(); auto item = (MenuItem*)sender; } void GameLayer::update(float dt) { Node* pPlayer = getChildByName("Game_Player"); t += dt; if (pPlayer) { if (t >= 1.0f) { GroundLayer *pGd = GroundLayer::create(); addChild(pGd, 15); t -= 1.0f; } if (meetGround) { move = 0; } else if (pPlayer->getPositionY() > 660) move = 250.0f*dt; else move = 250.0f*dt*jump; pPlayer->setPositionY(pPlayer->getPositionY() - move); if (jump != 0) jump /= 2; else jump = 1; if (pPlayer->getPositionY() < 0) { pPlayer->removeFromParent(); ++gameover; } } if (gameover && !gameoverButton) { auto mreStart = MenuItemImage::create("res/restart.png", "res/restart.png", CC_CALLBACK_1(GameLayer::RestartGame, this)); auto mEnd = MenuItemImage::create("res/end.png", "res/end.png", CC_CALLBACK_1(GameLayer::GameExit, this)); mreStart->setScale(0.5f); auto menu = Menu::create(mreStart, mEnd, NULL); menu->alignItemsVertically(); this->addChild(menu, 1000); auto scLayer = (ScoreLayer*)getChildByName("Game_ScoreBoard"); Data data; std::string fileName = FileUtils::getInstance()->getWritablePath() + "highscore.txt"; int a = scLayer->getHignPo(); /* data.copy((const unsigned char*)&a, sizeof(int)); FileUtils::getInstance()->writeDataToFile(data, fileName); */ Json::Value Json_HighScore; Json_HighScore["highpo"] = scLayer->getHignPo(); Json::StyledWriter sw; std::string jsonString = sw.write(Json_HighScore); FILE* pFile = NULL; std::string scoreFileName = FileUtils::getInstance()->getWritablePath() + "data.json"; fopen_s(&pFile, scoreFileName.c_str(), "wt"); fwrite(jsonString.c_str(), jsonString.length(), 1, pFile); fclose(pFile); } } void GameLayer::makePlayer() { CharacterAni* pPlayer = CharacterAni::create(); addChild(pPlayer, 0, "Game_Player"); pPlayer->setPosition(160, 160); } void GameLayer::MGOn() { ++meetGround; jumpcount = 0; } void GameLayer::MGOff() { meetGround = 0; } int GameLayer::getJump() { return jump; } void GameLayer::GameExit(Object * sender) { Director::getInstance()->end(); } | cs |
'BCA > 2. Cocos2d-x' 카테고리의 다른 글
16일 : 오디오, 3:3 AI 탱크게임 (0) | 2018.03.08 |
---|---|
15일 : 파일 입출력, 오디오, 러닝게임 완성 (0) | 2018.02.28 |
14일 : 애니메이션 (0) | 2018.02.27 |
13일 : 복습 겸 아주 자잘한 팁 (0) | 2018.02.26 |
12일 : 플래피 버드 완성하기 (0) | 2018.02.23 |
Comments