fixed #1377:reset texture parameter of CCTMXLayer after coming to foreground on android

This commit is contained in:
minggo 2012-08-20 14:06:29 +08:00
parent c8808b5be2
commit 738f150ecd
2 changed files with 91 additions and 54 deletions

View File

@ -32,6 +32,8 @@ THE SOFTWARE.
#include "shaders/CCGLProgram.h"
#include "support/CCPointExtension.h"
#include "support/data_support/ccCArray.h"
#include "support/CCNotificationCenter.h"
#include "CCEventType.h"
#include "CCDirector.h"
NS_CC_BEGIN
@ -96,53 +98,76 @@ bool CCTMXLayer::initWithTilesetInfo(CCTMXTilesetInfo *tilesetInfo, CCTMXLayerIn
m_bUseAutomaticVertexZ = false;
m_nVertexZvalue = 0;
// listen the event of "EVNET_COME_TO_FOREGROUND", this event only trigged on android
CCNotificationCenter::sharedNotificationCenter()->addObserver(this,
callfuncO_selector(CCTMXLayer::listenBackToForeground),
EVNET_COME_TO_FOREGROUND,
NULL);
return true;
}
return false;
}
void CCTMXLayer::listenBackToForeground(CCObject *sender)
{
if (m_pobTextureAtlas)
{
m_pobTextureAtlas->getTexture()->setAliasTexParameters();
}
}
CCTMXLayer::CCTMXLayer()
:m_tLayerSize(CCSizeZero)
,m_tMapTileSize(CCSizeZero)
,m_pTiles(NULL)
,m_pTileSet(NULL)
,m_pProperties(NULL)
,m_sLayerName("")
,m_pReusedTile(NULL)
,m_pAtlasIndexArray(NULL)
:m_tLayerSize(CCSizeZero)
,m_tMapTileSize(CCSizeZero)
,m_pTiles(NULL)
,m_pTileSet(NULL)
,m_pProperties(NULL)
,m_sLayerName("")
,m_pReusedTile(NULL)
,m_pAtlasIndexArray(NULL)
{}
CCTMXLayer::~CCTMXLayer()
{
CC_SAFE_RELEASE(m_pTileSet);
CC_SAFE_RELEASE(m_pReusedTile);
CC_SAFE_RELEASE(m_pProperties);
if( m_pAtlasIndexArray )
if (m_pAtlasIndexArray)
{
ccCArrayFree(m_pAtlasIndexArray);
m_pAtlasIndexArray = NULL;
}
CC_SAFE_DELETE_ARRAY(m_pTiles);
CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVNET_COME_TO_FOREGROUND);
}
CCTMXTilesetInfo * CCTMXLayer::getTileSet()
{
return m_pTileSet;
}
void CCTMXLayer::setTileSet(CCTMXTilesetInfo* var)
{
CC_SAFE_RETAIN(var);
CC_SAFE_RELEASE(m_pTileSet);
m_pTileSet = var;
}
void CCTMXLayer::releaseMap()
{
if( m_pTiles )
if (m_pTiles)
{
delete [] m_pTiles;
m_pTiles = NULL;
}
if( m_pAtlasIndexArray )
if (m_pAtlasIndexArray)
{
ccCArrayFree(m_pAtlasIndexArray);
m_pAtlasIndexArray = NULL;
@ -167,9 +192,9 @@ void CCTMXLayer::setupTiles()
// Parse cocos2d properties
this->parseInternalProperties();
for( unsigned int y=0; y < m_tLayerSize.height; y++ )
for (unsigned int y=0; y < m_tLayerSize.height; y++)
{
for( unsigned int x=0; x < m_tLayerSize.width; x++ )
for (unsigned int x=0; x < m_tLayerSize.width; x++)
{
unsigned int pos = (unsigned int)(x + m_tLayerSize.width * y);
unsigned int gid = m_pTiles[ pos ];
@ -181,7 +206,7 @@ void CCTMXLayer::setupTiles()
/* We support little endian.*/
// XXX: gid == 0 --> empty tile
if( gid != 0 )
if (gid != 0)
{
this->appendTileForGID(gid, ccp(x, y));
@ -207,10 +232,10 @@ void CCTMXLayer::parseInternalProperties()
// if cc_vertex=automatic, then tiles will be rendered using vertexz
CCString *vertexz = propertyNamed("cc_vertexz");
if( vertexz )
if (vertexz)
{
// If "automatic" is on, then parse the "cc_alpha_func" too
if( vertexz->m_sString == "automatic" )
if (vertexz->m_sString == "automatic")
{
m_bUseAutomaticVertexZ = true;
CCString *alphaFuncVal = propertyNamed("cc_alpha_func");
@ -292,7 +317,8 @@ void CCTMXLayer::setupTileSprite(CCSprite* sprite, CCPoint pos, unsigned int gid
CCSprite* CCTMXLayer::reusedTileWithRect(CCRect rect)
{
if( ! m_pReusedTile ) {
if (! m_pReusedTile)
{
m_pReusedTile = new CCSprite();
m_pReusedTile->initWithTexture(m_pobTextureAtlas->getTexture(), rect, false);
m_pReusedTile->setBatchNode(this);
@ -314,20 +340,20 @@ CCSprite* CCTMXLayer::reusedTileWithRect(CCRect rect)
// CCTMXLayer - obtaining tiles/gids
CCSprite * CCTMXLayer::tileAt(const CCPoint& pos)
{
CCAssert( pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert( m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCAssert(pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert(m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCSprite *tile = NULL;
unsigned int gid = this->tileGIDAt(pos);
// if GID == 0, then no tile is present
if( gid )
if (gid)
{
int z = (int)(pos.x + pos.y * m_tLayerSize.width);
tile = (CCSprite*) this->getChildByTag(z);
// tile not created yet. create it
if( ! tile )
if (! tile)
{
CCRect rect = m_pTileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
@ -345,6 +371,7 @@ CCSprite * CCTMXLayer::tileAt(const CCPoint& pos)
tile->release();
}
}
return tile;
}
@ -355,8 +382,8 @@ unsigned int CCTMXLayer::tileGIDAt(const CCPoint& pos)
unsigned int CCTMXLayer::tileGIDAt(const CCPoint& pos, ccTMXTileFlags* flags)
{
CCAssert( pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert( m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCAssert(pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert(m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
int idx = (int)(pos.x + pos.y * m_tLayerSize.width);
// Bits on the far end of the 32-bit global tile ID are used for tile flags
@ -367,6 +394,7 @@ unsigned int CCTMXLayer::tileGIDAt(const CCPoint& pos, ccTMXTileFlags* flags)
{
*flags = (ccTMXTileFlags)(tile & kCCFlipedAll);
}
return (tile & kCCFlippedMask);
}
@ -414,7 +442,7 @@ CCSprite * CCTMXLayer::insertTileForGID(unsigned int gid, const CCPoint& pos)
CCSprite * CCTMXLayer::updateTileForGID(unsigned int gid, const CCPoint& pos)
{
CCRect rect = m_pTileSet->rectForGID(gid);
rect = CCRectMake(rect.origin.x / m_fContentScaleFactor, rect.origin.y / m_fContentScaleFactor, rect.size.width/ m_fContentScaleFactor, rect.size.height/ m_fContentScaleFactor);
rect = CCRectMake(rect.origin.x / m_fContentScaleFactor, rect.origin.y / m_fContentScaleFactor, rect.size.width/ m_fContentScaleFactor, rect.size.height/ m_fContentScaleFactor);
int z = (int)(pos.x + pos.y * m_tLayerSize.width);
CCSprite *tile = reusedTileWithRect(rect);
@ -461,14 +489,14 @@ CCSprite * CCTMXLayer::appendTileForGID(unsigned int gid, const CCPoint& pos)
// CCTMXLayer - atlasIndex and Z
static inline int compareInts(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
return ((*(int*)a) - (*(int*)b));
}
unsigned int CCTMXLayer::atlasIndexForExistantZ(unsigned int z)
{
int key=z;
int *item = (int*)bsearch((void*)&key, (void*)&m_pAtlasIndexArray->arr[0], m_pAtlasIndexArray->num, sizeof(void*), compareInts);
CCAssert( item, "TMX atlas index not found. Shall not happen");
CCAssert(item, "TMX atlas index not found. Shall not happen");
int index = ((size_t)item - (size_t)m_pAtlasIndexArray->arr) / sizeof(void*);
return index;
@ -477,12 +505,15 @@ unsigned int CCTMXLayer::atlasIndexForNewZ(int z)
{
// XXX: This can be improved with a sort of binary search
unsigned int i=0;
for( i=0; i< m_pAtlasIndexArray->num ; i++)
for (i=0; i< m_pAtlasIndexArray->num ; i++)
{
int val = (size_t) m_pAtlasIndexArray->arr[i];
if( z < val )
if (z < val)
{
break;
}
}
}
return i;
}
@ -494,35 +525,33 @@ void CCTMXLayer::setTileGID(unsigned int gid, const CCPoint& pos)
void CCTMXLayer::setTileGID(unsigned int gid, const CCPoint& pos, ccTMXTileFlags flags)
{
CCAssert( pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert( m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCAssert( gid == 0 || gid >= m_pTileSet->m_uFirstGid, "TMXLayer: invalid gid" );
CCAssert(pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert(m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCAssert(gid == 0 || gid >= m_pTileSet->m_uFirstGid, "TMXLayer: invalid gid" );
ccTMXTileFlags currentFlags;
unsigned int currentGID = tileGIDAt(pos, &currentFlags);
if( currentGID != gid || currentFlags != flags )
if (currentGID != gid || currentFlags != flags)
{
unsigned gidAndFlags = gid | flags;
// setting gid=0 is equal to remove the tile
if( gid == 0 )
if (gid == 0)
{
removeTileAt(pos);
}
// empty tile. create a new one
else if( currentGID == 0 )
else if (currentGID == 0)
{
insertTileForGID(gidAndFlags, pos);
}
// modifying an existing tile with a non-empty tile
else
{
unsigned int z = (unsigned int)(pos.x + pos.y * m_tLayerSize.width);
CCSprite *sprite = (CCSprite*)getChildByTag(z);
if( sprite )
if (sprite)
{
CCRect rect = m_pTileSet->rectForGID(gid);
rect = CC_RECT_PIXELS_TO_POINTS(rect);
@ -552,25 +581,27 @@ void CCTMXLayer::removeChild(CCNode* node, bool cleanup)
{
CCSprite *sprite = (CCSprite*)node;
// allows removing nil objects
if( ! sprite )
if (! sprite)
{
return;
}
CCAssert( m_pChildren->containsObject(sprite), "Tile does not belong to TMXLayer");
CCAssert(m_pChildren->containsObject(sprite), "Tile does not belong to TMXLayer");
unsigned int atlasIndex = sprite->getAtlasIndex();
unsigned int zz = (size_t) m_pAtlasIndexArray->arr[atlasIndex];
unsigned int zz = (size_t)m_pAtlasIndexArray->arr[atlasIndex];
m_pTiles[zz] = 0;
ccCArrayRemoveValueAtIndex(m_pAtlasIndexArray, atlasIndex);
CCSpriteBatchNode::removeChild(sprite, cleanup);
}
void CCTMXLayer::removeTileAt(const CCPoint& pos)
{
CCAssert( pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert( m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
CCAssert(pos.x < m_tLayerSize.width && pos.y < m_tLayerSize.height && pos.x >=0 && pos.y >=0, "TMXLayer: invalid position");
CCAssert(m_pTiles && m_pAtlasIndexArray, "TMXLayer: the tiles map has been released");
unsigned int gid = tileGIDAt(pos);
if( gid )
if (gid)
{
unsigned int z = (unsigned int)(pos.x + pos.y * m_tLayerSize.width);
unsigned int atlasIndex = atlasIndexForExistantZ(z);
@ -583,7 +614,7 @@ void CCTMXLayer::removeTileAt(const CCPoint& pos)
// remove it from sprites and/or texture atlas
CCSprite *sprite = (CCSprite*)getChildByTag(z);
if( sprite )
if (sprite)
{
CCSpriteBatchNode::removeChild(sprite, true);
}
@ -616,14 +647,14 @@ void CCTMXLayer::removeTileAt(const CCPoint& pos)
CCPoint CCTMXLayer::calculateLayerOffset(const CCPoint& pos)
{
CCPoint ret = CCPointZero;
switch( m_uLayerOrientation )
switch (m_uLayerOrientation)
{
case CCTMXOrientationOrtho:
ret = ccp( pos.x * m_tMapTileSize.width, -pos.y *m_tMapTileSize.height);
break;
case CCTMXOrientationIso:
ret = ccp( (m_tMapTileSize.width /2) * (pos.x - pos.y),
(m_tMapTileSize.height /2 ) * (-pos.x - pos.y) );
ret = ccp((m_tMapTileSize.width /2) * (pos.x - pos.y),
(m_tMapTileSize.height /2 ) * (-pos.x - pos.y));
break;
case CCTMXOrientationHex:
CCAssert(pos.equals(CCPointZero), "offset for hexagonal map not implemented yet");
@ -634,7 +665,7 @@ CCPoint CCTMXLayer::calculateLayerOffset(const CCPoint& pos)
CCPoint CCTMXLayer::positionAt(const CCPoint& pos)
{
CCPoint ret = CCPointZero;
switch( m_uLayerOrientation )
switch (m_uLayerOrientation)
{
case CCTMXOrientationOrtho:
ret = positionForOrthoAt(pos);
@ -657,14 +688,14 @@ CCPoint CCTMXLayer::positionForOrthoAt(const CCPoint& pos)
}
CCPoint CCTMXLayer::positionForIsoAt(const CCPoint& pos)
{
CCPoint xy = CCPointMake(m_tMapTileSize.width /2 * ( m_tLayerSize.width + pos.x - pos.y - 1),
m_tMapTileSize.height /2 * (( m_tLayerSize.height * 2 - pos.x - pos.y) - 2));
CCPoint xy = CCPointMake(m_tMapTileSize.width /2 * (m_tLayerSize.width + pos.x - pos.y - 1),
m_tMapTileSize.height /2 * ((m_tLayerSize.height * 2 - pos.x - pos.y) - 2));
return xy;
}
CCPoint CCTMXLayer::positionForHexAt(const CCPoint& pos)
{
float diffY = 0;
if( (int)pos.x % 2 == 1 )
if ((int)pos.x % 2 == 1)
{
diffY = -m_tMapTileSize.height/2 ;
}
@ -677,9 +708,9 @@ int CCTMXLayer::vertexZForPos(const CCPoint& pos)
{
int ret = 0;
unsigned int maxVal = 0;
if( m_bUseAutomaticVertexZ )
if (m_bUseAutomaticVertexZ)
{
switch( m_uLayerOrientation )
switch (m_uLayerOrientation)
{
case CCTMXOrientationIso:
maxVal = (unsigned int)(m_tLayerSize.width + m_tLayerSize.height);
@ -700,6 +731,7 @@ int CCTMXLayer::vertexZForPos(const CCPoint& pos)
{
ret = m_nVertexZvalue;
}
return ret;
}

View File

@ -158,6 +158,11 @@ public:
virtual void addChild(CCNode * child, int zOrder, int tag);
// super method
void removeChild(CCNode* child, bool cleanup);
/** listen the event to invoke CCTexture2D::setAliasTexParameters() after
comming to foreground on android
*/
void listenBackToForeground(CCObject *sender);
inline const char* getLayerName(){ return m_sLayerName.c_str(); }
inline void setLayerName(const char *layerName){ m_sLayerName = layerName; }