Skip to content

Commit

Permalink
Туториал: убрал долгую задержку когда противники улетали за экран
Browse files Browse the repository at this point in the history
  • Loading branch information
HPW-dev committed Sep 16, 2024
1 parent 68c43c7 commit aa03df3
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 57 deletions.
29 changes: 17 additions & 12 deletions src/game/entity/entity-mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,20 +292,25 @@ struct Entity_mgr::Impl {
// удаление объектов за экраном
inline void bound_check() {
for (rauto entity: m_entities) {
if (entity->status.live && !entity->status.ignore_bound) {
crauto entity_pos = entity->phys.get_pos();
auto bound = entity->status.is_bullet ? hpw::shmup_bound_for_bullet : hpw::shmup_bound_for_other;
cont_if(!entity->status.live);
cont_if(entity->status.ignore_bound);

crauto entity_pos = entity->phys.get_pos();
auto bound = entity->status.is_bullet
? hpw::shmup_bound_for_bullet
: hpw::shmup_bound_for_other;

if (
// тихо убить объект за экраном
(entity->status.remove_by_out_of_screen && entity->status.out_of_screen) ||
// тихо убить объект, если он вышел за пределы
if (
entity_pos.x <= -bound ||
entity_pos.x >= graphic::width + bound ||
entity_pos.y <= -bound ||
entity_pos.y >= graphic::height + bound
) {
entity->remove();
}
} // if live
entity_pos.x <= -bound ||
entity_pos.x >= graphic::width + bound ||
entity_pos.y <= -bound ||
entity_pos.y >= graphic::height + bound
) {
entity->remove();
}
} // for m_entities
} // bound_check

Expand Down
13 changes: 13 additions & 0 deletions src/game/entity/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "game/core/core.hpp"
#include "game/entity/entity-mgr.hpp"
#include "game/entity/util/entity-util.hpp"
#include "game/core/canvas.hpp"

Entity::Entity()
: Entity_animated (*this)
Expand Down Expand Up @@ -42,13 +43,25 @@ void Entity::update(const Delta_time dt) {

if (!status.disable_motion)
move_it(dt);

process_update_cbs(dt);
check_out_of_screen();
}

void Entity::set_master(Master new_master) {
assert(new_master != this);
_master = new_master;
}

void Entity::check_out_of_screen() {
cauto pos = phys.get_pos();
constexpr real BOUND = 50;
status.out_of_screen =
(pos.x <= -BOUND) ||
(pos.x >= graphic::width + BOUND) ||
(pos.y <= -BOUND) ||
(pos.y >= graphic::height + BOUND);
}

void Entity::move_it(const Delta_time dt) { phys.update(dt); }
void Entity::set_pos(const Vec pos) { phys.set_pos(pos); }
1 change: 1 addition & 0 deletions src/game/entity/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ class Entity: public Entity_animated {
Master _master {}; // объект - создатель

void move_it(const Delta_time dt);
void check_out_of_screen();
}; // Entity
72 changes: 37 additions & 35 deletions src/game/entity/status.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,46 @@

// флаги управления и статуса игрового объекта
struct Entity_status {
bool live: 1 {}; // объект жив и активен
bool collidable: 1 {}; // можно сталкиваться
bool collided: 1 {}; // минимум один раз в объект врезались
bool killme: 1 {}; // указывает что объект нужно убить в Entity_mgr
bool removeme: 1 {}; // готов к удалению из Entity_mgr
bool removed: 1 {}; // объект успешно удалён из Entity_mgr
bool kill_by_end_anim: 1 {}; // убить объект концом анимации
bool live: 1 {}; // объект жив и активен
bool collidable: 1 {}; // можно сталкиваться
bool collided: 1 {}; // минимум один раз в объект врезались
bool killme: 1 {}; // указывает что объект нужно убить в Entity_mgr
bool removeme: 1 {}; // готов к удалению из Entity_mgr
bool removed: 1 {}; // объект успешно удалён из Entity_mgr
bool kill_by_end_anim: 1 {}; // убить объект концом анимации
bool kill_by_end_frame: 1 {}; // убить объект в конце его кадра анимации
bool kill_by_timeout: 1 {}; // убить объект концом времени жизни
bool is_bullet: 1 {}; // объект является пулей
bool is_enemy: 1 {}; // объект является врагом
bool is_player: 1 {}; // объект является игроком
bool end_anim: 1 {}; // анимация проигралась до конца
bool end_frame: 1 {}; // кадр проигрался до конца
bool layer_up: 1 {}; // рисовать объект на верхнем уровне
bool rnd_frame: 1 {}; // каждый кадр анимации будет случайным
bool rnd_deg: 1 {}; // каждый кадр анимации будет случайно повёрнут (не каждый игровой кадр)
bool kill_by_timeout: 1 {}; // убить объект концом времени жизни
bool remove_by_out_of_screen: 1 {}; // удалить объект за экраном
bool is_bullet: 1 {}; // объект является пулей
bool is_enemy: 1 {}; // объект является врагом
bool is_player: 1 {}; // объект является игроком
bool end_anim: 1 {}; // анимация проигралась до конца
bool end_frame: 1 {}; // кадр проигрался до конца
bool layer_up: 1 {}; // рисовать объект на верхнем уровне
bool rnd_frame: 1 {}; // каждый кадр анимации будет случайным
bool rnd_deg: 1 {}; // каждый кадр анимации будет случайно повёрнут (не каждый игровой кадр)
bool rnd_deg_evr_frame: 1 {}; // каждый игровой кадр, у анимации будет случайный угол
bool stop_anim: 1 {}; // выключить проигрывание анимации
bool ignore_player: 1 {}; // не сталкиваться с игроками
bool ignore_master: 1 {}; // не сталкиваться с создателем
bool ignore_bullet: 1 {}; // не сталкиваться с другими пулями
bool ignore_self_type: 1 {}; // не сталкиваться с объектами своего типа
bool ignore_bound: 1 {}; // не удалять объект, если он вышел за края экрана
bool ignore_damage: 1 {}; // не получать урон
bool fixed_deg: 1 {}; // будет искать в anim_ctx default_deg и поворачивать только на него
bool return_back: 1 {}; // включит флаг goto_prev_frame в конце анимации
bool goto_prev_frame: 1 {}; // отображает кадры в обратном порядке (дойдя до 0, выключается)
bool no_motion_interp: 1 {}; // выключает интерполяцию при движении
bool ignore_scatter: 1 {}; // игнор взрывных волн
bool ignore_enemy: 1 {}; // игнор других противников
bool disable_contour: 1 {}; // выключает отображение контура, если он есть
bool stop_anim: 1 {}; // выключить проигрывание анимации
bool ignore_player: 1 {}; // не сталкиваться с игроками
bool ignore_master: 1 {}; // не сталкиваться с создателем
bool ignore_bullet: 1 {}; // не сталкиваться с другими пулями
bool ignore_self_type: 1 {}; // не сталкиваться с объектами своего типа
bool ignore_bound: 1 {}; // не удалять объект, если он вышел за края экрана
bool ignore_damage: 1 {}; // не получать урон
bool ignore_scatter: 1 {}; // игнор взрывных волн
bool ignore_enemy: 1 {}; // игнор других противников
bool fixed_deg: 1 {}; // будет искать в anim_ctx default_deg и поворачивать только на него
bool return_back: 1 {}; // включит флаг goto_prev_frame в конце анимации
bool goto_prev_frame: 1 {}; // отображает кадры в обратном порядке (дойдя до 0, выключается)
bool disable_contour: 1 {}; // выключает отображение контура, если он есть
bool disable_heat_distort: 1 {}; // выключает отображение искажений воздуха
bool disable_light: 1 {}; // выключает отображение выспышки
bool no_restart_anim: 1 {}; // не перезапускать анимацию после окончания проигрывания
bool disable_render: 1 {}; // выключает отображение объекта и проигрывание анимации
bool no_sound: 1 {}; // выключить звук объекта
bool disable_motion: 1 {}; // запрет на перемещение
bool disable_light: 1 {}; // выключает отображение выспышки
bool disable_render: 1 {}; // выключает отображение объекта и проигрывание анимации
bool disable_motion: 1 {}; // запрет на перемещение
bool no_motion_interp: 1 {}; // выключает интерполяцию при движении
bool no_restart_anim: 1 {}; // не перезапускать анимацию после окончания проигрывания
bool no_sound: 1 {}; // выключить звук объекта
bool out_of_screen: 1 {}; // объект улетел чуть дальше границ экрана
}; // Entity_status

inline constexpr auto ENITY_STATUS_BYTES {sizeof(Entity_status)};
38 changes: 28 additions & 10 deletions src/game/level/level-tutorial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ struct Level_tutorial::Impl {
Timer spawn_timer {0.5}; // через сколько спавнить противника
Timer lifetime {}; // сколько времени будет работать спавнер
bool check_death {}; // начать проверять, что все соспавненные объекты умерли
uint live_count {}; // сколько объектов сейчас живы
Vector<Uid> spawned_list {}; // все кого соспавнили

explicit Spawner_enemy_noshoot(Impl& _master, const real _total_time=1.0)
: master {_master}
Expand All @@ -357,8 +357,17 @@ struct Level_tutorial::Impl {

if (lifetime.update(dt))
check_death = true;
if (check_death)
return live_count == 0 || live_count >= 100'000u;

if (check_death) {
uint lived {};
// если хоть один противник жив или на экране, то не заканчиваем
for (cauto uid: spawned_list)
if (cauto ent = hpw::entity_mgr->find(uid); ent)
if (ent->status.live && !ent->status.out_of_screen)
++lived;
return lived == 0;
}

return false;
} // op ()

Expand All @@ -377,8 +386,8 @@ struct Level_tutorial::Impl {
Collidable* spawn(const Vec pos) {
auto enemy = hpw::entity_mgr->make({}, "enemy.tutorial", pos);
enemy->add_update_cb(Zigzag_motion());
enemy->add_remove_cb([this](Entity&){ --live_count; });
++live_count;
spawned_list.push_back(enemy->uid);
enemy->status.remove_by_out_of_screen = true;
assert(enemy->status.collidable);
return ptr2ptr<Collidable*>(enemy);
}
Expand All @@ -390,7 +399,7 @@ struct Level_tutorial::Impl {
Timer spawn_timer {0.8}; // через сколько спавнить противника
Timer lifetime {}; // сколько времени будет работать спавнер
bool check_death {}; // начать проверять, что все соспавненные объекты умерли
uint live_count {}; // сколько объектов сейчас живы
Vector<Uid> spawned_list {}; // все кого соспавнили

explicit Spawner_enemy_shoot(Impl& _master, const real _total_time=1.0)
: master {_master}
Expand All @@ -409,8 +418,17 @@ struct Level_tutorial::Impl {

if (lifetime.update(dt))
check_death = true;
if (check_death)
return live_count == 0 || live_count >= 100'000u;

if (check_death) {
uint lived {};
// если хоть один противник жив или на экране, то не заканчиваем
for (cauto uid: spawned_list)
if (cauto ent = hpw::entity_mgr->find(uid); ent)
if (ent->status.live && !ent->status.out_of_screen)
++lived;
return lived == 0;
}

return false;
} // op ()

Expand All @@ -426,8 +444,8 @@ struct Level_tutorial::Impl {
bullet->phys.set_deg(deg_to_target(bullet->phys.get_pos(), hpw::entity_mgr->target_for_enemy()));
}
});
enemy->add_remove_cb([this](Entity&){ --live_count; });
++live_count;
spawned_list.push_back(enemy->uid);
enemy->status.remove_by_out_of_screen = true;
assert(enemy->status.collidable);
return ptr2ptr<Collidable*>(enemy);
}
Expand Down
1 change: 1 addition & 0 deletions src/game/util/cmd/cmd-entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static Vector<Flag_struct> g_entity_flags {
MAKE_FLAG (stop_anim)
MAKE_FLAG (ignore_player)
MAKE_FLAG (ignore_master)
MAKE_FLAG (out_of_screen)
MAKE_FLAG (ignore_bullet)
MAKE_FLAG (ignore_self_type)
MAKE_FLAG (ignore_bound)
Expand Down

0 comments on commit aa03df3

Please sign in to comment.