SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Не изменяется спрайт персонажа после смерти
В этой теме 5 ответов, 4 участника, последнее обновление Sinsinmin 8 года/лет, 1 месяц назад.
-
АвторСообщения
-
здравствуйте.Суть проблемы в том, что персонаж умирает и вместо застывшего обездвиженного героя появляется могила с крестом. Но ничего не выводится, а только пропадает персонаж и все.
эта строка должна выводить : if (p.life == false) { window.draw(text3); p.sprite.setTextureRect(IntRect(99, 2016, 32, 32));
вот код:C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303class Player{private: float x, y;public://обеспечиваем доступ к нему из различных частей программыfloat w, h, dx, dy, speed;//координаты игрока х и у, высота ширина, ускорение (по х и по у), сама скоростьint dir; //направление (direction) движения игрокаint playerScore;//добавили переменную для храния очков персонажа( на данный момент собранных бочекint health;//переменная жизни игрокаbool life;//переменная жизнь, логическаяString file;//файл с расширениемImage image;//сфмл изображениеTexture texture;//сфмл текстураSprite sprite;//сфмл спрайтPlayer(String F, float X, float Y, float W, float H)//Конструктор с параметрами(формальными) для класса Player. При создании объекта класса мы будем задавать имя файла, координату Х и У, ширину и высоту{dx = 0; dy = 0; speed = 0; dir = 0; playerScore = 0; health = 100;file = F;//имя файла + расширениеw = W; h = H;//высота и ширинаimage.loadFromFile("images/" + file);//запихиваем в image наше изображение вместо File мы передадим то, что пропишем при создании объекта. В нашем случае "hero.png" и получится запись идентичная image.loadFromFile("images/hero/png");image.createMaskFromColor(Color(103, 103, 103));texture.loadFromImage(image);//закидываем наше изображение в текстуруsprite.setTexture(texture);//заливаем спрайт текстуройx = X; y = Y;//координата появления спрайтаsprite.setTextureRect(IntRect(0, 0, h, w)); //Задаем спрайту один прямоугольник для вывода одного льва, а не кучи львов сразу. IntRect - приведение типов}void update(float time) //функция "оживления" объекта класса. update - обновление. принимает в себя время SFML , вследствие чего работает бесконечно, давая персонажу движение.{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); //выводим спрайт в позицию x y , посередине. бесконечно выводим в этой функции, иначе бы наш спрайт стоял на месте.interactionWithMap();if (health <= 0) { life = false; speed = 0; }//если жизней меньше либо равно 0, то умираем и исключаем движение игрока после смерти}float getPlayerCoordinateX()//забираем координату х;{return x;}float getPlayerCoordinateY()//соответственно У{return y;}void interactionWithMap()//функция взаимодействия с картой{for (int i = y / 32; i < (y + w) / 32; i++)//проходимся по тайликам, контактирующим с игроком, то есть по всем квадратикам размера 32*32, которые мы окрашивали в 9 уроке. про условия читайте ниже.for (int j = x / 32; j < (x + h) / 32; j++)//икс делим на 32, тем самым получаем левый квадратик, с которым персонаж соприкасается. (он ведь больше размера 32*32, поэтому может одновременно стоять на нескольких квадратах). А j<(x + w) / 32 - условие ограничения координат по иксу. то есть координата самого правого квадрата, который соприкасается с персонажем. таким образом идем в цикле слева направо по иксу, проходя по от левого квадрата (соприкасающегося с героем), до правого квадрата (соприкасающегося с героем){if (TileMap[i][j] == 'a')//если наш квадратик соответствует символу 0 (стена), то проверяем "направление скорости" персонажа:{if (dy > 0)//если мы шли вниз,{y = i * 32 - w;//то стопорим координату игрек персонажа. сначала получаем координату нашего квадратика на карте(стены) и затем вычитаем из высоты спрайта персонажа.}if (dy < 0){y = i * 32 + 32;//аналогично с ходьбой вверх. dy<0, значит мы идем вверх (вспоминаем координаты паинта)}if (dx > 0){x = j * 32 - h;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа}if (dx < 0){x = j * 32 + 32;//аналогично идем влево}}/*if (TileMap[i][j] == 'c'){ //если символ равен 's' (камень)playerScore++;//sprite.setPosition(150, 100);//какое то действие... например телепортация герояTileMap[i][j] = ' ';//убираем камень, типа взяли бонус. можем и не убирать, кстати.}*/if (TileMap[i][j] == 'f'){health -= 40;//если пенек,то переменная health=health-40;TileMap[i][j] = ' ';//убрали пенек}if (TileMap[i][j] == 'h'){health += 20;//если взяли эликсир,то переменная health=health+20;TileMap[i][j] = ' ';//убрали эликсир}}}};int main(){RenderWindow window(VideoMode(640, 480), "game");view.reset(sf::FloatRect(0, 0, 640, 480));//размер "вида" камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации/*создает обьект window - окно приложения.так же,после заголовка "game", можно задать различные параметры окна.например : Style::Fullscreen сделает окно развернутым во весь экран.*//*Image heroImage;//создаем обьект 'изображение'heroImage.loadFromFile("images/Human_HF1_Male_24.png");//загружаем изображение в обьект ImageTexture heroTexture; //создаем обьект 'текстура'heroTexture.loadFromImage(heroImage);//передаем в него обьект изображение.Sprite herosprite;//создаем обьект 'спрайт'herosprite.setTexture(heroTexture);//Передаем в него обьект текстураherosprite.setTextureRect(IntRect(0, 0, 70, 85));//таким образом выводим прямоугольникherosprite.setPosition(100, 100);//задаем спрайту начальную позицию// слово set переводится как "задавать"*/Player p("Human_HF1_Male_24.png", 200, 200, 70.0, 85.0);Image map_image;map_image.loadFromFile("images/map.png");Texture map;map.loadFromImage(map_image);Sprite s_map;s_map.setTexture(map);Font font;font.loadFromFile("fonts/arial.ttf");Text text("", font, 20);Text text1("", font, 20);Text text2("", font, 20);Text text3("", font, 50);//создаем объект текст. закидываем в объект текст строку, шрифт, размер шрифта(в пикселях);//сам объект текст (не строка)text.setColor(Color::Red);text.setStyle(Text::Bold);Clock clock;//создаем переменную времениfloat CurrentFrame = 0;//создаем переменную хранящую текущий кадрwhile (window.isOpen())// цикл с условием выполнения пока открыто окно.{float time = clock.getElapsedTime().asMicroseconds();//буквально переводится как "получить прошедшее время в миллисекундахclock.restart();//перезагружает времяtime = time / 800;//задаем скорость игры(можно сказать кол. кадров в сек.Event event;//событие,говорящее, что при его значении == Closed закрывается окно игры.while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();}if (p.life) {if (Keyboard::isKeyPressed(Keyboard::Left)){p.dir = 1; p.speed = 0.1;//dir =1 - направление вверх, speed =0.1 - скорость движения.время мы уже здесь ни на что не умножаем и нигде не используем каждый разCurrentFrame += 0.005*time; //служит для прохождения по "кадрам". переменная доходит до трех суммируя произведение времени и скорости. изменив 0.005 можно изменить скорость анимацииif (CurrentFrame > 3)//проходимся по кадрам с первого по третий включительно. если пришли к третьему кадру - откидываемся назад.{CurrentFrame -= 3;}p.sprite.setTextureRect(IntRect(70 * int(CurrentFrame), 92, 60, 85)); //проходимся по координатам Х. получается 70,85*2,70*3 и опять 70getPlayerCoordinateForView(p.getPlayerCoordinateX(), p.getPlayerCoordinateY());//функция слежения камеры за игроком}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(70 * int(CurrentFrame), 177, 60, 85));getPlayerCoordinateForView(p.getPlayerCoordinateX(), p.getPlayerCoordinateY());}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(70 * int(CurrentFrame), 262, 60, 85));getPlayerCoordinateForView(p.getPlayerCoordinateX(), p.getPlayerCoordinateY());}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(70 * int(CurrentFrame), 0, 60, 85));getPlayerCoordinateForView(p.getPlayerCoordinateX(), p.getPlayerCoordinateY());}if ((Keyboard::isKeyPressed(Keyboard::Z))){p.speed = 0.5;}}p.update(time);viewmap(time);//функция скроллинга карты, передаем ей время sfmlwindow.setView(view);//"оживляем" камеру в окне sfmlchangeview();window.clear(Color(199, 167, 109));//очищает экран и поставили вместо черного фона за картой корочневыйfor (int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){if (TileMap[i][j] == 'a'){s_map.setTextureRect(IntRect(63, 768, 32, 32));}if (TileMap[i][j] == ' '){s_map.setTextureRect(IntRect(0, 480, 32, 32));}if (TileMap[i][j] == 'c'){s_map.setTextureRect(IntRect(33, 2016, 32, 32));}if (TileMap[i][j] == 'f'){s_map.setTextureRect(IntRect(66, 2016, 32, 32));}if (TileMap[i][j] == 'h'){s_map.setTextureRect(IntRect(0, 2016, 32, 32));}s_map.setPosition(j * 32, i * 32);window.draw(s_map);}text.setPosition(view.getCenter().x-260, view.getCenter().y-230);//задаем позицию текста, центр камерыtext1.setPosition(view.getCenter().x + 260, view.getCenter().y - 230);text2.setPosition(view.getCenter().x + 260, view.getCenter().y - 200);text3.setPosition(view.getCenter().x-150, view.getCenter().y);std::ostringstream playerHealthString; // объявили переменнуюstd::ostringstream Corrdinate,Coordinate1;playerHealthString << p.health; //занесли в нее число очков, то есть формируем строкуCorrdinate <<int(p.getPlayerCoordinateX());Coordinate1 << int(p.getPlayerCoordinateY());text1.setString("X:"+ Corrdinate.str());text2.setString("Y:" + Coordinate1.str());text.setString(L"ЗДОРОВЬЕ:" + playerHealthString.str());//задаем строку тексту и вызываем сформированную выше строку методом .str()window.draw(text);//рисую этот текстwindow.draw(text1);window.draw(text2);text3.setString("GAME OVER");window.draw(p.sprite);//рисует обьект.draw-рисоватьif (p.life == false) { window.draw(text3); p.sprite.setTextureRect(IntRect(99, 2016, 32, 32));}window.display();//выводит на экран}return 0;})))Отвечу чисто для своего тестирования. Не претендую на истину.
Судя по всему вывод спрайта должен быть после присвоения p.sprite
То бишь
C++12if (p.life == false) { window.draw(text3); p.sprite.setTextureRect(IntRect(99, 2016, 32, 32));}window.draw(p.sprite);//рисует обьект.draw-рисоватьМестами пробуй поменять
Щас у тебя выходит сначала ты вывел картинку, потом поменял спрайт но не вывел. А что там будет в следующем проходе цикла фиг знает.
Надо бы сразу выводить.Просто поменяйте местами отрисовку спрайта и условия смерти.
не помогает. по всякому пытался менять местами. и время после смерти выводится почему то 0.
Найди место, где для управления проверяется жизнь персонажа: if(p.life) { код нажатий и передачи скорости и т.д. } , вот поставь для этого условия else { window.draw(text3); p.sprite.setTextureRect(IntRect(99, 2016, 32, 32)); }
1) А где у тебя изменяется p.life
2) Почему вначале не присвоено значение life = true; Для всех переменных есть какое то объявление ,А для life нету.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.