Созданные ответы форума
-
АвторСообщения
-
05.02.2018 в 10:38 в ответ на: объясните, пожалуйста, как создать соединение с использованием внешних адресов #4965
А вам знакомо определение Port Forwarding? У хоста должно быть правильное перенаправление портов, отсутсвие строгого NAT и в принципе открытый целевой порт. В первую очередь вам нужно проеврить это. Проверить доступность можно через сервис 2ip.
Моё объяснение будет всё же неправильным, но для понимания картины думаю сойдёт.
При TCP подключении устанавливается Point to Point соединение, в котором происходит вещание между 2 клиентами. Один ожидает подключение – второй производит дозвон. Когда оба устройства находят друг друга они начинаю с определённой переодичностью посылать между собой Ping Pong запроы(Жив ли собеседник или нет). При каждой отправке данных от одного клиента ко второму посылается последовательность байтов в синхронном режиме (Т.е. чтение 0 и 1 с определённой переодичностью о которых устройства скажем так договариваются сами.) и по окончании передачи части байтов клиент вещающий переходит в режим чтения ожидая ответа от того кто принимал. Если ответ положительный -> идёт следующая порция байтов, если ошибка -> последовательность передаётся заного.Оптимизация компилятором. На Debug она не распростроянется ибо кадр стека кучи может оказаться востребованым в любой момент.
Собственно файл буфферизируется единожды при первом обращении к файлу. Дальше все считывается из строки.
Здесь запись конечно не сортируется как ключ – значение, но никто не мешает тебе пропустить весь буффер через регулярные выражения (Regex) получив std::map<std::string, std::string>, проходится по нему итерациеq и присваивать значение если ключ совпадает с искомым. Это уже не твои проблемы если юзверь поковырялся и нагадил в конфигах поставив заместо числа строку, так что смело конвертируй где нужно число через функции std::stoi, std::stof.Ну на скорую руку могу только предоставить менеджер локализации написаный много времени назад, но новая студия вроде как спокойно “съела” код, для твоих целей он в принципе подойдёт
Но если тебе нужна только загрузка с файла тебе понадобится только этот кусок кода где localeBuffer будет полностью вмещать содержимое файла. И да, не забывай о том что потребуется приведение к типам из строки к числу – для этого есть std::stoi, std::stof, std::stod, std::stol, std::stoul и т.д. Перевод перевод делай желательно sf::String::toWideString() ибо мы работаем с юникодом при использовании строки sfmlC++12345678910111213141516171819202122232425262728293031323334353637sf::String curLocale = "ru_RU";std::string curDir = "";sf::String defaultLang = "en_UK";std::ifstream curLocaleFile;std::ifstream defaultLocaleFile;sf::String localeBuffer;if (localeBuffer.isEmpty()){curLocaleFile.open(std::string(curDir + curLocale + ".lang"), std::ios_base::in);char S;int count = 0;if (curLocaleFile.is_open()){while (!curLocaleFile.eof())//count simbols{curLocaleFile.get(S);count++;}curLocaleFile.close();curLocaleFile.open(std::string(curDir + curLocale + ".lang")); //open the file againint i = 0; //iterwhile (!curLocaleFile.eof()) //while not end of file{char buf;curLocaleFile.get(buf);localeBuffer += buf; //add simboli++; //move iter next}curLocaleFile.close();}else{//LOG("LocalisationManager::getLocalisation: Failed to open file(" + curDir + curLocale + ".lang" + ")", Logger::Info);}}C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283//LocalisationManager.h#pragma once//#include "SFGE\LabelButton.h"//#include <SFGE\SFGE.h>#include <fstream>#include <SFML\System\String.hpp>//#include <Windows.h>//#include <atlwin.h>#define lm sfge::LocalisationManager::instance()namespace sfge{/// \brief A localisation manager that give licalised names and descriptions in selected locale.////// In order not to let calling the class get verbose, a MACRO is defined.\n/// @code #define lm sfge::LocalisationManager::instance() @endcode/// This makes calling the localisation manager elsewere as this:/// @code/// #include <SFGE/LocalisationManager.h>/// lm->getLocalisation("block.dirt.name");/// @endcode/// And resulted string ben a localised string, or return input if localisation not existclass LocalisationManager{public:static LocalisationManager* instance();~LocalisationManager(){}/// \brief Set localisation (and filename) as main source of licalised names/// @param sf::String - locale in style en_UK, ru_RU, etc.void setLocale(sf::String locale){curLocale = locale;}/// \brief Set lang folder/// \@param string Dir rootvoid setDir(std::string root){curDir = root;}/// \brief Get localisation from .lang file/// @param sf::String Unlocalised Name/// @return sf::String resultsf::String getLocalisation(sf::String unlocalisedName);protected:LocalisationManager(){//curLocale = "ru_RU";}private:static LocalisationManager* lcr;sf::String curLocale = "ru_RU";std::string curDir = "";sf::String defaultLang = "en_UK";std::ifstream curLocaleFile;std::ifstream defaultLocaleFile;/// \brief Locale buffer is containing all chars from file/// and we no more need to load file in to memory again, and again, and again....sf::String localeBuffer;};//end LocalisationManager}// end namespace sfgeC++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147//LocalisationManager.cpp//#include "Block.h"//#include <SFGE\Block.h>//#include "gamestate.h"#include "LocalisationManager.h"sfge::LocalisationManager* sfge::LocalisationManager::lcr = 0;namespace sfge{LocalisationManager* LocalisationManager::instance(){//setlocale(LC_CTYPE, "rus");//We cant get <Windows.h> any moreif (lcr == NULL)lcr = new LocalisationManager;return lcr;}sf::String LocalisationManager::getLocalisation(sf::String unlocalisedName){sf::String temp;sf::String result;if (localeBuffer.isEmpty()){curLocaleFile.open(std::string(curDir + curLocale + ".lang"), std::ios_base::in);char S;int count = 0;if (curLocaleFile.is_open()){while (!curLocaleFile.eof())//count simbols{curLocaleFile.get(S);count++;}curLocaleFile.close();curLocaleFile.open(std::string(curDir + curLocale + ".lang")); //open the file againint i = 0; //iterwhile (!curLocaleFile.eof()) //while not end of file{char buf;curLocaleFile.get(buf);localeBuffer += buf; //add simboli++; //move iter next}curLocaleFile.close();}else{//LOG("LocalisationManager::getLocalisation: Failed to open file(" + curDir + curLocale + ".lang" + ")", Logger::Info);}}sf::String c1;auto c1it = localeBuffer.find(".");c1it = localeBuffer.find(".", c1it + 1);c1 = localeBuffer.substring(c1it + 1, 4);if (c1 == "name")//Here we determinate -> we search name or description{if (unlocalisedName == "block..name" || unlocalisedName == "item..name" || unlocalisedName == "entity..name"){//LOG("LocalisationManager::getLocalisation: Failed. Unlocalised name is missing", Logger::Error);return "missingNo.name";}int checkCode = 0;//if (localeBuffer.find(unlocalisedName))//{auto it = localeBuffer.find(unlocalisedName + "=");it += std::string(unlocalisedName + "=").size();if (localeBuffer.find("\n", it) != sf::String::InvalidPos)//We found \n or get end of string?checkCode = 1;else checkCode = -1;auto itE = localeBuffer.find("\n", it);if (checkCode == 1)//If we found \n we use it positionwhile (it < itE){//std::cout << std::to_string(it) << " " << std::to_string(itE) << std::endl;result += localeBuffer[it];it++;}else if (checkCode == -1)//Else use end of string position;while (it < localeBuffer.getSize() - 1){//std::cout << std::to_string(it) << " " << std::to_string(localeBuffer.getSize()) << std::endl;result += localeBuffer[it];it++;}//LOG("LocalisationManager::getLocalisation:(" + unlocalisedName + ") = " + result, Logger::Info);return result;}else if (c1 == "desc"){auto c2c = unlocalisedName.substring(0, unlocalisedName.find("."));if (c2c == "" || c2c == "."){//LOG("LocalisationManager::getLocalisation: Failed. Unlocalised name is missing", Logger::Error);return "missingNo.desc";}int checkCode = 0;auto it = localeBuffer.find(unlocalisedName + "=");it += std::string(unlocalisedName + "=").size();//if (localeBuffer.find("#enddesc", it) != sf::String::InvalidPos)//We found \n or get end of string?// checkCode = 1;//else checkCode = -1;auto itE = localeBuffer.find("#enddesc", it);if (itE != sf::String::InvalidPos)while (it < itE){//std::cout << std::to_string(it) << " " << std::to_string(itE) << std::endl;result += localeBuffer[it];it++;}else{//LOG("LocalisationManager::getLocalisation: Failed(" + unlocalisedName + "): #enddesc not found", Logger::Error);return "missingNo.desc.notEnded";}}//}//else//{//LOG("LocalisationManager::getLocalisation: Failed(" + unlocalisedName + ")", Logger::Warning);//LOG("LocalisationManager::getLocalisation: localeBuffer(\n" + localeBuffer + ")", Logger::Warning);return unlocalisedName;//}}}C++1234//ru_Ru.lang - exampleblock.dirt.name=Земляblock.cobble.name=Булыжникblock.grass.name=ТраваОбъясню оратора выше. В аргумент функции или метода по умолчанию мы передаём копию объекта, т.е. как правильно заметил makish под шрифт выделяется лишняя память которая удаляется при выходе из конструктора. Как по мне особо смысла передавать sf::Font даже через ссылку не совсем целесообразно. Лучше конечно сделать статичный загрузчик ресурсов который всегда будет иметь и передавать лишь 1 копию каждого ресурса, но ты можешь сделать шрифт и как глобальную переменную (Или статичную, принадлежащуюю какому-либо классу. Тогда вызов будет происходить как MyClass:MyFont). Если нужно получить доступ к тексту в другом .h .cpp файле с методом глобальной переменной то прописываешь где надо
C++1extern sf::Font fontNameСо статичным членом класса – указываем где надо наш хидер и получам доступ к классу::переменной
Так же лаги могет происходить из за: Кол-во объектов в поле отрисовки, Кол-во объектов в очереди обновления, Кол-во объектов проверяют друг с другом столкновения.
Если хочешь можешь обращатся ко мне через дискорд https://discord.gg/MC3zMHn . На сайт я не особо часто захожу, но всегда могу помочь в дискордеПравильно, ибо SFML производит отрисовку “По пиксельно” в отношении ОКНА и НЕ применяет сглаживание по умолчанию. Для активации сглаживания в конструктор окна надо передавать sf::ContextSettings с заданым значением зглаживани (Antialiasing).
Как понимать соприкосновение указателей? Посколько оба итератора принадлежат разным спискам они никогда не будут равны друг другу (Т.е. они не смогут указывать на общий массив в куче). Если ты хочешь просто удлять объект из вектора если Зомби задевает огонь то проверяй пересечение обоих через вложеный цикл
C++12345678for (auto it1 = enemyArray.begin(); it1 != enemyArray.end(); it++ ){for (auto itF = fireArray.begin(); itF != fireArray.end(); itF++){if (it1->Sprite.getGlobalBounds().intersects(itF->Sprite.getGlobalBounds()))fireArray.erase(itF);}}Выйдет примерно такая конструкция. IDE с плюсами под рукой сейчас нет что бы проверить названия методов.
А, и да, не пугайся конструкции auto it1 = enemyArray.begin(); Тип auto зарезервирован языком как автоматически определяемый тип на момент сборки объекта, следственно компьютер сам поймёт что от него тут требуют если полю сразу было передано значение. Единственный недостаток auto (var в C# и вроде Java) в том что он ухудшает читаемость кода человеком, но в циклах вполне себе используем.FPS никак не связан со временем. Время используется что бы несмортя на то, сколько времени бы не заняла обработка цикла объекты находились в момент времени там, где предполагается. То, что тут показывают умножать время и перемещение – всё же абсурд и влечёт за собой последствия, но зато позволяет отбрасывать объект в точку где он должен находится в данный момент времени.
На шарпе это выглядит примерно так
C#12345678910111213Keyboard.Key key = Keyboard.Key.F1;//Условная кнопка. Сидит среди прочих переменных в классе//Ивент нажатия клавиши отловелнный в пуле окнаprivate void Window_KeyPressed(object sender, KeyEventArgs e){if (e.Code == key){//Нажата ключевая кнопка.}elsekey = e.Code;//Если ключевая кнопка не нажата мы прослушываем другую кнопку, нажатую вместо нашей}При помощи ивента нажатия клавиши (sf::Event::KeyPressed).
Вы же в Keyboard::isKeyPressed(Keyboard::Key) передаёте аргумент Keyboard::Key который так же получаете при перехвате sf::Event::KeyPressedC++123456789101112Keyboard::Key hookedKey;Event e;//Цикл обработки ивента...if (e.type == sf::Event::KeyPressed){//Условный флаг что вы ждёте когда пользователь нажмёт желанную клавишуif (flag){hookedKey = e.key;}}Здесь hookedKey и будет олицетворять назначеную клавишу
C++123456if ((event.type == Event::KeyPressed) && (event.key.code == Keyboard::N)){fireArray.push_back(new Fire("f"));firepos = p.getplayercoordinateX();firepos2 = p.getplayercoordinateY();}Собственно, а почему тут выставляется глобальная позиция? Каждый объект должен хранить свою позицию, а не пользоватся одной глобальной
Собственно, а в чём проблема?
Есть же метод в классе окна window->setSize(Vector2u(800, 600));Хм, тогда вот
https://discord.gg/jTpSQBnЛучше пишите мне через этот сервер дискорда: https://discord.gg/55Zud5 Можно прямо из браузера работать
Вам просто нужно указывать всё без поворотов самой изометрии (Т.е. просчёт коллизии должен быть в обычной плоскости, а уже рендер – в изометрии)Хм, и далеко не все сегмены загружены на гитхаб. Используй GitHub Desktop – не придётся загружать файлы через браузер/ Git Bush
-
АвторСообщения