2014년 7월 21일 월요일

cocos2d-x 9patch 이미지.

안드로이드처럼 cocos2d도 9patch가 가능하다.

#include "GUI/CCControlExtension/CCControlExtensions.h"
...
using namespace cocos2d::extension;
...

1
2
3
4
5
6
   auto sprite9patch = Scale9Sprite::create(Rect(55, 115, 157, 97),  "TEST/btn9Patch/red.png");
    auto winSize = DK_GET_WINSIZE;
    sprite9patch->setContentSize(Size(winSize.width / 10 * 9,
                                      winSize.height / 10 * 9));
    sprite9patch->setPosition(winSize.width/2, winSize.height/2);
    addChild(sprite9patch);


위와 같이 Scale9Sprite를 쓰면된다.

생성 팩토리 함수의 매개변수는
첫번째 인자로 늘릴 범위의 Rect를 전달하고,
두번째 인자는 늘릴 이미지의 경로를 전달하면 된다.

단순.


C++ lambda는 정말 끝내주는구나.....

리스너나 콜백에 전달할때 정말 편하다.
자바의 이름없는 클래스보다 더 편한것 같다.

어떤 함수에 동작되야할 내용을 주욱 작성하다가, 다 작성하고 나니, 이게 애니메이션 이벤트가 끝내고 실행되야할 내용이란걸 알았다.

그냥 심플하게 람다로 묶어버리고, 함수포인터로 저장한다음에 콜백으로 전달했다.

...ㅎㄷㄷ 진짜 편함.

2014년 7월 18일 금요일

iptime nas I

사놓고나서 지금보니 nas III랑 nas I 이랑 가격이 같네...
뭥미...

ㅋㅋㅋㅋ 이미 늦은듯.

아무래도 꽤 오래전에 가격을 확인하고 그냥 지른거다보니 제대로 확인 안한것 같다.

아무래도 들어간 CPU나 기타등등에 차이가 있지 않을까 생각하는데, 그래도 한가지 마음에 드는건, nas III는 노트북용 하드를 지원하기 때문에 하드교체를 하고 싶거나 여러 상황에서 돈이 좀 더 들어갈 것 같긴 하다.

CPU라거나 메모리 차이가 클 줄 알았는데, 적혀있는 스펙은 둘다 ARM 32bit RISC 칩에 256 L2캐시, 256MB의 메인메모리를 장착하고 있었다.

어제 도착해서 처음 포장을 뜯었을때, 느낌은 좀 묵직하구나란 생각이 들었다.
아무래도 파워서플라이까지 다 들어있는 컴퓨터니깐 그럴만도 할것이다.

초기 세팅은 그렇게 어려운 점은 없지만, ipDisk에서 왠지 삽질을 조금 했다.
ipDisk는 이 제품을 고른 가장 큰 이유인데, 인터넷을 통해서 집에있는 NAS에 접근할 수 있는 서비스를 복잡한 설정없이 비교적 쉽게 제공을 한다.

...방금 이 문장을 쓰던 과정에서 다른 회사제품을 제대로 확인안하게 생각나서 검색을 해보고 땅을 치고 후회중이다. seagate의 센트럴이란 nas는 2TB가 약 15만원. ipTime제품은 1TB 약 15만원...
그리고 seagate역시 인터넷을 통해서 서비스에 접근하는 기능을 제공한다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
낭패다.

뭐 이미 늦었다고 생각한다. 잘 써야지.
apache웹서버와 mysql서버, svn저장소를 지원한다고 하니 개발용으로 잘 활용해줘야겠다.

itunes 서버는 개인적으로 비추다.
아이폰으로 컴퓨터의 itunes서버에 접근하는 것처럼 지원할 줄 알았는데, 아이폰에선 nas의 itunes서버에 접근하지 못한다. 별도의 프로그램을 사용하는 방법으로 접근이 가능하긴 한데, 해당 프로그램의 음악 재생관련 UI가 너무 별로라서 쓰고 싶지 않다.

afp를 지원하기 때문에 맥에서 종종 복사하다가 에러가 나는 파일은 전송프로토콜을 afp로 접근하면 문제 없이 전송이 가능했다.

