bool PhyTileEngine::IsRectCollidesTile(core::recti rect_, video::SColor blockType_, int tileX, int tileY) { const LayerTile* layerTile = m_physicLayerTile->GetLayerTile(tileX, tileY); if (layerTile->GetTilesetId() >= 0) { Tileset* tileset = m_tilemap->GetTileset( layerTile->GetTilesetId() ); video::ITexture* tilesetText = tileset->GetTexture( m_driver ); // Get intersection with physic layer image to be in bounds core::recti srcRect = rect_; core::recti tileRect( tileX * m_tilemap->GetTileWidth(), tileY * m_tilemap->GetTileHeight(), (tileX + 1) * m_tilemap->GetTileWidth(), (tileY + 1) * m_tilemap->GetTileHeight() ); //srcRect.clipAgainst(tileRect); srcRect.UpperLeftCorner.X = core::max_( rect_.UpperLeftCorner.X, tileRect.UpperLeftCorner.X); srcRect.LowerRightCorner.X = core::min_( rect_.LowerRightCorner.X, tileRect.LowerRightCorner.X); srcRect.UpperLeftCorner.Y = core::max_( rect_.UpperLeftCorner.Y, tileRect.UpperLeftCorner.Y); srcRect.LowerRightCorner.Y = core::min_( rect_.LowerRightCorner.Y, tileRect.LowerRightCorner.Y); // move to tileset coords s32 rectWidth = srcRect.getWidth(); s32 rectHeight = srcRect.getHeight(); srcRect.UpperLeftCorner.X = (srcRect.UpperLeftCorner.X % m_tilemap->GetTileWidth()) + tileset->GetTileX(layerTile->GetTileId()) * m_tilemap->GetTileWidth(); srcRect.UpperLeftCorner.Y = (srcRect.UpperLeftCorner.Y % m_tilemap->GetTileHeight()) + tileset->GetTileY(layerTile->GetTileId()) * m_tilemap->GetTileHeight(); srcRect.LowerRightCorner.X = srcRect.UpperLeftCorner.X + rectWidth; srcRect.LowerRightCorner.Y = srcRect.UpperLeftCorner.Y + rectHeight; u8* pixelData = static_cast<u8 *>( tilesetText->lock(true) ); core::dimension2du textSize = tilesetText->getSize(); u32 pixelSize = tilesetText->getPitch() / textSize.Width; bool isCollision = false; //!!!NOTE: suppose format video::ECOLOR_FORMAT::ECF_A8R8G8B8 for( s32 x = srcRect.UpperLeftCorner.X; x < srcRect.LowerRightCorner.X && !isCollision; ++x ) for( s32 y = srcRect.UpperLeftCorner.Y; y < srcRect.LowerRightCorner.Y && !isCollision; ++y ) { s32 index = y * tilesetText->getPitch() + x * pixelSize; video::SColor color( *((u32*)(pixelData + index)) ); if( color == blockType_ ) { isCollision = true; } } tilesetText->unlock(); return isCollision; } return false; }
void TileLayer::parseElement(tinyxml2::XMLElement* layerElement, Map* map) { // Get properties auto properties = layerElement->FirstChildElement("properties"); if(properties != 0) parseProperties(properties); m_name = layerElement->Attribute("name"); m_width = layerElement->UnsignedAttribute("width"); m_height = layerElement->UnsignedAttribute("height"); // Parse data unsigned int x = 0; unsigned int y = 0; auto tile = layerElement->FirstChildElement("data")->FirstChildElement("tile"); while(tile != 0) { unsigned int gid = tile->UnsignedAttribute("gid"); // Read out the flags bool flipped_horizontally = (gid & FLIPPED_HORIZONTALLY_FLAG) != 0; bool flipped_vertically = (gid & FLIPPED_VERTICALLY_FLAG) != 0; // TODO: implement this //bool flipped_diagonally = (gid & FLIPPED_DIAGONALLY_FLAG) != 0; // Clear the flags gid &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG); // Find correct tileset for(int i = map->tilesets.size() - 1; i >= 0; --i) { Tileset* tileset = map->tilesets[i]; if(tileset->GetFirstGID() <= gid) { if(x >= map->GetWidth()) { x = 0; y++; } const pmath::Rect t(static_cast<float>(x * tileset->GetTileWidth()), static_cast<float>(y * tileset->GetTileHeight()), static_cast<float>(tileset->GetTileWidth()), static_cast<float>(tileset->GetTileHeight())); auto tile = new Tile(t); if(flipped_horizontally) tile->transform.SetScale(-1, tile->transform.GetScale().y); if(flipped_vertically) tile->transform.SetScale(tile->transform.GetScale().x, -1); tile->parent = static_cast<GameObject*>(map); const pmath::Rect texCoords = tileset->GetTile(gid - tileset->GetFirstGID()); m_tiles.push_back(tile); m_spriteBatches.at(tileset->GetTexture())->AddSprite(&tile->transform, "", pmath::Vec4(1,1,1,1), texCoords); x++; break; } } tile = tile->NextSiblingElement("tile"); } }
void TileLayer::parseElement(tinyxml2::XMLElement* layerElement, Map* map) { // Get properties auto properties = layerElement->FirstChildElement("properties"); if(properties != 0) parseProperties(properties); m_name = layerElement->Attribute("name"); m_width = layerElement->UnsignedAttribute("width"); m_height = layerElement->UnsignedAttribute("height"); if (layerElement->Attribute("visible") != 0) { m_active = layerElement->IntAttribute("visible") == 0 ? false : true; } else m_active = true; // Parse data unsigned int x = 0; unsigned int y = 0; auto tile = layerElement->FirstChildElement("data")->FirstChildElement("tile"); while(tile != 0) { unsigned int gid = tile->UnsignedAttribute("gid"); // Go to the next "line" if (x >= map->GetWidth()) { x = 0; y++; } // Tile is "empty space" if (gid == 0) { x++; tile = tile->NextSiblingElement("tile"); continue; } // Read out the flags const bool flipped_horizontally = (gid & FLIPPED_HORIZONTALLY_FLAG) != 0; const bool flipped_vertically = (gid & FLIPPED_VERTICALLY_FLAG) != 0; const bool flipped_diagonally = (gid & FLIPPED_DIAGONALLY_FLAG) != 0; // Clear the flags gid &= ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG); // Find correct tileset for(int i = map->tilesets.size() - 1; i >= 0; --i) { Tileset* tileset = map->tilesets[i].get(); if (tileset->GetFirstGID() <= gid) { const pmath::Rect t(static_cast<float>(x * tileset->GetTileWidth()), static_cast<float>(y * tileset->GetTileHeight()), static_cast<float>(tileset->GetTileWidth()), static_cast<float>(tileset->GetTileHeight())); auto tile = new Tile(t); if (flipped_diagonally) { if (flipped_horizontally && flipped_vertically) { tile->transform.Rotate(90); tile->transform.SetScale(-1, tile->transform.GetScale().y); } else if (flipped_horizontally) { tile->transform.Rotate(90); } else if (flipped_vertically) { tile->transform.Rotate(-90); } else { tile->transform.Rotate(-90); tile->transform.SetScale(-1, tile->transform.GetScale().y); } } else { if (flipped_horizontally) tile->transform.SetScale(-1, tile->transform.GetScale().y); if (flipped_vertically) tile->transform.SetScale(tile->transform.GetScale().x, -1); } map->AddChild(tile); const pmath::Rect texCoords = tileset->GetTile(gid - tileset->GetFirstGID()); m_tiles.push_back(tile); m_spriteBatches.at(tileset->GetTexture())->AddSprite(&tile->transform, "", pmath::Vec4(1, 1, 1, 1), texCoords); x++; break; } } tile = tile->NextSiblingElement("tile"); } }