SFML и C++ Уроки \ Разработка игр › Форумы › Домашние задания › Домашнее задание 3 к уроку 25.
В этой теме 3 ответа, 2 участника, последнее обновление Alaz777 8 года/лет, 2 мес. назад.
-
АвторСообщения
-
Предлагаю своё решение задания 3 к уроку 25.
Первым делом я удалил несколько строк, там где мы прописывали столкновение игрока с врагом. А именно:
C++12345678std::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<<"(*it)->x"<<(*it)->x<<"\n";std::cout<<"p.x"<<p.x<<"\n\n";и
C++12(*it)->x = p.x + p.w;(*it)->dx = 0;а также
C++12if (p.dx < 0) { p.x = (*it)->x + (*it)->w; }if (p.dx > 0) { p.x = (*it)->x - p.w; }Это всё дело удалять совсем не обязательно ( ну кроме зануления скорости врага, т.к. это противоречит заданию ), но я удалил, т.к. иногда глючило и врага телепортировало внутрь текстур или он исчезал, хотя убийство врага – закомментировано.
Затем, в классе Entity я добавил 3 логические переменные kickL, kickR, kickUp:
C++1bool life, isMove, onGround, kickL, kickR, kickUp;И инициализировал их в конструкторе:
C++1kickL = false; kickR = false; kickUp = false;Затем, в int main (там где было прописано столкновение игрока с врагом) я написал:
C++12345678910111213141516171819for (it = entities.begin(); it != entities.end(); it++){if ((*it)->getRect().intersects(p.getRect())){if ((*it)->name == "EasyEnemy"){if ((*it)->dx > 0) {p.kickR = true; p.kickUp = true;p.onGround = false;p.health -= 5;}if ((*it)->dx < 0) {p.kickL = true; p.kickUp = true;p.onGround = false;p.health -= 5;}}}}Т.е. когда враг движется на нас, например, справа и пересекается с игроком, то переменные kickR, kickUp и onGround становятся равны false и у игрока отнимается здоровье. Аналогично для случая, когда враг едет на игрока слева.
OnGround = false здесь прописано, чтобы когда нас отталкнёт и подкинет вверх мы не могли подпрыгнуть в воздухе. Также это сделано для того, движение игрока по координате икс после толчка заканчивалось при приземлении на землю (так более красиво и реалистичнее).
И наконец, в классе игрока внутри функции update (сразу после “switch(){}”) я прописал следующие строки:
C++12345678if (kickUp) { dy = -0.65; kickUp = false; }if (kickR) {dx = 0.3;}if (kickL) {dx = -0.3;}if (onGround) { kickR = false; kickL = false; }Если kickUp = true, то нас подбрасывает и kickUp становится равным false. Если kickR = true, то мы отлетаем со скоростью dx = 0.3 вправо, если kickL = true, то с той же скоростью отлетаем влево. И когда мы приземлимся и onGround станет равным true, то kickR и kickL станут равными false.
Хотелось бы добавить, что поскольку нас сразу же отталкивает от врага, как бы мы ни пытались на него запрыгнуть или столкнуться с ним, пересечение спрайтов отсутствует.
П.С. Если откомменитировать убийство врага, то: либо враг будет умирать, как только наедет на нас, либо (если оставить строчки, связанные с пересечением прямоугольников) он будет периодически поглюкивать, и это не связано с отталкиванием, это было изначально.
Отлично:))) прям хоть медали впиливай на форум и давай ачивки за выполнение домашек)))
как тебе в целом задания? я перестал придумывать их к урокам т.к их никто не делает, хотя можно было бы возобновить..
Мне интересны задания. К тому же, решения многих из них 100% пригодится в будущем. Хотя, конечно, было бы интересно, если б и другие выкладывали свои решения, чтобы можно было сравнить свои с чьими-нибудь.
Кстати, я решил проблему со смертью врага. Просто if(){} отвечающее за смерть игрока переносим вначало функции отвечающей в int main за переключение логических переменных kickL, kickR и kickUp. Вот так:
C++1234567891011121314if ((*it)->name == "EasyEnemy"){if ((p.dy > 0) && (p.onGround == false)) {(*it)->dx = 0; p.dy = -0.3; (*it)->health = 0;}if ((*it)->dx > 0) {p.kickR = true; p.kickUp = true; p.onGround = false;p.health -= 1;}if ((*it)->dx < 0) {p.kickL = true; p.kickUp = true; p.onGround = false;p.health -= 1;}}Теперь, если нас толкает враг то мы его не убиваем. Ещё можно добавить, например, условие && (kickUp == false), чтобы и оно требовалось для убийства врага (это нужно для того, чтобы мы не убивали врага, если мы по каким-то причинам приземлились ему на голову просле откидывания), но я решил это не добавлять.
Старое убийство врага нужно удалить.
Чтобы не убивать врага падая ему на голову, после откидывания, надо прописывать доп. условия && (p.kickL == false) && (p.kickR == false), а не && (p.kickUp == false). Т.к. после подкидывания кикАп сразу становиться равным фолс. Я немного ошибся.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.