Урок 8 SFML постепенный переход к ООП, направление движения, прозрачность героя

Настало время перебраться к концепции ООП, потому что городить дальше кучи строк кода станет утомительным занятием :) На этом уроке перепишем код под ООП, уберем движение персонажа по диагонали,  персонажа льва сделаем прозрачным в одном его “синеватом” месте.


Видеоверсия: sfml урок 8

Итак, представьте, что у нас есть враги, пули, бонусы, игрок и все это взаимодействует между собой. Чокнемся , если это будет структурно описано. :-)

Сначала сделаем класс Игрока, поскольку он у нас в игре и существует пока что.

До функции int main пишем

В данном случае создали класс Player и задали ему свойства. Они публичны (public) потому, что этот класс мы потом преобразуем в родительский и будем его наследовать, а так же обращаться оператором точка в функции main. У всех – врагов, пулей, игрока и тд есть много общего – текстура, спрайт, изображение, жизни, скорость и чего только вы не пожелаете, поэтому лучше будет создать главный класс, обладающий общими свойствами и методами и наследовать эти же свойства и методы для других классов, которым эти свойства и методы тоже нужны. Это поможет избежать лишних строк в коде и добавит удобства в работе. Такой класс и наследование мы потом когда-нибудь запилим.

После свойств идет конструктор. В нем задаем значения всем нашим переменным. В нашем случае он с параметрами, которые мы будем передавать при создании объекта:

Давайте представим ситуацию и разберем как это работает. В ф-ции main написано (пока не пишите):
Player p(“hero.png”,250,250,96.0, 96.0);

Получается , что так мы создали объект класса Player, картинка для него берется по адресу images/hero.png , координаты x и y у нас 250,а ширина и высота изображения 96. Всё примерно то же самое, что и в прошлых уроках, только другими способами :)

Далее для тех у кого картинка тоже лев – объяснение строки image.createMaskFromColor(Color(41, 33, 59)) в конце урока, пока сосредоточьтесь на другом :-)

После конструктора создадим метод update, который оживит нашего игрока с помощью времени SFML. в конце закроем скобку класса и на этом с классом пока всё.

Чуть подробнее о листинге выше. У нас четыре направления движения. Когда мы нажимаем клавишу мы изменяем dir и таким образом изменяем направление. Если идем влево, то dir=1, по иксу получаем отрицательное значение ( как видим speed в этом случае <0), по игреку 0, таким образом не сможем идти по диагонали. Аналогично другим случаям. Ну а в конце мы пишем x+=dx*time – оживляем это движение с помощью времени sfml, которое мы приняли в качестве параметра для этого метода update. То же самое делаем с игреком – y+=…
Чуть ниже обнуляем скорость. Если вы этого не сделаете – ваш персонаж будет двигаться как старая добрая Змейка. )) попробуйте потом в конце урока для интереса не обнулять. Если вам нужен именно такой персонаж “без тормозов” – оставляйте :)

 Итак, чтобы все это заработало – нам необходимо создать объект класса игрока в функции main. давайте  сделаем это:

Уже сейчас мы можем, (но не будем:-)) сделать двух игроков. Нам нужно два объекта, можем задать им разные картинки, задать разные координаты появления. Пока что они могут пересекаться.
Как видите мы подгружаем файл в процессе создания объекта. Это не прокатит, если у вас объект пуля, который постоянно надо удалять и создавать заново. В последствии переделаем на другой лад, когда будем делать класс анимации и другие объекты (особенно динамические).

Заменим старое управление персонажем на новое:

Обращаемся к свойствам объекта – скорости и направлению, тем самым реализуя движение. Движется герой в четырех направлениях будто на него смотрят сверху (как в танчиках на денди, например). Для реализации в стиле марио нам нужно будет убрать одно направление (вниз) и реализовать силу притяжения. Будет урок, в котором я расскажу как это сделать.

Ну а пока ниже пишем:

 И последнее – меняем draw и (кстати удаляем старое spritehero и вобще все, что с ним связано):

Мы перешли на ООП , осталась анимация и отдельный её класс. Это тема для отдельной статьи, поэтому анимацию здесь я не трогал. С анимацией не все так просто, поэтому пока поживем с тем, что имеем и затронем другие темы.
Так же стоит отметить публичный модификатор public в нашем классе и обращение к свойствам класса в функции main. Хорошим тоном является как можно меньше публичных модификаторов доступа (который public) к полям (в нашем случае можем называть их свойствами) . Обращаться напрямую извне класса к свойству объекта (полю) мы не должны, для этого необходимо описывать метод, способствующий изменению какого-то свойства класса, тем самым мы реализуем инкапсуляцию (гуглить ООП) . В нашем случае мы обратились – меняли скорость (p.speed=0.1), направление движения (p.dir=1). Далее я буду постепенно уходить от этого, но без фанатизма, поскольку наша главная задача – понять суть работы с sfml. В конце концов у нас не большой проект и команда разработчиков – мы только учимся. Всякие там красивости и правильные вещи вы наведете (или не наведете) по своему желанию, когда будете делать свою полноценную игру. :)




На следующем уроке загрузим карту, а то бегать в темноте уже становится страшно :-)

А теперь объяснение строки createMaskFromColor из начала статьи, где мы писали свойства объекта класса. Мне не понравился вывод игрока с его тенью, как – то не очень выглядит и я решил убрать эту тень. Как узнать код цвета в paint’e (паинте) ? Открыл картинку паинтом, выбрал пипеткой этот цвет тени под его пузом, потом нажал “изменение цветов” и справа смотрел код цвета (красн 41, зел 33, син 59) , добавил этот код как вы видели выше в маску цветов спрайта:  “image.createMaskFromColor(Color(41, 33, 59));”

Ниже картинка как я это сделал по шагам куда тыкал:

узнать код цвета в паинте
узнать код цвета в паинте

Код урока:

 

 

 

Буду благодарен, если поделитесь:
SFML вопросы, прошу, задавайте на форуме.
  1. Здравствуйте, подскажите почему происходит эта ошибка и как ее исправить? (использование инициализатора элемента данных не допускается)

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

  3. Выдает такую ошибку и выводит вместо льва белый квадрат
    До этого это решалось указанием полного пути, но теперь и это не помогает
    Может, подскажете, как решить?

    Вложение: Безымянный

  4. До этого решалось, а что изменилось?) Код настоялся?

    Попробуйте загрузить картинку в текстуру без параметра конструктора, то есть в самом конструкторе напрямую написать путь до картинки. И еще: ” Что за ошибка такая – неверный размер текстуры?”

    1. Попробовал, ничего не изменилось. Сам удивляюсь, не может же ни с того ни с сего такое быть. А ошибка наверное из-за того, что файл не открылся, потому и размер 0х0

  5. Здравствуйте!
    возникла проблема с определением констант..
    прилагаю скрин.. заранее спасибо!

    Вложение: Безымянный

  6. У меня такая ошибка…помогите!

    я переменные speed и dir в конструкторе ввел = 0.

    Но теперь такая фигня! – Спрайт карты мне показывает а спрайт игрока – нет! (p.sprite)

    я не знаю что делать….

Добавить комментарий