Созданные ответы форума
-
АвторСообщения
-
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169Vector2f vectorNormalize(Vector2f vector, Vector2f vector2){float velocity = 1 / std::sqrt((abs((vector - vector2).x * 5)*abs((vector - vector2).x) * 5) + (abs((vector - vector2).y * 5)*abs((vector - vector2).y * 5)));return Vector2f(vector.x * velocity, vector.y * velocity);}class projectiles {public:float speed_projectiles = 3;float distance;Texture texture_projectiles;Sprite sprite_projectiles;Vector2i size_projectiles; //Размер спрайтаVector2f temp;//Vector2f player;Vector2f velocity;projectiles(Image &image, int size_projectiles_x, int size_projectiles_y, /*float tempX, float tempY, float player_x, float player_y*/ Vector2f startPosition, Vector2f velocity, float duration = 5000){texture_projectiles.loadFromImage(image);sprite_projectiles.setTexture(texture_projectiles);//player.x = player_x; player.y = player_y;//temp.x = tempX; temp.y = tempY;sprite.setPosition(startPosition);this.velocity = velocity;}void update(float delta){duration -= delta;sprite.move(velocity.x * (delta/1000), velocity.y * (delta/1000);}};int main(){RenderWindow window;Vector2i position_window = window.getPosition();window.create(VideoMode(800, 600), "Game");window.setFramerateLimit(60); //FPSRectangleShape rectangle_tab(sf::Vector2f(230, 580)); //Окно информации на "Tab"rectangle_tab.setFillColor(sf::Color(0, 0, 0, 128)); //Черный цвет с прозрачностьюrectangle_tab.setPosition(position_window.y + 10, position_window.x + 10);Clock clock; //ВремяImage image_player; //Игрокimage_player.loadFromFile("images/sprite1.png");image_player.createMaskFromColor(Color::White); // Цвет прозрачностиImage image_projectiles; //Выстрелimage_projectiles.loadFromFile("images/shoot.png");image_projectiles.createMaskFromColor(Color::White); // Цвет прозрачностиFont font; //ТекстText text_stats("", font, 14);font.loadFromFile("fonts/font_SEVENET_7_CYR.ttf");text_stats.setColor(Color::White);///Вектор проджектайловstd::vector<*projectiles> projectiles;// Объект класса playerplayer p(image_player, "Player", 48, 48, 0, 0, 300, 400);/*1. Image - Изображение2. Name - Имя игрока3. size_player_x - Размер по Х4. size_player_y - Размер по Y5. origin_player_x - Начало первого спрайта по Х6. origin_player_y - Начало первого спрайта по Y7. position_x - Начальная позиция спрайта по Y8. position_y - Начальная позиция спрайта по Y*/while (window.isOpen()){//float time = clock.getElapsedTime().asMicroseconds(); //Лучше использовать милисикунды. Шаг в микросекунду ты никогда не поймаешь.float time = clock.getElapsedTime().asMiliseconds();clock.restart();time = time / 800;p.update(time); //Обновляем класс player с течением времениEvent event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();if (event.type == Event::MouseButtonPressed) //Нажата клавиша мыши //Если ты смотришь в сторону ивента то ты должен хватать его в пуле, а не в остатке;if (event.key.code == Mouse::Left) //Левая{float speed = 1;Vector2f velocity = vectorNormalize(Vector2f(Mouse::getPosition(window).x, Mouse::getPosition(window).y), p.sprite.getPosition());velocity.x *= speed;velocity.y *= speed;projectiles.push_back(new projectiles(image_projectiles, 32, 32, p.sprite.getPosition(), velocity));}}for (auto it : projectiles){if (it != nullptr)//Если ссылка валидна{it->update(time);if (it->duration <= 0)//Если время жизни подошло к концу{delete it;//Удаляем обьектprojectiles.erase(it);//Удаляем ссылку на него}}else projectiles.erase(it);//Удаляем ссылку на него}window.clear(Color(128, 128, 128)); //Серый фон игрыfor (auto it : projectiles){if (it != nullptr)//Если ссылка валидна{window.draw(it->sprite_projectiles);//Рисуем спрайт}else projectiles.erase(it);//Удаляем ссылку на него}window.draw(p.sprite); //Рисуем персонажаif (Keyboard::isKeyPressed(Keyboard::Tab)) //Окно информации на "Tab"{ostringstream name_player; name_player << p.name_player; //Имя персонажаostringstream health_player; health_player << (int)p.health; //Здоровье персонажаostringstream level_player; level_player << p.level; //Уровень персонажаostringstream exp_player; exp_player << p.level_experience; //Опыт персонажаostringstream position_player_x; position_player_x << (int)p.x; //Координата Xostringstream position_player_y; position_player_y << (int)p.y; //Координата Yostringstream free_point_player; free_point_player << p.free_point; //Доступные очки характеристикtext_stats.setString("Имя: " + name_player.str() + "\n\nЗдоровье: " + health_player.str() + "\n\nУровень: " + level_player.str() + "\nОпыт: " + exp_player.str() + "\n\nКоординаты:\nX: " + position_player_x.str() + "\nY: " + position_player_y.str() + "\n\nОчки характеристик: " + free_point_player.str());text_stats.setPosition(position_window.y + 20, position_window.x + 20);window.draw(rectangle_tab); //Выводим окно при нажатии "Tab"window.draw(text_stats); //Выводим текст при нажатии "Tab"}window.display();}return 0;}
//deleted
Для начала разберитесь как вы вобще заставили всё это работать через select case. По сути вы можете вовсе без него прожить передавая ускорение напрямую с каждой кнопки
C++123456789if (Keyboard::isKeyPressed(Keyboard::Right))dx += -0.1; //Когда зажата стрелка вправо мы придаём импульс движения вправоpublic void onUpdate(Time delta){//...sprite.move(dx * delta.asSeconds(), dy * delta.asSeconds());//Применяем смещение//...}Ну а направить пулю проще простого:
C++12345678910111213141516171819202122232425Vector2f vectorNormalize(Vector2f vector, Vector2f vector2){float velocity = 1 / std::sqrt((abs((vector - vector2).x * 5)*abs((vector - vector2).x) * 5) + (abs((vector - vector2).y * 5)*abs((vector - vector2).y * 5)));return Vector2f(vector.x * velocity, vector.y * velocity);}//...if (event.type == Event::MouseButtonPressed){if (event.key.code == Mouse::Left){entities.push_back(new Bullet(BulletImage, "Bullet", lvl, p.x, p.y, 16, 16, p.state));Vector2f direction = Vector2f(Mouse::getPosition(window).x - p.sprite.getPosition().x, Mouse::getPosition(window).y - p.sprite.getPosition().y);direction = vectorNormilize(direction, Vector(0, 0));entities.back().velocity = Vector2f(direction.x * speed, direction.y * speed);}}//...//...public void onUpdate(Time delta){sprite.move(velocity.x * delta.asSeconds(), velocity.y * delta.asSeconds());}//...А, и ещё. Если ты пытаешься отловить нажатие в poolEvent(event) то нужно использовать if(event.type == sf::Event::KeyPressed) if (event.key.code == Keyboard::Up)
Ну а собственно в чём проблема? По факту анимация должна быть заключена внутри p.update(time) а не в главном цикле.
На MSDN же было TimedMathQuiz
Вобще тебе придётся позаботиться о переключении управления и использовать в window.poolEvent(event)
C++12345678910111213141516171819202122232425262728293031//В while (window.pollEvent(event))if (true /*bool который тригерится при столкновении с блоком 's' */){if (event.type == sf::Event::TextEntered){if (event.text.unicode == '0' || event.text.unicode == '1' || event.text.unicode == '2' || event.text.unicode == '3' || event.text.unicode == '4' || event.text.unicode == '5' || event.text.unicode == '6' || event.text.unicode == '7' || event.text.unicode == '8' || event.text.unicode == '9'){result.setString(result.getString() + event.text.unicode);}}if (event.type == sf::Event::KeyPressed){if (event.key.code == sf::Keyboard::Return)//Enter{if (resCheck == std::stoi(result.getString().toAnsiString())){//Ввод верный}else{//Ввод неверный}}}}else{//...//}C++123456789101112131415161718//При проверке коллизии игрока проверяй с чем сталкиваешсяif (true /*При столкновении с блоком 's' */){std::srand(time(0));//Это сбрасывает таблицу псевдослучайных чисел/*Тригерим bool*/string buf;std::stringstream ss;ss << std::rand(); ss >> buf;//Здесь число ограничено [0; std::numeric_limits<int>::infinity();]var1.setString(buf);//Первое рандомное числоss << (std::rand() % 100); ss >> buf;//Здесь случайное число ограничено в диапазоне [0; 99]var2.setString(buf);//Второе рандомное числоresult.setString("");//Обнуляем ответresCheck = std::stoi(var1.getString().toAnsiString()) + std::stoi(var2.getString().toAnsiString());}Код набросан на вскидку как помню статью с MSDN так что не факт что проверка на символы юникода будет работать. Если текст вводится вовсе не будет убери ту проверку.
Я для себя когда-то состряпал такую конструкцию
C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071#ifndef NODE_H#define NODE_H#include <SFML/Graphics.hpp>class GameState;namespace sfge{class Node{public:/// \brief Base ctorNode(const std::string& name = "Node");virtual ~Node();/// \brief Get node name/// return stringstd::string getName();/// \brief Set node name/// @param stringvoid setName(const std::string& name);void draw(sf::RenderWindow* window);void update(sf::Time delta);void handle(const sf::Event& event);void addNode(Node* node);void removeNode(Node* node);/// \brief called after onUpdate()void applyUpdate(sf::Time delta) {}void setWindow(sf::RenderWindow* window);int getZ() const;void setZ(int z);Node* getParent();void setParent(Node* parentnode);std::vector<Node*>& getChildren();protected:/// \brief Sort all added childrens/// use carefulyvoid sortChildrenByZValue();/// \brief Draw things. Allways called last in game loopvirtual void onDraw(sf::RenderWindow * window) {}/// \brief Called evry game tickvirtual void onUpdate(sf::Time delta) {}/// \brief Called when window get event. For example - window get focused/// or key pressed;virtual void onHandle(const sf::Event& event) {}virtual void onWindowSet(){}Node* parent;sf::RenderWindow* window;private:std::vector<Node*> children;std::string name;int z;};}#endif // NODE_HC++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120//Node.cpp#include "Node.h"#include <algorithm>#include <tmx/Log.h>using namespace tmx;namespace sfge{bool sortByZValue(const Node* a, const Node* b){return (a->getZ() < b->getZ());}Node::Node(const std::string& name) : name(name), parent(NULL), z(0), window(NULL){//ctor}Node::~Node(){for(Node* node : children){LOG("deleting node: " + node->getName(),Logger::Type::Info);delete node;}}std::string Node::getName(){return name;}void Node::setName(const std::string& name){this->name = name;}void Node::setZ(int z){this->z = z;}int Node::getZ() const{return z;}void Node::setWindow(sf::RenderWindow* window){this->window = window;for(Node* node : children)node->setWindow(window);onWindowSet();}void Node::sortChildrenByZValue(){std::sort(begin(children), end(children), sortByZValue);}void Node::draw(sf::RenderWindow* window){onDraw(window);for(Node* node : children)node->draw(window);}void Node::update(sf::Time delta){onUpdate(delta);for(Node* node : children)node->update(delta);}void Node::handle(const sf::Event& event){onHandle(event);for(Node* node : children)node->handle(event);}void Node::addNode(Node* node){node->setParent(this);node->setWindow(window);children.push_back(node);std::sort(begin(children), end(children), sortByZValue);}void Node::removeNode(Node* node){for(auto itr = children.begin(); itr != children.end(); itr++){if(node == (*itr)){children.erase(itr);return;}}}Node* Node::getParent(){return parent;}void Node::setParent(Node* parentnode){parent = parentnode;}std::vector<Node*>& Node::getChildren(){return children;}}Энтити наследуется уже от узла. Дальше сортировка идёт по std::sort(begin(children), end(children), sortByZValue); (т.е. по int z) и вызываешь в цикле handle, update и draw. Но делалось это не для постоянного обновления, а для отрисовки бекграунда статично позади – используй с осторожностью.
udp И добавлялись все эти обьекты в State () который сам от наследуется от ноды. Если хочешь использовать мой способ придётся для Main loop сделать наследование от ноды и добавлять ссылки на обьекты через addChildren(Node * node); Т.е.
C++123456789101112131415161718sfge::State app();sf::Clock stopwatch;stopwatch.restart();while (window.isOpen){sf::Event e;while (window.pollEvent(e)){app.handle(e);}app.update(stopwatch.restart());app.draw(window);}Точки дебаг останова активируются нажатием ЛКМ в столбце напротив строки где нужно вызвать ‘паузу’ приложения.
Студия в момент дебаг остнова. Думаю не нужно обьяснять что делает кнопка продолжить. Убрать точку останова можно так же как и поставили – ЛКМ по ней.Вобще – учитесь с самого начала пользоватся дебагом, гораздо упрощает жизнь в отлове ошибок. Понаставляйте отметок останова в циклах и через шаг с обходом смотрите на каком моменте игрок теряет хп даже не пересекаясь.
И не проще вместо
sprite.setPosition(x+w/2,y+h/2);
использовать единожды в конструкторе
sprite.setOrigin(w/2,h/2);
и дальше спокойно использовать sprite.setPosition(x,y);Вобще, когда надоест изобретать велосипе… *Кхм* парсер tmx карт можешь воспользоватся этим форком . В нём есть поддержка загрузки ConvexHull’ов (Фигур состоящих из вершин) а так же загрузка карт сжатых при помощи Base64 и zlib (Кстати, zlib хидеры в комплект не входят да и воспользоваться zlib сжатием я так и не смог)
Подгрузились скрины. Вобще мучать телефон/фотоаппарат было незачем т.к. есть множество программ позволяющих захватить определённую часть экрана. К примеру те же самые системны ножницы(Пуск -> Стандартные) или Print Screen на клавиатуре отправит снимок экрана прямо в буфер обмена.
Ну и для tiled. Помести карту к main.cpp, открой её в tiled, укажи пусть до тайлсета, выставь в настройках карты Формат слоя тайлов = XML и пихай куда вздумается. После загружай его в программе и всё должно работать если нет сжатия.Либо вы забыли добавить криншоты, либо хостинг их не хочет принимать.
Возможно неверно были выставлены настройки в карте. Обязательно не должно быть никакого сжатия(Формат слоя тайлов = XML)
Так же твой код может парсить только ортогональную карту.Прошу прощения что ввёл в заблуждение. Картинка должна быть расположена по пути указаном в файле релативно рабочей папки , а не .tmx
СкриншотЛибо парсер не смог найти ни одного тайла, либо он не нашёл тайлсет. Тайлсет расположен релативно к map.tmx? Перепроверь что бы относительно map.tmx текстуры находились именно там, от куда были превязаны: Скриншот
А ты не пробовал сохранить tmx формат карты и открыть его к примеру в notepad++? Думаю результат тебя приятно удивит так как это и есть искомый нами xml документ.
-
АвторСообщения