사용한지 이제 하루라서 더 좋은점, 더 나쁜점들을 다 보진 못헀지만, 대충 총평은 지원되는 기능이 많은 만큼 가격은 비싸다. 만약 파일저장용으로만 쓸거면, seagate제품이 더 저렴하고 필요한 기능은 대부분 있으니 권장하고 싶다.

...제길.

2014년 7월 10일 목요일

cocos2d::LayerColor의 앵커포인트.

 버전마다 다를 수 있지만, 현재 내가 쓰고 있는 Cocos2d-x 3.1에서는 Layer에 AnchorPoint를 적용하면 제대로 적용되지 않는다.

 검색을 해보니 다음과 같은 내용을 찾았다.

http://discuss.cocos2d-x.org/t/set-the-anchor-point-of-cclayer/6084

대충 보니깐 레이어 노드에 ignoreAnchorPointForPosition(false) 함수를 실행시키면 된다고 한다.

해보니 제대로 앵커포인트가 적용된다.

퍼니파우더 1집..

뻥삼이 말고는 딱히 들을만한거 안보이네...
아무래도 나온 시기가 시기이다 보니 랩이라고 있는 부분들이 좀 많이 민망하긴 하다.
카페에서 케잌먹으면서 작업하고 싶다.
날이 더워서 시원한 곳에서 단거 먹고 싶은걸까?

2014년 7월 7일 월요일

SQLite편집도구는 역시..

SQLite Expert가 최고인것 같다.

맥용으로 쓰는 여러툴들이 제대로 안되는 문제가 많은데, 이 툴은 정말이지...

대박.

2014년 7월 4일 금요일

cocos2d-x의 터치 이벤트 리스너의 remove에 대한 생각.

 무언가 자동으로 이뤄지는것을 마냥 믿기도 하지만, 보통 내가 모르는 오류는 꼭 남의 것을 제대로 읽어보지 않고 써서 생기는 문제들이다.(당연한건가?)

 Anyway.

 나는 레이어의 onEnter함수에서 터치이벤트 리스너를 만들고, 레이어의 멤버로 가지고 있다가,
 레이어가 onExit함수를 호출할때, 멤버로 가진 리스너를 지우는 식으로 구현한다.

근데 생각해보니 이벤트리스너를 적용할때, 여러 노드에 같은 이벤트리스너를 적용할때는 복제해서 쓰기 때문에 이런식으로 하면 메모리상에 해제되지 않고 남아있는 리스너가 있을 것이다.

그렇기 때문에 대부분 책의 예제에선 이벤트디스패쳐에서 같은 종류의 이벤트들을 한번에 지워주는 함수를 이용하는가보다.

당연한 것인데 별생각 없이 만들면 종종 이런 짓을 할때가 있다.

2014년 7월 2일 수요일

터치펜 세가지를 써보고 내린 결과.

Jot Script, Jot Pro, 3M 문구점 터치 펜.

위 세가지 펜을 써보고 내린 결론.

Jot Pro가 짱이다.

3M 펜이 3천원
Jot Pro는 약 4~5만원?
Jot Script는 11만원인데,

Jot Script가 가장 구리다.

Jot Script의 스펙은 훌륭하다.
다른 펜들과 달리 그냥 일반 볼펜처럼 생겼고, 블루투스로 아이패드와 연결되서 필기용 앱에선 펜만 터치가 인식되게 해준다. 하지만 정확한 포인팅이 안되고 자꾸 펜을 기울인 방향쪽으로 터치가 쏠린다. 때문에 원하는 글씨를 제대로 쓰려면 연습을 해야하는 우스운 상황이 벌어진다. 일반펜처럼 쓰려고 11만원을 줬지만 사용법을 연습해야하는 우스운 일이 벌어진다. 블루투스를 연결해서 펜만 인식되게 하는 처리는 소프트웨어 적으로 훌륭하게 제공하는 앱들이 이미 많이 있다.(NoteShelf추천)

