SFML и C++ Уроки \ Разработка игр › Форумы › SFML System, Window и другие вопросы › Стрельба из автомата
В этой теме 8 ответов, 2 участника, последнее обновление saxartom 7 года/лет назад.
-
АвторСообщения
-
Доброго времени суток) Не подскажете, как можно реализовать “имитацию автоматной очереди”. Получается сделать либо сплошным потоком (на подобии лазера), либо поштучно(как пистолетная стрельба). А вот как сделать, чтобы пули шли непрерывно, пока нажата клавиша стрельбы, но при этом, чтобы была задержка между каждым патроном.
Заранее спасибо)
C++1234567891011float timer_Bullet = 0;while(window.isOpen()){timer_Bullet += time;if(timer_Bullet > 50.f){bullet.push_back(new Bullet(...));timer_Bullet = 0.f;}}Спасибо. В “стационарном” положение работает. Но если стрелять “на ходу”, то по какой-то причине, при зажатой клавише стрельбы, он стреляет один – два раза и прекращает. Не подскажете где искать ошибку. Если надо скинуть какой-то сегмент кода – говорите.
Хватит болтовни, покажите нам код.
You’re God damn right. ))
Вот упрощенная версия кода:main.cpp
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354while (window.isOpen()){timer_Bullet += time;while (window.pollEvent(event)){.....}for (it = Bullet.begin(); it != Bullet.end(); it++){if (!((*it)->isMove)){(*it)->mouseCoord.x = pos.x;(*it)->mouseCoord.y = pos.y;(*it)->rotBull = atan2f(pos.x - hero.x, hero.y - pos.y) * 180.0 / M_PI;}(*it)->isMove = true;}for (it = Bullet.begin(); it != Bullet.end(); it++){if ((*it)->isMove){distanceBull = sqrt(pow(((*it)->mouseCoord.x - (*it)->x), 2) + pow(((*it)->mouseCoord.y - (*it)->y), 2));if (distanceBull > 100){(*it)->x += (*it)->speed*time*((*it)->mouseCoord.x - (*it)->x) / distanceBull;(*it)->y += (*it)->speed*time*((*it)->mouseCoord.y - (*it)->y) / distanceBull;}else{(*it)->isMove = false;(*it)->life = false;}}}for (it = Bullet.begin(); it != Bullet.end();){(*it)->update(time);if ((*it)->life == false){it = Bullet.erase(it);}else it++;}if (event.type == Event::MouseButtonPressed)if (event.key.code == Mouse::Left){if (timer_Bullet > 150.f){Bullet.push_back(new TBullet(weaponsSprite, "MachineBullet", hero.x, hero.y, hero.anim.anim.sprite.getTextureRect().width, hero.anim.anim.sprite.getTextureRect().height, hero.STATE));--(static_cast<TWeapons*>(Inventory.inventory[2])->ammo);timer_Bullet = 0.f;}}}else{hero.shoot = false;if (hero.onHandM) static_cast<TWeapons*>(Inventory.inventory[2])->reloadWeap(hero);}for (it = Bullet.begin(); it != Bullet.end(); it++)if ((*it)->life)window.draw((*it)->sprite);}У вас событийные условия находятся вне обработчика событий.
Попробуй так.
Перенеси эти условия в обработчик событий и добавь герою флаг is_ShootC++12345678910111213141516171819while (window.pollEvent(event)){if (event.type == Event::MouseButtonPressed)if (event.key.code == Mouse::Left)is_Shoot = true;if (event.type == Event::MouseButtonReleased)if (event.key.code == Mouse::Left)is_Shoot = false;}if(is_Shoot) timer_Bullet += time;if(timer_Bullet > 150.f){timer_Bullet = 0.f;Bullet.push_back(new TBullet(weaponsSprite,"MachineBullet",hero.x,hero.y,hero.anim.anim.sprite.getTextureRect().width,hero.anim.anim.sprite.getTextureRect().height, hero.STATE));--(static_cast<TWeapons*>(Inventory.inventory[2])->ammo);}Сначала я попробовал запихнуть эту конструкцию в обработчик событий:
C++12345678910111213if (event.type == Event::MouseButtonPressed)if (event.key.code == Mouse::Left){if (timer_Bullet > 150.f){Bullet.push_back(new TBullet(weaponsSprite, "MachineBullet", hero.x, hero.y, hero.anim.anim.sprite.getTextureRect().width, hero.anim.anim.sprite.getTextureRect().height, hero.STATE));--(static_cast<TWeapons*>(Inventory.inventory[2])->ammo);timer_Bullet = 0.f;}}}else{hero.shoot = false;if (hero.onHandM) static_cast<TWeapons*>(Inventory.inventory[2])->reloadWeap(hero);}Но так пули стали вылетать только по одной за одно нажатие.
Потом я попробовал реализовать ваш вариант, и пули вообще перестали вылетать.
Я отследил ход обработки кода, и если во время стрельбы начать двигаться, то прерывается это условие
C++12345if (timer_Bullet > 150.f){Bullet.push_back(new TBullet(weaponsSprite, "MachineBullet", hero.x, hero.y, hero.anim.anim.sprite.getTextureRect().width, hero.anim.anim.sprite.getTextureRect().height, hero.STATE));--(static_cast<TWeapons*>(Inventory.inventory[2])->ammo);timer_Bullet = 0.f;}и соответственно стрельба прекращается((
Как я предполагаю условие выше нужно обрабатывать параллельно с ходьбой. Это случайно не в сторону потоков надо копать?
Или я уже не туда полез?
while(window.pollEvent(event))
{
if (event.type == Event::MouseButtonPressed) // Если клавиша нажата shoot true
if (event.type == Event::MouseButtonReleased) // Если клавиша отжата shoot false
}if(shoot == true) timer += time;
else timer = 0;if(timer > 150) стрелять и обнулить таймер
Спасибо, отчасти работает, но почему то при ходьбе по диагонали вверх-вправо и вверх-влево и стрельбе, он идет просто вверх. При ходьбе аналогично по диагонали вниз все нормально.
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.