Renderwindow c что это
Что такое SFML? Установка SFML в C++
Обновл. 30 Окт 2021 |
Пссс, парень! Не хочешь попробовать немного SFML? Убойная штука. Достаточно самой малости и с её помощью ты сможешь воплотить в жизнь то, о чем раньше мог только мечтать. Тебе понравится, гарантирую. Тем более тебе, как новичку, первая порция бесплатно, я угощаю. Ну что, договорились? Тогда по рукам.
Что такое SFML?
С её помощью можно легко и непринужденно создавать любую 2D-графику: начиная от простейших одиночных геометрических фигур (типа треугольника) и заканчивая полноценными играми-платформерами.
Исходный код библиотеки предоставляется под лицензией zlib/png, а скачать SFML можно с оф. сайта разработчика www.sfml-dev.org.
Примечание: Все примеры этого урока были сделаны мной в ОС Windows 7 с использованием IDE MS Visual Studio 2017 Community Edition и библиотеки SFML 2.5.1.
Ну что, парень, ты готов? Да вижу, что готов. Погнали!
Установка библиотеки SFML в Visual Studio
Я не буду рассказывать, как установить Visual Studio, а перейду сразу к SFML. Для того, чтобы установить библиотеку, нужно зайти на сайт www.sfml-dev.org и перейти в пункт меню «Download» и скачать «SFML 2.5.1»:
Как уже говорилось ранее, в качестве IDE я буду использовать Visual Studio 2017, поэтому скачиваем соответствующую версию SFML. Вы также можете заметить наличие готового пакета для эстетов Code Blocks. Помимо этого, в глаза бросаются варианты библиотеки для других версий Visual Studio. Сразу дам совет — не пытайтесь лепить Франкенштейна, используя неподходящий билд SFML, иначе вы рискуете получить вагон и маленькую тележку всякого рода проблем на свою голову.
Теперь, когда у нас есть проект, нужно добавить в него файл, который будет содержать исходный код нашей программы. Для этого в окне «Обозреватель решений» клацните ПКМ по строке «Исходные файлы» > «Добавить» > «Создать элемент…» :
В поле «Имя» укажите main.cpp :
Отлично! Следующим шагом будет подключение библиотеки SFML к нашему проекту. Для этого нужно:
подключить каталог заголовочных и исходных файлов SFML ( /include );
подключить каталог библиотечных файлов SFML ( /lib );
подключить библиотечные файлы SFML в качестве дополнительных зависимостей.
Переходим в «Проект» > «Свойства: SFML_Tutorial…» :
sfml-graphics-d.lib
sfml-window-d.lib
sfml-audio-d.lib
sfml-system-d.lib
Должно получиться следующее:
Первые шаги и первые…
На этом этапе подключение библиотеки SFML к проекту завершено, и мы можем перейти к непосредственному написанию кода для нашей первой программы. Ниже представлен минимальный каркас приложения:
Я вижу, как ваша рука уже потянулась к кнопке «Скомпилировать и запустить проект», но не торопитесь, давайте сначала разберем данный код:
Строка №8: Создаем объект window класса RenderWindow. Данный объект — это наше окно, в котором будет отображаться 2D-графика. Первый параметр VideoMode(200, 200) задает видеоразрешение окна (ширину и высоту). Второй параметр «SFML Works!» — это заголовок окна.
Далее идут 2 цикла while: внешний (строка №11) и внутренний (строка №15). Сложного здесь ничего нет. SFML предлагает удобные средства для работы с событиями. Именно их мы и будем использовать для создания цикла работы приложения и обработки событий окна. Во внешнем цикле while при помощи метода isOpen() мы проверяем, открыто ли наше окно в данный момент. Во внутреннем цикле while метод pollEvent(event) перебирает очередь событий (сообщений), которые возникают в нашем окне.
Очередь может содержать любое количество сообщений, именно по этой причине мы и используем цикл, чтобы перебрать их все. Предположим, например, что пользователь перемещает курсор во время выполнения нашей программы или нажимает на какие-то объекты. SFML обнаружит это и поместит два события в очередь: одно на перемещение курсора и одно на нажатие на объект. Выбрать определенное сообщение из очереди можно с помощью метода pollEvent() класса RenderWindow. Так вот, если какое-то событие из этой очереди совпадает с Event::Closed (т.е. пользователь нажал на крестик, тем самым послав сигнал «Закрыть окно»), то при помощи windows.close() мы закрываем окно. По сути, этот цикл бесконечен, и выход из него только один — закрыть окно программы.
В строке №23 мы вызываем метод display(), который отвечает за отрисовку нашего окна.
Вот теперь можно перейти к компиляции и первому запуску программы. Для этого нажмите в Visual Studio «Отладка» > «Запуск без отладки» (или Ctrl+F5 ). Ииии, вот и она! Ваша первая… ЧТО…. ОШИБКА…. WTF….
«Что за хрень. » — спросите вы. Столько времени потрачено на ковыряние, настройку и прочее ради вот этого вот?! Долбанного окна с ошибкой?! Нафиг всё, дизлайк/отписка, го даст2 я создал.
Попробуйте теперь скомпилировать и запустить проект. В результате должно получиться следующее:
1.1 SFML и Visual Studio
От переводчика: данная статья является первой в цикле переводов официального руководства по библиотеке SFML. Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML — это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти тут. Начнем.
Библиотека SFML предоставляет простой интерфейс для различных компонентов вашего компьютера, чтобы облегчить разработку игр и мультимедийных приложений. Она состоит из пяти модулей: system, window, graphics, audio и network.
Используя SFML, ваше приложение может быть скомпилировано и запущено на наиболее распространенных платформах: Windows, Linux, Mac OS X(планируется поддержка Android и IOS).
Предварительно скомпилированные SDK для вашей ОС доступны на странице загрузки.
1. Приступая к работе
Вступление
Эта статья — первая, которую вам следует прочитать, если вы используете среду разработки Visual Studio (Visual C++ compiler). В ней будет рассказано, как настроить ваш проект.
Установка SFML
Для начала вам необходимо скачать SFML SDK со страницы загрузки.
Скаченный вами пакет должен соответствовать вашей версии Visual C++. Например, библиотека, скомпилированная с помощью VC++ 10 (Visual Studio 2010) не будет совместима с VC++ 12 (Visual Studio 2013). Если вы не найдете на странице загрузки пакет SFML, скомпилированный для вашей версии Visual C++, вам придется собрать SFML самостоятельно.
Далее вы должны распаковать архив с SFML в любую удобную для вас директорию. Копировать заголовочные файлы и библиотеки в вашу установку Visual Studio не рекомендуется. Лучше держать библиотеки в отдельном месте, особенно если вы намереваетесь использовать несколько версий одной библиотеки или несколько компиляторов.
Создание и конфигурирование проекта SFML
Первое, что вам необходимо сделать — это выбрать тип создаваемого проекта: вы должны выбрать «Win32 application». Мастер предложит вам несколько опций для настройки проекта: выберите «Console application» в том случае, если вам нужна консоль, либо «Windows application» в обратном случае. Выберите «Empty project», если вам не нужен автоматически сгенерированный код.
Создайте файл main.cpp и добавьте его в проект. Этим вы примените настройки C++ (в противном случае Visual Studio не будет знать, какой язык мы будем использовать для данного проекта). Содержимое файла main.cpp будет приведено ниже.
Добавьте в свойства проекта следующее:
Важно указать библиотеки, соответствующие конфигурации: «sfml-xxx-d.lib» для Debug и «sfml-xxx.lib» для Release, иначе могут возникнуть ошибки.
Настройки, приведенные выше, позволят вам скомпоновать ваш проект с динамической версией SFML, для которой требуются DLL файлы. Если вы хотите напрямую интегрировать SFML в ваш исполняемый файл, а не использовать компоновку с динамической библиотекой, вы должны скомпоновать статическую версию библиотеки. Статические библиотеки SFML имеют суффикс «-s»: «sfml-xxx-s-d.lib» для конфигурации Debug и «sfml-xxx-s.lib» для Release.
Также вам необходимо определить макрос SFML_STATIC в опциях препроцессора вашего проекта.
Начиная с SFML 2.2 при статической компоновке вам также необходимо скомпоновать все зависимости SFML. Это означает, что если, к примеру, вы скомпонуете sfml-window-s.lib или sfml-window-s-d.lib, вам также придется скомпоновать opengl32.lib, winmm.lib и gdi32.lib. Некоторые из этих библиотек, возможно, уже перечислены в разделе «Inherited values», но добавление их не должно вызвать каких либо проблем.
Если вы немного запутались, не волнуйтесь, для начинающего совершенно нормально быть перегруженным всей этой информацией о статическом связывании.Если у вас что-то не получится с первого раза, вы можете попробовать еще раз имея в виду все сказанное выше. Если у вас все же возникнут трудности со статическим связыванием, вы можете попробовать поискать решение в разделе FAQ или на форуме.
Если вы не знаете чем отличаются динамические (также называемые общими) и статические библиотеки и какой тип библиотек использовать, вы можете найти больше информации в интернете. На данную тему есть множество хороших статей/блогов/постов.
Ваш проект готов, давайте напишем немного кода, что бы проверить, что все работает правильно. Поместите следующий код в файл main.cpp:
Если при создании проекта вы выбрали опцию «Windows application», то точкой входа в вашу программу должна быть функция «WinMain» вместо «main». Так как это специфика Windows, ваш код не будет компилироваться на Linux или Mac OS X. SFML предоставляет способ сохранить стандартной точкой входа «main» в том случае, если вы скомпонуете свой проект с модулем sfml-main («sfml-main-d.lib» для Debug, «sfml-main.lib» для Release) таким же способом, которым вы скомпоновали sfml-graphics, sfml-window и sfml-system.
Если вы используете модуль sfml-audio (независимо от того, статическую или динамическую его версию), вы также должны скопировать внешнюю dll библиотеку OpenAL32.dll. Этот файл также может быть найден в директории /bin.
SFML — sf :: RenderWindow, разделение файлов
так что это, вероятно, что-то тривиальное, но мне действительно нужно знать, почему это происходит так, как это происходит, и как я могу это изменить.
Итак, я начал изучать SFML сегодня и читал книгу по разработке игр SFML и увидел очень интересный и хорошо написанный код. Я прошел учебные курсы по SFML и начал изучать язык, поскольку понял общее представление о том, как он должен работать.
Поэтому я хотел запомнить новые ключевые слова, конструкторы, методы, а также сделать мой код хорошо организованным — используя то, что я узнал, чтобы он был чистым и легким для редактирования, отладки.
Мой первый код должен был отобразить Window, и я создал один и тот же код обоими способами, обычно помещая все в основную функцию и разделяя ее. Дело в том, что первое окно отображается до тех пор, пока я не закрою его, а второе отображается менее секунды, и программа выключается.
Это, вероятно, потому, что деструктор вызывается сразу после того, как я его включаю, и добавление дополнительных функций, чтобы держать объект занятым, — путь, но хорошо, я хочу понять это. Это последняя вещь, которую я не очень понимаю, поскольку я изучил объективное программирование. Как работают объекты. Сразу после их создания я использую их для выполнения определенной задачи, но затем, когда я закончу, они удаляются, иногда мне они снова нужны. Я просто хочу понять, как это работает, и найти действительно легкое и быстрое решение проблемы, чтобы заставить его работать так долго, как я этого хочу.
Первая программа:
Вторая программа:
main.cpp
Game.cpp
Game.h
Решение
В вашем конструкторе вы создаете новый RenderWindow объект, который немедленно уничтожается при выходе из конструктора. Что вы хотите сделать, это инициализировать RenderWindow который является членом вашего класса. Вы можете сделать это одним из двух способов, либо используя RenderWindow конструктор в списке инициализатора члена:
Или вызывая функцию create в теле конструктора.
Другие решения
Вам нужно изменить это:
В первом примере вы создаете sf::RenderWindow внутри конструктора, затем немедленно его уничтожаем, тогда как во втором примере вы инициализируете версию переменной-члена, которая будет сохранять ваше окно до тех пор, пока Game содержащий его объект не уничтожается (или до тех пор, пока вы не уничтожите окно вручную).
Ваша вторая программа должна работать с одним небольшим изменением.
У вас уже есть переменная с именем mainWindow типа RenderWindow. Вместо того, чтобы создавать его так, как вы это делаете, вам придется использовать функцию create () в главном окне.
Просто совет, как правило, вы не хотите использовать isOpen () для игрового цикла. Я рекомендую вам заглянуть в enum классы.
Вот отличное видео, объясняющее, как вы будете их использовать.
Урок 2. Разбор тестового кода, основной принцип работы sfml, обязательные функции SFML
В предыдущем уроке мы настроили среду разработки и запустили тестовый код. В этом уроке разберем каждую строку этого кода для лучшего понимания происходящего и рассмотрим пример из реальной жизни.
Видеоверсия http://www.youtube.com/watch?v=N1lovpBQTF4
Вот тот тестовый код:
Первой строкой кода нам необходимо подключить заголовочный файл, отвечающий за работу с графикой:
(к примеру когда будем использовать звуки в игре – мы подключим Audio.hpp)
Уже в теле этой функции происходят вызовы других функций. У SFML тоже есть обязательные функции и объекты. Например мы будем использовать объект, отвечающий за появление окна нашей игры. Выглядит он так:
Разберем по порядку эту строчку:
sf:: это пространство имён библиотеки SFML. Чтобы использовать функции и создавать объекты, относящиеся к этой библиотеке, необходимо перед началом каждой строки писать sf:: как в этом случае. Чтобы этого не делать каждый раз – можно написать такую строку перед int main()
В тестовом коде этого нету поэтому дальше примере с “sf::”. просто на будущее говорю вам.
Идём дальше. RenderWindow window создаёт как бы переменную (объект) окна с названием “window”. Затем в скобках идёт конструктор с параметрами. Первый параметр VideoMode(200, 200) – размер окна, далее идёт строка “SFML works!”, являющаяся заголовком окна. после этого можно использовать необязательные параметры, например sf::Style::Fullscreen, что сделает наше окно развернутым на весь экран, как полноценную игру.
После того, как мы создали окно, давайте что нибудь нарисуем. В прошлом уроке в тестовом коде был зеленый круг. Здесь он красный:)
Первая строка создали объект shape класса CircleShape. В скобках указан размер. Вторая строка – залили круг красным цветом.
Далее идёт обязательный цикл для SFML, который можете переводить для понимания как : “Пока окно открыто – выполняй то, что внутри цикла”, встречайте:
По сути этот цикл бесконечен и выход из него только один – закрыть окно программы. (или выдернуть компьютер из розетки:))
Чтобы окно могло закрыться ниже идет 6 строк кода. Итак, есть некое “SFML-евское” событие event, строка – sf::Event event;
Это событие принимает состояние закрытого, когда мы закрываем окно нашей игры (на крестик например, или альт+ф4) и попросту говоря условие (6 строка) спрашивает : “если событие event приняло значение Closed, то программа закрывает окно. Такие вот необходимые условности. Более подробно написано опять же здесь:
После этого идут функции :
window.clear(); – очищает экран.
window.draw(shape); – рисует объект.
window.display(); – всё это показывает.
P.S. Знайте перевод всех английских слов, использованных в коде. Это ускорит понимание. Если встретили незнакомое слово – не поленитесь и зайдите в переводчик
Рисуем в 2D
Введение ===
К счастью, SFML предоставляет графический модуль, который вам поможет нарисовать различные 2D объекты более простым способом, чем если бы вы использовали OpenGL.
Окно рисования ===
Для рисования разных вещей нам предоставляется графический модуль, вместе с которым вам нужно использовать специальный класс окна sf::RenderWindow. Этот класс получен от класса sf::Window и содержит все его функции. Все, что вы уже знаете об sf::Window (создание, управление событиями, управление частотой кадров, использование OpenGL), также применимо и к sf::RenderWindow.
В добавок к этому, sf::RenderWindow дает высоко-уровневые функции, которые помогут вам очень просто рисовать разные вещи. В этой статье мы остановимся на двух из этих функций : очищении и рисовании. Они напрямую соответствуют своим названиям : функция очистки экрана очищает всё окно и заливает заданным цветом, а функция рисования рисует любой переданный ей объект.
Ниже представлен типичный главный цикл с окном рисования:
Вызов очистки перед рисование чего-либо является обязательным, иначе то, что было отображено предыдущим кадром будет нарисовано позади нового кадра и смешается. Исключением является, если вы перерисовываете окно полностью так, что ни один пиксель из предыдущего кадра не будет показан. В этом случае вы можете не вызывать функцию очистки (хотя это и не будет иметь большого влияния на производительность).
Современное графическое оборудование и API создано для постоянных циклов очистки\рисования\отображения, в которых всё полностью очищается на каждой итерации главного цикла. Не бойтесь рисовать 1000 спрайтов 60 раз в секунду, это все равно намного меньше рисования миллионов треугольников, которые ваш компьютер может обработать.
Что мы теперь можем нарисовать? ===
Сейчас, когда главный цикл готов для рисования, давайте посмотрим что и как мы можем в нем нарисовать.
Хотя они имеют некоторые общие свойства, каждый из этих объектов поставляются с собственными нюансами, которые описаны в специальных учебных пособиях, которые постепенно будут мной переводиться и ссылки буду даны ниже.
Рисование вне окна ===
SFML также предоставляет способ рисования в текстуру или в окно. Для этого используйте класс sf::RenderTexture, вместо sf::RenderWindow. Он имеет такие же функции для рисования, наследованные от общего класса sf::RenderTarget.
Функция getTexture возвращает текстуру «только для чтения», это значит, что вы можете только использовать её, не изменяя. Если вы хотите её изменить, перед использованием, вы можете скопировать её в собственную sf::Texture и изменять её.
Класс sf::RenderTexture также имеет такие же функции, как и sf::RenderWindow для управления видом и OpenGL. Если вы используете OpenGL для рисования в render-texture, вы можете запросить создания буфера глубины с помощью передачи третьего параметра в функцию создания текстуры.
Рисуем из потоков ===
Как вы можете видеть, вам не требуется возиться с активацией окна в потоке рисования, SFML делает это за вас автоматически, когда это требуется.