VioletaBabel

11일 : 터치, 업데이트, 배경, 장애물 등장 본문

BCA/2. Cocos2d-x
11일 : 터치, 업데이트, 배경, 장애물 등장
Beabletoet 2018. 2. 22. 10:19

어떤 이미지가 다른 이미지를 따라다니려면 그 이미지의 자식으로 다른 이미지를 만들면 된다.


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, 00); // 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, 00); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐
    pSprite->setPosition(240160);
 
    //터치를 받으면 연결해주는 것을 만들어야 한다.
    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, 00); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐
    pSprite->setPosition(240160);
 
    //터치를 받으면 연결해주는 것을 만들어야 한다.
    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(1280720);
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, 01);
    addChild(pSky2, 02); // 각자 1, 2라는 태그를 주었다.
    pSky1->setPosition(0270); // 1280x720 사이즈의 그림인데 어째서 -800이 되어야 딱 맞게 전환이 되는건지..
    pSky2->setPosition(1600270);
    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, 01);
    addChild(pSky2, 02); // 각자 1, 2라는 태그를 주었다.
    pSky1->setPosition(0360);
    pSky2->setPosition(1280360);
    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, 00); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐
    pSprite->setPosition(640180);
 
 
 
    //터치를 받으면 연결해주는 것을 만들어야 한다.
    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, 01);
    addChild(pHd2, 02);
    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, 01);
    addChild(pHd2, 02);
    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, 00); // 3번째 인수는 id나 이름을 준다. 이제 얘는 0번 아이디를 가짐
    pSprite->setPosition(640180);
 
 
 
    //터치를 받으면 연결해주는 것을 만들어야 한다.
    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


Comments