这个错误发生在我使用tiledmap的时候,其中,tiledmap里面编辑好的地图在同一个层(layer)使用了多个图块。
加载地图时弹出断言失败窗口,跟踪进去发现崩毁地点:
CCAssert( m_uMaxGID >= m_pTileSet->m_uFirstGid && m_uMinGID >= m_pTileSet->m_uFirstGid, "TMX: Only 1 tileset per layer is supported");
解决办法:(一)将多个图块绘制在同一个图块上使用。 (二)放弃其他图块,使用专一图块。
我们用tileGIDAt获取某一层上的某一格对应的图块ID,GID是什么呢?可以理解为全局唯一ID,而我们的图块集合可能会有多个,所以每个的图块的ID不是从该图块集合1,2,3…这样的,而是紧接着上一个图块集合的最后一个ID顺序下来的!
所以我们要获得正确的ID,应该:
cocos2d::CCTMXLayer *towerLayer = map->layerNamed("tower"); cocos2d::CCTMXTilesetInfo *towerSet = towerLayer->getTileSet(); int nGid = towerLayer->tileGIDAt(ccp(0, 0)) - towerSet->m_uFirstGid; if(nGid >= 0) { }
先获取这一层对应的图块集合的首ID,然后相减就获得了正确的ID.
解决参考:http://blog.csdn.net/crane406/article/details/16825125
如果是ios平台,要在 AppController.mm 中加入
//开启多点触控.. 默认是关闭的。
[__glView setMultipleTouchEnabled:YES];
如果是android就不用,因为默认是开启的...
因为这个问题曾经浪费了我大把时间。 mark!
报错原因:
removeFood( nowFood ); girlItemArr->addObject(nowFood);
其中,removeFood实现如下:
//移除食物 void PickScene::removeFood( CCSprite *food_ ) { food_->removeFromParentAndCleanup(true); foodArr->removeObject(food_); }
解决办法: removeFood 和 addObject这两条语句调换个顺序就可以了。
下面科普下cocos2d-x 的内存管理机制:
cocos2dx 采用引用计数管理自己的内存:
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
|
class
CC_DLL Object
{
public
:
/// object id, ScriptSupport need public _ID
unsigned
int
_ID;
/// Lua reference id
int
_luaID;
protected
:
/// count of references
unsigned
int
_reference;
/// count of autorelease
unsigned
int
_autoReleaseCount;
public
:
/**
* Constructor
*
* The object's reference count is 1 after construction.
* @js NA
*/
Object();
/**
* @js NA
* @lua NA
*/
virtual ~Object();
/**
* Release the ownership immediately.
*
* This decrements the object's reference count.
*
* If the reference count reaches 0 after the descrement, this object is
* destructed.
*
* @see retain, autorelease
* @js NA
*/
inline
void
release()
{
CCASSERT(_reference >
0
,
"reference count should greater than 0"
);
--_reference;
if
(_reference ==
0
)
delete
this
;
}
/**
* Retains the ownership.
*
* This increases the object's reference count.
*
* @see release, autorelease
* @js NA
*/
inline
void
retain()
{
CCASSERT(_reference >
0
,
"reference count should greater than 0"
);
++_reference;
}
/**
* Release the ownership sometime soon automatically.
*
* This descrements the object's reference count at the end of current
* autorelease pool block.
*
* If the reference count reaches 0 after the descrement, this object is
* destructed.
*
* @returns The object itself.
*
* @see AutoreleasePool, retain, release
* @js NA
* @lua NA
*/
Object* autorelease();
/**
* Returns a boolean value that indicates whether there is only one
* reference to the object. That is, whether the reference count is 1.
*
* @returns Whether the object's reference count is 1.
* @js NA
*/
bool isSingleReference()
const
;
/**
* Returns the object's current reference count.
*
* @returns The object's reference count.
* @js NA
*/
unsigned
int
retainCount()
const
;
/**
* Returns a boolean value that indicates whether this object and a given
* object are equal.
*
* @param object The object to be compared to this object.
*
* @returns True if this object and @p object are equal, otherwise false.
* @js NA
* @lua NA
*/
virtual bool isEqual(
const
Object* object);
/**
* @js NA
* @lua NA
*/
virtual
void
acceptVisitor(DataVisitor &visitor);
/**
* @js NA
* @lua NA
*/
virtual
void
update(
float
dt) {CC_UNUSED_PARAM(dt);};
friend
class
AutoreleasePool;
};
|
1
2
3
4
5
6
7
8
9
|
auto sprite1 =
new
Sprite();
sprite1->initWithSpriteFrameName(
"btn_adventure_normal_CN.png"
);
//引用计数器+1
CCLOG(
"retaincount = %d"
,sprite1->retainCount());
sprite1->retain();
//引用计数器+1
CCLOG(
"retaincount = %d"
,sprite1->retainCount());
sprite1->release();
//引用计数器-1
CCLOG(
"retaincount = %d"
,sprite1->retainCount());
sprite1->autorelease();
//只是把该sprite放入自动释放池中。引用计数器不变。等待管理器自动释放
CCLOG(
"retaincount = %d"
,sprite1->retainCount());
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#define CC_SYNTHESIZE_RETAIN(varType, varName, funName) \
private
: varType varName; \
public
: virtual varType get##funName(
void
)
const
{
return
varName; } \
public
: virtual
void
set##funName(varType var) \
{ \
if
(varName != var) \
{ \
CC_SAFE_RETAIN(var); \
CC_SAFE_RELEASE(varName); \
varName = var; \
} \
}
#define CC_SAFE_DELETE(p)
do
{ delete (p); (p) = nullptr; }
while
(
0
)
#define CC_SAFE_DELETE_ARRAY(p)
do
{
if
(p) { delete[] (p); (p) = nullptr; } }
while
(
0
)
#define CC_SAFE_FREE(p)
do
{
if
(p) { free(p); (p) = nullptr; } }
while
(
0
)
#define CC_SAFE_RELEASE(p)
do
{
if
(p) { (p)->release(); } }
while
(
0
)
#define CC_SAFE_RELEASE_NULL(p)
do
{
if
(p) { (p)->release(); (p) = nullptr; } }
while
(
0
)
#define CC_SAFE_RETAIN(p)
do
{
if
(p) { (p)->retain(); } }
while
(
0
)
|
学习的路上,与君共勉。