mirror of https://github.com/axmolengine/axmol.git
issue #4437: add new tmx.
This commit is contained in:
parent
bd00e17190
commit
a8a5f6b230
|
@ -1775,6 +1775,14 @@
|
|||
B3AF01A31842FBA400A98B85 /* b2MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */; };
|
||||
B3B12A5A17E7F44000026B4A /* libchipmunk Mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A03F2CB81780BD04006731B9 /* libchipmunk Mac.a */; };
|
||||
B3B12A5B17E7F45C00026B4A /* libchipmunk iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A07A4F3B178387670073F6A7 /* libchipmunk iOS.a */; };
|
||||
C0940CAC19419BDA00B8BB48 /* CCTMXLayer2.h in Headers */ = {isa = PBXBuildFile; fileRef = C0940CA819419BDA00B8BB48 /* CCTMXLayer2.h */; };
|
||||
C0940CAD19419BDA00B8BB48 /* CCTMXLayer2.h in Headers */ = {isa = PBXBuildFile; fileRef = C0940CA819419BDA00B8BB48 /* CCTMXLayer2.h */; };
|
||||
C0940CAE19419BDA00B8BB48 /* CCTMXTiledMap2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0940CA919419BDA00B8BB48 /* CCTMXTiledMap2.cpp */; };
|
||||
C0940CAF19419BDA00B8BB48 /* CCTMXTiledMap2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0940CA919419BDA00B8BB48 /* CCTMXTiledMap2.cpp */; };
|
||||
C0940CB019419BDA00B8BB48 /* CCTMXTiledMap2.h in Headers */ = {isa = PBXBuildFile; fileRef = C0940CAA19419BDA00B8BB48 /* CCTMXTiledMap2.h */; };
|
||||
C0940CB119419BDA00B8BB48 /* CCTMXTiledMap2.h in Headers */ = {isa = PBXBuildFile; fileRef = C0940CAA19419BDA00B8BB48 /* CCTMXTiledMap2.h */; };
|
||||
C0940CB219419BDA00B8BB48 /* CCTMXLayer2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0940CAB19419BDA00B8BB48 /* CCTMXLayer2.cpp */; };
|
||||
C0940CB319419BDA00B8BB48 /* CCTMXLayer2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0940CAB19419BDA00B8BB48 /* CCTMXLayer2.cpp */; };
|
||||
ED9C6A9418599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
|
||||
ED9C6A9518599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
|
||||
ED9C6A9618599AD8000A5232 /* CCNodeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */; };
|
||||
|
@ -2810,6 +2818,10 @@
|
|||
B375104F1823AC7B00B3BA6A /* CCPhysicsWorldInfo_chipmunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPhysicsWorldInfo_chipmunk.h; sourceTree = "<group>"; };
|
||||
B3AF019E1842FBA400A98B85 /* b2MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MotorJoint.cpp; sourceTree = "<group>"; };
|
||||
B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = "<group>"; };
|
||||
C0940CA819419BDA00B8BB48 /* CCTMXLayer2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTMXLayer2.h; sourceTree = "<group>"; };
|
||||
C0940CA919419BDA00B8BB48 /* CCTMXTiledMap2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTMXTiledMap2.cpp; sourceTree = "<group>"; };
|
||||
C0940CAA19419BDA00B8BB48 /* CCTMXTiledMap2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTMXTiledMap2.h; sourceTree = "<group>"; };
|
||||
C0940CAB19419BDA00B8BB48 /* CCTMXLayer2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCTMXLayer2.cpp; sourceTree = "<group>"; };
|
||||
ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CCNodeGrid.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||
ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCNodeGrid.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
@ -3307,6 +3319,10 @@
|
|||
1A5702DF180BCE610088DEC7 /* tilemap-parallax-nodes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C0940CA819419BDA00B8BB48 /* CCTMXLayer2.h */,
|
||||
C0940CAB19419BDA00B8BB48 /* CCTMXLayer2.cpp */,
|
||||
C0940CA919419BDA00B8BB48 /* CCTMXTiledMap2.cpp */,
|
||||
C0940CAA19419BDA00B8BB48 /* CCTMXTiledMap2.h */,
|
||||
1A5702FE180BCE890088DEC7 /* CCParallaxNode.cpp */,
|
||||
1A5702FF180BCE890088DEC7 /* CCParallaxNode.h */,
|
||||
1A5702E0180BCE750088DEC7 /* CCTileMapAtlas.cpp */,
|
||||
|
@ -4998,6 +5014,7 @@
|
|||
50ABBED51925AB6F00A911A9 /* utlist.h in Headers */,
|
||||
50FCEBAD18C72017004AD434 /* PageViewReader.h in Headers */,
|
||||
1A5702F4180BCE750088DEC7 /* CCTMXObjectGroup.h in Headers */,
|
||||
C0940CB019419BDA00B8BB48 /* CCTMXTiledMap2.h in Headers */,
|
||||
50ABBDAF1925AB4100A911A9 /* CCRenderer.h in Headers */,
|
||||
1A5702F8180BCE750088DEC7 /* CCTMXTiledMap.h in Headers */,
|
||||
5034CA21191D591100CE6051 /* ccShader_PositionTextureColorAlphaTest.frag in Headers */,
|
||||
|
@ -5114,6 +5131,7 @@
|
|||
1AAF536C180E3374000584C8 /* HttpClient.h in Headers */,
|
||||
50ABBD9D1925AB4100A911A9 /* ccGLStateCache.h in Headers */,
|
||||
50ABBEB91925AB6F00A911A9 /* ccUTF8.h in Headers */,
|
||||
C0940CAC19419BDA00B8BB48 /* CCTMXLayer2.h in Headers */,
|
||||
1AAF536E180E3374000584C8 /* HttpRequest.h in Headers */,
|
||||
29CB8F551929D7A900C841D6 /* UIScrollInterface.h in Headers */,
|
||||
1AAF5370180E3374000584C8 /* HttpResponse.h in Headers */,
|
||||
|
@ -5467,6 +5485,7 @@
|
|||
1A570230180BCC1A0088DEC7 /* CCParticleSystemQuad.h in Headers */,
|
||||
5034CA2C191D591100CE6051 /* ccShader_PositionTextureA8Color.vert in Headers */,
|
||||
50ABBE981925AB6F00A911A9 /* CCProtocols.h in Headers */,
|
||||
C0940CB119419BDA00B8BB48 /* CCTMXTiledMap2.h in Headers */,
|
||||
2905FA8B18CF08D100240AA3 /* UITextField.h in Headers */,
|
||||
50FCEBA618C72017004AD434 /* ListViewReader.h in Headers */,
|
||||
50ABBD431925AB0000A911A9 /* CCMathBase.h in Headers */,
|
||||
|
@ -5478,6 +5497,7 @@
|
|||
50ABBE701925AB6F00A911A9 /* CCEventListenerKeyboard.h in Headers */,
|
||||
1A57028D180BCC900088DEC7 /* CCSpriteFrameCache.h in Headers */,
|
||||
1A570295180BCCAB0088DEC7 /* CCAnimation.h in Headers */,
|
||||
C0940CAD19419BDA00B8BB48 /* CCTMXLayer2.h in Headers */,
|
||||
50ABBDB81925AB4100A911A9 /* CCTexture2D.h in Headers */,
|
||||
50ABBE341925AB6F00A911A9 /* CCConfiguration.h in Headers */,
|
||||
1A570299180BCCAB0088DEC7 /* CCAnimationCache.h in Headers */,
|
||||
|
@ -6121,6 +6141,7 @@
|
|||
50ABBD831925AB4100A911A9 /* CCBatchCommand.cpp in Sources */,
|
||||
1A5701C7180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */,
|
||||
1A5701CB180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */,
|
||||
C0940CAE19419BDA00B8BB48 /* CCTMXTiledMap2.cpp in Sources */,
|
||||
50ABBE711925AB6F00A911A9 /* CCEventListenerMouse.cpp in Sources */,
|
||||
1A5701DE180BCB8C0088DEC7 /* CCLayer.cpp in Sources */,
|
||||
1A5701E2180BCB8C0088DEC7 /* CCScene.cpp in Sources */,
|
||||
|
@ -6208,6 +6229,7 @@
|
|||
1AD71DE5180E26E600808F54 /* CCMenuItemImageLoader.cpp in Sources */,
|
||||
50ABBD8B1925AB4100A911A9 /* CCGLProgram.cpp in Sources */,
|
||||
1AD71DE9180E26E600808F54 /* CCMenuItemLoader.cpp in Sources */,
|
||||
C0940CB219419BDA00B8BB48 /* CCTMXLayer2.cpp in Sources */,
|
||||
50ABBDA31925AB4100A911A9 /* CCQuadCommand.cpp in Sources */,
|
||||
2905FA6A18CF08D100240AA3 /* UIPageView.cpp in Sources */,
|
||||
B29594C61926D61F003EEF37 /* CCObjLoader.cpp in Sources */,
|
||||
|
@ -6550,6 +6572,7 @@
|
|||
503DD8E21926736A00CD74DD /* CCCommon.mm in Sources */,
|
||||
1A5701A2180BCB590088DEC7 /* CCFontAtlas.cpp in Sources */,
|
||||
50ABC00E1926664800A911A9 /* CCFileUtils.cpp in Sources */,
|
||||
C0940CB319419BDA00B8BB48 /* CCTMXLayer2.cpp in Sources */,
|
||||
50ABBE241925AB6F00A911A9 /* base64.cpp in Sources */,
|
||||
1A5701A6180BCB590088DEC7 /* CCFontAtlasCache.cpp in Sources */,
|
||||
1A5701B2180BCB590088DEC7 /* CCFontFNT.cpp in Sources */,
|
||||
|
@ -6733,6 +6756,7 @@
|
|||
50ABC0001926664800A911A9 /* CCFileUtilsApple.mm in Sources */,
|
||||
2905FA7918CF08D100240AA3 /* UISlider.cpp in Sources */,
|
||||
1A8C59A4180E930E00EF57C3 /* CCArmatureAnimation.cpp in Sources */,
|
||||
C0940CAF19419BDA00B8BB48 /* CCTMXTiledMap2.cpp in Sources */,
|
||||
1A8C59A8180E930E00EF57C3 /* CCArmatureDataManager.cpp in Sources */,
|
||||
2905FA8918CF08D100240AA3 /* UITextField.cpp in Sources */,
|
||||
1A8C59AC180E930E00EF57C3 /* CCArmatureDefine.cpp in Sources */,
|
||||
|
|
|
@ -0,0 +1,805 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
Copyright (c) 2011 HKASoftware
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Original rewrite of TMXLayer was based on HKTMXTiledMap by HKASoftware http://hkasoftware.com
|
||||
Further info: http://www.cocos2d-iphone.org/forums/topic/hktmxtiledmap/
|
||||
|
||||
It was rewritten again, and only a small part of the original HK ideas/code remains in this implementation
|
||||
|
||||
*/
|
||||
#include "CCTMXLayer2.h"
|
||||
#include "CCTMXXMLParser.h"
|
||||
#include "CCTMXTiledMap.h"
|
||||
#include "CCSprite.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCGLProgramCache.h"
|
||||
#include "CCGLProgram.h"
|
||||
#include "ccCArray.h"
|
||||
#include "CCDirector.h"
|
||||
#include "CCConfiguration.h"
|
||||
#include "renderer/CCRenderer.h"
|
||||
#include "deprecated/CCString.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
static const int MAX_QUADS_COUNT = 65536 / 6;
|
||||
}
|
||||
|
||||
// TMXLayer2 - init & alloc & dealloc
|
||||
|
||||
TMXLayer2 * TMXLayer2::create(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
TMXLayer2 *ret = new TMXLayer2();
|
||||
if (ret->initWithTilesetInfo(tilesetInfo, layerInfo, mapInfo))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool TMXLayer2::initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
|
||||
if( tilesetInfo )
|
||||
{
|
||||
_texture = Director::getInstance()->getTextureCache()->addImage(tilesetInfo->_sourceImage);
|
||||
_texture->retain();
|
||||
}
|
||||
|
||||
// layerInfo
|
||||
_layerName = layerInfo->_name;
|
||||
_layerSize = layerInfo->_layerSize;
|
||||
_tiles = layerInfo->_tiles;
|
||||
setOpacity( layerInfo->_opacity );
|
||||
setProperties(layerInfo->getProperties());
|
||||
|
||||
// tilesetInfo
|
||||
_tileSet = tilesetInfo;
|
||||
CC_SAFE_RETAIN(_tileSet);
|
||||
|
||||
// mapInfo
|
||||
_mapTileSize = mapInfo->getTileSize();
|
||||
_layerOrientation = mapInfo->getOrientation();
|
||||
|
||||
// offset (after layer orientation is set);
|
||||
Point offset = this->calculateLayerOffset(layerInfo->_offset);
|
||||
this->setPosition(CC_POINT_PIXELS_TO_POINTS(offset));
|
||||
|
||||
this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(Size(_layerSize.width * _mapTileSize.width, _layerSize.height * _mapTileSize.height)));
|
||||
|
||||
this->tileToNodeTransform();
|
||||
|
||||
// shader, and other stuff
|
||||
setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
|
||||
|
||||
_useAutomaticVertexZ = false;
|
||||
_vertexZvalue = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TMXLayer2::TMXLayer2()
|
||||
:_layerName("")
|
||||
,_layerSize(Size::ZERO)
|
||||
,_mapTileSize(Size::ZERO)
|
||||
,_tiles(nullptr)
|
||||
,_tileSet(nullptr)
|
||||
,_layerOrientation(TMXOrientationOrtho)
|
||||
,_texture(nullptr)
|
||||
,_reusedTile(nullptr)
|
||||
,_previousRect(0,0,0,0)
|
||||
,_verticesToDraw(0)
|
||||
,_vertexZvalue(0)
|
||||
,_useAutomaticVertexZ(false)
|
||||
,_quads(nullptr)
|
||||
,_indices(nullptr)
|
||||
,_numQuads(0)
|
||||
{}
|
||||
|
||||
TMXLayer2::~TMXLayer2()
|
||||
{
|
||||
CC_SAFE_RELEASE(_tileSet);
|
||||
CC_SAFE_RELEASE(_texture);
|
||||
CC_SAFE_DELETE_ARRAY(_tiles);
|
||||
CC_SAFE_FREE(_quads);
|
||||
CC_SAFE_FREE(_indices);
|
||||
}
|
||||
|
||||
void TMXLayer2::draw(Renderer *renderer, const Mat4& transform, uint32_t flags)
|
||||
{
|
||||
_customCommand.init(_globalZOrder);
|
||||
_customCommand.func = CC_CALLBACK_0(TMXLayer2::onDraw, this, transform, flags);
|
||||
renderer->addCommand(&_customCommand);
|
||||
}
|
||||
|
||||
void TMXLayer2::onDraw(const Mat4 &transform, bool transformUpdated)
|
||||
{
|
||||
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_TEX_COORD);
|
||||
GL::bindTexture2D( _texture->getName() );
|
||||
|
||||
|
||||
// tex coords + indices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
|
||||
|
||||
|
||||
if( transformUpdated ) {
|
||||
|
||||
Size s = Director::getInstance()->getWinSize();
|
||||
auto rect = Rect(0, 0, s.width, s.height);
|
||||
|
||||
Mat4 inv = transform;
|
||||
inv.inverse();
|
||||
rect = RectApplyTransform(rect, inv);
|
||||
|
||||
if( !rect.equals(_previousRect) )
|
||||
{
|
||||
if (Configuration::getInstance()->supportsShareableVAO())
|
||||
{
|
||||
V2F_T2F_Quad* quads = (V2F_T2F_Quad*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
GLushort* indices = (GLushort *)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
_verticesToDraw = updateTiles(rect, quads, indices);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
else
|
||||
{
|
||||
_verticesToDraw = updateTiles(rect, nullptr, nullptr);
|
||||
|
||||
if (_quads != nullptr && _indices != nullptr && _verticesToDraw > 0)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0]) * _numQuads , _quads, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices[0]) * _numQuads * 6 , _indices, GL_STATIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
_previousRect = rect;
|
||||
}
|
||||
|
||||
// don't draw more than 65535 vertices since we are using GL_UNSIGNED_SHORT for indices
|
||||
_verticesToDraw = std::min(_verticesToDraw, 65535);
|
||||
}
|
||||
|
||||
if(_verticesToDraw > 0) {
|
||||
|
||||
getGLProgram()->use();
|
||||
getGLProgram()->setUniformsForBuiltins(_modelViewTransform);
|
||||
|
||||
// vertices
|
||||
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_T2F), (GLvoid*) offsetof(V2F_T2F, vertices));
|
||||
|
||||
// tex coords
|
||||
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, sizeof(V2F_T2F), (GLvoid*) offsetof(V2F_T2F, texCoords));
|
||||
|
||||
// color
|
||||
glVertexAttrib4f(GLProgram::VERTEX_ATTRIB_COLOR, _displayedColor.r/255.0f, _displayedColor.g/255.0f, _displayedColor.b/255.0f, _displayedOpacity/255.0f);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, _verticesToDraw, GL_UNSIGNED_SHORT, nullptr);
|
||||
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,_verticesToDraw);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
int TMXLayer2::updateTiles(const Rect& culledRect, V2F_T2F_Quad *quads, GLushort *indices)
|
||||
{
|
||||
int tilesUsed = 0;
|
||||
|
||||
Rect visibleTiles = culledRect;
|
||||
Size mapTileSize = CC_SIZE_PIXELS_TO_POINTS(_mapTileSize);
|
||||
Size tileSize = CC_SIZE_PIXELS_TO_POINTS(_tileSet->_tileSize);
|
||||
Mat4 nodeToTile = _tileToNodeTransform;
|
||||
nodeToTile.inverse();
|
||||
//transform to tile
|
||||
visibleTiles = RectApplyTransform(visibleTiles, nodeToTile);
|
||||
|
||||
visibleTiles.origin.x = floor(visibleTiles.origin.x);
|
||||
visibleTiles.origin.y = floor(visibleTiles.origin.y);
|
||||
visibleTiles.size.width = ceil(visibleTiles.size.width);
|
||||
visibleTiles.size.height = ceil(visibleTiles.size.height);
|
||||
|
||||
V2F_T2F_Quad* quadsTmp = quads;
|
||||
GLushort* indicesTmp = indices;
|
||||
// doesn't support VBO
|
||||
if (quadsTmp == nullptr)
|
||||
{
|
||||
int quadsNeed = std::min(static_cast<int>((visibleTiles.size.width + 1) * (visibleTiles.size.height + 1)), MAX_QUADS_COUNT);
|
||||
if (_numQuads < quadsNeed)
|
||||
{
|
||||
_numQuads = quadsNeed;
|
||||
_quads = (V2F_T2F_Quad*)realloc(_quads, _numQuads * sizeof(V2F_T2F_Quad));
|
||||
_indices = (GLushort*)realloc(_indices, _numQuads * 6 * sizeof(GLushort));
|
||||
}
|
||||
|
||||
quadsTmp = _quads;
|
||||
indicesTmp = _indices;
|
||||
}
|
||||
|
||||
int rows_per_tile = ceil(tileSize.height / mapTileSize.height) - 1;
|
||||
|
||||
Size texSize = _tileSet->_imageSize;
|
||||
for (int y = visibleTiles.origin.y - rows_per_tile; y <= visibleTiles.origin.y + visibleTiles.size.height; ++y)
|
||||
{
|
||||
if(y<0 || y >= _layerSize.height)
|
||||
continue;
|
||||
for (int x = visibleTiles.origin.x; x <= visibleTiles.origin.x + visibleTiles.size.width; x++)
|
||||
{
|
||||
if(x<0 || x >= _layerSize.width)
|
||||
continue;
|
||||
|
||||
int tileGID = _tiles[x + y * (int)_layerSize.width];
|
||||
|
||||
// GID==0 empty tile
|
||||
if(tileGID!=0) {
|
||||
|
||||
V2F_T2F_Quad *quad = &quadsTmp[tilesUsed];
|
||||
|
||||
Vec3 nodePos(static_cast<float>(x), static_cast<float>(y), 0);
|
||||
_tileToNodeTransform.transformPoint(&nodePos);
|
||||
|
||||
float left, right, top, bottom;
|
||||
|
||||
// vertices
|
||||
left = nodePos.x;
|
||||
right = nodePos.x + tileSize.width;
|
||||
bottom = nodePos.y + tileSize.height;
|
||||
top = nodePos.y;
|
||||
|
||||
if(tileGID & kTMXTileVerticalFlag)
|
||||
std::swap(top, bottom);
|
||||
if(tileGID & kTMXTileHorizontalFlag)
|
||||
std::swap(left, right);
|
||||
|
||||
if(tileGID & kTMXTileDiagonalFlag)
|
||||
{
|
||||
// XXX: not working correcly
|
||||
quad->bl.vertices.x = left;
|
||||
quad->bl.vertices.y = bottom;
|
||||
quad->br.vertices.x = left;
|
||||
quad->br.vertices.y = top;
|
||||
quad->tl.vertices.x = right;
|
||||
quad->tl.vertices.y = bottom;
|
||||
quad->tr.vertices.x = right;
|
||||
quad->tr.vertices.y = top;
|
||||
}
|
||||
else
|
||||
{
|
||||
quad->bl.vertices.x = left;
|
||||
quad->bl.vertices.y = bottom;
|
||||
quad->br.vertices.x = right;
|
||||
quad->br.vertices.y = bottom;
|
||||
quad->tl.vertices.x = left;
|
||||
quad->tl.vertices.y = top;
|
||||
quad->tr.vertices.x = right;
|
||||
quad->tr.vertices.y = top;
|
||||
}
|
||||
|
||||
// texcoords
|
||||
Rect tileTexture = _tileSet->getRectForGID(tileGID);
|
||||
left = (tileTexture.origin.x / texSize.width);
|
||||
right = left + (tileTexture.size.width / texSize.width);
|
||||
bottom = (tileTexture.origin.y / texSize.height);
|
||||
top = bottom + (tileTexture.size.height / texSize.height);
|
||||
|
||||
quad->bl.texCoords.u = left;
|
||||
quad->bl.texCoords.v = bottom;
|
||||
quad->br.texCoords.u = right;
|
||||
quad->br.texCoords.v = bottom;
|
||||
quad->tl.texCoords.u = left;
|
||||
quad->tl.texCoords.v = top;
|
||||
quad->tr.texCoords.u = right;
|
||||
quad->tr.texCoords.v = top;
|
||||
|
||||
|
||||
GLushort *idxbase = indicesTmp + tilesUsed * 6;
|
||||
int vertexbase = tilesUsed * 4;
|
||||
|
||||
idxbase[0] = vertexbase;
|
||||
idxbase[1] = vertexbase + 1;
|
||||
idxbase[2] = vertexbase + 2;
|
||||
idxbase[3] = vertexbase + 3;
|
||||
idxbase[4] = vertexbase + 2;
|
||||
idxbase[5] = vertexbase + 1;
|
||||
|
||||
tilesUsed++;
|
||||
}
|
||||
|
||||
if (tilesUsed >= MAX_QUADS_COUNT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} // for x
|
||||
|
||||
if (tilesUsed >= MAX_QUADS_COUNT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} // for y
|
||||
|
||||
return tilesUsed * 6;
|
||||
}
|
||||
|
||||
void TMXLayer2::setupVBO()
|
||||
{
|
||||
glGenBuffers(2, &_buffersVBO[0]);
|
||||
|
||||
// 10922 = 65536/6
|
||||
int total = std::min(static_cast<int>(_layerSize.width * _layerSize.height), MAX_QUADS_COUNT);
|
||||
|
||||
// Vertex + Tex Coords
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, total * sizeof(V2F_T2F_Quad), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Indices
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, total * 6 * sizeof(GLushort), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
|
||||
// TMXLayer2 - setup Tiles
|
||||
void TMXLayer2::setupTiles()
|
||||
{
|
||||
// Optimization: quick hack that sets the image size on the tileset
|
||||
_tileSet->_imageSize = _texture->getContentSizeInPixels();
|
||||
|
||||
// By default all the tiles are aliased
|
||||
// pros: easier to render
|
||||
// cons: difficult to scale / rotate / etc.
|
||||
_texture->setAliasTexParameters();
|
||||
|
||||
//CFByteOrder o = CFByteOrderGetCurrent();
|
||||
|
||||
// Parse cocos2d properties
|
||||
this->parseInternalProperties();
|
||||
|
||||
Size screenSize = Director::getInstance()->getWinSize();
|
||||
|
||||
switch (_layerOrientation)
|
||||
{
|
||||
case TMXOrientationOrtho:
|
||||
_screenGridSize.width = ceil(screenSize.width / _mapTileSize.width) + 1;
|
||||
_screenGridSize.height = ceil(screenSize.height / _mapTileSize.height) + 1;
|
||||
|
||||
// tiles could be bigger than the grid, add additional rows if needed
|
||||
_screenGridSize.height += _tileSet->_tileSize.height / _mapTileSize.height;
|
||||
break;
|
||||
case TMXOrientationIso:
|
||||
_screenGridSize.width = ceil(screenSize.width / _mapTileSize.width) + 2;
|
||||
_screenGridSize.height = ceil(screenSize.height / (_mapTileSize.height/2)) + 4;
|
||||
break;
|
||||
case TMXOrientationHex:
|
||||
break;
|
||||
}
|
||||
|
||||
_screenTileCount = _screenGridSize.width * _screenGridSize.height;
|
||||
|
||||
setupVBO();
|
||||
}
|
||||
|
||||
Mat4 TMXLayer2::tileToNodeTransform()
|
||||
{
|
||||
float w = _mapTileSize.width / CC_CONTENT_SCALE_FACTOR();
|
||||
float h = _mapTileSize.height / CC_CONTENT_SCALE_FACTOR();
|
||||
float offY = (_layerSize.height - 1) * h;
|
||||
|
||||
switch(_layerOrientation)
|
||||
{
|
||||
case TMXOrientationOrtho:
|
||||
{
|
||||
_tileToNodeTransform = Mat4
|
||||
(
|
||||
w, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -h, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, offY, 0.0f, 1.0f
|
||||
);
|
||||
|
||||
return _tileToNodeTransform;
|
||||
}
|
||||
case TMXOrientationIso:
|
||||
{
|
||||
float offX = (_layerSize.width - 1) * w / 2;
|
||||
_tileToNodeTransform = Mat4
|
||||
(
|
||||
w/2, -h/2, 0.0f, 0.0f,
|
||||
-w/2, -h/2, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
offX, offY, 0.0f, 1.0f
|
||||
|
||||
);
|
||||
return _tileToNodeTransform;
|
||||
}
|
||||
case TMXOrientationHex:
|
||||
{
|
||||
_tileToNodeTransform = Mat4::IDENTITY;
|
||||
return _tileToNodeTransform;
|
||||
}
|
||||
default:
|
||||
{
|
||||
_tileToNodeTransform = Mat4::IDENTITY;
|
||||
return _tileToNodeTransform;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// removing / getting tiles
|
||||
Sprite* TMXLayer2::getTileAt(const Point& tileCoordinate)
|
||||
{
|
||||
CCASSERT( tileCoordinate.x < _layerSize.width && tileCoordinate.y < _layerSize.height && tileCoordinate.x >=0 && tileCoordinate.y >=0, "TMXLayer: invalid position");
|
||||
CCASSERT( _tiles, "TMXLayer: the tiles map has been released");
|
||||
|
||||
Sprite *tile = nullptr;
|
||||
int gid = this->getTileGIDAt(tileCoordinate);
|
||||
|
||||
// if GID == 0, then no tile is present
|
||||
if( gid ) {
|
||||
int index = tileCoordinate.x + tileCoordinate.y * _layerSize.width;
|
||||
|
||||
auto it = _spriteContainer.find(index);
|
||||
if (it != _spriteContainer.end())
|
||||
{
|
||||
tile = it->second.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
// tile not created yet. create it
|
||||
Rect rect = _tileSet->getRectForGID(gid);
|
||||
rect = CC_RECT_PIXELS_TO_POINTS(rect);
|
||||
tile = Sprite::createWithTexture(_texture, rect);
|
||||
|
||||
Point p = this->getPositionAt(tileCoordinate);
|
||||
tile->setAnchorPoint(Point::ZERO);
|
||||
tile->setPosition(p);
|
||||
tile->setPositionZ((float)getVertexZForPos(tileCoordinate));
|
||||
tile->setOpacity(this->getOpacity());
|
||||
tile->setTag(index);
|
||||
this->addChild(tile, -index);
|
||||
_spriteContainer.insert(std::pair<int, std::pair<Sprite*, int> >(index, std::pair<Sprite*, int>(tile, gid)));
|
||||
|
||||
// tile is converted to sprite.
|
||||
_tiles[index] = 0;
|
||||
}
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
int TMXLayer2::getTileGIDAt(const Point& tileCoordinate, TMXTileFlags* flags/* = nullptr*/)
|
||||
{
|
||||
CCASSERT(tileCoordinate.x < _layerSize.width && tileCoordinate.y < _layerSize.height && tileCoordinate.x >=0 && tileCoordinate.y >=0, "TMXLayer: invalid position");
|
||||
CCASSERT(_tiles, "TMXLayer: the tiles map has been released");
|
||||
|
||||
int idx = static_cast<int>((tileCoordinate.x + tileCoordinate.y * _layerSize.width));
|
||||
|
||||
// Bits on the far end of the 32-bit global tile ID are used for tile flags
|
||||
int tile = _tiles[idx];
|
||||
auto it = _spriteContainer.find(idx);
|
||||
|
||||
// converted to sprite.
|
||||
if (tile == 0 && it != _spriteContainer.end())
|
||||
{
|
||||
tile = it->second.second;
|
||||
}
|
||||
|
||||
// issue1264, flipped tiles can be changed dynamically
|
||||
if (flags)
|
||||
{
|
||||
*flags = (TMXTileFlags)(tile & kTMXFlipedAll);
|
||||
}
|
||||
|
||||
return (tile & kTMXFlippedMask);
|
||||
}
|
||||
|
||||
Point TMXLayer2::getPositionAt(const Point& pos)
|
||||
{
|
||||
return PointApplyTransform(pos, _tileToNodeTransform);
|
||||
}
|
||||
|
||||
int TMXLayer2::getVertexZForPos(const Point& pos)
|
||||
{
|
||||
int ret = 0;
|
||||
int maxVal = 0;
|
||||
if (_useAutomaticVertexZ)
|
||||
{
|
||||
switch (_layerOrientation)
|
||||
{
|
||||
case TMXOrientationIso:
|
||||
maxVal = static_cast<int>(_layerSize.width + _layerSize.height);
|
||||
ret = static_cast<int>(-(maxVal - (pos.x + pos.y)));
|
||||
break;
|
||||
case TMXOrientationOrtho:
|
||||
ret = static_cast<int>(-(_layerSize.height-pos.y));
|
||||
break;
|
||||
case TMXOrientationHex:
|
||||
CCASSERT(0, "TMX Hexa zOrder not supported");
|
||||
break;
|
||||
default:
|
||||
CCASSERT(0, "TMX invalid value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = _vertexZvalue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TMXLayer2::removeTileAt(const Point& tileCoordinate)
|
||||
{
|
||||
|
||||
CCASSERT( tileCoordinate.x < _layerSize.width && tileCoordinate.y < _layerSize.height && tileCoordinate.x >=0 && tileCoordinate.y >=0, "TMXLayer: invalid position");
|
||||
CCASSERT( _tiles, "TMXLayer: the tiles map has been released");
|
||||
|
||||
uint32_t gid = this->getTileGIDAt(tileCoordinate);
|
||||
|
||||
if( gid ) {
|
||||
|
||||
int z = tileCoordinate.x + tileCoordinate.y * _layerSize.width;
|
||||
|
||||
// remove tile from GID map
|
||||
_tiles[z] = 0;
|
||||
|
||||
// remove it from sprites
|
||||
auto it = _spriteContainer.find(z);
|
||||
if (it != _spriteContainer.end())
|
||||
{
|
||||
this->removeChild(it->second.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TMXLayer2::removeChild(Node* node, bool cleanup)
|
||||
{
|
||||
int tag = node->getTag();
|
||||
auto it = _spriteContainer.find(tag);
|
||||
if (it != _spriteContainer.end() && it->second.first == node)
|
||||
{
|
||||
_spriteContainer.erase(it);
|
||||
}
|
||||
Node::removeChild(node, cleanup);
|
||||
}
|
||||
|
||||
// TMXLayer2 - Properties
|
||||
Value TMXLayer2::getProperty(const std::string& propertyName) const
|
||||
{
|
||||
if (_properties.find(propertyName) != _properties.end())
|
||||
return _properties.at(propertyName);
|
||||
|
||||
return Value();
|
||||
}
|
||||
|
||||
void TMXLayer2::parseInternalProperties()
|
||||
{
|
||||
auto vertexz = getProperty("cc_vertexz");
|
||||
if (!vertexz.isNull())
|
||||
{
|
||||
std::string vertexZStr = vertexz.asString();
|
||||
// If "automatic" is on, then parse the "cc_alpha_func" too
|
||||
if (vertexZStr == "automatic")
|
||||
{
|
||||
_useAutomaticVertexZ = true;
|
||||
auto alphaFuncVal = getProperty("cc_alpha_func");
|
||||
float alphaFuncValue = alphaFuncVal.asFloat();
|
||||
setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST));
|
||||
|
||||
GLint alphaValueLocation = glGetUniformLocation(getGLProgram()->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
|
||||
|
||||
// NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison
|
||||
|
||||
// use shader program to set uniform
|
||||
getGLProgram()->use();
|
||||
getGLProgram()->setUniformLocationWith1f(alphaValueLocation, alphaFuncValue);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
}
|
||||
else
|
||||
{
|
||||
_vertexZvalue = vertexz.asInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//CCTMXLayer2 - obtaining positions, offset
|
||||
Point TMXLayer2::calculateLayerOffset(const Point& pos)
|
||||
{
|
||||
Point ret = Point::ZERO;
|
||||
switch (_layerOrientation)
|
||||
{
|
||||
case TMXOrientationOrtho:
|
||||
ret = Point( pos.x * _mapTileSize.width, -pos.y *_mapTileSize.height);
|
||||
break;
|
||||
case TMXOrientationIso:
|
||||
ret = Point((_mapTileSize.width /2) * (pos.x - pos.y),
|
||||
(_mapTileSize.height /2 ) * (-pos.x - pos.y));
|
||||
break;
|
||||
case TMXOrientationHex:
|
||||
CCASSERT(pos.equals(Point::ZERO), "offset for hexagonal map not implemented yet");
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//void TMXLayer2::releaseMap()
|
||||
//{
|
||||
// if (_tiles)
|
||||
// {
|
||||
// delete [] _tiles;
|
||||
// _tiles = nullptr;
|
||||
// }
|
||||
//}
|
||||
|
||||
// TMXLayer - adding / remove tiles
|
||||
void TMXLayer2::setTileGID(int gid, const Point& tileCoordinate)
|
||||
{
|
||||
setTileGID(gid, tileCoordinate, (TMXTileFlags)0);
|
||||
}
|
||||
|
||||
void TMXLayer2::setTileGID(int gid, const Point& tileCoordinate, TMXTileFlags flags)
|
||||
{
|
||||
CCASSERT(tileCoordinate.x < _layerSize.width && tileCoordinate.y < _layerSize.height && tileCoordinate.x >=0 && tileCoordinate.y >=0, "TMXLayer: invalid position");
|
||||
CCASSERT(_tiles, "TMXLayer: the tiles map has been released");
|
||||
CCASSERT(gid == 0 || gid >= _tileSet->_firstGid, "TMXLayer: invalid gid" );
|
||||
|
||||
TMXTileFlags currentFlags;
|
||||
int currentGID = getTileGIDAt(tileCoordinate, ¤tFlags);
|
||||
|
||||
if (currentGID != gid || currentFlags != flags)
|
||||
{
|
||||
int gidAndFlags = gid | flags;
|
||||
|
||||
// setting gid=0 is equal to remove the tile
|
||||
if (gid == 0)
|
||||
{
|
||||
removeTileAt(tileCoordinate);
|
||||
}
|
||||
// empty tile. create a new one
|
||||
else if (currentGID == 0)
|
||||
{
|
||||
int z = tileCoordinate.x + tileCoordinate.y * _layerSize.width;
|
||||
_tiles[z] = gidAndFlags;
|
||||
}
|
||||
// modifying an existing tile with a non-empty tile
|
||||
else
|
||||
{
|
||||
int z = tileCoordinate.x + tileCoordinate.y * _layerSize.width;
|
||||
auto it = _spriteContainer.find(z);
|
||||
if (it != _spriteContainer.end())
|
||||
{
|
||||
Sprite *sprite = it->second.first;
|
||||
Rect rect = _tileSet->getRectForGID(gid);
|
||||
rect = CC_RECT_PIXELS_TO_POINTS(rect);
|
||||
|
||||
sprite->setTextureRect(rect, false, rect.size);
|
||||
this->reorderChild(sprite, z);
|
||||
if (flags)
|
||||
{
|
||||
setupTileSprite(sprite, sprite->getPosition(), gidAndFlags);
|
||||
}
|
||||
|
||||
it->second.second = gidAndFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiles[z] = gidAndFlags;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TMXLayer2::setupTileSprite(Sprite* sprite, Point pos, int gid)
|
||||
{
|
||||
sprite->setPosition(getPositionAt(pos));
|
||||
sprite->setPositionZ((float)getVertexZForPos(pos));
|
||||
sprite->setAnchorPoint(Point::ZERO);
|
||||
sprite->setOpacity(this->getOpacity());
|
||||
|
||||
//issue 1264, flip can be undone as well
|
||||
sprite->setFlippedX(false);
|
||||
sprite->setFlippedY(false);
|
||||
sprite->setRotation(0.0f);
|
||||
|
||||
// Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles.
|
||||
if (gid & kTMXTileDiagonalFlag)
|
||||
{
|
||||
// put the anchor in the middle for ease of rotation.
|
||||
sprite->setAnchorPoint(Point(0.5f,0.5f));
|
||||
sprite->setPosition(Point(getPositionAt(pos).x + sprite->getContentSize().height/2,
|
||||
getPositionAt(pos).y + sprite->getContentSize().width/2 ) );
|
||||
|
||||
int flag = gid & (kTMXTileHorizontalFlag | kTMXTileVerticalFlag );
|
||||
|
||||
// handle the 4 diagonally flipped states.
|
||||
if (flag == kTMXTileHorizontalFlag)
|
||||
{
|
||||
sprite->setRotation(90.0f);
|
||||
}
|
||||
else if (flag == kTMXTileVerticalFlag)
|
||||
{
|
||||
sprite->setRotation(270.0f);
|
||||
}
|
||||
else if (flag == (kTMXTileVerticalFlag | kTMXTileHorizontalFlag) )
|
||||
{
|
||||
sprite->setRotation(90.0f);
|
||||
sprite->setFlippedX(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->setRotation(270.0f);
|
||||
sprite->setFlippedX(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gid & kTMXTileHorizontalFlag)
|
||||
{
|
||||
sprite->setFlippedX(true);
|
||||
}
|
||||
|
||||
if (gid & kTMXTileVerticalFlag)
|
||||
{
|
||||
sprite->setFlippedY(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sprite* TMXLayer2::reusedTileWithRect(Rect rect)
|
||||
{
|
||||
if (! _reusedTile)
|
||||
{
|
||||
_reusedTile = Sprite::createWithTexture(_texture, rect);
|
||||
_reusedTile->retain();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-init the sprite
|
||||
_reusedTile->setTextureRect(rect, false, rect.size);
|
||||
}
|
||||
|
||||
return _reusedTile;
|
||||
}
|
||||
|
||||
std::string TMXLayer2::getDescription() const
|
||||
{
|
||||
return StringUtils::format("<TMXLayer2 | tag = %d, size = %d,%d>", _tag, (int)_mapTileSize.width, (int)_mapTileSize.height);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __CCTMX_LAYER2_H__
|
||||
#define __CCTMX_LAYER2_H__
|
||||
|
||||
#include "CCTMXObjectGroup.h"
|
||||
#include "CCTMXXMLParser.h"
|
||||
#include "CCNode.h"
|
||||
#include "renderer/CCCustomCommand.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class TMXMapInfo;
|
||||
class TMXLayerInfo;
|
||||
class TMXTilesetInfo;
|
||||
class Texture2D;
|
||||
class Sprite;
|
||||
struct _ccCArray;
|
||||
|
||||
/**
|
||||
* @addtogroup tilemap_parallax_nodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief TMXLayer2 represents the TMX layer.
|
||||
|
||||
It is a subclass of SpriteBatchNode. By default the tiles are rendered using a TextureAtlas.
|
||||
If you modify a tile on runtime, then, that tile will become a Sprite, otherwise no Sprite objects are created.
|
||||
The benefits of using Sprite objects as tiles are:
|
||||
- tiles (Sprite) can be rotated/scaled/moved with a nice API
|
||||
|
||||
If the layer contains a property named "cc_vertexz" with an integer (in can be positive or negative),
|
||||
then all the tiles belonging to the layer will use that value as their OpenGL vertex Z for depth.
|
||||
|
||||
On the other hand, if the "cc_vertexz" property has the "automatic" value, then the tiles will use an automatic vertex Z value.
|
||||
Also before drawing the tiles, GL_ALPHA_TEST will be enabled, and disabled after drawing them. The used alpha func will be:
|
||||
|
||||
glAlphaFunc( GL_GREATER, value )
|
||||
|
||||
"value" by default is 0, but you can change it from Tiled by adding the "cc_alpha_func" property to the layer.
|
||||
The value 0 should work for most cases, but if you have tiles that are semi-transparent, then you might want to use a different
|
||||
value, like 0.5.
|
||||
|
||||
For further information, please see the programming guide:
|
||||
|
||||
http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps
|
||||
|
||||
@since v0.8.1
|
||||
Tiles can have tile flags for additional properties. At the moment only flip horizontal and flip vertical are used. These bit flags are defined in TMXXMLParser.h.
|
||||
|
||||
@since 1.1
|
||||
*/
|
||||
|
||||
class CC_DLL TMXLayer2 : public Node
|
||||
{
|
||||
public:
|
||||
/** creates a TMXLayer2 with an tileset info, a layer info and a map info */
|
||||
static TMXLayer2 * create(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
|
||||
/**
|
||||
* @js ctor
|
||||
*/
|
||||
TMXLayer2();
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
virtual ~TMXLayer2();
|
||||
|
||||
/** returns the tile gid at a given tile coordinate. It also returns the tile flags.
|
||||
*/
|
||||
int getTileGIDAt(const Point& tileCoordinate, TMXTileFlags* flags = nullptr);
|
||||
CC_DEPRECATED_ATTRIBUTE int tileGIDAt(const Point& tileCoordinate, TMXTileFlags* flags = nullptr){
|
||||
return getTileGIDAt(tileCoordinate, flags);
|
||||
};
|
||||
|
||||
/** sets the tile gid (gid = tile global id) at a given tile coordinate.
|
||||
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
|
||||
If a tile is already placed at that position, then it will be removed.
|
||||
*/
|
||||
void setTileGID(int gid, const Point& tileCoordinate);
|
||||
|
||||
/** sets the tile gid (gid = tile global id) at a given tile coordinate.
|
||||
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
|
||||
If a tile is already placed at that position, then it will be removed.
|
||||
|
||||
Use withFlags if the tile flags need to be changed as well
|
||||
*/
|
||||
|
||||
void setTileGID(int gid, const Point& tileCoordinate, TMXTileFlags flags);
|
||||
|
||||
/** removes a tile at given tile coordinate */
|
||||
void removeTileAt(const Point& tileCoordinate);
|
||||
|
||||
/** returns the position in points of a given tile coordinate */
|
||||
Point getPositionAt(const Point& tileCoordinate);
|
||||
CC_DEPRECATED_ATTRIBUTE Point positionAt(const Point& tileCoordinate) { return getPositionAt(tileCoordinate); };
|
||||
|
||||
/** return the value for the specific property name */
|
||||
Value getProperty(const std::string& propertyName) const;
|
||||
CC_DEPRECATED_ATTRIBUTE Value propertyNamed(const std::string& propertyName) const { return getProperty(propertyName); };
|
||||
|
||||
/** Creates the tiles */
|
||||
void setupTiles();
|
||||
|
||||
inline const std::string& getLayerName(){ return _layerName; }
|
||||
inline void setLayerName(const std::string& layerName){ _layerName = layerName; }
|
||||
|
||||
/** size of the layer in tiles */
|
||||
inline const Size& getLayerSize() const { return _layerSize; };
|
||||
inline void setLayerSize(const Size& size) { _layerSize = size; };
|
||||
|
||||
/** size of the map's tile (could be different from the tile's size) */
|
||||
inline const Size& getMapTileSize() const { return _mapTileSize; };
|
||||
inline void setMapTileSize(const Size& size) { _mapTileSize = size; };
|
||||
|
||||
/** pointer to the map of tiles
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
uint32_t* getTiles() const { return _tiles; };
|
||||
void setTiles(uint32_t* tiles) { _tiles = tiles; };
|
||||
|
||||
/** Tileset information for the layer */
|
||||
inline TMXTilesetInfo* getTileSet() const { return _tileSet; };
|
||||
inline void setTileSet(TMXTilesetInfo* info) {
|
||||
CC_SAFE_RETAIN(info);
|
||||
CC_SAFE_RELEASE(_tileSet);
|
||||
_tileSet = info;
|
||||
};
|
||||
|
||||
/** Layer orientation, which is the same as the map orientation */
|
||||
inline int getLayerOrientation() const { return _layerOrientation; };
|
||||
inline void setLayerOrientation(int orientation) { _layerOrientation = orientation; };
|
||||
|
||||
/** properties from the layer. They can be added using Tiled */
|
||||
inline const ValueMap& getProperties() const { return _properties; };
|
||||
inline ValueMap& getProperties() { return _properties; };
|
||||
inline void setProperties(const ValueMap& properties) {
|
||||
_properties = properties;
|
||||
};
|
||||
|
||||
/** returns the tile (Sprite) at a given a tile coordinate.
|
||||
The returned Sprite will be already added to the TMXLayer. Don't add it again.
|
||||
The Sprite can be treated like any other Sprite: rotated, scaled, translated, opacity, color, etc.
|
||||
You can remove either by calling:
|
||||
- layer->removeChild(sprite, cleanup);
|
||||
*/
|
||||
Sprite* getTileAt(const Point& tileCoordinate);
|
||||
|
||||
Sprite* reusedTileWithRect(Rect rect);
|
||||
|
||||
Sprite* updateTileForGID(int gid, const Point& pos);
|
||||
|
||||
void setupTileSprite(Sprite* sprite, Point pos, int gid);
|
||||
|
||||
//
|
||||
// Override
|
||||
//
|
||||
virtual std::string getDescription() const override;
|
||||
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags) override;
|
||||
void removeChild(Node* child, bool cleanup = true) override;
|
||||
|
||||
protected:
|
||||
|
||||
bool initWithTilesetInfo(TMXTilesetInfo *tilesetInfo, TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
|
||||
int updateTiles(const Rect& culledRect, V2F_T2F_Quad *quads, GLushort *indices);
|
||||
void setupVBO();
|
||||
Point calculateLayerOffset(const Point& offset);
|
||||
|
||||
/* The layer recognizes some special properties, like cc_vertez */
|
||||
void parseInternalProperties();
|
||||
|
||||
Mat4 tileToNodeTransform();
|
||||
Rect tileBoundsForClipTransform(const Mat4 &tileToClip);
|
||||
|
||||
void onDraw(const Mat4 &transform, bool transformUpdated);
|
||||
|
||||
int getVertexZForPos(const Point& pos);
|
||||
|
||||
void insertTileForGID(int gid, const Point& pos);
|
||||
|
||||
protected:
|
||||
CustomCommand _customCommand;
|
||||
|
||||
//! name of the layer
|
||||
std::string _layerName;
|
||||
|
||||
/** size of the layer in tiles */
|
||||
Size _layerSize;
|
||||
/** size of the map's tile (could be different from the tile's size) */
|
||||
Size _mapTileSize;
|
||||
/** pointer to the map of tiles */
|
||||
uint32_t* _tiles;
|
||||
/** Tileset information for the layer */
|
||||
TMXTilesetInfo* _tileSet;
|
||||
/** Layer orientation, which is the same as the map orientation */
|
||||
int _layerOrientation;
|
||||
/** properties from the layer. They can be added using Tiled */
|
||||
ValueMap _properties;
|
||||
|
||||
Texture2D *_texture;
|
||||
Sprite* _reusedTile;
|
||||
|
||||
/** container for sprite children. map<index, pair<sprite, gid> > */
|
||||
std::map<int, std::pair<Sprite*, int> > _spriteContainer;
|
||||
|
||||
GLuint _buffersVBO[3]; //0: vertex, 1: tex coords, 2: indices
|
||||
|
||||
Size _screenGridSize;
|
||||
Rect _screenGridRect;
|
||||
int _screenTileCount;
|
||||
Rect _previousRect;
|
||||
int _verticesToDraw;
|
||||
|
||||
int _vertexZvalue;
|
||||
bool _useAutomaticVertexZ;
|
||||
|
||||
|
||||
/** tile coordinate to node coordinate transform */
|
||||
Mat4 _tileToNodeTransform;
|
||||
/** quads to be rendered */
|
||||
V2F_T2F_Quad* _quads;
|
||||
/** number of quads */
|
||||
int _numQuads;
|
||||
/** indices */
|
||||
GLushort* _indices;
|
||||
};
|
||||
|
||||
// end of tilemap_parallax_nodes group
|
||||
/// @}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif //__CCTMX_LAYER2_H__
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2009-2010 Ricardo Quesada
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "CCTMXTiledMap2.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "CCTMXXMLParser.h"
|
||||
#include "CCTMXLayer2.h"
|
||||
#include "CCSprite.h"
|
||||
#include "deprecated/CCString.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
// implementation TMXTiledMap2
|
||||
|
||||
TMXTiledMap2 * TMXTiledMap2::create(const std::string& tmxFile)
|
||||
{
|
||||
TMXTiledMap2 *ret = new TMXTiledMap2();
|
||||
if (ret->initWithTMXFile(tmxFile))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TMXTiledMap2* TMXTiledMap2::createWithXML(const std::string& tmxString, const std::string& resourcePath)
|
||||
{
|
||||
TMXTiledMap2 *ret = new TMXTiledMap2();
|
||||
if (ret->initWithXML(tmxString, resourcePath))
|
||||
{
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TMXTiledMap2::initWithTMXFile(const std::string& tmxFile)
|
||||
{
|
||||
CCASSERT(tmxFile.size()>0, "TMXTiledMap2: tmx file should not be empty");
|
||||
|
||||
setContentSize(Size::ZERO);
|
||||
|
||||
TMXMapInfo *mapInfo = TMXMapInfo::create(tmxFile);
|
||||
|
||||
if (! mapInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CCASSERT( !mapInfo->getTilesets().empty(), "TMXTiledMap2: Map not found. Please check the filename.");
|
||||
buildWithMapInfo(mapInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TMXTiledMap2::initWithXML(const std::string& tmxString, const std::string& resourcePath)
|
||||
{
|
||||
setContentSize(Size::ZERO);
|
||||
|
||||
TMXMapInfo *mapInfo = TMXMapInfo::createWithXML(tmxString, resourcePath);
|
||||
|
||||
CCASSERT( !mapInfo->getTilesets().empty(), "TMXTiledMap2: Map not found. Please check the filename.");
|
||||
buildWithMapInfo(mapInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TMXTiledMap2::TMXTiledMap2()
|
||||
:_mapSize(Size::ZERO)
|
||||
,_tileSize(Size::ZERO)
|
||||
{
|
||||
}
|
||||
|
||||
TMXTiledMap2::~TMXTiledMap2()
|
||||
{
|
||||
}
|
||||
|
||||
// private
|
||||
TMXLayer2 * TMXTiledMap2::parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
TMXTilesetInfo *tileset = tilesetForLayer(layerInfo, mapInfo);
|
||||
TMXLayer2 *layer = TMXLayer2::create(tileset, layerInfo, mapInfo);
|
||||
|
||||
// tell the layerinfo to release the ownership of the tiles map.
|
||||
layerInfo->_ownTiles = false;
|
||||
layer->setupTiles();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
TMXTilesetInfo * TMXTiledMap2::tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo)
|
||||
{
|
||||
Size size = layerInfo->_layerSize;
|
||||
auto& tilesets = mapInfo->getTilesets();
|
||||
if (tilesets.size()>0)
|
||||
{
|
||||
TMXTilesetInfo* tileset = nullptr;
|
||||
for (auto iter = tilesets.crbegin(); iter != tilesets.crend(); ++iter)
|
||||
{
|
||||
tileset = *iter;
|
||||
if (tileset)
|
||||
{
|
||||
for( int y=0; y < size.height; y++ )
|
||||
{
|
||||
for( int x=0; x < size.width; x++ )
|
||||
{
|
||||
int pos = static_cast<int>(x + size.width * y);
|
||||
int gid = layerInfo->_tiles[ pos ];
|
||||
|
||||
// gid are stored in little endian.
|
||||
// if host is big endian, then swap
|
||||
//if( o == CFByteOrderBigEndian )
|
||||
// gid = CFSwapInt32( gid );
|
||||
/* We support little endian.*/
|
||||
|
||||
// XXX: gid == 0 --> empty tile
|
||||
if( gid != 0 )
|
||||
{
|
||||
// Optimization: quick return
|
||||
// if the layer is invalid (more than 1 tileset per layer) an CCAssert will be thrown later
|
||||
if( (gid & kTMXFlippedMask) >= tileset->_firstGid )
|
||||
return tileset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If all the tiles are 0, return empty tileset
|
||||
CCLOG("cocos2d: Warning: TMX Layer '%s' has no tiles", layerInfo->_name.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TMXTiledMap2::buildWithMapInfo(TMXMapInfo* mapInfo)
|
||||
{
|
||||
_mapSize = mapInfo->getMapSize();
|
||||
_tileSize = mapInfo->getTileSize();
|
||||
_mapOrientation = mapInfo->getOrientation();
|
||||
|
||||
_objectGroups = mapInfo->getObjectGroups();
|
||||
|
||||
_properties = mapInfo->getProperties();
|
||||
|
||||
_tileProperties = mapInfo->getTileProperties();
|
||||
|
||||
int idx=0;
|
||||
|
||||
auto& layers = mapInfo->getLayers();
|
||||
for(const auto &layerInfo : layers) {
|
||||
if (layerInfo->_visible)
|
||||
{
|
||||
TMXLayer2 *child = parseLayer(layerInfo, mapInfo);
|
||||
addChild(child, idx, idx);
|
||||
|
||||
// update content size with the max size
|
||||
const Size& childSize = child->getContentSize();
|
||||
Size currentSize = this->getContentSize();
|
||||
currentSize.width = std::max( currentSize.width, childSize.width );
|
||||
currentSize.height = std::max( currentSize.height, childSize.height );
|
||||
this->setContentSize(currentSize);
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public
|
||||
TMXLayer2 * TMXTiledMap2::getLayer(const std::string& layerName) const
|
||||
{
|
||||
CCASSERT(layerName.size() > 0, "Invalid layer name!");
|
||||
|
||||
for (auto& child : _children)
|
||||
{
|
||||
TMXLayer2* layer = dynamic_cast<TMXLayer2*>(child);
|
||||
if(layer)
|
||||
{
|
||||
if(layerName.compare( layer->getLayerName()) == 0)
|
||||
{
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// layer not found
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TMXObjectGroup * TMXTiledMap2::getObjectGroup(const std::string& groupName) const
|
||||
{
|
||||
CCASSERT(groupName.size() > 0, "Invalid group name!");
|
||||
|
||||
if (_objectGroups.size()>0)
|
||||
{
|
||||
TMXObjectGroup* objectGroup = nullptr;
|
||||
for (auto iter = _objectGroups.cbegin(); iter != _objectGroups.cend(); ++iter)
|
||||
{
|
||||
objectGroup = *iter;
|
||||
if (objectGroup && objectGroup->getGroupName() == groupName)
|
||||
{
|
||||
return objectGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// objectGroup not found
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Value TMXTiledMap2::getProperty(const std::string& propertyName) const
|
||||
{
|
||||
if (_properties.find(propertyName) != _properties.end())
|
||||
return _properties.at(propertyName);
|
||||
|
||||
return Value();
|
||||
}
|
||||
|
||||
Value TMXTiledMap2::getPropertiesForGID(int GID) const
|
||||
{
|
||||
if (_tileProperties.find(GID) != _tileProperties.end())
|
||||
return _tileProperties.at(GID);
|
||||
|
||||
return Value();
|
||||
}
|
||||
|
||||
std::string TMXTiledMap2::getDescription() const
|
||||
{
|
||||
return StringUtils::format("<TMXTiledMap2 | Tag = %d, Layers = %d", _tag, static_cast<int>(_children.size()));
|
||||
}
|
||||
|
||||
|
||||
NS_CC_END
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2009-2010 Ricardo Quesada
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2011 Zynga Inc.
|
||||
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __CCTMX_TILE_MAP2_H__
|
||||
#define __CCTMX_TILE_MAP2_H__
|
||||
|
||||
#include "CCNode.h"
|
||||
#include "CCTMXObjectGroup.h"
|
||||
#include "CCValue.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class TMXObjectGroup;
|
||||
class TMXLayer2;
|
||||
class TMXLayerInfo;
|
||||
class TMXTilesetInfo;
|
||||
class TMXMapInfo;
|
||||
|
||||
/**
|
||||
* @addtogroup tilemap_parallax_nodes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Possible orientations of the TMX map */
|
||||
enum
|
||||
{
|
||||
/** Orthogonal orientation */
|
||||
TMXOrientationOrtho2,
|
||||
|
||||
/** Hexagonal orientation */
|
||||
TMXOrientationHex2,
|
||||
|
||||
/** Isometric orientation */
|
||||
TMXOrientationIso2,
|
||||
};
|
||||
|
||||
/** @brief TMXTiledMap2 knows how to parse and render a TMX map.
|
||||
|
||||
It adds support for the TMX tiled map format used by http://www.mapeditor.org
|
||||
It supports isometric, hexagonal and orthogonal tiles.
|
||||
It also supports object groups, objects, and properties.
|
||||
|
||||
Features:
|
||||
- Each tile will be treated as an Sprite
|
||||
- The sprites are created on demand. They will be created only when you call "layer->tileAt(position)"
|
||||
- Each tile can be rotated / moved / scaled / tinted / "opaqued", since each tile is a Sprite
|
||||
- Tiles can be added/removed in runtime
|
||||
- The z-order of the tiles can be modified in runtime
|
||||
- Each tile has an anchorPoint of (0,0)
|
||||
- The anchorPoint of the TMXTileMap is (0,0)
|
||||
- The TMX layers will be added as a child
|
||||
- The TMX layers will be aliased by default
|
||||
- The tileset image will be loaded using the TextureCache
|
||||
- Each tile will have a unique tag
|
||||
- Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z
|
||||
- Each object group will be treated as an MutableArray
|
||||
- Object class which will contain all the properties in a dictionary
|
||||
- Properties can be assigned to the Map, Layer, Object Group, and Object
|
||||
|
||||
Limitations:
|
||||
- It only supports one tileset per layer.
|
||||
- Embedded images are not supported
|
||||
- It only supports the XML format (the JSON format is not supported)
|
||||
|
||||
Technical description:
|
||||
Each layer is created using an TMXLayer2 (subclass of SpriteBatchNode). If you have 5 layers, then 5 TMXLayer2 will be created,
|
||||
unless the layer visibility is off. In that case, the layer won't be created at all.
|
||||
You can obtain the layers (TMXLayer2 objects) at runtime by:
|
||||
- map->getChildByTag(tag_number); // 0=1st layer, 1=2nd layer, 2=3rd layer, etc...
|
||||
- map->getLayer(name_of_the_layer);
|
||||
|
||||
Each object group is created using a TMXObjectGroup which is a subclass of MutableArray.
|
||||
You can obtain the object groups at runtime by:
|
||||
- map->getObjectGroup(name_of_the_object_group);
|
||||
|
||||
Each object is a TMXObject.
|
||||
|
||||
Each property is stored as a key-value pair in an MutableDictionary.
|
||||
You can obtain the properties at runtime by:
|
||||
|
||||
map->getProperty(name_of_the_property);
|
||||
layer->getProperty(name_of_the_property);
|
||||
objectGroup->getProperty(name_of_the_property);
|
||||
object->getProperty(name_of_the_property);
|
||||
|
||||
@since v0.8.1
|
||||
*/
|
||||
class CC_DLL TMXTiledMap2 : public Node
|
||||
{
|
||||
public:
|
||||
/** creates a TMX Tiled Map with a TMX file.*/
|
||||
static TMXTiledMap2* create(const std::string& tmxFile);
|
||||
|
||||
/** initializes a TMX Tiled Map with a TMX formatted XML string and a path to TMX resources */
|
||||
static TMXTiledMap2* createWithXML(const std::string& tmxString, const std::string& resourcePath);
|
||||
|
||||
/** return the TMXLayer2 for the specific layer */
|
||||
TMXLayer2* getLayer(const std::string& layerName) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
CC_DEPRECATED_ATTRIBUTE TMXLayer2* layerNamed(const std::string& layerName) const { return getLayer(layerName); };
|
||||
|
||||
/** return the TMXObjectGroup for the specific group */
|
||||
TMXObjectGroup* getObjectGroup(const std::string& groupName) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
CC_DEPRECATED_ATTRIBUTE TMXObjectGroup* objectGroupNamed(const std::string& groupName) const { return getObjectGroup(groupName); };
|
||||
|
||||
/** return the value for the specific property name */
|
||||
Value getProperty(const std::string& propertyName) const;
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
CC_DEPRECATED_ATTRIBUTE Value propertyNamed(const char *propertyName) const { return getProperty(propertyName); };
|
||||
|
||||
/** return properties dictionary for tile GID */
|
||||
Value getPropertiesForGID(int GID) const;
|
||||
CC_DEPRECATED_ATTRIBUTE Value propertiesForGID(int GID) const { return getPropertiesForGID(GID); };
|
||||
|
||||
/** the map's size property measured in tiles */
|
||||
inline const Size& getMapSize() const { return _mapSize; };
|
||||
inline void setMapSize(const Size& mapSize) { _mapSize = mapSize; };
|
||||
|
||||
/** the tiles's size property measured in pixels */
|
||||
inline const Size& getTileSize() const { return _tileSize; };
|
||||
inline void setTileSize(const Size& tileSize) { _tileSize = tileSize; };
|
||||
|
||||
/** map orientation */
|
||||
inline int getMapOrientation() const { return _mapOrientation; };
|
||||
inline void setMapOrientation(int mapOrientation) { _mapOrientation = mapOrientation; };
|
||||
|
||||
/** object groups */
|
||||
inline const Vector<TMXObjectGroup*>& getObjectGroups() const { return _objectGroups; };
|
||||
inline Vector<TMXObjectGroup*>& getObjectGroups() { return _objectGroups; };
|
||||
inline void setObjectGroups(const Vector<TMXObjectGroup*>& groups) {
|
||||
_objectGroups = groups;
|
||||
};
|
||||
|
||||
/** properties */
|
||||
inline ValueMap& getProperties() { return _properties; };
|
||||
inline void setProperties(const ValueMap& properties) {
|
||||
_properties = properties;
|
||||
};
|
||||
|
||||
virtual std::string getDescription() const override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @js ctor
|
||||
*/
|
||||
TMXTiledMap2();
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
*/
|
||||
virtual ~TMXTiledMap2();
|
||||
|
||||
/** initializes a TMX Tiled Map with a TMX file */
|
||||
bool initWithTMXFile(const std::string& tmxFile);
|
||||
|
||||
/** initializes a TMX Tiled Map with a TMX formatted XML string and a path to TMX resources */
|
||||
bool initWithXML(const std::string& tmxString, const std::string& resourcePath);
|
||||
|
||||
TMXLayer2 * parseLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
|
||||
TMXTilesetInfo * tilesetForLayer(TMXLayerInfo *layerInfo, TMXMapInfo *mapInfo);
|
||||
void buildWithMapInfo(TMXMapInfo* mapInfo);
|
||||
|
||||
/** the map's size property measured in tiles */
|
||||
Size _mapSize;
|
||||
/** the tiles's size property measured in pixels */
|
||||
Size _tileSize;
|
||||
/** map orientation */
|
||||
int _mapOrientation;
|
||||
/** object groups */
|
||||
Vector<TMXObjectGroup*> _objectGroups;
|
||||
/** properties */
|
||||
ValueMap _properties;
|
||||
|
||||
//! tile properties
|
||||
ValueMapIntKey _tileProperties;
|
||||
|
||||
private:
|
||||
CC_DISALLOW_COPY_AND_ASSIGN(TMXTiledMap2);
|
||||
|
||||
};
|
||||
|
||||
// end of tilemap_parallax_nodes group
|
||||
/// @}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif //__CCTMX_TILE_MAP2_H__
|
||||
|
||||
|
|
@ -254,6 +254,15 @@ struct V3F_C4B_T2F
|
|||
Tex2F texCoords; // 8 bytes
|
||||
};
|
||||
|
||||
//! a Vec2 with a vertex point, a tex coord point
|
||||
struct V2F_T2F
|
||||
{
|
||||
//! vertices (2F)
|
||||
Vec2 vertices;
|
||||
//! tex coords (2F)
|
||||
Tex2F texCoords;
|
||||
};
|
||||
|
||||
//! A Triangle of V2F_C4B_T2F
|
||||
struct V2F_C4B_T2F_Triangle
|
||||
{
|
||||
|
@ -304,6 +313,18 @@ struct V2F_C4F_T2F_Quad
|
|||
V2F_C4F_T2F tr;
|
||||
};
|
||||
|
||||
struct V2F_T2F_Quad
|
||||
{
|
||||
//! bottom left
|
||||
V2F_T2F bl;
|
||||
//! bottom right
|
||||
V2F_T2F br;
|
||||
//! top left
|
||||
V2F_T2F tl;
|
||||
//! top right
|
||||
V2F_T2F tr;
|
||||
};
|
||||
|
||||
//! Blend Function used for textures
|
||||
struct BlendFunc
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue