GameMenu 클래스

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
#include "GameMenu.h"
#include "GameLayer.h"
#include "UILayer.h"
 
 
GameMenu::GameMenu()
{
    gamestart = false;
}
 
 
GameMenu::~GameMenu()
{
}
 
bool GameMenu::init()
{
    return true;
}
 
void GameMenu::printstart()
{
    // 일반이미지, 선택이미지, 비활성화이미지
    auto item1 = MenuItemImage::create("res/ui/buttonStart.png","res/ui/buttonStart.png", CC_CALLBACK_1(GameMenu::startmenuCallback, this));
    item1->setScale(1.5f);
    auto menu = Menu::create(item1, NULL);
    menu->alignItemsVertically();
    addChild(menu, 0"startmenu");
}
 
void GameMenu::printrestart()
{
    auto item1 = MenuItemImage::create("res/ui/restart.png""res/ui/restart.png", CC_CALLBACK_1(GameMenu::restartmenuCallback, this));
    auto menu2 = Menu::create(item1, NULL);
    menu2->setPositionY(290.0f);
    addChild(menu2, 0"restartmenu");
 
    auto sq = Sequence::create(Hide::create(), DelayTime::create(1.0f), Show::create(), NULL);
    menu2->setVisible(false);
    menu2->runAction(sq);
}
 
void GameMenu::startmenuCallback(Object * sender)
{
    auto item = (MenuItem*)sender;
 
    auto ul = (UILayer*)getParent();
    auto gl = (GameLayer*)ul->getParent()->getChildByName("gl");
    gl->start();
    ul->printhp();
 
    // 클릭 후 메뉴삭제
    auto pmenu1 = getChildByName("startmenu");
    pmenu1->removeFromParent();
}
 
void GameMenu::restartmenuCallback(Object * sender)
{
    auto item = (MenuItem*)sender;
    
    auto ul = (UILayer*)getParent();
    auto gl = (GameLayer*)ul->getParent()->getChildByName("gl");
    gl->start();
    ul->printhp();
 
    auto gameover = ul->getChildByName("gameover");
    gameover->removeFromParent();
 
    // 클릭 후 메뉴삭제
    auto pmenu2 = getChildByName("restartmenu");
    pmenu2->removeFromParent();
}
 
bool GameMenu::getgs()
{
    return gamestart;
}
 
cs

start와 restart 메뉴가 있고 관련 콜백함수가 있다.



Barrier 클래스

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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#include "Barrier.h"
#include "GameLayer.h"
#include "Tank.h"
 
 
Barrier::Barrier()
{
    brownnum = 0;
    beigenum = 100;
    treenum = 200;
    drumnum = 300;
}
 
 
Barrier::~Barrier()
{
}
 
bool Barrier::init()
{
    // 샌드백
    Sprite* sandbag[12];
 
    for (int i = 0; i < 12; i++)
    {
        sandbag[i] = Sprite::create("res/barrier/sandbagBrown.png");
        addChild(sandbag[i], 0, brownnum);
 
        if (i == 0)
        {
            sandbag[i]->setPosition(60650);
            sandbag[i]->setRotation(-30.0f);
        }
        else if (i == 1)
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66675);
            sandbag[i]->setRotation(-10.0f);
        }
        else if (i == 2)
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66670);
            sandbag[i]->setRotation(10.0f);
        }
        else if (i == 3)
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66650);
            sandbag[i]->setRotation(30.0f);
        }
        else if (i == 4)
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66630);
            sandbag[i]->setRotation(10.0f);
        }
        else if (i == 5)
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66640);
            sandbag[i]->setRotation(-20.0f);
        }
 
 
        // 오른쪽아래
        else if (i == 6)
            sandbag[i]->setPosition(103060);
        else if (i <= 8)
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66, sandbag[i - 1]->getPositionY());
        else if (i == 9)
        {
            sandbag[i]->setPosition(1220120);
            sandbag[i]->setRotation(90.0f);
        }
        else
        {
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX(), sandbag[i - 1]->getPositionY() + 66);
            sandbag[i]->setRotation(90.0f);
        }
 
        brownnum++;
    }
 
    for (int i = 0; i < 6; i++)
    {
        sandbag[i] = Sprite::create("res/barrier/sandbagBeige.png");
        addChild(sandbag[i], 0, beigenum);
        if (i == 0)
            sandbag[i]->setPosition(460350);
        else
            sandbag[i]->setPosition(sandbag[i - 1]->getPositionX() + 66, sandbag[i - 1]->getPositionY());
        beigenum++;
    }
 
    // 나무
    Sprite* tree;
    for (int i = 0; i < 8; i++)
    {
        if (i % 3)
            tree = Sprite::create("res/barrier/treeLarge.png");
        else
            tree = Sprite::create("res/barrier/treeSmall.png");
        addChild(tree, 0, treenum);
 
        if (i == 0)
            tree->setPosition(60100);
        else if (i <= 2)
            tree->setPosition(60100 + 90 * i);
        else if (i == 3)
            tree->setPosition(900650);
        else if (i <= 5)
            tree->setPosition(900 + 90 * (i - 3), 650);
        else if (i == 6)
            tree->setPosition(45080);
        else
            tree->setPosition(450 + 90 * (i - 6), 80);
 
        treenum++;
    }
 
    //드럼통
    Sprite* drum;
    for (int i = 0; i < 7; i++)
    {
        if (i < 4)
            drum = Sprite::create("res/barrier/drumRed2.png");
        else
            drum = Sprite::create("res/barrier/drumRed.png");
        addChild(drum, 0, drumnum);
 
        if (i == 0)
        {
            drum->setPosition(600430);
            drum->setRotation(70.0f);
        }
        else if (i == 1)
        {
            drum->setPosition(72080);
            drum->setRotation(105.0f);
        }
        else if (i == 2)
        {
            drum->setPosition(1000250);
            drum->setRotation(80.0f);
        }
        else if (i == 3)
        {
            drum->setPosition(1190560);
            drum->setRotation(135.0f);
        }
        else if (i == 4)
            drum->setPosition(280300);
        else if (i == 5)
            drum->setPosition(740670);
        else if (i == 6)
            drum->setPosition(1200470);
 
        drumnum++;
    }
 
    scheduleUpdate();
    return true;
}
 
