Example #1
0
bool Level::collidesY(const sf::FloatRect& boundingBox, const DynamicTile* exclude) const
{
	// check for collision with level rect
	if (boundingBox.top < m_levelData.levelRect.top || boundingBox.top + boundingBox.height > m_levelData.levelRect.top + m_levelData.levelRect.height)
	{
		return true;
	}

	// normalize bounding box values so they match our collision grid. Wondering about the next two lines? Me too. We just don't want to floor values that are exactly on the boundaries. But only those that are down and right.
	int bottomY = static_cast<int>(floor((boundingBox.top + boundingBox.height) / tileHeight) == (boundingBox.top + boundingBox.height) / tileHeight ? (boundingBox.top + boundingBox.height) / tileHeight - 1 : floor((boundingBox.top + boundingBox.height) / tileHeight));
	int rightX = static_cast<int>(floor((boundingBox.left + boundingBox.width) / tileWidth) == (boundingBox.left + boundingBox.width) / tileWidth ? (boundingBox.left + boundingBox.width) / tileWidth - 1 : floor((boundingBox.left + boundingBox.width) / tileWidth));
	sf::Vector2i topLeft(static_cast<int>(floor(boundingBox.left / tileWidth)), static_cast<int>(floor(boundingBox.top / tileHeight)));
	sf::Vector2i topRight(rightX, static_cast<int>(floor(boundingBox.top / tileHeight)));
	sf::Vector2i bottomLeft(static_cast<int>(floor(boundingBox.left / tileWidth)), bottomY);
	sf::Vector2i bottomRight(rightX, bottomY);

	// check top side
	int y = topLeft.y;
	for (int x = topLeft.x; x <= topRight.x; x++)
	{
		if (y > m_levelData.collidableTilePositions.size() || y < 0 || x < 0 || x > m_levelData.collidableTilePositions[y].size())
		{
			// check for out of range (happens seldom because of rounding problems above)
			return true;
		}
		if (m_levelData.collidableTilePositions[y][x])
		{
			return true;
		}
	}

	// check bottom side
	y = bottomLeft.y;
	for (int x = bottomLeft.x; x <= bottomRight.x; x++)
	{
		if (y > m_levelData.collidableTilePositions.size() || y < 0 || x < 0 || x > m_levelData.collidableTilePositions[y].size())
		{
			// check for out of range (happens seldom because of rounding problems above)
			return true;
		}
		if (m_levelData.collidableTilePositions[y][x])
		{
			return true;
		}
	}

	// check collidable dynamic tiles
	for (GameObject* go : *m_dynamicTiles)
	{
		if (!go->isViewable()) continue;
		DynamicTile* tile = dynamic_cast<DynamicTile*>(go);
		if (tile != nullptr && tile != exclude && tile->getIsCollidable() && tile->getBoundingBox()->intersects(boundingBox))
		{
			return true;
		}
	}

	return false;
}
Example #2
0
void Level::collideWithDynamicTiles(LevelMovableGameObject* mob, const sf::FloatRect* boundingBox) const
{
	for (auto& it : *m_dynamicTiles)
	{
		DynamicTile* tile = dynamic_cast<DynamicTile*>(it);
		if (tile != nullptr && (tile->getBoundingBox()->intersects(*boundingBox)))
		{
			tile->onHit(mob);
		}
	}
}
Example #3
0
void Level::collideWithDynamicTiles(Spell* spell, const sf::FloatRect* boundingBox) const
{
	size_t size = m_dynamicTiles->size(); // Note: this loop type allows objects to be added to the back of the list while iterating over it.
	for (size_t i = 0; i < size; ++i)
	{
		DynamicTile* tile = dynamic_cast<DynamicTile*>(m_dynamicTiles->at(i));
		if (tile != nullptr && (tile->getBoundingBox()->intersects(*boundingBox)))
		{
			tile->onHit(spell);
		}
	}
}