3M펜은 딱보기엔 불편하다.
끝의 뭉뚝한 고무팁은 내가 쓰고있는 글씨가 가려져서 안보이고, 고무팁을 험하게 쓰면 고무팁 위에 코팅된 비닐이 허옇게 일어나는 경우도 종종있다. 때로는 고무팁이 찢어질 수도 있다. 하지만 가격이 저렴해서 부담이 없으며, 망가진 펜은 볼펜으로도 사용가능하다. 그리고 NoteShelf에 한해서 약간 큰 글씨정도는 확대창을 쓰지 않고 편하게 쓰는것이 가능하다.(...이건 그냥 내가 너무 오래써서 익숙해져서인것 같다.)

Jot Pro는 만족스럽다.
끝에 투명한 디스크가 달려있어서 내가 쓰고 있는 글씨가 펜팁에 의해 가려지지 않고 펜팁이 정확히 뭘 쓰고 있는지 잘 보인다. 친구거를 빌려서 써본거라 내구성은 잘 모르겠지만, 써봤을때, 3M펜을 쓰면서 답답하던게 싹 해소가 된 기분이었다. 친구에게 물어보니 6개월정도 썼는데 아무문제 없다고 한다. 괜찮은 듯.

Jot Script는 NoteShelf가 아닌 Good Note, Penultimate와 같은 앱에선 손목방향을 설정해서 쓰면 내가 쓰고 있는 포인팅을 보정해주는 기능이 있다. 하지만 Penultimate는 필기중 오조작으로 페이지가 넘어가는일이 매우 잦았고, Good Note는 NoteShelf보다 미묘하게 필기감이 별로였다.

이해가 안되는 것.
리뷰중에 종종 Jot Script의 필기감이 짱이라고 하는 리뷰를 보면 도저히 이해가 되지 않는다.
다른거는 개인의 취향이니 하겠는데, 이건 좀.
어쩌면 내가 저가형 고무팁 펜을 너무 오래써서 Jot Script의 장점을 딱히 못느끼는 걸지도 모르겠다.

2014년 6월 28일 토요일

jQuery. json to string

..내가 검색을 잘못하는건가..?
json을 문자열로 바꿔주는 방법을 찾으면 대부분 직접 구현한 함수들이 검색된다.
웹개발을 잘 안해서 모르겠지만, 아무래도 jQuery에 있는 함수가 일부 브라우저에선 제대로 안되기 때문인걸까?
아무튼 내가 찾은건 간단하다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

1
2
3
4
5
6
7
8
9
$(document).ready(function(){
    //alert("HELLO WORLD!");
    $.getJSON('./Json/Furnitures.txt', function(data) {
          var jsonString = JSON.stringify(data);
          $("#jsonResult").append(jsonString);
    });
});

2014년 6월 27일 금요일

타일맵 4방향 경로 탐색 A* 알고리즘.

cocos2d-x용으로 만들었으며, 다음의 블로그의 내용을 참조하였다.
http://blog.daum.net/jty71/15645104

위 두 블로그 다 같은소스가 첨부파일로 올라가있었는데, 내공과 영어실력이 부족하기도 하고,
4방향으로 Cocos2d 타
가급적 객체지향으로 만들어보았는데, 사실 제대로 짠거인지도 잘 모르겠다.

경로탐색의 노드 클래스 - 헤더
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
//
//  DK_PathFindNode.h
//  Marionette
//
//  Created by choi on 2014. 6. 26..
//
//
#ifndef __Marionette__DK_PathFindNode__
#define __Marionette__DK_PathFindNode__
#include "cocos2d.h"
#define _ASTAR_3_G_DIAGONAL 20
#define _ASTAR_3_G_DIRECT 10
class DK_PathFindNode : public cocos2d::Ref
{
public:
    static DK_PathFindNode* create();
    //-------------------------------------------------
    // 나의 포지션(타일 좌표)
    //-------------------------------------------------
    CC_PROPERTY(cocos2d::Point, _targetPos, TileCnt);
    //-------------------------------------------------
    // 출발점에서의 거리.
    //-------------------------------------------------
    CC_PROPERTY(int, _g, G);
    //-------------------------------------------------
    // 도착점에서의 거리.
    //-------------------------------------------------
    CC_PROPERTY(int, _h, H);
    //-------------------------------------------------
    // 경로 선택 비교값.
    //-------------------------------------------------
    int getF();
    //-------------------------------------------------
    // 부모 타일 정보. 탐색이후 경로추적용.
    //-------------------------------------------------
    CC_PROPERTY(DK_PathFindNode*, _parent, Parent);
    //-------------------------------------------------
    // 노드정보 초기화(권장)
    // @parent. 부모노드.
    // @currentTileCnt. 이 노드의 타일좌표.
    // @destiTileCnt. 도착지점.
    //-------------------------------------------------
    void setAll(DK_PathFindNode* parent,
                const cocos2d::Point& currentTileCnt,
                const cocos2d::Point& destiTileCnt);
};
#endif /* defined(__Marionette__DK_PathFindNode__) */

경로탐색의 노드 클래스 - 구현부
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
//
//  DK_PathFindNode.cpp
//  Marionette
//
//  Created by choi on 2014. 6. 26..
//
//
#include "DK_PathFindNode.h"
USING_NS_CC;
DK_PathFindNode* DK_PathFindNode::create()
{
    auto ret = new DK_PathFindNode();
    ret->autorelease();
    return ret;
}
void DK_PathFindNode::setTileCnt(cocos2d::Point var)
{
    _targetPos = var;
}
cocos2d::Point DK_PathFindNode::getTileCnt()
{
    return _targetPos;
}
void DK_PathFindNode::setG(int g)
{
    _g = g;
}
int DK_PathFindNode::getG()
{
    return _g;
}
void DK_PathFindNode::setH(int h)
{
    _h = h;
}
int DK_PathFindNode::getH()
{
    return _h;
}
int DK_PathFindNode::getF()
{
    return _g + _h;
}
void DK_PathFindNode::setParent(DK_PathFindNode *var){
    _parent= var;
}
DK_PathFindNode* DK_PathFindNode::getParent(){
    return _parent;
}
void DK_PathFindNode::setAll(DK_PathFindNode* parent,
                               const cocos2d::Point& currentTileCnt,
                               const cocos2d::Point& destiTileCnt)
{
    //현재 포지션.
    DK_PathFindNode::setTileCnt(currentTileCnt);
    //부모
    setParent(parent);
    
    //출발점에서의 거리. G
    Point parentTileCnt = getParent()->getTileCnt();
    //좌상
    if(parentTileCnt.x - 1 == currentTileCnt.x &&
       parentTileCnt.y - 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIAGONAL);
    }
    //상
    else if(parentTileCnt.x - 0 == currentTileCnt.x &&
            parentTileCnt.y - 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIRECT);
    }
    //우상
    else if(parentTileCnt.x + 1 == currentTileCnt.x &&
            parentTileCnt.y - 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIAGONAL);
    }
    //우
    else if(parentTileCnt.x + 1 == currentTileCnt.x &&
            parentTileCnt.y - 0 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIRECT);
    }
    //우하
    else if(parentTileCnt.x + 1 == currentTileCnt.x &&
            parentTileCnt.y + 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIAGONAL);
    }
    //하
    else if(parentTileCnt.x + 0 == currentTileCnt.x &&
            parentTileCnt.y + 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIRECT);
    }
    //좌하
    else if(parentTileCnt.x - 1 == currentTileCnt.x &&
            parentTileCnt.y + 1 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIAGONAL);
    }
    //좌
    else if(parentTileCnt.x - 1 == currentTileCnt.x &&
            parentTileCnt.y - 0 == currentTileCnt.y)
    {
        setG(parent->getG()+_ASTAR_3_G_DIRECT);
    }
    //동일
    else {
        setG(0);
    }
    
    //도착점에서의 거리. H
    const int START_2_DESTI_DISTANCE_X = destiTileCnt.x - getTileCnt().x;
    const int START_2_DESTI_DISTANCE_Y = destiTileCnt.y - getTileCnt().y;
    const int START_2_DESTI_DISTANCE =
    abs(START_2_DESTI_DISTANCE_X) + abs(START_2_DESTI_DISTANCE_Y);
    setH(START_2_DESTI_DISTANCE * _ASTAR_3_G_DIRECT);
}

경로탐색 클래스 - 헤더
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
//
//  DK_PathFinder.h
//  Marionette
//
//  Created by choi on 2014. 6. 27..
//
//
/*
 4방향 탐색 알고리즘.
 */
#ifndef __Marionette__DK_PathFinder__
#define __Marionette__DK_PathFinder__
#include "cocos2d.h"
#include "DK_PathFindNode.h"
class DK_PathFinder
{
public:
    //--------------------------
    // 생성자.
    // @startTileCnt : 경로 탐색을 시작할 시작지점의 타일좌표.
    // @destiTileCnt : 경로 탐색을 마칠 도착지점의 타일좌표.
    // @onCheckBlock : 타일좌표를 받으면 해당 좌표가 장애물인지, 비 장애물인지 알려줄 콜백함수.
    // @maxLoopCnt : 무한 반복을 막기위한 반복 카운트 (기본값 100)
    //--------------------------
    DK_PathFinder(cocos2d::Point startTileCnt,
                  cocos2d::Point destiTileCnt,
                  std::function<bool(const cocos2d::Point&)> onCheckBlock,
                  int maxLoopCnt = 100);
    //--------------------------
    // 시작지점에서 도착지점까지의 경로를 탐색하여 리턴한다.
    //--------------------------
    std::vector<cocos2d::Point> getPath();
    
private:
    int _maxLoopCnt = 0; //무한반복을 막기위한 반복 카운트
    cocos2d::Point _startPos; //경로 탐색 시작좌표.
    cocos2d::Point _destiPos; //경로 탐색 종료좌표.
    cocos2d::Vector<DK_PathFindNode*> _openList; //경로 탐색에 쓰일 열린 노드.
    cocos2d::Vector<DK_PathFindNode*> _closeList; //이미 관계설정을 마친 닫힌 노드.
    std::function<bool(const cocos2d::Point&)> _onCheckBlock; //장애물여부 콜백.
};
#endif /* defined(__Marionette__DK_PathFinder__) */

경로탐색 클래스 - 구현

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
//
//  DK_PathFinder.cpp
//  Marionette
//
//  Created by choi on 2014. 6. 27..
//
//
 
#include "DK_PathFinder.h"
 
USING_NS_CC;
DK_PathFinder::DK_PathFinder(cocos2d::Point startTileCnt,
              cocos2d::Point destiTileCnt,
              std::function<bool(const cocos2d::Point&)> onCheckBlock,
                             int maxLoopCnt)
{
    _startPos = startTileCnt;
    _destiPos = destiTileCnt;
    _onCheckBlock = onCheckBlock;
    _maxLoopCnt = maxLoopCnt;
}
 
