VioletaBabel

16일 : 파일 입출력 - 바이너리 저장, JSON 본문

BCA/2. Cocos2d-x
16일 : 파일 입출력 - 바이너리 저장, JSON
Beabletoet 2018. 3. 2. 11:04
바이너리 저장 방식

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(50695);
    pHighScoreString1->setScale(0.8f);
    pHighScoreString2->setPosition(165695);
    pHighScoreString2->setScale(0.8f);
    pScoreString->setPosition(1100695);
    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(160160);
 
}
 
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


Comments