Sfml подключение: Урок 1. Подключение библиотеки SFML к среде разработки Microsoft Visual Studio 2013 | kychka-pc
Подключение библиотеки SFML к Visual Studio
Среда программирования:
В этом уроке я хотел бы показать, как подключить библиотеку SFML к среде разработки Visual Studio.
SFML содержит ряд модулей для простого программирования игр и мультимедиа приложений.
Перед тем как начать. Нужно пройти по ссылке: http://www.sfml-dev.org/download/sfml/2.3.2/ (это официальный сайт) и скачать библиотеку. Выбирайте версию для своей VS.
Распаковываем куда вам угодно, на всякий случай старайтесь избегать русских букв в папках пути.
Запускаем Visual Studio, файл->создать->проект->пустой проект. (Имя проекта, решений и путь выбирайте сами).
Добавляем исходный код – для этого слева в обозревателе решений находим вкладку «Файлы исходного кода»->правый клик->добавить->создать элемент->файл C++ (имя main.cpp)->добавить.
Далее вставляем вот этот тестовый код в файл main.cpp
#include <SFML/Graphics.hpp> int main() { sf::RenderWindow window(sf::VideoMode(200, 200), "SFMLworks"); sf::CircleShape shape(100.f); shape.setFillColor(sf::Color::Green); while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(); window.draw(shape); window.display(); } return 0; }
После попытки запуска мы сталкиваемся с подобной проблемой:
Для того, чтобы всё это работало – необходимо подключить библиотеку SFML.
Для начала, все действия мы делаем для конфигурации Debug.
Заходим вверху «проект»->свойства “имя проекта”->свойства конфигурации->C++->общие
В пункте «дополнительные каталоги включаемых файлов прописываем путь до раннее распакованного архива с библиотекой (+ \include.)
Например: C:\Program Files\SFML-2.3.2\include
Затем идем в компоновщик->общие и в пункте «дополнительные каталоги библиотек» прописываем путь к папке lib;
Далее идем в компоновщике во вкладку ввод и в первой строке «дополнительные зависимости» вписываем перед всеми библиотеками следующую строчку:
sfml-graphics-d.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-audio-d.lib;
Только что подключили основные необходимые для работы библиотеки.
Последний штрих – идем во вкладку C++->препроцессор и в первой строке «определение препроцессора» в самом начале дописываем: SFML_DYNAMIC;
Напоминаю, все действия мы делали для конфигурации Debug. Все тоже самое нужно проделать для конфигурации Release.
Заходим вверху «проект»->свойства “имя проекта”->свойства конфигурации. В левом верхнем углу находим Конфигурация, нажимаем на слайдер и выбираем Release.
И повторяем несколько предыдущих пунктов.
Запустим и словим ошибку. Зато соберется проект и появится папка debug.
Теперь идем в папку бинарников “bin”, которую вы скачали и распаковали с библиотекой (мой вариант D:\SFML-2.2\bin\) и копируем всё содержимое этой папки (dll файлы типа sfml-graphics-2.dll) в папку с вашим проектом в папку debug (после сборки появилась эта папка), но не в тот debug, где лежит файл с исходным кодом “main.cpp”, а тот, где появляется exe файл.
В эту же папку копируем и вот эти файлы :
msvcp100d.dll;msvcp110.dll;msvcp110d.dll;msvcr100d.dll;msvcr110.dll;msvcr110d.dll;
Все эти файлы можно скачать в zip архиве, который я прикрепил снизу.
Теперь проект можно запустить и если вы всё сделали правильно, то увидите зелёный круг как на скриншоте ниже:
Если возникла вот такая проблема:
Советую воспользоваться программой: Dll-Files Fixer.
Прикрепленный файл | Размер |
---|---|
msvcp.zip | 550.93 кб |
msvcr.zip | 1.61 Мб |
Подключение SFML к среде разработки DEV-CPP 5.11 | kychka-pc
Доброго времени суток!
Решил помочь создателю сайта с наполнением его контентом, то есть обучающим материалом. Так как на сайте уже разбиралось использование MS Visual Studio для сборки проектов, я разберу использование связки SFML 2.4.2 и среды разработки Dev-Cpp 5.11 с поставляемым к нему компилятором TDM-GCC 4.9.2.
Так как данная статья о «прикрутке» библиотеки SFML к Dev-Cpp описывать как достоинства и недостатки использования данной среды, так и все тонкость загрузки и установки среды смысла не имеет, так как приведёт к раздуванию статьи. Эта статья для тех, кто сделал выбор на этой связке.
Для начала качаем требуемый для нас готовый вариант библиотеки:и/или:В крайнем случае загружаем исходники и компилируем сами. Как это делать написано здесь. (англ.яз)
После того как загрузили, распаковываем архив в удобном для нас месте. Для себя сделал такой выбор:
<место размещения компилятора>/SFML/x32 , и
<место размещения компилятора>/SFML/x64
– обе версии для разных архитектур. Если вам необходима только одна, то качаем нужную. Оставляем лишь папки: \bin, \include и \lib.
Переходим к финальной части: указываем среде разработки место расположение всех частей библиотеки. Запускаем IDE и переходим в верхнем меню: Сервис -> Параметры компилятора.
Нажимаем на вкладку “Каталоги” и начинаем добавлять места расположений частей SFML, набивая полный путь сами, либо находя каталоги через кнопочку справа:Делаем это для:
«Программы» – <место размещения библиотеки>\bin,
«Библиотеки» – <место размещения библиотеки>\lib,
«Включаемые файлы С++» – <место размещения библиотеки>\include,
– и повторяем для всех требуемых для вас наборов настроек компилятора:
Теперь SFML полностью готова для использования в ваших проектах. В следующей статье я расскажу нюансы использование библиотеки SFML в ваших проектах в среде разработки Dev-Cpp.
Буду благодарен, если поделитесь:
Урок 33 SFML C++, загружаем следующий уровень | kychka-pc
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include «view.h»
#include <iostream>
//#include <sstream>//сейчас не нужно. раньше выводили текст ( в 13 ом уроке )
#include «mission.h»
#include «iostream»
#include «level.h»
#include <vector>
#include <list>
using namespace sf;
////////////////////////////////////Общий класс-родитель//////////////////////////
class Entity {
public:
std::vector<Object> obj;
float dx, dy, x, y, speed,moveTimer;
int w,h,health;
bool life, isMove, onGround;
Texture texture;
Sprite sprite;
String name;
Entity(Image &image, String Name, float X, float Y, int W, int H){
x = X; y = Y; w = W; h = H; name = Name; moveTimer = 0;
speed = 0; health = 100; dx = 0; dy = 0;
life = true; onGround = false; isMove = false;
texture.loadFromImage(image);
sprite.setTexture(texture);
sprite.setOrigin(w / 2, h / 2);
}
FloatRect getRect(){
return FloatRect(x, y, w, h);
}
virtual void update(float time) = 0;//все потомки переопределяют эту ф-цию
};
////////////////////////////////////////////////////КЛАСС ИГРОКА////////////////////////
class Player :public Entity
{
public:
enum { left, right, up, down, jump, stay, right_Top } state;
int playerScore;
bool isShoot;
Player(Image &image, String Name, Level &lev, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H ){
playerScore = isShoot = 0; state = stay; obj = lev.GetAllObjects();
if (name == «Player1»){
sprite.setTextureRect(IntRect(4, 19, w, h));
}
}
void control()
{
if (Keyboard::isKeyPressed){
if (Keyboard::isKeyPressed(Keyboard::Left)) {
state = left; speed = 0.1;
}
if (Keyboard::isKeyPressed(Keyboard::Right)) {
state = right; speed = 0.1;
}
if ((Keyboard::isKeyPressed(Keyboard::Up)) && (onGround)) {
state = jump; dy = -0.6; onGround = false;
}
if (Keyboard::isKeyPressed(Keyboard::Down)) {
state = down;
}
if ((Keyboard::isKeyPressed(Keyboard::Right)) && (Keyboard::isKeyPressed(Keyboard::Up))) {
state = right_Top;
}
/////выстрел
if (Keyboard::isKeyPressed(Keyboard::Space)) {
isShoot = true;
}
}
}
void checkCollisionWithMap(float Dx, float Dy)
{
for (int i = 0; i<obj.size(); i++)
if (getRect().intersects(obj[i].rect))
{
if (obj[i].name == «solid»)
{
if (Dy>0) { y = obj[i].rect.top — h; dy = 0; onGround = true; }
if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }
if (Dx>0) { x = obj[i].rect.left — w; }
if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; }
}
// else { onGround = false; }
}
}
void update(float time)
{
control();
switch (state)
{
case right:dx = speed; break;
case left:dx = -speed; break;
case up: break;
case down: dx = 0; break;
case stay: break;
case right_Top: dx = speed; break;//состояние вправо вверх, просто продолжаем идти вправо
}
x += dx*time;
checkCollisionWithMap(dx, 0);
y += dy*time;
checkCollisionWithMap(0, dy);
sprite.setPosition(x+w/2,y+h/2);
if (health <= 0){ life = false; }
if (!isMove){ speed = 0; }
if (life) { setPlayerCoordinateForView(x, y); }
dy = dy + 0.0015*time;
}
};
class Enemy :public Entity{
public:
Enemy(Image &image, String Name,Level &lvl, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H){
obj = lvl.GetObjects(«solid»);//инициализируем.получаем нужные объекты для взаимодействия врага с картой
if (name == «EasyEnemy»){
sprite.setTextureRect(IntRect(0, 0, w, h));
dx = 0.1;
}
}
void checkCollisionWithMap(float Dx, float Dy)
{
for (int i = 0; i<obj.size(); i++)
if (getRect().intersects(obj[i].rect))
{
if (obj[i].name == «solid»)//если встретили препятствие
{
if (Dy>0) { y = obj[i].rect.top — h; dy = 0; onGround = true; }
if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }
if (Dx>0) { x = obj[i].rect.left — w; dx = -0.1; sprite.scale(-1, 1); }
if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; dx = 0.1; sprite.scale(-1, 1); }
}
}
}
void update(float time)
{
if (name == «EasyEnemy»){
//moveTimer += time;if (moveTimer>3000){ dx *= -1; moveTimer = 0; }//меняет направление примерно каждые 3 сек(альтернативная версия смены направления)
checkCollisionWithMap(dx, 0);
x += dx*time;
sprite.setPosition(x+w/2, y+h/2);
if (health <= 0){ life = false; }
}
}
};
class Bullet :public Entity//класс пули
{
public:
float targetX, targetY;//отвечают за направление движения пули к цели
float vx,vy, distance;
Bullet(Image &image, String Name, Level &lvl, float X, float Y, int W, int H, float tX, float tY) :Entity(image, Name, X, Y, W, H){//всё так же, только взяли в конце состояние игрока (int dir)
obj = lvl.GetObjects(«solid»);//инициализируем .получаем нужные объекты для взаимодействия пули с картой
x = X;
y = Y;
targetX = tX;
targetY = tY;
speed = 0.2;
w = h = 16;
life = true;
distance = sqrt((targetX — x) — (targetY — y));
vx = (targetX — x)/100; // 100 — дистанция
vy = (targetY — y)/100;
//выше инициализация в конструкторе
}
void update(float time)
{
//x += speed*time*(targetX — x) /20;//само движение пули по х
//y += speed*time*(targetY — y) /20;//по у
x += vx*time*speed;
y += vy*time*speed;
if (x <= 0) x = 1;// задержка пули в левой стене, чтобы при проседании кадров она случайно не вылетела за предел карты и не было ошибки
if (y <= 0) y = 1;
for (int i = 0; i < obj.size(); i++) {//проход по объектам solid
if (getRect().intersects(obj[i].rect)) //если этот объект столкнулся с пулей,
{
life = false;// то пуля умирает
}
}
sprite.setPosition(x+w/2, y+h/2);//задается позицию пуле
}
};
class MovingPlatform : public Entity{//класс движущейся платформы
public:
MovingPlatform(Image &image, String Name, Level &lvl, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H){
sprite.setTextureRect(IntRect(0, 0, W, H));//прямоугольник
dx = 0.08;//изначальное ускорение по Х
}
void update(float time)//функция обновления платформы.
{
x += dx * time;//реализация движения по горизонтали
moveTimer += time;//наращиваем таймер
if (moveTimer>2000) { dx*= -1; moveTimer = 0; }//если прошло примерно 2 сек, то меняется направление движения платформы, а таймер обнуляется
sprite.setPosition(x+w/2, y+h/2);//задаем позицию спрайту
}
};
void changeLevel(Level &lvl,int &numberLevel) {
if (numberLevel == 1) { lvl.LoadFromFile(«map.tmx»); }
if (numberLevel == 2) { lvl.LoadFromFile(«map2.tmx»); }
if (numberLevel == 3) { lvl.LoadFromFile(«map3.tmx»); }
}
bool startGame(RenderWindow &window,int &numberLevel){
view.reset(FloatRect(0, 0, 640, 480));
Level lvl;
changeLevel(lvl,numberLevel);//для загрузки карты для нужного уровня
SoundBuffer shootBuffer;//создаём буфер для звука
shootBuffer.loadFromFile(«shoot.ogg»);//загружаем в него звук
Sound shoot(shootBuffer);//создаем звук и загружаем в него звук из буфера
Music music;//создаем объект музыки
music.openFromFile(«music.ogg»);//загружаем файл
music.play();//воспроизводим музыку
music.setLoop(true);
Image heroImage;
heroImage.loadFromFile(«images/MilesTailsPrower.gif»);
Image easyEnemyImage;
easyEnemyImage.loadFromFile(«images/shamaich.png»);
easyEnemyImage.createMaskFromColor(Color(255, 0, 0));
Image movePlatformImage;
movePlatformImage.loadFromFile(«images/MovingPlatform.png»);
Image BulletImage;//изображение для пули
BulletImage.loadFromFile(«images/bullet.png»);//загрузили картинку в объект изображения
BulletImage.createMaskFromColor(Color(0, 0, 0));//маска для пули по черному цвету
std::list<Entity*> entities;
std::list<Entity*>::iterator it;
std::list<Entity*>::iterator it2;//второй итератор.для взаимодействия между объектами списка
std::vector<Object> e = lvl.GetObjects(«EasyEnemy»);
for (int i = 0; i < e.size(); i++) entities.push_back(new Enemy(easyEnemyImage, «EasyEnemy», lvl, e[i].rect.left, e[i].rect.top, 200, 97));
Object player = lvl.GetObject(«player»);
Player p(heroImage, «Player1», lvl, player.rect.left, player.rect.top, 40, 30);
e = lvl.GetObjects(«MovingPlatform»);//забираем все платформы в вектор
for (int i = 0; i < e.size(); i++) entities.push_back(new MovingPlatform(movePlatformImage, «MovingPlatform», lvl, e[i].rect.left, e[i].rect.top, 95, 22));//закидываем платформу в список.передаем изображение имя уровень координаты появления (взяли из tmx карты), а так же размеры
Clock clock;
while (window.isOpen())
{
float time = clock.getElapsedTime().asMicroseconds();
clock.restart();
time = time / 800;
Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == Event::MouseButtonPressed)//если нажата клавиша мыши
if (event.key.code == Mouse::Left) //а именно левая, то стреляем
{ //и тут же снимаем координаты мыши в этом месте
Vector2i pixelPos = Mouse::getPosition(window);//забираем коорд курсора
Vector2f pos = window.mapPixelToCoords(pixelPos);//переводим их в игровые (уходим от коорд окна)
entities.push_back(new Bullet(BulletImage, «Bullet», lvl, p.x, p.y, 16, 16, pos.x, pos.y)); //и передаем в конструктор пули. создается пуля
shoot.play();//играем звук пули
}
}
for (it = entities.begin(); it != entities.end();)//говорим что проходимся от начала до конца
{
Entity *b = *it;//для удобства, чтобы не писать (*it)->
b->update(time);//вызываем ф-цию update для всех объектов (по сути для тех, кто жив)
if (b->life == false) { it = entities.erase(it); delete b; }// если этот объект мертв, то удаляем его
else it++;//и идем курсором (итератором) к след объекту. так делаем со всеми объектами списка
}
for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка
{
if (((*it)->name == «MovingPlatform») && ((*it)->getRect().intersects(p.getRect())))//если игрок столкнулся с объектом списка и имя этого объекта movingplatform
{
Entity *movPlat = *it;
if ((p.dy>0) || (p.onGround == false))//при этом игрок находится в состоянии после прыжка, т.е падает вниз
if (p.y + p.h<movPlat->y + movPlat->h)//если игрок находится выше платформы, т.е это его ноги минимум (тк мы уже проверяли что он столкнулся с платформой)
{
p.y = movPlat->y — p.h + 3; p.x += movPlat->dx*time; p.dy = 0; p.onGround = true; // то выталкиваем игрока так, чтобы он как бы стоял на платформе
}
}
if (((*it)->name == «EasyEnemy») && ((*it)->getRect().intersects(p.getRect())))
{
////////выталкивание врага
if ((*it)->dx>0)//если враг идет вправо
{
std::cout << «(*it)->x» << (*it)->x << «\n»;//коорд игрока
std::cout << «p.x» << p.x << «\n\n»;//коорд врага
(*it)->x = p.x — (*it)->w; //отталкиваем его от игрока влево (впритык)
(*it)->dx = 0;//останавливаем
std::cout << «new (*it)->x» << (*it)->x << «\n»;//новая коорд врага
std::cout << «new p.x» << p.x << «\n\n»;//новая коорд игрока (останется прежней)
}
if ((*it)->dx < 0)//если враг идет влево
{
(*it)->x = p.x + p.w; //аналогично — отталкиваем вправо
(*it)->dx = 0;//останавливаем
}
///////выталкивание игрока
if (p.dx < 0) { p.x = (*it)->x + (*it)->w; }//если столкнулись с врагом и игрок идет влево то выталкиваем игрока
if (p.dx > 0) { p.x = (*it)->x — p.w; }//если столкнулись с врагом и игрок идет вправо то выталкиваем игрока
}
for (it2 = entities.begin(); it2 != entities.end(); it2++)
{
if ((*it)->getRect() != (*it2)->getRect())//при этом это должны быть разные прямоугольники
if (((*it)->getRect().intersects((*it2)->getRect())) && ((*it)->name == «EasyEnemy») && ((*it2)->name == «EasyEnemy»))//если столкнулись два объекта и они враги
{
(*it)->dx *= -1;//меняем направление движения врага
(*it)->sprite.scale(-1, 1);//отражаем спрайт по горизонтали
}
}
}
if (Keyboard::isKeyPressed(Keyboard::T)) { lvl.levelNumber++; return true; }
if (Keyboard::isKeyPressed(Keyboard::Tab)) { return true; }//если таб, то перезагружаем игру
if (Keyboard::isKeyPressed(Keyboard::Escape)) { return false; }//если эскейп, то выходим из игры
p.update(time);//перенесли сюда update игрока
window.setView(view);
window.clear(Color(77, 83, 140));
lvl.Draw(window);
for (it = entities.begin(); it != entities.end(); it++){
window.draw((*it)->sprite);
}
window.draw(p.sprite);
window.display();
}
}
void gameRunning(RenderWindow & window, int & numberLevel){//ф-ция перезагружает игру , если это необходимо
if (startGame(window,numberLevel)) { numberLevel++; gameRunning(window,numberLevel); }//принимает с какого уровня начать игру
}
int main()
{
RenderWindow window(VideoMode(640, 480), «Lesson 33. kychka-pc.ru»);
int numberLevel = 1;//сначала 1-ый уровень
gameRunning(window,numberLevel);
return 0;
}
Урок 22 SFML C++ работа с Tiled Map Editor | kychka-pc
#ifndef LEVEL_H
#define LEVEL_H
#include <string>
#include <vector>
#include <map>
#include <SFML/Graphics.hpp>
#include <iostream>
#include «TinyXML/tinyxml.h»
struct Object
{
int GetPropertyInt(std::string name);//номер свойства объекта в нашем списке
float GetPropertyFloat(std::string name);
std::string GetPropertyString(std::string name);
std::string name;//объявили переменную name типа string
std::string type;//а здесь переменную type типа string
sf::Rect<float> rect;//тип 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);//возвращает false если не получилось загрузить
Object GetObject(std::string name);
std::vector<Object> GetObjects(std::string name);//выдаем объект в наш уровень
std::vector<Object> GetAllObjects();//выдаем все объекты в наш уровень
void Draw(sf::RenderWindow &window);//рисуем в окно
sf::Vector2i GetTileSize();//получаем размер тайла
private:
int width, height, tileWidth, tileHeight;//в tmx файле width height в начале,затем размер тайла
int firstTileID;//получаем айди первого тайла
sf::Rect<float> drawingBounds;//размер части карты которую рисуем
sf::Texture tilesetImage;//текстура карты
std::vector<Object> objects;//массив типа Объекты, который мы создали
std::vector<Layer> layers;
};
///////////////////////////////////////
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());//загружаем файл в TiXmlDocument
// загружаем 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»
// 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;
}
img.createMaskFromColor(sf::Color(255, 255, 255));//для маски цвета.сейчас нет маски
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)
{
// получаем все данные — тип, имя, позиция, и тд
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 <float> 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;
}
std::vector<Object> Level::GetAllObjects()
{
return objects;
};
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]);
}
#endif
Урок 11 SFML Взаимодействие персонажа с картой | kychka-pc
#include <SFML/Graphics.hpp>
#include <iostream>
#include «map.h»
#include «view.h»
using namespace sf;
////////////////////////////////////////////////////КЛАСС ИГРОКА////////////////////////
class Player {
private: float x, y ;
public:
float w, h, dx, dy, speed ;
int dir;
String File;
Image image;
Texture texture;
Sprite sprite;
Player(String F, float X, float Y, float W, float H){
dx=0; dy=0; speed=0; dir =0;
File = F;
w = W; h = H;
image.loadFromFile(«images/» + File);
image.createMaskFromColor(Color(41, 33, 59));
texture.loadFromImage(image);
sprite.setTexture(texture);
x = X; y = Y;
sprite.setTextureRect(IntRect(0, 0, w, h));
}
void update(float time)
{
switch (dir)
{
case 0: dx = speed; dy = 0; break;
case 1: dx = -speed; dy = 0; break;
case 2: dx = 0; dy = speed; break;
case 3: dx = 0; dy = -speed; break;
}
x += dx*time;
y += dy*time;
speed = 0;
sprite.setPosition(x,y);
interactionWithMap();//вызываем функцию, отвечающую за взаимодействие с картой
}
void interactionWithMap()//ф-ция взаимодействия с картой
{
for (int i = y / 32; i < (y + h) / 32; i++)//проходимся по тайликам, контактирующим с игроком,, то есть по всем квадратикам размера 32*32, которые мы окрашивали в 9 уроке. про условия читайте ниже.
for (int j = x / 32; j<(x + w) / 32; j++)//икс делим на 32, тем самым получаем левый квадратик, с которым персонаж соприкасается. (он ведь больше размера 32*32, поэтому может одновременно стоять на нескольких квадратах). А j<(x + w) / 32 — условие ограничения координат по иксу. то есть координата самого правого квадрата, который соприкасается с персонажем. таким образом идем в цикле слева направо по иксу, проходя по от левого квадрата (соприкасающегося с героем), до правого квадрата (соприкасающегося с героем)
{
if (TileMap[i][j] == ‘0’)//если наш квадратик соответствует символу 0 (стена), то проверяем «направление скорости» персонажа:
{
if (dy>0)//если мы шли вниз,
{
y = i * 32 — h;//то стопорим координату игрек персонажа. сначала получаем координату нашего квадратика на карте(стены) и затем вычитаем из высоты спрайта персонажа.
}
if (dy<0)
{
y = i * 32 + 32;//аналогично с ходьбой вверх. dy<0, значит мы идем вверх (вспоминаем координаты паинта)
}
if (dx>0)
{
x = j * 32 — w;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа
}
if (dx < 0)
{
x = j * 32 + 32;//аналогично идем влево
}
}
if (TileMap[i][j] == ‘s’) { //если символ равен ‘s’ (камень)
x = 300; y = 300;//какое то действие… например телепортация героя
TileMap[i][j] = ‘ ‘;//убираем камень, типа взяли бонус. можем и не убирать, кстати.
}
}
}
float getplayercoordinateX(){
return x;
}
float getplayercoordinateY(){
return y;
}
};
int main()
{
RenderWindow window(sf::VideoMode(640, 480), «Lesson 11. kychka-pc.ru»);
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», 250, 250, 96.0, 96.0);
float CurrentFrame = 0;
Clock clock;
while (window.isOpen())
{
float time = clock.getElapsedTime().asMicroseconds();
clock.restart();
time = time / 800;
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
float coordinatePlayerX, coordinatePlayerY = 0;
coordinatePlayerX = p.getplayercoordinateX();
coordinatePlayerY = p.getplayercoordinateY();
///////////////////////////////////////////Управление персонажем с анимацией////////////////////////////////////////////////////////////////////////
if (Keyboard::isKeyPressed(Keyboard::Left)) {
p.dir = 1; p.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
p.sprite.setTextureRect(IntRect(96 * int(CurrentFrame), 96, 96, 96));
}
if (Keyboard::isKeyPressed(Keyboard::Right)) {
p.dir = 0; p.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
p.sprite.setTextureRect(IntRect(96 * int(CurrentFrame), 192, 96, 96));
}
if (Keyboard::isKeyPressed(Keyboard::Up)) {
p.dir = 3; p.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
p.sprite.setTextureRect(IntRect(96 * int(CurrentFrame), 288, 96, 96));
}
if (Keyboard::isKeyPressed(Keyboard::Down)) {
p.dir = 2; p.speed = 0.1;
CurrentFrame += 0.005*time;
if (CurrentFrame > 3) CurrentFrame -= 3;
p.sprite.setTextureRect(IntRect(96 * int(CurrentFrame), 0, 96, 96));
}
getplayercoordinateforview(coordinatePlayerX, coordinatePlayerY);
p.update(time);
window.setView(view);
window.clear();
/////////////////////////////Рисуем карту/////////////////////
for (int i = 0; i < HEIGHT_MAP; i++)
for (int j = 0; j < WIDTH_MAP; j++)
{
if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(0, 0, 32, 32));
if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(32, 0, 32, 32));
if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(64, 0, 32, 32));
s_map.setPosition(j * 32, i * 32);
window.draw(s_map);
}
window.draw(p.sprite);
window.display();
}
return 0;
}
Сетевой модуль (SFML / Learn / 2.5.1 Документация)
Коммуникация через сокеты, утилиты и сетевые протоколы более высокого уровня (HTTP, FTP).
Подробнее …
Классы | |
class | sf :: Ftp |
FTP-клиент. Подробнее … | |
class | sf :: Http |
HTTP-клиент. Подробнее … | |
class | sf :: IpAddress |
Инкапсулирует сетевой адрес IPv4.Подробнее … | |
class | sf :: Packet |
Служебный класс для создания блоков данных для передачи по сети. Подробнее … | |
class | sf :: Socket |
Базовый класс для всех типов розеток. Подробнее … | |
class | sf :: SocketSelector |
Мультиплексор, позволяющий читать с нескольких сокетов.Подробнее … | |
class | sf :: TcpListener |
Сокет, который прослушивает новые TCP-соединения. Подробнее … | |
class | sf :: TcpSocket |
Специализированный сокет, использующий протокол TCP. Подробнее … | |
class | sf :: UdpSocket |
Специализированный сокет, использующий протокол UDP.Подробнее … | |
Подробное описание
Коммуникация через сокеты, утилиты и сетевые протоколы более высокого уровня (HTTP, FTP).
.
новейших вопросов sfml — qaru
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
.