std::vector<cocos2d::Point> DK_PathFinder::getPath()
{
    //현재 노드 만들기
    auto currentNode = DK_PathFindNode::create();
    currentNode->setAll(currentNode, _startPos, _destiPos);
    
    //최초 노드 열기
    _openList.pushBack(currentNode);
 
    //반복
    int loopCnt = 0;
    //--------------------------
    // 현재 노드의 타일이 도착지점 타일이거나,(탐색 성공)
    // 더이상 열린 노드가 없거나, (탐색 실패)
    // 반복횟수가 최대 수치인 경우. (탐색 실패)
    // 탐색을 종료한다.
    //--------------------------
    while (currentNode->getTileCnt() != _destiPos &&
           loopCnt < _maxLoopCnt)
    {
        CCLOG("%d. 현재 노드 f, x, y : %d, %.0f, %.0f", loopCnt,
              currentNode->getF(), currentNode->getTileCnt().x, currentNode->getTileCnt().y);
        //현재 노드 닫기
        _openList.eraseObject(currentNode);
        _closeList.pushBack(currentNode);
        
        //현재 노드의 주변 노드 열기
        cocos2d::Vector<DK_PathFindNode*> neighborNodes;
        for(int i = 0; i < 4; i++){
            //주변 타일 탐색.
            auto currentPos = currentNode->getTileCnt();
            cocos2d::Point neighborPos;
            switch (i) {
                case 0:
                    neighborPos = Point(currentPos.x, currentPos.y+1);
                    break;
                case 1:
                    neighborPos = Point(currentPos.x, currentPos.y-1);
                    break;
                case 2:
                    neighborPos = Point(currentPos.x-1, currentPos.y);
                    break;
                case 3:
                    neighborPos = Point(currentPos.x+1, currentPos.y);
                    break;
            }
            
            //막힘 체크.
            if(_onCheckBlock(neighborPos)){
                continue; //다음 주변 타일 체크.
            }
            //닫힘 체크.
            bool isClosed = false;
            for(auto elementNode : _closeList){
                if(elementNode->getTileCnt() == neighborPos){
                    isClosed = true;
                }
            }
            if(isClosed){
                continue; //다음 주변 타일 체크.
            }
 
            //--------------------------
            // 탐색된 주변타일이 이미 열린 노드 목록에 있는 경우.
            // 탐색된 주변 타일 : A, 이미 열린 노드 B.
            // A가 B보다 출발 지점에서 가까우면(g값이 작으면),
            // 열린 목록에서 B를 제거하고, A를 열린 목록에 추가한다.
            // B가 A보다 출발 지점에서 가까우면(g값이 작으면),
            // A를 열린 목록에 추가하지 않는다.
            //--------------------------
            bool isDontOpen = false;
            for(auto openedNode : _openList){
                if(openedNode->getTileCnt() == neighborPos){
                    DK_PathFindNode* containNode = DK_PathFindNode::create();
                    containNode->setAll(currentNode, neighborPos, _destiPos);
                    
                    //이미 열린 노드가 더 출발지점에서 가까움.
                    if(openedNode->getG() < containNode->getG()){
                        isDontOpen = true;
                    }
                    //새로 발견된 노드가 출발지점에서 더 가깝거나 동일.
                    else {
                        _openList.eraseObject(openedNode);
                    }
                }
            }
            //새로 발견된 타일을 열지 않음.
            if(isDontOpen){
                continue; //다음 주변 타일 체크.
            }
            
            
            DK_PathFindNode* neighborNode = DK_PathFindNode::create();
            neighborNode->setAll(currentNode, neighborPos, _destiPos);
            CCLOG("노드 열림 g, x, y : %d, %.0f, %.0f",
                  neighborNode->getG(), neighborNode->getTileCnt().x, neighborNode->getTileCnt().y);
            neighborNodes.pushBack(neighborNode);
        }
        _openList.pushBack(neighborNodes);
 
        //열린 노드 없음. 탐색 실패(종료)
        if(_openList.size() < 1){
            break;
        }
        //열린 노드에서 가장 작은 F비용을 현재 노드로 선택.
        DK_PathFindNode* lowestF_node = nullptr;;
        for(auto openElement : _openList){
            if (lowestF_node == nullptr) {
                lowestF_node = openElement;
            }
            if (lowestF_node->getF() >= openElement->getF()){
                lowestF_node = openElement;
            }
        }
        CCLOG("선택된 노드 f, x, y : %d, %.0f, %.0f", lowestF_node->getF(), lowestF_node->getTileCnt().x, lowestF_node->getTileCnt().y);
        currentNode = lowestF_node;
        loopCnt++;
    }
    
    std::vector<Point> rstVector;
    //마지막으로 선택된 노드가 종착노드인가?
    if(currentNode->getTileCnt() != _destiPos){
        CCLOG("갈 수 없음.");
        return rstVector;
    }
    
    //마지막에 선택된 노드로부터 부모노드 추적.
    std::vector<Point> tempVector;
    auto node = currentNode;
    CCLOG("탐색된 경로{");
    for (int k = 0;
         currentNode->getParent()->getTileCnt() != currentNode->getTileCnt();
         k++) {
        CCLOG("%d - F : %d / pos : %.0f, %.0f",
              k, node->getF(), node->getTileCnt().x, node->getTileCnt().y);
        tempVector.push_back(node->getTileCnt());
        auto parentNode = node->getParent();
        if(parentNode->getTileCnt() == node->getTileCnt()){
            break;
        }
        node = parentNode;
    }
    CCLOG("}탐색된 경로");
    
    //완성된 배열을 거꾸로 저장.
    for (int k = 0; k < tempVector.size(); k++)
    {
        auto item = tempVector.at(tempVector.size()-k-1);
        rstVector.push_back(item);
    }
    
    return rstVector;
}



END.

리스트