SFML и C++ Уроки \ Разработка игр › Форумы › Логика игр › движение врага и его преследование игрока
В этой теме 5 ответов, 2 участника, последнее обновление Павел Букреев 7 года/лет, 4 мес. назад.
-
АвторСообщения
-
Ребята, помогите с движением врагов по карте и их взаимодействием с героем. Мне нужно, что бы они двигались как в пакмане, а у меня получились “тормоза”. Сначала вроде начинают двигаться, а потом, когда соприкасаются со стенкой замирают и не двигаются пока не подойдет герой, потом начинают его преследовать.
Это мой класс врагC++1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253class Enemy:public Entity{int zq,timer;public:Enemy (sf::Image &image,sf::String Name,Level &lvl,float X, float Y, float W, float H): Entity(image,Name,X,Y,W,H){zq=1;state=left;timer=0;obj=lvl.GetObjects("solid");//иницилизируем нужные объекты для взаимодействия врага с картойif(name=="EasyEnemy"){sprite.setTextureRect(sf::IntRect(0,0,w,h));}}void checkCollisionWithMap()//ф ция проверки столкновений с картой{for (int i = 0; i<obj.size(); i++)//проходимся по объектамif (getRect().intersects(obj[i].rect))//проверяем пересечение игрока с объектом{if (obj[i].name == "solid")//если встретили препятствие{if (dy>0) { y = obj[i].rect.top - h;}if (dy<0) { y = obj[i].rect.top + obj[i].rect.height;}if (dx>0) { x = obj[i].rect.left - w; }if (dx<0) { x = obj[i].rect.left + obj[i].rect.width; }}}}void update(float time){if (name == "EasyEnemy"){//для персонажа с таким именем логика будет такойtimer+=time;if (timer+1000>1000) {zq=rand()%3;}if (timer>500) {if (zq==0) {if (x>px) {speed=0.1,state=left; timer=0;} {if (y>py) {speed=0.1,state=up; timer=0;} }}}if (timer>500) {if (zq==1) {if (x<px) {speed=0.1,state=right; timer=0;} {if (y<py) {speed=0.1,state=down; timer=0;} }}}switch(state){case right: dx=speed; dy=0; break;case left: dx=-speed; dy=0; break;case down: dx=0; dy=speed; break;case up: dx=0; dy=-speed; break;case stay:break;}x += dx*time;y += dy*time;checkCollisionWithMap();sprite.setPosition(x + w / 2, y + h / 2); //задаем позицию спрайта в место его центра}}};А это в функции main кусочек кода где расписан алгоритм обнаружения и преследования.
C++12345678910for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка{if ((*it)->name=="EasyEnemy"){(*it)->getPlayerCoord(pacman.x,pacman.y);if (((*it)->x-pacman.x<55)&&((*it)->y>pacman.y)) {(*it)->dy=-0.5,(*it)->dx=0;}if (((*it)->x-pacman.x<54)&&((*it)->y<pacman.y)) {(*it)->dy=0.5,(*it)->dx=0;}if ((pacman.y-(*it)->y<53)&&((*it)->x<pacman.x)) {(*it)->dx=0.5,(*it)->dy=0;}if (((*it)->y-pacman.y<56)&&((*it)->x>pacman.x)) {(*it)->dx=-0.5,(*it)->dy=0;}}И еще хотела спросить, когда мои враги взаимодействуют с друг другом и вид опять таки не как в платформере, а вид сверху как змейка, пакман нужно ли что-то менять здесь, а то они периодически, если соприкасаются начинают “плясать” друг на друге и никак не могут разойтись.
C++123456789for(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;//меняем направление движения врага}}код из танчиков на сфмл, там zq в update было дико не красиво , не думал, что дойдёт до кого-то код))
враги замирают потому, что упираются в стену , если игрок за ней. попробуй прописать в ф-ции checkCollisionWithMap смену направления врага, при столкновении со стеной.
вот интересно, если использовать Tiled Map, как с ним подружить волновой алгоритм? Или какой алгоритм с использованием TiledMap подойдет для умный врагов? Просто если брать тотже волновой алгоритм , то он завязан на том, что мы создаем аналогичную карту этой. А как это реализовать с TiledMap? Может кто видел именно для использования TiledMap и для варианта как в игре с пакманом?
Решила использовать алгоритм поиска пути. Начала с того что на прорисовке карты сразу указала G и S
if (map->TileMap[i][j] == ‘G’) s_map.setTextureRect(sf::IntRect(65,1380, 32, 32));//герой
if (map->TileMap[i][j] == ‘S’) s_map.setTextureRect(sf::IntRect(0,1186, 32, 32));//враг
if (map->TileMap[i][j] == ‘+’) s_map.setTextureRect(sf::IntRect(960,96, 32, 32));//путь
Реализовала алгоритм в классе map поиска пути и получилась такая картина как во вложении. Т.е. все работает и поиск работает.Теперь хочу передавать координаты игрока и врага и прорисовывать на карте в этом месте ‘G’ ‘S’. Соответственно уже будет прокладываться дорожка к реальным персонажам.
Реализация игры такая же как в кодах на сайте через двумерный массив. В классе Main в обработчике событий пытаюсь передать эти координаты, но возникает ошибка. Как это исправить?C++12345678910111213141516171819202122232425Player pacman(map,view, heroimage,"Player1",460,730,32.0,32.0);//передаем координаты прямоугольника player из карты в координаты нашего игрокаstd::list<Entity*> entities;//список,куда будем бросать объектыstd::list <Entity*>::iterator it;//итератор, чтобы проходить по элементам спискаstd::list <Entity*>::iterator it2;//враг-врагentities.push_back(new Enemy(map,easyEnemyImage,"EasyEnemy",410,290,32.0,32.0));//entities.push_back(new Enemy(map,easyEnemyImage,"EasyEnemy",425,290,32.0,32.0));//entities.push_back(new Enemy(map,easyEnemyImage,"EasyEnemy",440,190,32.0,32.0));.......for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка{if ((*it)->name=="EasyEnemy"){// int i=int(pacman.x);// int j=int(pacman.y);// map->TileMap[i][j] = 'G';// map->TileMap[int((*it)->x)][int((*it)->y)] = 'S';}Вложения:
You must be logged in to view attached files.не очень понятно про main класс, ты же не на джаве пишешь, по коду видно.
и что за ошибка возникает при этом?
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.