SFML и C++ Уроки \ Разработка игр › Форумы › Логика игр › Стрельба и удаления врагов при стрельбе
В этой теме 4 ответа, 2 участника, последнее обновление Павел Букреев 7 года/лет, 6 мес. назад.
-
АвторСообщения
-
Делал все как по урокам но сталкнулся с проблемой удаления врага при поподании может кто-нибудь помочь.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210#include "supperheader.h"using namespace sf;class Bullet :public Entity{//класс пулиpublic:int direction;//направление пулиint member;bool formy;Bullet(Image &image, String Name, Level &lvl, float X, float Y, int W, int H, int dir) :Entity(image, Name, X, Y, W, H){//всё так же, только взяли в конце состояние игрока (int dir)obj = lvl.GetObjects("solid");//инициализируем .получаем нужные объекты для взаимодействия пули с картойx = X+6;y = Y+9;direction = dir;speed = 0.17;cikle = 0;w = h = 16;sprite.setScale(0.5, 0.5);life = true;//выше инициализация в конструкторе}void update(float time){switch (direction){case 0: dx = -speed; dy = 0; formy = false; break;//интовое значение state = leftcase 1: dx = speed; dy = 0; formy = false; break;//интовое значение state = rightcase 2: dx = 0; dy = -speed; formy = false; break;//интовое значение state = upcase 3: dx = speed; dy = 0; formy = true; break;//интовое значение не имеющее отношения к направлению, пока просто стрельнем вверх, нам сейчас это не важноcase 4: dx = 0; dy = -speed; formy = false; break;//интовое значение не имеющее отношения к направлению, пока просто стрельнем вверх, нам сейчас это не важноcase 5: dx = 0; dy = -speed; formy = false; break;//интовое значение не имеющее отношения к направлению, пока просто стрельнем вверх, нам сейчас это не важно}x += dx*time;//само движение пули по хy += dy*time;//по уif (x <= 0) x = 1;// задержка пули в левой стене, чтобы при проседании кадров она случайно не вылетела за предел карты и не было ошибкиif (y <= 0) y = 1;member = x;for (int i = 0; i < obj.size(); i++) {//проход по объектам solidif (getRect().intersects(obj[i].rect)) //если этот объект столкнулся с пулей,{life = false;cikle = 0;}// то пуля умираетif (cikle >= 1000){life = false;}cikle++;std::cout << cikle << std::endl;}if (formy == true){sprite.setPosition(x + 30, y +15);}if (formy == false){sprite.setPosition(x + w / 2, y + h / 2);}//задается позицию пуле}};int main(){RenderWindow window(VideoMode(640, 480), "Lesson 22. kychka-pc.ru", sf::Style::Fullscreen);view.reset(FloatRect(0, 0, 640, 480));Level lvl;//создали экземпляр класса уровеньlvl.LoadFromFile("map.tmx");//загрузили в него карту, внутри класса с помощью методов он ее обработает.Image heroImage;heroImage.loadFromFile("images/hero.gif");Image easyEnemyImage;easyEnemyImage.loadFromFile("images/shamaich.png");easyEnemyImage.createMaskFromColor(Color(255, 255, 213));Image BulletImage;//изображение для пулиBulletImage.loadFromFile("images/bullet.png");//загрузили картинку в объект изображенияBulletImage.createMaskFromColor(Color(255, 255, 255));//маска для пули по черному цветуSoundBuffer shootBuffer;//создаём буфер для звукаshootBuffer.loadFromFile("shoot.ogg");//загружаем в него звукSound shoot(shootBuffer);//создаем звук и загружаем в него звук из буфераSoundBuffer jumpBuffer;//создаём буфер для звукаjumpBuffer.loadFromFile("jump.ogg");//загружаем в него звукSound jump(jumpBuffer);//создаем звук и загружаем в него звук из буфераstd::list<Entity*> entities;//создаю список, сюда буду кидать объекты.например врагов.std::list<Entity*>::iterator it;//итератор чтобы проходить по эл-там спискаstd::list<Entity*>::iterator it2;std::vector<Object> e = lvl.GetObjects("EasyEnemy");//все объекты врага на tmx карте хранятся в этом вектореfor (int i = 0; i < e.size(); i++)//проходимся по элементам этого вектора(а именно по врагам)entities.push_back(new Enemy(easyEnemyImage, "EasyEnemy", lvl, e[i].rect.left, e[i].rect.top, 18, 18));Object player=lvl.GetObject("player");//объект игрока на нашей карте.задаем координаты игроку в начале при помощи негоPlayer p(heroImage, "Player1", lvl, player.rect.left, player.rect.top, 20, 30);//передаем координаты прямоугольника player из карты в координаты нашего игрокаClock clock;while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();time = time / 800;Event event;while (window.pollEvent(event)){if (event.type == sf::Event::Closed)window.close();if (event.type == sf::Event::KeyPressed && sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))window.close();if (p.isShoot == true) { shoot.play(); p.isShoot = false; entities.push_back(new Bullet(BulletImage, "Bullet", lvl, p.x, p.y, 16, 16, p.state)); }//если выстрелили, то появляется пуля. enum передаем как intif ((p.onGround == true) && (Keyboard::isKeyPressed(Keyboard::Space))){ jump.play(); }}if (p.onGround == true){p.update(time);}if (p.onGround == false){p.update(time/1.4);}for (it = entities.begin(); it != entities.end();)//говорим что проходимся от начала до конца{Entity *b = *it;//для удобства, чтобы не писать (*it)->b->update(time);//вызываем ф-цию update для всех объектов (по сути для тех, кто жив)if (b->life == false) { it = entities.erase(it); delete b; }// если этот объект мертв, то удаляем егоelse it++;//и идем курсором (итератором) к след объекту. так делаем со всеми объектами списка}for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка{if ((*it)->getRect().intersects(p.getRect()))//если прямоугольник спрайта объекта пересекается с игроком{if ((*it)->name == "EasyEnemy"){if ((p.dy>0) && (p.onGround == false)) { (*it)->dx = 0; p.dy = -0.2; (*it)->health = 0; }//если прыгнули на врага,то даем врагу скорость 0,отпрыгиваем от него чуть вверх,даем ему здоровье 0else{p.health -= 5; //иначе враг подошел к нам сбоку и нанес урон}}}if ((*it)->getRect().intersects(p.getRect()))//если прямоугольник спрайта объекта пересекается с игроком{if ((*it)->name == "EasyEnemy" && (*it)->dx<0){//и при этом имя объекта EasyEnemy,то..(*it)->x = p.x + p.w; //аналогично - отталкиваем вправо(*it)->dx *= -1;//останавливаем}}if ((*it)->getRectForRight().intersects(p.getRectForRight()))//если прямоугольник спрайта объекта пересекается с игроком{if ((*it)->name == "EasyEnemy" && (*it)->dx>0){(*it)->x = p.x-p.w; //отталкиваем его от игрока влево (впритык)(*it)->dx *= -1;//останавливаем}}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);//отражаем спрайт по горизонтали}}}//for (it = entities.begin(); it != entities.end(); it++) { (*it)->update(time); }//для всех элементов списка(пока это только враги,но могут быть и пули к примеру) активируем ф-цию updatewindow.setView(view);window.clear(Color(77, 83, 140));lvl.Draw(window);for (it = entities.begin(); it != entities.end(); it++){window.draw((*it)->sprite); //рисуем entities объекты (сейчас это только враги)}//window.draw(easyEnemy.sprite);//старый вариант рисования одного врагаwindow.draw(p.sprite);window.display();}return 0;}возьми за основу урок про пересечение игрока с врагом. только пересекаться будет не игрок с врагом, а пуля с врагом. в остальном всё то же самое. при пересечении сделаешь удаление как в уроке, когда прыгали на голову и убивали врага. вот
Если враги тоже стреляют – чтобы враги не убивали друг друга добавь пуле дополнительную переменную имя, и называй типа “PlayerBullet” “EnemyBullet”. Так сможешь различить.Я просто не понимаю как обращаться к обекту пули .
пока я пытался только сделать так что бы пуля при поподании исчезала но она все равно летит сквозь персонажа
я делал вот такое уловие
for (std::list<Entity*>::iterator it2 = entities.begin(); it2 != entities.end(); it2++)
{
Entity *bullet = *it2;
if (bullet->name == “Bullet”)
if (bullet->live==true)
if (bullet->getRect().intersects(enemy->getRect()))
{
bullet->life= false;
}
}ребят я решил проблему может и вам поможет
C++123456789101112131415161718192021if ((*it)->name == "EasyEnemy"){Entity *enemy = *it;for (std::list<Entity*>::iterator it2 = entities.begin(); it2 != entities.end(); it2++){Entity *bullet = *it2;if (bullet->name == "Bullet")if (bullet->life == true){if (bullet->getRect().intersects(enemy->getRect())){bullet->life = false;std::cout << bullet->life << std::endl;enemy->life =false;}}}молодец:) спасибо, что поделился)
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.