SFML и C++ Уроки \ Разработка игр › Форумы › Домашние задания › Домашнее задание 2 к уроку 25
В этой теме 2 ответа, 2 участника, последнее обновление Alaz777 8 года/лет, 2 мес. назад.
-
АвторСообщения
-
Предлагаю своё решение задания 2 (при виде поблизости игрока (ну скажем в пределах 400 координат) враг должен резко ускориться в его сторону и постараться задавить игрока, при этом над головой врага должно появиться диалоговое облачко (как в комиксах) с надписью “ААААААH!!!” или типа того).
Для начала, я добавил в int main шрифт и диалоговое облачко:
C++12345678910111213Font font;font.loadFromFile("CyrilicOld.ttf");Text text("", font, 20);text.setColor(Color::Black);Image dialogImage;dialogImage.loadFromFile("images/dialogCloud.png");Texture dialogTexture;dialogTexture.loadFromImage(dialogImage);Sprite c_sprite;c_sprite.setTexture(dialogTexture);c_sprite.setTextureRect(IntRect(0, 0, 2400, 1790));c_sprite.setScale(0.045f, 0.02f); //уменьшаем картинку, а то уж слишком огромнаяЗатем, я прописал ещё 2 логические переменные в классе Entity:
C++1bool changeD, showDialogText;И инициализировал их в конструкторе:
C++1changeD = false; showDialogText = false;Также, в int main нужно добавить таймер, благодаря которому диалоговое облачко будет исчезать через пару секунд после своего появления:
C++1float dialogAppTimer = 0;Затем, в цикл for (там где мы прописывали столкновения игрока с врагом в 25-м уроке и под тем местом где было прописано взаимодействие врагов в 26-м уроке) добавил несколько строк, и этот цикл стал выглядеть вот так:
C++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556for (it = entities.begin(); it != entities.end(); it++){if ((*it)->getRect().intersects(p.getRect())){if ((*it)->name == "EasyEnemy"){/////////////////////////////////////////////Задание 3 (отталкивание)//////////////////////////////////////////////if ((p.dy > 0) && (p.onGround == false) && (p.kickL == false) && (p.kickR == 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 -= 5;}if ((*it)->dx < 0) {p.kickL = true; p.kickUp = true; p.onGround = false;p.health -= 5;}}}/////////////////////////////////////////////Урок 26//////////////////////////////////////////////////////////////for (it2 = entities.begin(); it2 != entities.end(); it2++){if ((*it)->getRect() != (*it2)->getRect())if (((*it)->getRect().intersects((*it2)->getRect())) && ((*it)->name == "EasyEnemy") && ((*it2)->name == "EasyEnemy")){(*it)->dx *= -1;(*it)->sprite.scale(-1, 1);}}////////////////////////////////////////////////Задание 2///////////////////////////////////////////////////////////////////////if ((*it)->name == "EasyEnemy") //если имя эл-та списка "EasyEnemy" (причём эл-т списка не обязан пересекаться с игроком),{if (((*it)->x - p.x < 400) && ((*it)->x - p.x > 0) && (p.y > (*it)->y)) { //и если игрок находится ниже врага и находится на расстояние 400 слева от него, то...(*it)->showDialogText = true;if ((*it)->dx > 0) { (*it)->changeD = true; } //если при этом враг движется вправо, changeD = true.(*it)->dx = -0.25; //задаём скорость, немного больше обычной влево}if ((p.x - (*it)->x < 400) && (p.x - (*it)->x > 0) && (p.y > (*it)->y)) { //аналогично для случая, когда игрок правее врага(*it)->showDialogText = true;if ((*it)->dx < 0) { (*it)->changeD = true; }(*it)->dx = 0.25;}}if ((*it)->showDialogText) //{text.setString("Задавлю!"); //пишем текст "задавлю!"text.setPosition((*it)->x + 55, (*it)->y - 63); //задаём позицию текста относительно коорд. конкретного врага (так чтобы помещался в облачко)c_sprite.setPosition((*it)->x + 45, (*it)->y - 60); //задаём позицию облачкуdialogAppTimer += time; //активируем таймерif (dialogAppTimer > 2000) { //если таймер дошёл до 2-х секунд, то...(*it)->showDialogText = false; // шоуДиалогТект приравниваем к фолсdialogAppTimer = 0; //обнуляем таймер}}}Теперь, в классе врага (в самом конце функции update) надо написать:
C++1234if (changeD) {sprite.scale(-1, 1);changeD = false;}Это нужно для того, чтобы отразить один раз врага в сторону игрока, если враг в этот момент смотрит в другую сторону.
Ну и в конце концов надо рисовать текст и облачко, когда надо. Там, где всё рисуем добавляем:
C++1234567for (it = entities.begin(); it != entities.end(); it++) {if ((*it)->showDialogText) { //если (*it)->showDialogText ==true, тоwindow.draw(c_sprite); //рисуем облачкоwindow.draw(text); //рисуем текст}window.draw((*it)->sprite);}Вроде ничего не забыл. Теперь, когда игрок находиться на расстоянии 400 координат от врага и, при том расположен не выше него, враг поворачивается в сторону игрока и начинает ехать в его сторону с криками “Задавлю!”, до тех пор пока игрок не уйдёт с его пути. Можно ещё добавить условие, чтобы игрок был не слишком ниже врага, а на его уровне, но я не стал этого делать.
Картинка с диалоговым облачком и шрифт вложены в тему. Шрифт я взял из урока 13.
П.С. Код получился довольно большим, особенно для текста с облачком, поэтому очень хотелось бы увидеть ещё варианты. Возможно есть более короткое решение.
Вложения:
You must be logged in to view attached files.отлично) ещё бы скрин работы увидеть)) вместо таймера можно было и на координаты сравнить “если приблизился на n , то убрать надпись”, но это уже как хочется. чтобы кода было поменьше лучше создать класс для этого, в нем будет метод update который в зависимости от условия запустит текст и нарисует его, прям там же и рисование можно прописать (как в уроке с lifebar’ ом).
Я бы добавил скрин, но к сожалению у меня на компе не работает скриншот.((
Результат можно посмотреть вставив в код.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.