void Barrier::update(float dt)
{
    auto gl = (GameLayer*)getParent();
    auto tank = gl->getChildByName("mytank")->getChildByName("mytank");
    auto barrel = gl->getChildByName("mytank")->getChildByName("barrel");
 
 
    // 장애물에 탱크충돌시
    // 브라운
    for (int i = 0; i < brownnum; i++)
    {
        auto barrier = getChildByTag(i);
        Point tp = tank->getPosition();
        Point bp = barrier->getPosition();
        Point bdir = bp - tp;
        float tblength = bdir.length();
        if (tblength < tank->getContentSize().width/2 + barrier->getContentSize().width/2)
        {
            bdir.normalize();
            tank->setPosition(tank->getPosition() - bdir * 150.0f * dt);
            barrel->setPosition(tank->getPosition());
        }
    }
 
    // 베이지
    for (int i = 0; i < beigenum - 100; i++)
    {
        auto barrier = getChildByTag(i + 100);
        Point tp = tank->getPosition();
        Point bp = barrier->getPosition();
        Point bdir = bp - tp;
        float tblength = bdir.length();
        if (tblength < tank->getContentSize().width / 2 + barrier->getContentSize().width / 2)
        {
            bdir.normalize();
            tank->setPosition(tank->getPosition() - bdir * 150.0f * dt);
            barrel->setPosition(tank->getPosition());
        }
    }
 
    // 트리
    for (int i = 0; i < treenum - 200; i++)
    {
        auto barrier = getChildByTag(i + 200);
        Point tp = tank->getPosition();
        Point bp = barrier->getPosition();
        Point bdir = bp - tp;
        float tblength = bdir.length();
        if (tblength < tank->getContentSize().width / 2 + barrier->getContentSize().height / 2)
        {
            bdir.normalize();
            tank->setPosition(tank->getPosition() - bdir * 150.0f * dt);
            barrel->setPosition(tank->getPosition());
        }
    }
 
    // 드럼
    for (int i = 0; i < drumnum - 300; i++)
    {
        auto barrier = getChildByTag(i + 300);
        Point tp = tank->getPosition();
        Point bp = barrier->getPosition();
        Point bdir = bp - tp;
        float tblength = bdir.length();
        if (tblength < tank->getContentSize().width / 2 + barrier->getContentSize().height / 2)
        {
            bdir.normalize();
            tank->setPosition(tank->getPosition() - bdir * 150.0f * dt);
            barrel->setPosition(tank->getPosition());
        }
    }
}
 
int Barrier::getbrown()
{
    return brownnum;
}
 
int Barrier::getbeige()
{
    return beigenum;
}
 
int Barrier::gettree()
{
    return treenum;
}
 
int Barrier::getdrum()
{
    return drumnum;
}
 
cs

장애물을 노가다로 생성하고(맵 배치), 장애물과 탱크간의 충돌체크를 넣어주었다.


장애물과 충돌 판정은 원 충돌 개념을 이용해 만들었는데 

BoundingBox로 Rect 충돌시 장애물이 회전되면 회전 후의 가장 작은좌표와 큰 좌표 기준으로 박스를 잡아주더라.

즉 위의 사진처럼 장애물이 검은색 네모일때 빨간원만큼의 범위를 잡아준다.

그래서 너무 충돌이 부자연스러워져 장애물의 가로, 세로 중 가장 긴 길이로 원끼리의 충돌을 이용해 충돌처리하였다.

이것도 부자연스럽지만 굉장히 많이 괜찮아진 것 같다.


이후 충돌이 판정되면 탱크가 장애물을 미는 방향의 반대방향으로 탱크를 밀어내어 마치 벽이 있는것처럼 만들었다. 


'프로그래밍 공부 > cocos2d-x' 카테고리의 다른 글

Tank Game 만들기 - 3  (0) 2018.03.28
Tank Game 만들기 - 1  (0) 2018.03.28
Running Game 만들기 - 2  (0) 2018.03.28
Running Game 만들기 - 1  (0) 2018.03.28
기타 잡다한 팁들  (0) 2018.03.28
Posted by misty_
,