Проблема взаимодействия персонажа с картой.

SFML и C++ Уроки \ Разработка игр Форумы SFML Graphics Проблема взаимодействия персонажа с картой.

В этой теме 7 ответов, 3 участника, последнее обновление  Nodira 6 мес., 4 нед. назад.

Просмотр 8 сообщений - с 1 по 8 (из 8 всего)
  • Автор
    Сообщения
  • #2483

    RobBag2
    Участник
    Сообщений:2

    Зарегистрирован:
    30.11.2015

    Репутация:0

    Здравствуйте! Уже какой день не получается исправить некорректное взаимодействие с картой, поэтому обращаюсь к вам за помощью. Пожалуйста, помогите!

    Я делаю платформер. Вот в чём проблема: персонаж при падении на землю, проваливается сквозь тайл земли и выталкивается наружу снова и снова.

    Создаю класс в отдельном .cpp файле, а описываю его в файле .h.

    Код по началу был другим, но и с ним были проблемы похожего рода, потом я попробовал в точности воспроизвести Ваш код:

    #2486
    +1
    Павел Букреев
    Павел Букреев
    Хранитель
    Сообщений:584

    Зарегистрирован:
    04.01.2015

    Репутация:103

    к сожалению сейчас времени совсем нет, завалило делами даже на форуме посидеть не могу( посмотрите урок про пересечение прямоугольников (25ый вроде). и ещё  посмотрите урок 11.

    у вас здесь вижу вроде всё норм, единственно подозрение вызывает строка после (if Dy </>0), где вы сначала прибавляете +70, а затем почему то в аналогичном случае вычитаете height. возможно от этого одно значение больше другого и происходит бесконечное плавание вверх вниз.

    #2487

    RobBag2
    Участник
    Сообщений:2

    Зарегистрирован:
    30.11.2015

    Репутация:0

    Спасибо, что находите хоть какое-то время, чтобы ответить! Я попробовал вывести Dy и оказывается, что он постоянно растёт, т.е. персонаж постоянно проваливается. Но пока не смог исправить эту проблему:(

    #2495
    Павел Букреев
    Павел Букреев
    Хранитель
    Сообщений:584

    Зарегистрирован:
    04.01.2015

    Репутация:103

    персонаж и должен постоянно проваливаться. он же притягивается к земле типа. главное вытолкнуть его правильно и убрать проваливание когда он на земле уже..

    #2496

    RobBag2
    Участник
    Сообщений:2

    Зарегистрирован:
    30.11.2015

    Репутация:0

    Уже догнал… А в чём ещё проблема может быть? Может ли размер тайла земли играть какую-то роль?

    #2497
    Павел Букреев
    Павел Букреев
    Хранитель
    Сообщений:584

    Зарегистрирован:
    04.01.2015

    Репутация:103

    Да, конечно. Нужно вычитать размер тайла земли, чтобы вытолкнуть. если есть где то setOrigin – попробуйте его пока что убрать везде и сделать без него

    #3777

    Nodira
    Участник
    Сообщений:2

    Зарегистрирован:
    13.05.2016

    Репутация:0

    Доброго времени суток. У меня проблема при взаимодействии с картой. точнее когда я, в метод update добавляю метод interactionWithMap(), то у меня при запуске появляется окно и все норм, но как только я нажимаю какую либо из клавиш, появляется какая то непонятная штука :( Посмотрите пожалуйста, а то я не могу найти причину:

     

    #include <SFML/Graphics.hpp>
    #include “map.h”
    #include”view.h”
    using namespace sf;
    //класс игрока//
    class Player { // класс Игрока
    private: float x, y = 0;
    public:
    bool onGround, life;
    float w, h, dx, dy, speed; //координаты игрока х и у, высота ширина, ускорение (по х и по у), сама скорость
    int dir; //направление (direction) движения игрока
    String File; //файл с расширением
    Image image;//сфмл изображение
    Texture texture;//сфмл текстура
    Sprite sprite;//сфмл спрайт
    Player(String F, float X, float Y, float W, float H) { //Конструктор с параметрами(формальными) для класса Player. При создании объекта класса мы будем задавать имя файла, координату Х и У, ширину и высоту
    dx = 0; dy = 0; speed = 0; dir = 0;
    File = F;//имя файла+расширение
    w = W; h = H;//высота и ширина
    image.loadFromFile(“images/” + File);//запихиваем в image наше изображение вместо File мы передадим то, что пропишем при создании объекта. В нашем случае “hero.png” и получится запись идентичная image.loadFromFile(“images/hero/png”);
    image.createMaskFromColor(Color(41, 33, 59));//убираем ненужный темно-синий цвет, эта тень мне показалась не красивой.
    texture.loadFromImage(image);//закидываем наше изображение в текстуру
    sprite.setTexture(texture);//заливаем спрайт текстурой
    x = X; y = Y;//координата появления спрайта
    sprite.setTextureRect(IntRect(0, 0, w, h));
    sprite.setTextureRect(IntRect(0, 0, w, h)); //Задаем спрайту один прямоугольник для вывода одного льва, а не кучи львов сразу. IntRect – приведение типов
    }
    void update(float time) //функция “оживления” объекта класса. update – обновление. принимает в себя время SFML , вследствие чего работает бесконечно, давая персонажу движение.
    {
    switch (dir)//реализуем поведение в зависимости от направления. (каждая цифра соответствует направлению)
    {
    case 0: dx = speed; dy = 0; break;//по иксу задаем положительную скорость, по игреку зануляем. получаем, что персонаж идет только вправо
    case 1: dx = -speed; dy = 0; break;//по иксу задаем отрицательную скорость, по игреку зануляем. получается, что персонаж идет только влево
    case 2: dx = 0; dy = -speed; break;//по иксу задаем нулевое значение, по игреку отрицательное. получается, что персонаж идет только вверх
    }

    x += dx*time;// наше ускорение на время получаем смещение координат и как следствие движение
    y += dy*time;//аналогично по игреку

    speed = 0;//зануляем скорость, чтобы персонаж остановился.

    sprite.setPosition(x, y); //выводим спрайт в позицию x y , посередине. бесконечно выводим в этой функции, иначе бы наш спрайт стоял на месте.
    interactionWithMap();//вызываем функцию, отвечающую за взаимодействие с картой
    }

    float getplayercoordinateX() { //этим методом будем забирать координату Х
    return x;
    }
    float getplayercoordinateY() { //этим методом будем забирать координату Y
    return y;
    }
    void interactionWithMap()//ф-ция взаимодействия с картой
    {

    for (int k = y / 32; k < (y + h)/32; k++)//проходимся по тайликам, контактирующим с игроком, то есть по всем квадратикам размера 32*32, которые мы окрашивали в 9 уроке. про условия читайте ниже.
    for (int l = x / 32; l < (x + w)/32; l++)//икс делим на 32, тем самым получаем левый квадратик, с которым персонаж соприкасается. (он ведь больше размера 32*32, поэтому может одновременно стоять на нескольких квадратах). А j<(x + w) / 32 – условие ограничения координат по иксу. то есть координата самого правого квадрата, который соприкасается с персонажем. таким образом идем в цикле слева направо по иксу, проходя по от левого квадрата (соприкасающегося с героем), до правого квадрата (соприкасающегося с героем)
    {
    if (TileMap[k][l] == ‘0’)//если наш квадратик соответствует символу 0 (стена), то проверяем “направление скорости” персонажа:
    {
    if (dy>0)//если мы шли вниз,
    {
    y = k * 32 – h;//то стопорим координату игрек персонажа. сначала получаем координату нашего квадратика на карте(стены) и затем вычитаем из высоты спрайта персонажа.
    }
    if (dy<0)
    {
    y = k * 32 + 32;//аналогично с ходьбой вверх. dy<0, значит мы идем вверх (вспоминаем координаты паинта)
    }
    if (dx>0)
    {
    x = l * 32 – w;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа
    }
    if (dx < 0)
    {
    x = l * 32 + 32;//аналогично идем влево
    }
    }

    }
    }
    };
    int main() {

    RenderWindow window(VideoMode(640, 480), “SFML Application”);
    view.reset(sf::FloatRect(0, 0, 640, 480));//размер “вида” камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации.
    Image map_image;//объект изображения для карты
    map_image.loadFromFile(“images/map.png”);//загружаем файл для карты
    Texture map;//текстура карты
    map.loadFromImage(map_image);//заряжаем текстуру картинкой
    Sprite s_map;//создаём спрайт для карты
    s_map.setTexture(map);//заливаем текстуру спрайтом
    Player p(“hero.png”, 30, 388, 64.0, 64.0);//создаем объект p класса player,задаем “hero.png” как имя файла+расширение, далее координата Х,У, ширина, высота
    float CurrentFrame = 0;//хранит текущий кадр
    Clock clock;

    while (window.isOpen()) {
    float time = clock.getElapsedTime().asMicroseconds();
    clock.restart();
    time = time / 800;
    Event event;
    while (window.pollEvent(event)) {
    if (event.type == Event::Closed)
    window.close();
    }
    if (Keyboard::isKeyPressed(Keyboard::Left)) {
    p.dir = 1; p.speed = 0.2;//dir =1 – направление вверх, speed =0.2 – скорость движения. Заметьте – время мы уже здесь ни на что не умножаем и нигде не используем каждый раз
    CurrentFrame += 0.008*time;
    if (CurrentFrame > 8) CurrentFrame -= 8;
    p.sprite.setTextureRect(IntRect(64 * int(CurrentFrame), 128, 64, 64)); //через объект p класса player меняем спрайт, делая анимацию (используя оператор точку)
    }
    if ((Keyboard::isKeyPressed(Keyboard::Right) || (Keyboard::isKeyPressed(Keyboard::D)))) {
    p.dir = 0; p.speed = 0.2;//направление вправо, см выше
    CurrentFrame += 0.008*time;
    if (CurrentFrame > 8) CurrentFrame -= 8;
    p.sprite.setTextureRect(IntRect(64 * int(CurrentFrame), 0, 64, 64)); //через объект p класса player меняем спрайт, делая анимацию (используя оператор точку)
    }
    getPlayerCoorinateForView(p.getplayercoordinateX(), p.getplayercoordinateY());//передаем координаты игрока в функцию управления камерой
    p.update(time);//оживляем объект p класса Player с помощью времени sfml, передавая время в качестве параметра функции update. благодаря этому персонаж может двигаться
    //viewmap(time);//функция скроллинга карты, передаем ей время sfml
    window.setView(view);//”оживляем” камеру в окне sfml
    window.clear();
    /////////////////////////////Рисуем карту/////////////////////
    for (int i = 0; i < H_MAP; i++)
    for (int j = 0; j < W_MAP; j++)
    {
    if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(32, 0, 32, 32)); //если встретили символ пробел, то рисуем 1й квадратик
    if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(0, 0, 32, 32));//если встретили символ s, то рисуем 2й квадратик
    if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(64, 0, 32, 32));//если встретили символ 0, то рисуем 3й квадратик
    s_map.setPosition(j * 32, i * 32);//по сути раскидывает квадратики, превращая в карту. то есть задает каждому из них позицию. если убрать, то вся карта нарисуется в одном квадрате 32*32 и мы увидим один квадрат

    window.draw(s_map);//рисуем квадратики на экран
    }
    window.draw(p.sprite);//рисуем спрайт объекта p класса player
    window.display();
    }

    }

    Вложения:
    You must be logged in to view attached files.
    #3779

    Nodira
    Участник
    Сообщений:2

    Зарегистрирован:
    13.05.2016

    Репутация:0
Просмотр 8 сообщений - с 1 по 8 (из 8 всего)

Для ответа в этой теме необходимо авторизоваться.