SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Работа с состоянием персонажа
В этой теме 1 ответ, 2 участника, последнее обновление Alaz777 7 года/лет, 6 мес. назад.
-
АвторСообщения
-
Доброго времени суток, списываю пример с видео: https://www.youtube.com/watch?v=T6o5OlgsCew
C первым пунктом я разобрался, там надо было сделать класс анимаций.
А вот проблема со вторым пунктом, <b><u>персонаж не двигается</u></b> (нажимая на кнопки) и не меняется анимация
В видео это представлено с 3:58 по 8:00Код Animation.hpp не буду кидать, там всё ровно. Код main’a:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215#include <SFML/Graphics.hpp>#include <C:\\Users\\alosha folel\\Desktop\\Проект1\\Проект1\\Animation.hpp>//#include "C:\\Users\\alosha folel\\Desktop\\Code\\source\\Entity.hpp"using namespace sf;//int ground = 300; //земля (пол)float offsetX = 0, offsetY = 0; //смещение картыconst int H = 12;const int W = 40;String TileMap[H] = { //карта 12/40"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB","B B B","B B B","B B B","B B B","B 0000 BBBB B","B B B","BBB B B","B BB BB B","B BB B","B B BB BB B","BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",};class PLAYER {public:std::map<std::string, bool> key; //информация о нажатых клавишах будем хранить в ассоциативном массивеfloat x, y, dx, dy, w, h;AnimationManager anim;bool onLadder, shoot, hit;bool dir;enum { stay, walk, duck, jump, climb, swim } STATE;FloatRect rect;bool onGround;PLAYER(AnimationManager &a) // в конструктор игрока принимаем класс анимаций{anim = a;STATE = stay; // в начале состояние stay}void KeyCheck() //обработка клавиш{//-=======================//---ЕСЛИ КЛАВИША НАЖАТА--//-=======================if (key["L"]){dir = 1;if (STATE != duck) dx = -0.1; // если мы сели, то мы не передвигаемсяif (STATE != stay) STATE = walk; //если мы находились в состоянии stay, то переходим в состояние walk}if (key["R"]){dir = 0;if (STATE != duck) dx = 0.1; // если мы сели, то мы не передвигаемсяif (STATE != stay) STATE = walk; //если мы находились в состоянии stay, то переходим в состояние walk}if (key["Up"]){if (STATE == stay || STATE == walk) { dy = -0.27; STATE = jump; } //если мы стояли или шли, то переходим в прэжок и dy присваевается ускорениеif (STATE == stay || STATE == climb) dy = -0.05; //если плаваем или на лестнице, медленно поднимаемся вверх}if (key["Down"]){if (STATE == stay || STATE == walk) { dx = 0; STATE = duck; }if (STATE == stay || STATE == climb) dy = 0.05;}if (key["Spase"]){shoot = true;}//-=========================//---ЕСЛИ КЛАВИША ОТПУЩЕНА--//-=========================if (!(key["R"] || key["L"])) //если ни право, ни лево{dx = 0;if (STATE == walk) STATE = stay;}if (!(key["Up"] || key["Down"])){if (STATE == swim || STATE == climb) dy = 0; // если мы отпустили на леснице, останавливаемся}if (!key["Down"]){if (STATE == duck) { STATE = stay; } // если мы сидели, то переходим в состояние stay}if (!key["Spase"]){shoot = false; // если отпущена клавиша "Пробел", то перестаём стрелять}}void update(float time){KeyCheck();if (STATE == stay) anim.set("stay");if (STATE == walk) anim.set("walk");if (STATE == jump) anim.set("jump");if (STATE == duck) anim.set("duck");if (STATE == climb) anim.set("climb"); { anim.pause(); if (dy != 0) anim.play(); if (!onLadder) STATE = stay; } //если не на лестнице то stayif (shoot) {anim.set("shoot");if (STATE == walk) anim.set("shootAndWalk");}if (dir) anim.flip(); //зеркальноx += dx * time;Collision(0); //Функция столкновенийdy += 0.0005*time;y += dy*time;Collision(1);anim.tick(time);key["L"] = key["R"] = key["Up"] = key["Down"] = key["Space"] = false;}void Collision(int dir) //обработка столкновений{for (int i = rect.top / 32; i < (rect.top + rect.height) / 32; i++)for (int j = rect.left / 32; j<(rect.left + rect.width) / 32; j++){if (TileMap[i][j] == 'B'){if ((dx>0) && (dir == 0)) rect.left = j * 32 - rect.width;if ((dx<0) && (dir == 0)) rect.left = j * 32 + 32;if ((dy>0) && (dir == 1)) { rect.top = i * 32 - rect.height; dy = 0; onGround = true; }if ((dy < 0) && (dir == 1)) { rect.top = i * 32 + 32; dy = 0; }}if (TileMap[i][j] == '0'){TileMap[i][j] = ' ';}}}};int main(){RenderWindow window(VideoMode(600, 300), "SFML works!");Texture t; //создаём текстуруt.loadFromFile("C:\\Users\\alosha folel\\Documents\\Visual Studio 2013\\Projects\\Проект1\\Debug\\fang2.png"); //загружаем картинкуAnimationManager anim;anim.create("walk", t, 0, 244, 40, 50, 6, 0.005, 40);anim.create("jump", t, 0, 528, 29, 30, 4, 0.0045, 38);anim.create("duck", t, 0, 436, 80, 20, 1, 0.005);anim.create("stay", t, 0, 187, 42, 52, 3, 0.002, 42);anim.create("shoot", t, 0, 572, 45, 52, 5, 0.004, 45);PLAYER p(anim);Clock clock; //время прошедшее с последнего тикаRectangleShape rectangle(Vector2f(32, 32));while (window.isOpen()) //пока окно открыто{float time = clock.getElapsedTime().asMicroseconds();clock.restart();time = time / 800; //регулируем скорость игрыEvent event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();}if (Keyboard::isKeyPressed(Keyboard::Left)) p.key["L"] = true;if (Keyboard::isKeyPressed(Keyboard::Right)) p.key["R"] = true;if (Keyboard::isKeyPressed(Keyboard::Up)) p.key["Up"] = true;if (Keyboard::isKeyPressed(Keyboard::Down)) p.key["Down"] = true;if (Keyboard::isKeyPressed(Keyboard::Space)) p.key["Space"] = true;anim.set("stay");anim.tick(time);window.clear(Color::White);anim.draw(window, 50, 100);window.display();}return 0;}<b>Я так понимаю, не работает вот это:</b>
C++1if (Keyboard::isKeyPressed(Keyboard::Left)) p.key["L"] = true;<i>p.key</i> придумал сам, с помощью <b>PLAYER p(anim);</b>.
По идее в функции KeyCheck должно отрабатыватьC++123456if (key["L"]){dir = 1;if (STATE != duck) dx = -0.1; // если мы сели, то мы не передвигаемсяif (STATE != stay) STATE = walk; //если мы находились в состоянии stay, то переходим в состояние walk}Твоя самая главная ошибка, что ты копируешь и не смотришь что копируешь. Твоя ошибка находится тут:
C++123456if (key["L"]){dir = 1;if (STATE != duck) dx = -0.1; // если мы сели, то мы не передвигаемсяif (STATE != stay) STATE = walk; //ОШИБКА! (если мы находились в состоянии stay,то переходим в состояние walk)}Измени условие в ошибочной строке на: if (STATE == stay) state = walk;
Сейчас у тебя получается что игрок должен уже не стоять чтобы состояние изменилось на walk. А поскольку ты из стоячего положения идешь, то ты STATE не меняешь он все время остается stay, и ты никак не можешь его переключить на walk.
Ну а вообще у тебя слишком сложная задача состояний, есть много возможностей где-то ошибиться в ней. Можно сделать меньше строчек и менее забагованой.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.