Flappy Bird는 터치할때마다 새가 점프하여 장애물에 박지않고 멀리 가는 게임이다.
(https://namu.wiki/w/Flappy%20Bird?from=%ED%94%8C%EB%9E%98%ED%94%BC%20%EB%B2%84%EB%93%9C)
이때까지 만들었던 기본요소들로 플래피 버드를 만들어보았다.
우선 해상도는 1280 * 720이다.
Scene에서는 게임이 진행될 GameLayer와 배경화면을 나타낼 BgLayer를 자식으로 넣어주었다.
1 2 3 4 5 6 7 8 9 10 | bool GameScene::init() { GameLayer* pLayer = GameLayer::create(); addChild(pLayer, 1, "player"); BgLayer* bgLayer1 = BgLayer::create(); addChild(bgLayer1, 0, "bg"); return true; } | cs |
BgLayer는 아래와 같다.
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 | bool BgLayer::init() { // 같은 이미지를 2개 생성 Sprite* pSprite1 = Sprite::create("res/background.png"); Sprite* pSprite2 = Sprite::create("res/background.png"); addChild(pSprite1, 0, 100); addChild(pSprite2, 0, 200); pSprite1->setPosition(640, 384); pSprite2->setPosition(1920, 384); scheduleUpdate(); return true; } void BgLayer::update(float dt) { Sprite* pSprite1 = (Sprite*)getChildByTag(100); Sprite* pSprite2 = (Sprite*)getChildByTag(200); // 첫 이미지가 화면에서 사라지면 2번째 이미지 뒤로 붙여줌 if (pSprite1->getPositionX() <= -640) pSprite1->setPositionX(pSprite2->getPositionX()+1280); else if (pSprite2->getPositionX() <= -640) pSprite2->setPositionX(pSprite1->getPositionX()+1280); // 부모(씬)의 자식 중 Player(GameLayer)를 찾아줌 auto gl = (GameLayer*)getParent()->getChildByName("player"); // 캐릭터가 죽지않으면 배경화면을 계속 if (!gl->getdeath()) { pSprite1->setPositionX(pSprite1->getPositionX() - 200.0f * dt); pSprite2->setPositionX(pSprite2->getPositionX() - 200.0f * dt); } } | cs |
init()에서 똑같은 배경화면을 2개 생성한 후 이어지게 붙여
배경화면이 왼쪽으로 계속 이동하면서 화면에서 벗어나면 뒤에 붙여주는 식으로 반복하는 것이다.
GameLayer는 아래와 같다.
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 | #pragma once #include <cocos2d.h> USING_NS_CC; class GameLayer : public Layer { private: float jump; int jumpcount; int score; int death; int start; int hiscore; float t; public: GameLayer(); ~GameLayer(); bool init(); virtual bool onTouchBegan(Touch *touch, Event *unused_event); virtual void onTouchMoved(Touch *touch, Event *unused_event); virtual void onTouchEnded(Touch *touch, Event *unused_event); virtual void onTouchCancelled(Touch *touch, Event *unused_event); void update(float dt); void scoreup(); void hstop(); void enablestart(); void sethuddleerase(); int getdeath(); int getscore(); CREATE_FUNC(GameLayer); }; | 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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | #include "GameLayer.h" #include "Huddle.h" #include "PrintNum.h" #include "PrintAlpha.h" #include "menu.h" #include "json/json.h" // 태그번호 : 캐릭터(105) / 알파벳(601) / 점수(552) / 스타트메뉴(1000) / 노드(700) GameLayer::GameLayer() { jump = 0; // 점프를 하기위해 y값을 조정해주기 위한 수치 t = 0; // 1초마다 장애물을 찍어주기 위해 시간을 저장할 변수 jumpcount = 0; // 점프횟수 제한을 하기위해 (지금은 해제하여 사용하지않는중) score = 0; // 점수를 저장할 변수 death = 0; // 죽었는지 확인하는 변수. 1이면 죽음 start = 0; // 시작을 확인하는 변수. 1이면 시작 hiscore = 0; // 하이스코어값을 저장하는 변수 } GameLayer::~GameLayer() { } bool GameLayer::init() { Sprite* pSprite = Sprite::create("res/c1.png"); pSprite->setPosition(200, 150); pSprite->setScale(0.15f); addChild(pSprite,1,105); // 터치리스너 등록 auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // SCORE 글자를 이미지로 출력 auto pScore1 = PrintAlpha::create(); pScore1->print("SCORE"); addChild(pScore1, 2, 601); // SCORE 실제 점수를 표시(초기값 0) auto pNum1 = PrintNum::create(); addChild(pNum1, 2, 552); pNum1->print(0); // 스타트 메뉴 표시 auto MenuStart = menu::create(); addChild(MenuStart, 5, 1000); MenuStart->printstart(); // 허들을 동시에 삭제하기 위해 노드의 자식으로 관리하려고 만듬 Node* pNode = Node::create(); addChild(pNode, 0, 700); // HISCORE 글자 출력 auto pHiScore = PrintAlpha::create(); pHiScore->print2("HISCORE"); addChild(pHiScore, 2, 602); // json에서 highscore 읽어와서 변수에넣기 Json::Value root; Data data; char path[256] = {}; GetCurrentDirectoryA(256, path); std::string fileName = path; fileName += "/data.json"; data = FileUtils::getInstance()->getDataFromFile(fileName); char* pBuffer = (char*)data.getBytes(); std::string strJson = pBuffer; Json::Reader reader; reader.parse(strJson.c_str(), root); hiscore = root["highscore"].asInt(); // 읽어온 highscore를 이미지로 출력 auto pHiScore2 = PrintNum::create(); addChild(pHiScore2, 2, 553); //pHiScore2->print2(0); pHiScore2->print2(hiscore); scheduleUpdate(); return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) jump = 650.0f; return true; } void GameLayer::update(float dt) { if (start) { Sprite* pSprite = (Sprite*)getChildByTag(105); if (pSprite) { // 중력이 -400.0f만큼 작용하여 계속 떨어짐 pSprite->setPositionY(pSprite->getPositionY() + (jump - 400.0f) * dt); // 캐릭터가 바닥에 떨어지지않게 가상의 바닥을 깔아줌(삭제할것. 테스트위해) if (pSprite->getPositionY() < 150) { pSprite->setPositionY(150.0f); //jumpcount = 0; } } // 점프값이 점점 줄어들게 if (jump != 0) jump -= 400.0f * dt; else jump = 0; t += dt; // 1초마다 허들생성 if (t >= 1) { // 허들을 노드의 자식으로 넣어줌 auto pNode = getChildByTag(700); Huddle* newHuddle = Huddle::create(); pNode->addChild(newHuddle, 0); t -= 1; } } } // 점수를 올리는 함수 void GameLayer::scoreup() { score += 521; auto pNum = (PrintNum*)getChildByTag(552); pNum->print(score); } // 게임을 멈추는 함수 void GameLayer::hstop() { death = 1; start = 0; // 리스타트 메뉴를 출력 auto MenuRestart = menu::create(); addChild(MenuRestart, 5, 1001); MenuRestart->printrestart(); // 하이스코어 검사, 저장 if (score > hiscore) hiscore = score; auto pNum = (PrintNum*)getChildByTag(553); pNum->print2(hiscore); Json::Value root; root["highscore"] = hiscore; Json::StyledWriter sw; std::string jsonString = sw.write(root); FILE* pFile = NULL; std::string fileName = ""; // 파일이름이 최대길이가 256자라서 최대로 만듬 char path[256] = {}; // 현재 디렉토리 주소를 가져옴 (path) GetCurrentDirectoryA(256, path); fileName = path; fileName += "/data.json"; fopen_s(&pFile, fileName.c_str(), "wt"); fwrite(jsonString.c_str(), jsonString.length(), 1, pFile); fclose(pFile); } // 시작을 세팅 void GameLayer::enablestart() { start = 1; death = 0; score = 0; // 스코어 출력 auto pNum = (PrintNum*)getChildByTag(552); pNum->print(score); // 캐릭터 보이게함 auto pHero = (Sprite*)getChildByTag(105); pHero->setVisible(true); } // 허들 삭제하는 함수 void GameLayer::sethuddleerase() { // 노드를 찾아 자식을 전부 삭제 auto pNode = getChildByTag(700); pNode->removeAllChildren(); } int GameLayer::getdeath() { return death; } int GameLayer::getscore() { return score; } | cs |
GameLayer에는 많은 부분들이 들어가서 설명이 부족한 부분만 다음글에서 설명하겠음.
'프로그래밍 공부 > cocos2d-x' 카테고리의 다른 글
라벨, 메뉴 사용하기 (0) | 2018.03.28 |
---|---|
Flappy Bird 게임 만들기 - 2 (0) | 2018.03.27 |
충돌체크하기 (0) | 2018.03.27 |
터치, 마우스, 키보드 사용하기 (0) | 2018.03.27 |
오브젝트 삭제하기 (0) | 2018.03.26 |