1111111 1000001 1001001 1000011 1000111 1111111
#ifndef LEVEL_H #define LEVEL_H #pragma comment(lib,"Box2D.lib") #pragma comment(lib,"sfml-graphics.lib") #pragma comment(lib,"sfml-window.lib") #pragma comment(lib,"sfml-system.lib") #include <string> #include <vector> #include <map> #include <SFML/Graphics.hpp>
struct Object { int GetPropertyInt(std::string name); float GetPropertyFloat(std::string name); std::string GetPropertyString(std::string name); std::string name; std::string type; sf::Rect<int> rect; std::map<std::string, std::string> properties; sf::Sprite sprite; };
struct Layer { int opacity; std::vector<sf::Sprite> tiles; };
class Level { public: bool LoadFromFile(std::string filename); Object GetObject(std::string name); std::vector<Object> GetObjects(std::string name); void Draw(sf::RenderWindow &window); sf::Vector2i GetTileSize(); private: int width, height, tileWidth, tileHeight; int firstTileID; sf::Rect<float> drawingBounds; sf::Texture tilesetImage; std::vector<Object> objects; std::vector<Layer> layers; }; #endif
#include "level.h" #include <iostream> #include "tinyxml.h"
int Object::GetPropertyInt(std::string name) { return atoi(properties[name].c_str()); } float Object::GetPropertyFloat(std::string name) { return strtod(properties[name].c_str(), NULL); } std::string Object::GetPropertyString(std::string name) { return properties[name]; }
bool Level::LoadFromFile(std::string filename) { TiXmlDocument levelFile(filename.c_str()); // XML- if(!levelFile.LoadFile()) { std::cout << "Loading level \"" << filename << "\" failed." << std::endl; return false; } // map TiXmlElement *map; map = levelFile.FirstChildElement("map"); // : <map version="1.0" orientation="orthogonal" // width="10" height="10" tilewidth="34" tileheight="34"> width = atoi(map->Attribute("width")); height = atoi(map->Attribute("height")); tileWidth = atoi(map->Attribute("tilewidth")); tileHeight = atoi(map->Attribute("tileheight")); // TiXmlElement *tilesetElement; tilesetElement = map->FirstChildElement("tileset"); firstTileID = atoi(tilesetElement->Attribute("firstgid")); // source - image TiXmlElement *image; image = tilesetElement->FirstChildElement("image"); std::string imagepath = image->Attribute("source"); // sf::Image img; if(!img.loadFromFile(imagepath)) { std::cout << "Failed to load tile sheet." << std::endl; return false; } // (109, 159, 185) // - , , 16- // "6d9fb9" img.createMaskFromColor(sf::Color(109, 159, 185)); // tilesetImage.loadFromImage(img); // tilesetImage.setSmooth(false); // int columns = tilesetImage.getSize().x / tileWidth; int rows = tilesetImage.getSize().y / tileHeight; // (TextureRect) std::vector<sf::Rect<int>> subRects; for(int y = 0; y < rows; y++) for(int x = 0; x < columns; x++) { sf::Rect<int> rect; rect.top = y * tileHeight; rect.height = tileHeight; rect.left = x * tileWidth; rect.width = tileWidth; subRects.push_back(rect); } // TiXmlElement *layerElement; layerElement = map->FirstChildElement("layer"); while(layerElement) { Layer layer; // opacity, , if (layerElement->Attribute("opacity") != NULL) { float opacity = strtod(layerElement->Attribute("opacity"), NULL); layer.opacity = 255 * opacity; } else { layer.opacity = 255; } // <data> TiXmlElement *layerDataElement; layerDataElement = layerElement->FirstChildElement("data"); if(layerDataElement == NULL) { std::cout << "Bad map. No layer information found." << std::endl; } // <tile> - TiXmlElement *tileElement; tileElement = layerDataElement->FirstChildElement("tile"); if(tileElement == NULL) { std::cout << "Bad map. No tile information found." << std::endl; return false; } int x = 0; int y = 0; while(tileElement) { int tileGID = atoi(tileElement->Attribute("gid")); int subRectToUse = tileGID - firstTileID; // TextureRect if (subRectToUse >= 0) { sf::Sprite sprite; sprite.setTexture(tilesetImage); sprite.setTextureRect(subRects[subRectToUse]); sprite.setPosition(x * tileWidth, y * tileHeight); sprite.setColor(sf::Color(255, 255, 255, layer.opacity)); layer.tiles.push_back(sprite); } tileElement = tileElement->NextSiblingElement("tile"); x++; if (x >= width) { x = 0; y++; if(y >= height) y = 0; } } layers.push_back(layer); layerElement = layerElement->NextSiblingElement("layer"); } // TiXmlElement *objectGroupElement; // if (map->FirstChildElement("objectgroup") != NULL) { objectGroupElement = map->FirstChildElement("objectgroup"); while (objectGroupElement) { // <object> TiXmlElement *objectElement; objectElement = objectGroupElement->FirstChildElement("object"); while(objectElement) { // - , , , etc std::string objectType; if (objectElement->Attribute("type") != NULL) { objectType = objectElement->Attribute("type"); } std::string objectName; if (objectElement->Attribute("name") != NULL) { objectName = objectElement->Attribute("name"); } int x = atoi(objectElement->Attribute("x")); int y = atoi(objectElement->Attribute("y")); int width, height; sf::Sprite sprite; sprite.setTexture(tilesetImage); sprite.setTextureRect(sf::Rect<int>(0,0,0,0)); sprite.setPosition(x, y); if (objectElement->Attribute("width") != NULL) { width = atoi(objectElement->Attribute("width")); height = atoi(objectElement->Attribute("height")); } else { width = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].width; height = subRects[atoi(objectElement->Attribute("gid")) - firstTileID].height; sprite.setTextureRect(subRects[atoi(objectElement->Attribute("gid")) - firstTileID]); } // Object object; object.name = objectName; object.type = objectType; object.sprite = sprite; sf::Rect <int> objectRect; objectRect.top = y; objectRect.left = x; objectRect.height = height; objectRect.width = width; object.rect = objectRect; // "" TiXmlElement *properties; properties = objectElement->FirstChildElement("properties"); if (properties != NULL) { TiXmlElement *prop; prop = properties->FirstChildElement("property"); if (prop != NULL) { while(prop) { std::string propertyName = prop->Attribute("name"); std::string propertyValue = prop->Attribute("value"); object.properties[propertyName] = propertyValue; prop = prop->NextSiblingElement("property"); } } } // objects.push_back(object); objectElement = objectElement->NextSiblingElement("object"); } objectGroupElement = objectGroupElement->NextSiblingElement("objectgroup"); } } else { std::cout << "No object layers found..." << std::endl; } return true; }
Object Level::GetObject(std::string name) { // for (int i = 0; i < objects.size(); i++) if (objects[i].name == name) return objects[i]; } std::vector<Object> Level::GetObjects(std::string name) { // std::vector<Object> vec; for(int i = 0; i < objects.size(); i++) if(objects[i].name == name) vec.push_back(objects[i]); return vec; } sf::Vector2i Level::GetTileSize() { return sf::Vector2i(tileWidth, tileHeight); } void Level::Draw(sf::RenderWindow &window) { // ( !) for(int layer = 0; layer < layers.size(); layer++) for(int tile = 0; tile < layers[layer].tiles.size(); tile++) window.draw(layers[layer].tiles[tile]); }
#include "level.h" int main() { Level level; level.LoadFromFile("test.tmx"); sf::RenderWindow window; window.create(sf::VideoMode(800, 600), "Level.h test"); while(window.isOpen()) { sf::Event event; while(window.pollEvent(event)) { if(event.type == sf::Event::Closed) window.close(); } window.clear(); level.Draw(window); window.display(); } return 0; }
#include "level.h" #include <iostream> int main() { Level level; level.LoadFromFile("test.tmx"); Object kolobosha = level.GetObject("Kolobosha"); std::cout << kolobosha.name << std::endl; std::cout << kolobosha.type << std::endl; std::cout << kolobosha.GetPropertyInt("health") << std::endl; std::cout << kolobosha.GetPropertyString("mood") << std::endl; sf::RenderWindow window; window.create(sf::VideoMode(800, 600), "Kolobosha adventures"); while(window.isOpen()) { sf::Event event; while(window.pollEvent(event)) { if(event.type == sf::Event::Closed) window.close(); } window.clear(); level.Draw(window); window.display(); } return 0; }
#include "level.h" #include <Box2D\Box2D.h> #include <iostream> #include <random> Object player; b2Body* playerBody; std::vector<Object> coin; std::vector<b2Body*> coinBody; std::vector<Object> enemy; std::vector<b2Body*> enemyBody;
int main() { srand(time(NULL)); Level lvl; lvl.LoadFromFile("platformer.tmx"); b2Vec2 gravity(0.0f, 1.0f); b2World world(gravity); sf::Vector2i tileSize = lvl.GetTileSize();
std::vector<Object> block = lvl.GetObjects("block"); for(int i = 0; i < block.size(); i++) { b2BodyDef bodyDef; bodyDef.type = b2_staticBody; bodyDef.position.Set(block[i].rect.left + tileSize.x / 2 * (block[i].rect.width / tileSize.x - 1), block[i].rect.top + tileSize.y / 2 * (block[i].rect.height / tileSize.y - 1)); b2Body* body = world.CreateBody(&bodyDef); b2PolygonShape shape; shape.SetAsBox(block[i].rect.width / 2, block[i].rect.height / 2); body->CreateFixture(&shape,1.0f); }
bodyDef.type = b2_staticBody;
bodyDef.position.Set(block[i].rect.left + tileSize.x / 2 * (block[i].rect.width / tileSize.x - 1), block[i].rect.top + tileSize.y / 2 * (block[i].rect.height / tileSize.y - 1));
b2Body* body = world.CreateBody(&bodyDef);
b2PolygonShape shape; shape.SetAsBox(block[i].rect.width / 2, block[i].rect.height / 2);
body->CreateFixture(&shape,1.0f);
coin = lvl.GetObjects("coin"); for(int i = 0; i < coin.size(); i++) { b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(coin[i].rect.left + tileSize.x / 2 * (coin[i].rect.width / tileSize.x - 1), coin[i].rect.top + tileSize.y / 2 * (coin[i].rect.height / tileSize.y - 1)); bodyDef.fixedRotation = true; b2Body* body = world.CreateBody(&bodyDef); b2PolygonShape shape; shape.SetAsBox(coin[i].rect.width / 2, coin[i].rect.height / 2); body->CreateFixture(&shape,1.0f); coinBody.push_back(body); } enemy = lvl.GetObjects("enemy"); for(int i = 0; i < enemy.size(); i++) { b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(enemy[i].rect.left + tileSize.x / 2 * (enemy[i].rect.width / tileSize.x - 1), enemy[i].rect.top + tileSize.y / 2 * (enemy[i].rect.height / tileSize.y - 1)); bodyDef.fixedRotation = true; b2Body* body = world.CreateBody(&bodyDef); b2PolygonShape shape; shape.SetAsBox(enemy[i].rect.width / 2, enemy[i].rect.height / 2); body->CreateFixture(&shape,1.0f); enemyBody.push_back(body); } player = lvl.GetObject("player"); b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(player.rect.left, player.rect.top); bodyDef.fixedRotation = true; playerBody = world.CreateBody(&bodyDef); b2PolygonShape shape; shape.SetAsBox(player.rect.width / 2, player.rect.height / 2); b2FixtureDef fixtureDef; fixtureDef.shape = &shape; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f; playerBody->CreateFixture(&fixtureDef);
bodyDef.fixedRotation = true;
sf::Vector2i screenSize(800, 600); sf::RenderWindow window; window.create(sf::VideoMode(screenSize.x, screenSize.y), "Game");
sf::View view; view.reset(sf::FloatRect(0.0f, 0.0f, screenSize.x, screenSize.y)); view.setViewport(sf::FloatRect(0.0f, 0.0f, 2.0f, 2.0f));
while(window.isOpen()) { sf::Event evt; while(window.pollEvent(evt)) { switch(evt.type) { case sf::Event::Closed: window.close(); break;
case sf::Event::KeyPressed: if(evt.key.code == sf::Keyboard::W) playerBody->SetLinearVelocity(b2Vec2(0.0f, -15.0f)); if(evt.key.code == sf::Keyboard::D) playerBody->SetLinearVelocity(b2Vec2(5.0f, 0.0f)); if(evt.key.code == sf::Keyboard::A) playerBody->SetLinearVelocity(b2Vec2(-5.0f, 0.0f)); break;
world.Step(1.0f / 60.0f, 1, 1);
for(b2ContactEdge* ce = playerBody->GetContactList(); ce; ce = ce->next) { b2Contact* c = ce->contact;
for(int i = 0; i < coinBody.size(); i++) if(c->GetFixtureA() == coinBody[i]->GetFixtureList()) { coinBody[i]->DestroyFixture(coinBody[i]->GetFixtureList()); coin.erase(coin.begin() + i); coinBody.erase(coinBody.begin() + i); }
for(int i = 0; i < enemyBody.size(); i++) if(c->GetFixtureA() == enemyBody[i]->GetFixtureList()) { if(playerBody->GetPosition().y < enemyBody[i]->GetPosition().y) { playerBody->SetLinearVelocity(b2Vec2(0.0f, -10.0f)); enemyBody[i]->DestroyFixture(enemyBody[i]->GetFixtureList()); enemy.erase(enemy.begin() + i); enemyBody.erase(enemyBody.begin() + i); }
else { int tmp = (playerBody->GetPosition().x < enemyBody[i]->GetPosition().x) ? -1 : 1; playerBody->SetLinearVelocity(b2Vec2(10.0f * tmp, 0.0f)); } } }
for(int i = 0; i < enemyBody.size(); i++) { if(enemyBody[i]->GetLinearVelocity() == b2Vec2_zero) { int tmp = (rand() % 2 == 1) ? 1 : -1; enemyBody[i]->SetLinearVelocity(b2Vec2(5.0f * tmp, 0.0f)); } }
b2Vec2 pos = playerBody->GetPosition(); view.setCenter(pos.x + screenSize.x / 4, pos.y + screenSize.y / 4); window.setView(view);
player.sprite.setPosition(pos.x, pos.y); for(int i = 0; i < coin.size(); i++) coin[i].sprite.setPosition(coinBody[i]->GetPosition().x, coinBody[i]->GetPosition().y); for(int i = 0; i < enemy.size(); i++) enemy[i].sprite.setPosition(enemyBody[i]->GetPosition().x, enemyBody[i]->GetPosition().y);
window.clear(); lvl.Draw(window); window.draw(player.sprite); for(int i = 0; i < coin.size(); i++) window.draw(coin[i].sprite); for(int i = 0; i < enemy.size(); i++) window.draw(enemy[i].sprite); window.display();
} return 0; }
Source: https://habr.com/ru/post/199064/
All Articles