VioletaBabel
11일 : 터치, 업데이트, 배경, 장애물 등장 본문
어떤 이미지가 다른 이미지를 따라다니려면 그 이미지의 자식으로 다른 이미지를 만들면 된다.
GameLayer의 부모인 Layer를 뜯어보면 CC_DEPRECATED_ATTRIBUTE 라고 되어있는데
이건 예전엔 썼지만 이젠 쓰지 않는 것들. 엔진을 새로 갱신해도 과거의 것들이 돌아가기 위해 남아는 있지만 앞으로는 이렇게 적힌건 쓰지 말아야 함.
터치는
onTouchBegan // 터치 한 순간
onTouchMoved // 터치를 하고 움직일 때
onTouchEnded // 터치를 뗄 때
onTouchCancelled // 터치를 하고 무브를 하다가 화면 밖으로 나갈 때.
함수가 있다.
그리고
onTouchesBegan // 터치 한 순간
onTouchesMoved // 터치를 하고 움직일 때
onTouchesEnded // 터치를 뗄 때
onTouchesCancelled // 터치를 하고 무브를 하다가 화면 밖으로 나갈 때.
함수는 터치가 두 개 이상일 때이다.(여러 손가락)
--
Node의 update함수는 float형의 delta를 인수로 가지는데, 초당 2프레임이면 delta는 0.5
update함수는 매 프레임마다 실행되는 함수라고 보면 된다.
터치를 하면 그 곳으로 스프라이트의 위치를 바꾸고, 매 프레임마다 스프라이트가 아래로 추락하는 코드
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 | //GameLayer.h #include "GameLayer.h" GameLayer::GameLayer() { } GameLayer::~GameLayer() { } bool GameLayer::init() { //인터넷에 다운받아 프로젝트 폴더의 Resources 폴더의 res 폴더에 넣은 이미지파일을 스프라이트로 만든다. Sprite* pSprite = Sprite::create("res/moomin.png"); addChild(pSprite, 0, 0); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐 //터치를 받으면 연결해주는 것을 만들어야 한다. auto listener = EventListenerTouchOneByOne::create(); // 멀티터치가 아닌 손가락 하나 전용 리스너 생성 listener->setSwallowTouches(true); //그냥 터치하는건 이렇게 생겨먹었으니 이해보다는 이런 식이구나~ 하자 listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); scheduleUpdate(); // 이걸 호출해야지만 update 함수가 계속 불리게 된다. //unscheduleUpdate(); //이 함수를 부르면 update 함수가 더 이상 불리지 않는다. return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) { Sprite* pSprite = (Sprite*)getChildByTag(0); // 위에서 addChild에 숫자를 넣었으니 Tag, 이름을 했으면 GetChildByName //Node* pSprite = getChildByTag(0); // 이렇게 하면 Node를 상속받은 Sprite에 비해 함수가 적다. 활용성에 있어서 위의 방법이 더 좋음. pSprite->setPosition(touch->getLocation()); return false; } void GameLayer::onTouchMoved(Touch * touch, Event * unused_event) { } void GameLayer::onTouchEnded(Touch * touch, Event * unused_event) { } void GameLayer::onTouchCancelled(Touch * touch, Event * unused_event) { } void GameLayer::update(float dt) { Node* pSprite = getChildByTag(0); // 새로 만든 스프라이트. 위에 만든 0을 그대로 받아온다. pSprite->setPositionY(pSprite->getPositionY() - 30.0f * dt); // 초마다 해당 스프라이트의 Y를 -30.0f씩 이동시킨다. } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //GameLayer.h #pragma once #include <cocos2d.h> USING_NS_CC; class GameLayer : public Layer { 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); CREATE_FUNC(GameLayer); }; | cs |
=============
계속 추락하는데 클릭할 때마다 약간씩 점프하는 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //GameLayer.h #pragma once #include <cocos2d.h> USING_NS_CC; class GameLayer : public Layer { private: int jump; 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); 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 | //GameLayer.h #include "GameLayer.h" GameLayer::GameLayer() { jump = 1; } GameLayer::~GameLayer() { } bool GameLayer::init() { //인터넷에 다운받아 프로젝트 폴더의 Resources 폴더의 res 폴더에 넣은 이미지파일을 스프라이트로 만든다. Sprite* pSprite = Sprite::create("res/moomin.png"); addChild(pSprite, 0, 0); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐 pSprite->setPosition(240, 160); //터치를 받으면 연결해주는 것을 만들어야 한다. auto listener = EventListenerTouchOneByOne::create(); // 멀티터치가 아닌 손가락 하나 전용 리스너 생성 listener->setSwallowTouches(true); //그냥 터치하는건 이렇게 생겨먹었으니 이해보다는 이런 식이구나~ 하자 listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); scheduleUpdate(); // 이걸 호출해야지만 update 함수가 계속 불리게 된다. //unscheduleUpdate(); //이 함수를 부르면 update 함수가 더 이상 불리지 않는다. return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) { //Sprite* pSprite = (Sprite*)getChildByTag(0); // 위에서 addChild에 숫자를 넣었으니 Tag, 이름을 했으면 GetChildByName //Node* pSprite = getChildByTag(0); // 이렇게 하면 Node를 상속받은 Sprite에 비해 함수가 적다. 활용성에 있어서 위의 방법이 더 좋음. //pSprite->setPosition(touch->getLocation()); jump = -20; return false; } void GameLayer::onTouchMoved(Touch * touch, Event * unused_event) { } void GameLayer::onTouchEnded(Touch * touch, Event * unused_event) { } void GameLayer::onTouchCancelled(Touch * touch, Event * unused_event) { } void GameLayer::update(float dt) { Node* pSprite = getChildByTag(0); // 새로 만든 스프라이트. 위에 만든 0을 그대로 받아온다. pSprite->setPositionY(pSprite->getPositionY() - 30.0f * dt * jump); // 초마다 해당 스프라이트의 Y를 -30.0f씩 이동시킨다. 다만 점프 값을 주어 점프 하는 도중엔 역행 if (jump < 1) // 점프 안할 때는 1이다. jump += 3; } | cs |
================
2단 점프까지만 가능하고 바닥이 존재하게 수정한 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //GameLayer.h #pragma once #include <cocos2d.h> USING_NS_CC; class GameLayer : public Layer { private: int jump; double move; int jumpcount; 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); 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 | //GameLayer.h #include "GameLayer.h" GameLayer::GameLayer() { jump = 1; jumpcount = 0; } GameLayer::~GameLayer() { } bool GameLayer::init() { //인터넷에 다운받아 프로젝트 폴더의 Resources 폴더의 res 폴더에 넣은 이미지파일을 스프라이트로 만든다. Sprite* pSprite = Sprite::create("res/moomin.png"); addChild(pSprite, 0, 0); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐 pSprite->setPosition(240, 160); //터치를 받으면 연결해주는 것을 만들어야 한다. auto listener = EventListenerTouchOneByOne::create(); // 멀티터치가 아닌 손가락 하나 전용 리스너 생성 listener->setSwallowTouches(true); //그냥 터치하는건 이렇게 생겨먹었으니 이해보다는 이런 식이구나~ 하자 listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); scheduleUpdate(); // 이걸 호출해야지만 update 함수가 계속 불리게 된다. //unscheduleUpdate(); //이 함수를 부르면 update 함수가 더 이상 불리지 않는다. return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) { //Sprite* pSprite = (Sprite*)getChildByTag(0); // 위에서 addChild에 숫자를 넣었으니 Tag, 이름을 했으면 GetChildByName //Node* pSprite = getChildByTag(0); // 이렇게 하면 Node를 상속받은 Sprite에 비해 함수가 적다. 활용성에 있어서 위의 방법이 더 좋음. //pSprite->setPosition(touch->getLocation()); if (jumpcount < 2) // 점프는 2단점프까지로 한정 { jump = -20; ++jumpcount; } return false; } void GameLayer::onTouchMoved(Touch * touch, Event * unused_event) { } void GameLayer::onTouchEnded(Touch * touch, Event * unused_event) { } void GameLayer::onTouchCancelled(Touch * touch, Event * unused_event) { } void GameLayer::update(float dt) { Node* pSprite = getChildByTag(0); // 새로 만든 스프라이트. 위에 만든 0을 그대로 받아온다. if (pSprite->getPositionY() < 114 && jump == 1) // 바닥이 되면 정지하게 만든다. move = 0; else move = 30.0f * dt * jump; // 점프와 중력대로 pSprite->setPositionY(pSprite->getPositionY() - move); // 초마다 해당 스프라이트의 Y를 move만큼 이동시킨다. if (jump < 1) // 점프하면 값 변환시켜서 대응 jump += 3; else if(move == 0) // 바닥으로 돌아가면 다시 0이 된다. jumpcount = 0; } | cs |
appdelegate.cpp에서
1 | static cocos2d::Size designResolutionSize = cocos2d::Size(1280, 720); | cs |
의 인수를 고치면 창 크기가 변한다.
=====================
배경 넣기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //GameScene.cpp #include "GameScene.h" #include "GameLayer.h" #include "BackGround.h" GameScene::GameScene() { } GameScene::~GameScene() { } bool GameScene::init() { GameLayer *pLayer = GameLayer::create(); BackGround *pBack1 = BackGround::create(); addChild(pLayer, 1); // 위에 게임레이어헤더를 부르고 이렇게 함으로써 씬에서도 레이어를 갖다붙일 수 있게 됨. addChild(pBack1, 0); // 레이어의 z값을 바꿔 레이어마다의 층을 만들어준다. return true; } | 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 | //BackGround.cpp #include "BackGround.h" BackGround::BackGround() { } BackGround::~BackGround() { } bool BackGround::init() { Sprite* pSky1 = Sprite::create("res/sky.png"); Sprite* pSky2 = Sprite::create("res/sky.png"); // 하늘 배경 두 개 생성 addChild(pSky1, 0, 1); addChild(pSky2, 0, 2); // 각자 1, 2라는 태그를 주었다. pSky1->setPosition(0, 270); // 1280x720 사이즈의 그림인데 어째서 -800이 되어야 딱 맞게 전환이 되는건지.. pSky2->setPosition(1600, 270); scheduleUpdate(); return true; } void BackGround::update(float dt) { Node* pSky[2]; for (int i = 0; i < 2; ++i) pSky[i] = getChildByTag(i + 1); for (int i = 1; i > -1; --i) if (pSky[i]->getPositionX() < -800) // -800이 되면 이동시킨다. pSky[i]->setPositionX(2400 - 30.0f*dt); // 딱 맞아 떨어질 해당 위치로! else pSky[i]->setPositionX(pSky[i]->getPositionX() - 30.0f * dt); // 평소엔 그냥 왼쪽 이동 } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //BackGround.h #pragma once #include <cocos2d.h> USING_NS_CC; class BackGround : public Layer { public: BackGround(); ~BackGround(); bool init(); void update(float dt); CREATE_FUNC(BackGround); }; | cs |
허나 이 코드엔 문제가 있다!
속도가 빨라지면 제대로 틈이 벌어진다.
그리고 해상도 문제 해결하는 방법은 appdelegate.cpp 에서
static cocos2d::Size designResolutionSize = cocos2d::Size(1280, 720);
부분 밑의 3줄을 지워주고, 그로 인해 빨간 줄 뜨는 부분도 지워주는 것.
그 부분을 지운 후 속도 문제를 해결하면 코드가 이렇게 된다.
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 | //BackGround.cpp #include "BackGround.h" BackGround::BackGround() { } BackGround::~BackGround() { } bool BackGround::init() { Sprite* pSky1 = Sprite::create("res/sky.png"); Sprite* pSky2 = Sprite::create("res/sky.png"); // 하늘 배경 두 개 생성 addChild(pSky1, 0, 1); addChild(pSky2, 0, 2); // 각자 1, 2라는 태그를 주었다. pSky1->setPosition(0, 360); pSky2->setPosition(1280, 360); scheduleUpdate(); return true; } void BackGround::update(float dt) { Node* pSky[2]; for (int i = 0; i < 2; ++i) pSky[i] = getChildByTag(i + 1); for (int i = 1; i > -1; --i) { pSky[i]->setPositionX(pSky[i]->getPositionX() - 500.0f * dt); // 평소엔 그냥 왼쪽 이동 if (pSky[i]->getPositionX() < -640) // -640이 되면 이동시킨다. pSky[i]->setPositionX(pSky[i]->getPositionX() + 2560); // 딱 맞아 떨어질 해당 위치로! } } | cs |
틈이 벌어지는 것은 속도가 빠른 경우 정확히 내가 원하는 부분에 가지 않기 때문.
나는 -640에 도달하면 해당 위치로 보내버린 셈이지만, 그 대신 수치를 더함으로써 속도에 그대로 대응할 수 있게 한 것이다.
=================
장애물 등장
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //GameLayer.h #pragma once #include <cocos2d.h> USING_NS_CC; class GameLayer : public Layer { private: int jump; double move; int jumpcount; int frame; 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); 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 | //GameLayer.h #include "GameLayer.h" #include "Hurdle.h" GameLayer::GameLayer() { jump = 1; jumpcount = 0; frame = 0; srand(time(NULL)); } GameLayer::~GameLayer() { } bool GameLayer::init() { //인터넷에 다운받아 프로젝트 폴더의 Resources 폴더의 res 폴더에 넣은 이미지파일을 스프라이트로 만든다. Sprite* pSprite = Sprite::create("res/moomin.png"); addChild(pSprite, 0, 0); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐 pSprite->setPosition(640, 180); //터치를 받으면 연결해주는 것을 만들어야 한다. auto listener = EventListenerTouchOneByOne::create(); // 멀티터치가 아닌 손가락 하나 전용 리스너 생성 listener->setSwallowTouches(true); //그냥 터치하는건 이렇게 생겨먹었으니 이해보다는 이런 식이구나~ 하자 listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); scheduleUpdate(); // 이걸 호출해야지만 update 함수가 계속 불리게 된다. //unscheduleUpdate(); //이 함수를 부르면 update 함수가 더 이상 불리지 않는다. return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) { //Sprite* pSprite = (Sprite*)getChildByTag(0); // 위에서 addChild에 숫자를 넣었으니 Tag, 이름을 했으면 GetChildByName //Node* pSprite = getChildByTag(0); // 이렇게 하면 Node를 상속받은 Sprite에 비해 함수가 적다. 활용성에 있어서 위의 방법이 더 좋음. //pSprite->setPosition(touch->getLocation()); if (jumpcount < 2) // 점프는 2단점프까지로 한정 { jump = -20; ++jumpcount; } return false; } void GameLayer::onTouchMoved(Touch * touch, Event * unused_event) { } void GameLayer::onTouchEnded(Touch * touch, Event * unused_event) { } void GameLayer::onTouchCancelled(Touch * touch, Event * unused_event) { } void GameLayer::update(float dt) { frame = (frame + 1) % 60; Node* pSprite = getChildByTag(0); // 새로 만든 스프라이트. 위에 만든 0을 그대로 받아온다. if (pSprite->getPositionY() < 142 && jump == 1) // 바닥이 되면 정지하게 만든다. move = 0; else move = 30.0f * dt * jump; // 점프와 중력대로 pSprite->setPositionY(pSprite->getPositionY() - move); // 초마다 해당 스프라이트의 Y를 move만큼 이동시킨다. if (jump < 1) // 점프하면 값 변환시켜서 대응 jump += 3; else if(move == 0) // 바닥으로 돌아가면 다시 0이 된다. jumpcount = 0; if (frame == 0) { Hurdle *pHd = Hurdle::create(); addChild(pHd, 15); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //Hurdle.h #pragma once #include <cocos2d.h> USING_NS_CC; class Hurdle : public Node { public: const int Back_X_Size = 1280; Hurdle(); ~Hurdle(); bool init(); void update(float dt); CREATE_FUNC(Hurdle); void move(Node *a, float dt); }; | 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 | //Hurdle.cpp #include "Hurdle.h" #include<cstdlib> #include<ctime> Hurdle::Hurdle() { } Hurdle::~Hurdle() { } bool Hurdle::init() { int term = 180, down = rand()%540-360, up=down+term+720; Sprite *pHd1 = Sprite::create("res/hurdle.png"); Sprite *pHd2 = Sprite::create("res/hurdle.png"); addChild(pHd1, 0, 1); addChild(pHd2, 0, 2); pHd1->setPosition(1280, up); pHd2->setPosition(1280, down); scheduleUpdate(); return true; } void Hurdle::update(float dt) { Node *pHdUp, *pHdDown; pHdUp = getChildByTag(1); pHdDown = getChildByTag(2); move(pHdUp, dt); move(pHdDown, dt); if (pHdUp->getPositionX() < -32) this->removeFromParent(); } void Hurdle::move(Node * a, float dt) { a->setPositionX(a->getPositionX() - 500.0f * dt); // 평소엔 그냥 왼쪽 이동 if (a->getPositionX() < Back_X_Size / (-2)) // 음수로 해상도의 절반 값으로 갈 경우 이동시킨다. a->setPositionX(a->getPositionX() + (Back_X_Size * 2)); // 딱 맞아 떨어질 해당 위치로! } | cs |
근데 내가 짠 코드를 보면, 허들을 만들고 그 안에 스프라이트를 만들어서 움직이는 비효율적인 일을 하고 있다.
그러므로 스프라이트를 만든 후 허들을 통째로 옮기기로 하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //Hurdle.h #pragma once #include <cocos2d.h> #include<cstdlib> #include<ctime> USING_NS_CC; class Hurdle : public Node { public: const int Back_X_Size = 1280; Hurdle(); ~Hurdle(); bool init(); void update(float dt); CREATE_FUNC(Hurdle); }; | 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 | //Hurdle.cpp #include "Hurdle.h" Hurdle::Hurdle() { } Hurdle::~Hurdle() { } bool Hurdle::init() { int term = 180, down = rand()%540-360, up=down+term+720; Sprite *pHd1 = Sprite::create("res/hurdle.png"); Sprite *pHd2 = Sprite::create("res/hurdle.png"); addChild(pHd1, 0, 1); addChild(pHd2, 0, 2); pHd1->setPosition(0, up); // 스프라이트의 X좌표가 허들의 원점에 오도록 수정하자. pHd2->setPosition(0, down); setPositionX(1312); // 허들을 통째로 옮겨준다.(1280+32) 이러면 무브가 필요가 없다!! scheduleUpdate(); return true; } void Hurdle::update(float dt) { setPositionX(getPositionX() - 500.0f * dt); if (getPositionX() < -32) this->removeFromParent(); } | 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 | //GameLayer.h #include "GameLayer.h" #include "Hurdle.h" GameLayer::GameLayer() { jump = 1; jumpcount = 0; t = 0; srand(time(NULL)); } GameLayer::~GameLayer() { } bool GameLayer::init() { //인터넷에 다운받아 프로젝트 폴더의 Resources 폴더의 res 폴더에 넣은 이미지파일을 스프라이트로 만든다. Sprite* pSprite = Sprite::create("res/moomin.png"); addChild(pSprite, 0, 0); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐 pSprite->setPosition(640, 180); //터치를 받으면 연결해주는 것을 만들어야 한다. auto listener = EventListenerTouchOneByOne::create(); // 멀티터치가 아닌 손가락 하나 전용 리스너 생성 listener->setSwallowTouches(true); //그냥 터치하는건 이렇게 생겨먹었으니 이해보다는 이런 식이구나~ 하자 listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); scheduleUpdate(); // 이걸 호출해야지만 update 함수가 계속 불리게 된다. //unscheduleUpdate(); //이 함수를 부르면 update 함수가 더 이상 불리지 않는다. return true; } bool GameLayer::onTouchBegan(Touch * touch, Event * unused_event) { //Sprite* pSprite = (Sprite*)getChildByTag(0); // 위에서 addChild에 숫자를 넣었으니 Tag, 이름을 했으면 GetChildByName //Node* pSprite = getChildByTag(0); // 이렇게 하면 Node를 상속받은 Sprite에 비해 함수가 적다. 활용성에 있어서 위의 방법이 더 좋음. //pSprite->setPosition(touch->getLocation()); if (jumpcount < 2) // 점프는 2단점프까지로 한정 { jump = -20; ++jumpcount; } return false; } void GameLayer::onTouchMoved(Touch * touch, Event * unused_event) { } void GameLayer::onTouchEnded(Touch * touch, Event * unused_event) { } void GameLayer::onTouchCancelled(Touch * touch, Event * unused_event) { } void GameLayer::update(float dt) { Node* pSprite = getChildByTag(0); // 새로 만든 스프라이트. 위에 만든 0을 그대로 받아온다. if (pSprite->getPositionY() < 142 && jump == 1) // 바닥이 되면 정지하게 만든다. move = 0; else move = 30.0f * dt * jump; // 점프와 중력대로 pSprite->setPositionY(pSprite->getPositionY() - move); // 초마다 해당 스프라이트의 Y를 move만큼 이동시킨다. if (jump < 1) // 점프하면 값 변환시켜서 대응 jump += 3; else if(move == 0) // 바닥으로 돌아가면 다시 0이 된다. jumpcount = 0; t += dt; if (t>=1.0f) { Hurdle *pHd = Hurdle::create(); addChild(pHd, 15); t -= 1.0f; } } | cs |
'BCA > 2. Cocos2d-x' 카테고리의 다른 글
15일 : 파일 입출력, 오디오, 러닝게임 완성 (0) | 2018.02.28 |
---|---|
14일 : 애니메이션 (0) | 2018.02.27 |
13일 : 복습 겸 아주 자잘한 팁 (0) | 2018.02.26 |
12일 : 플래피 버드 완성하기 (0) | 2018.02.23 |
10일 : cocos2d-x 입문 (0) | 2018.02.21 |