Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SFML\Graphics.hpp>
- #include <string>
- #include <iostream>
- #include <utility>
- #include <set>
- #include <vector>
- class Level {
- public:
- enum ObjectType {
- Intangible,
- Material
- };
- enum Change {
- High,
- Low,
- Right,
- Left,
- Nothing
- };
- private:
- sf::Image image;
- sf::Texture texture;
- sf::Sprite sprite;
- std::string path_to_textures;
- sf::Vector2u window_size;
- sf::Vector2<int> last_object_size; //размер последнего установленного спрайта. Нужен для передачи объекта в контейнер, в методе SetObjectPosition
- class Object {
- public:
- float x_position, y_position;
- Level::ObjectType object_type;
- sf::Vector2<int> object_size;
- Object(const float& x_position) {
- this->x_position = x_position;
- }
- Object(const float& x_position, const float& y_position, const sf::Vector2<int>& object_size, const Level::ObjectType& object_type) {
- this->x_position = x_position;
- this->y_position = y_position;
- this->object_type = object_type;
- this->object_size = object_size;
- }
- bool operator < (const Object& object) const {
- if (x_position < object.x_position) {
- return true;
- }
- else if (x_position == object.x_position) {
- if (y_position < object.y_position) {
- return true;
- }
- }
- return false;
- }
- };
- std::set<Object> level_material_objects; //контейнер для хранения объектов карты
- public:
- Level(const std::string& path_to_textures, const sf::Vector2u& window_size) {
- this->path_to_textures = path_to_textures;
- this->window_size = window_size;
- image.loadFromFile(path_to_textures);
- texture.loadFromImage(image);
- sprite.setTexture(texture);
- }
- const sf::Sprite& GetSprite() const {
- return sprite;
- }
- void SetSprite(const int& x_texture_coord, const int& y_texture_coord, const int& texture_width, const int& texture_height) {
- sprite.setTextureRect(sf::IntRect(x_texture_coord, y_texture_coord, texture_width, texture_height));
- last_object_size.x = texture_width;
- last_object_size.y = texture_height;
- }
- void SetObjectPosition(const float& x_position, const float& y_position, const ObjectType& object_type) {
- sprite.setPosition(x_position, y_position);
- if (object_type == Material) {
- level_material_objects.emplace(x_position, y_position, last_object_size, object_type);
- }
- }
- std::pair<sf::Vector2f, sf::Vector2u> NearMaterialObject(const float& x_position, const float& y_position, const int& width, const int& height) {
- bool find_object = false;
- std::pair<sf::Vector2f, sf::Vector2u> object;
- std::set<Object>::iterator it = --(level_material_objects.lower_bound(x_position));
- if (it == --(level_material_objects.begin())) {
- it = level_material_objects.begin();
- }
- else {
- --it;
- if (it == --(level_material_objects.begin())) {
- it = level_material_objects.begin();
- }
- }
- for (it; it != level_material_objects.end(); ++it) {
- if (((x_position <= it->x_position) && ((x_position + width) > it->x_position)) // правая часть в объекте или внутри объекта, или с краю (слева)
- || ((x_position > it->x_position) && ((x_position + width) < (it->x_position + it->object_size.x))) //внутри объекта
- || (((x_position + width) >= (it->x_position + it->object_size.x)) && (x_position < (it->x_position + it->object_size.x)))/* левая часть в объекте или внутри объекта, или с краю (справа) */) {
- if (!find_object) {
- find_object = true;
- object.first.x = it->x_position;
- object.first.y = it->y_position;
- object.second.x = it->object_size.x;
- object.second.y = it->object_size.y;
- }
- if (((y_position < it->y_position) && ((y_position + height) > it->y_position))
- || ((y_position > it->y_position) && ((y_position + height) < (it->y_position + it->object_size.y)))
- || ((y_position < (it->y_position + it->object_size.y)) && ((y_position + height) >=(it->y_position + it->object_size.y)))) {
- object.first.x = it->x_position;
- object.first.y = it->y_position;
- object.second.x = it->object_size.x;
- object.second.y = it->object_size.y;
- break;
- }
- if (find_object && ((it->y_position - (y_position + height)) >= 0) && ((it->y_position - (y_position + height)) < (object.first.y - (y_position + height)))) {
- object.first.x = it->x_position;
- object.first.y = it->y_position;
- object.second.x = it->object_size.x;
- object.second.y = it->object_size.y;
- }
- //std::cout << "Объект: " << it->x_position << ";" << it->y_position << " " << it->object_size.x << "x" << it->object_size.y << std::endl;
- //std::cout << "Персонаж: " << y_position + height << " Объект: " << it->y_position + it->object_size.y << std::endl;
- //std::cout << "Объект для возврата: " << object.first.x << ";" << object.first.y << " " << object.second.x << "x" << object.second.y << std::endl;
- }
- else if (find_object) {
- break;
- }
- //system("pause");
- }
- //std::cout << "Объект: " << object.first.x << ";" << object.first.y << " " << object.second.x << "x" << object.second.y << std::endl;
- return object;
- }
- };
- class Character {
- public:
- enum Direction {
- Forward = 1,
- Backward = -1,
- Up = 2,
- Stay = 0
- };
- private:
- sf::Image image;
- sf::Texture texture;
- sf::Sprite sprite;
- std::string path_to_textures;
- sf::Vector2u window_size;
- sf::Vector2f last_position; //последняя позиция персонажа
- sf::Vector2u base_character_rack_coords, base_character_rack_size; //координаты и размер базовой стойки персонажа
- float character_speed = 0, character_weight = 0;
- sf::Vector2f character_dimensions; //габариты персонажа
- float jump_speed, fall_speed;
- sf::Clock clock;
- double time;
- bool is_jump = false, is_fall = false;
- bool block_control = false;
- void CharacterDirection(const Direction& direction) {
- if (direction == Direction::Forward) {
- sprite.setOrigin(0, 0);
- sprite.setScale(character_dimensions.x / base_character_rack_size.x, character_dimensions.y / base_character_rack_size.y);
- }
- else if (direction == Direction::Backward) {
- sprite.setOrigin(base_character_rack_size.x, 0);
- sprite.setScale(-character_dimensions.x / base_character_rack_size.x, character_dimensions.y / base_character_rack_size.y);
- }
- }
- public:
- Character(const std::string& path_to_textures, const sf::Vector2u& window_size, const sf::Vector2u& base_character_rack_coords, const sf::Vector2u& base_character_rack_size) {
- this->path_to_textures = path_to_textures;
- image.loadFromFile(path_to_textures);
- image.createMaskFromColor(sf::Color(0, 14, 88));
- texture.loadFromImage(image);
- sprite.setTexture(texture);
- sprite.setTextureRect(sf::IntRect(base_character_rack_coords.x, base_character_rack_coords.y, base_character_rack_size.x, base_character_rack_size.y));
- this->window_size = window_size;
- this->base_character_rack_coords = base_character_rack_coords;
- this->base_character_rack_size = base_character_rack_size;
- character_dimensions.x = base_character_rack_size.x;
- character_dimensions.y = base_character_rack_size.y;
- }
- const sf::Sprite& GetSprite() const {
- return sprite;
- }
- void SetCharacterSpeed(const float& character_speed) {
- this->character_speed = character_speed;
- }
- const float& GetChatacterSpeed() const {
- return character_speed;
- }
- void SetCharacterWeight(const float& character_weight) {
- this->character_weight = character_weight;
- }
- const float& GetChatacterWeight() const {
- return character_weight;
- }
- void Update() {
- time = clock.getElapsedTime().asMicroseconds()*0.000001;
- clock.restart();
- if (is_jump) {
- Jump();
- }
- }
- void Move(const Direction& direction) {
- last_position = sprite.getPosition();
- if (direction != Stay) {
- if (!block_control) {
- if (direction == Forward || direction == Backward) {
- CharacterDirection(direction);
- sprite.move(direction*character_speed * 1000 * 0.07*time, 0);
- }
- else if (direction == Up) {
- Jump();
- }
- }
- }
- else {
- }
- }
- const sf::Vector2f& GetCharacterPosition() const {
- return sprite.getPosition();
- }
- void SetCharacterPosition(const float& x, const float& y) {
- sprite.setPosition(x, y);
- }
- const bool& IsJump() const {
- return is_jump;
- }
- const bool& IsFall() const {
- return is_fall;
- }
- void Fall(const bool& fall) {
- if (!is_jump) {
- if (!is_fall) {
- is_fall = true;
- fall_speed = 0;
- }
- if (!fall) {
- is_fall = false;
- }
- else {
- last_position = sprite.getPosition();
- sprite.move(0, fall_speed * 1000 * 0.07*time);
- fall_speed += 9.8*time;
- }
- }
- }
- void Jump(const bool& jump = true) {
- if (!jump) {
- is_jump = false;
- is_fall = true;
- fall_speed = 0;
- }
- if (!is_fall) {
- if (!is_jump) {
- jump_speed = 300 / character_weight;
- is_jump = true;
- }
- else {
- last_position = sprite.getPosition();
- sprite.move(0, -jump_speed * 1000 * 0.07*time);
- jump_speed -= 9.8*time;
- if (jump_speed <= 0) {
- is_jump = false;
- is_fall = true;
- fall_speed = 0;
- }
- }
- }
- }
- void SetCharacterDimensions(const float& scale) {
- sprite.setScale(1 * scale, 1 * scale);
- character_dimensions.x *= scale;
- character_dimensions.y *= scale;
- }
- const sf::Vector2f& GetCharacterDimensions() const {
- return character_dimensions;
- }
- const sf::Vector2f& GetCharacterLastPosition() const {
- return last_position;
- }
- void SetBlock(const bool& block) {
- block_control = block;
- }
- };
- void Move(Character*& character, Level*& level) {
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
- character->Move(Character::Direction::Forward);
- }
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
- character->Move(Character::Direction::Backward);
- }
- std::pair<sf::Vector2f, sf::Vector2u> object = level->NearMaterialObject(character->GetCharacterPosition().x + 22, character->GetCharacterPosition().y, character->GetCharacterDimensions().x - 44, character->GetCharacterDimensions().y); // +22 по X и -44 по размеру спрайта для того, чтобы были задействованы только ноги персонажа
- if (!character->IsJump()) {
- if (!character->IsFall()) {
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
- character->Move(Character::Direction::Up);
- }
- }
- if ((character->GetCharacterPosition().y + character->GetCharacterDimensions().y) >= object.first.y) { // если персонаж на объекте
- character->Fall(false);
- character->SetBlock(false);
- if ((character->GetCharacterPosition().y + character->GetCharacterDimensions().y) > object.first.y) { // если персонаж внутри объекта
- if ((character->GetCharacterPosition().y + character->GetCharacterDimensions().y) - object.first.y <= 2) { //если разница между положением персонажа и объекта составляет 2 пикселя
- character->SetCharacterPosition(character->GetCharacterLastPosition().x, object.first.y - character->GetCharacterDimensions().y);
- }
- else {
- character->SetBlock(true);
- character->SetCharacterPosition(character->GetCharacterLastPosition().x, character->GetCharacterLastPosition().y);
- }
- }
- }
- else {
- character->Fall(true);
- }
- /*std::cout << "Положение объекта: x [" << object.first.x << ";" << object.first.x + object.second.x << ")"
- << ", y [" << object.first.y << "; " << object.first.y + object.second.y << ")" << std::endl;
- std::cout << "Положение персонажа: x [" << character->GetCharacterPosition().x + 22 << "; " << character->GetCharacterPosition().x + character->GetCharacterDimensions().x - 44 << ")"
- << ", y [" << character->GetCharacterPosition().y << "; " << character->GetCharacterPosition().y + character->GetCharacterDimensions().y << ")\n" << std::endl;*/
- //std::cout << "Падение " << character->IsFall() << std::endl;
- }
- else {
- if ((character->GetCharacterPosition().y < (object.first.y + object.second.y)) && ((character->GetCharacterPosition().y + character->GetCharacterDimensions().y) > (object.first.y + object.second.y))) { //если персонаж в прыжке ударяется об объект
- character->SetCharacterPosition(character->GetCharacterLastPosition().x, character->GetCharacterLastPosition().y);
- character->Jump(false);
- }
- }
- }
- int main() {
- setlocale(LC_ALL, "ru");
- sf::RenderWindow window(sf::VideoMode(1000, 388), "Uganda Adventure");
- sf::Event window_event;
- Character* main_character = new Character("uganda_textures.png", window.getSize(), sf::Vector2u(1, 1), sf::Vector2u(144, 164));
- main_character->SetCharacterSpeed(1);
- main_character->SetCharacterWeight(50);
- main_character->SetCharacterDimensions(0.5);
- main_character->SetCharacterPosition(1, 0);
- Level* level1 = new Level("level_1.png", window.getSize());
- while (window.isOpen()) {
- main_character->Update();
- if (window.pollEvent(window_event)) {
- if (window_event.type == sf::Event::EventType::Closed) {
- window.close();
- }
- }
- window.clear(); // очистка предыдущего кадра
- for (float x = -20; x < 1200; x += 97) {
- level1->SetSprite(1, 1, 97, 97); // спрайт неба
- level1->SetObjectPosition(x, 0, Level::ObjectType::Intangible);
- window.draw(level1->GetSprite());
- level1->SetObjectPosition(x, 97, Level::ObjectType::Intangible);
- window.draw(level1->GetSprite());
- level1->SetObjectPosition(x, 194, Level::ObjectType::Intangible);
- window.draw(level1->GetSprite());
- level1->SetSprite(1, 100, 97, 97); // спрайт земли
- level1->SetObjectPosition(x, 291, Level::ObjectType::Material);
- window.draw(level1->GetSprite());
- }
- level1->SetSprite(1, 100, 97, 97); // спрайт земли
- level1->SetObjectPosition(220, 194, Level::ObjectType::Material);
- window.draw(level1->GetSprite());
- level1->SetSprite(1, 100, 97, 97); // спрайт земли
- level1->SetObjectPosition(420, 20, Level::ObjectType::Material);
- window.draw(level1->GetSprite());
- Move(main_character, level1);
- window.draw(main_character->GetSprite());
- window.display();
- }
- system("pause");
- delete level1;
- delete main_character;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment