count matching balls system
This commit is contained in:
parent
f6b5765b83
commit
745ed5cc54
3 changed files with 95 additions and 5 deletions
|
|
@ -19,3 +19,9 @@ pub enum DebugToggle{
|
||||||
Grid,
|
Grid,
|
||||||
Laser,
|
Laser,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Copy, Clone)]
|
||||||
|
pub struct HitMarker;
|
||||||
|
|
||||||
|
#[derive(Component, Copy, Clone)]
|
||||||
|
pub struct ToRemoveMarker;
|
||||||
|
|
@ -47,6 +47,7 @@ impl Plugin for LinearPlayPlugin {
|
||||||
calculate_projectile_hits,
|
calculate_projectile_hits,
|
||||||
linear_move_projectiles,
|
linear_move_projectiles,
|
||||||
insert_projectile_into_track,
|
insert_projectile_into_track,
|
||||||
|
count_matching_balls,
|
||||||
).in_set(LinearUpdateSet::Track),
|
).in_set(LinearUpdateSet::Track),
|
||||||
)
|
)
|
||||||
.add_systems(OnExit(LinearPlayState), cleanup);
|
.add_systems(OnExit(LinearPlayState), cleanup);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ pub fn move_round_balls(
|
||||||
let t_local = (ball.track_progress - seg.t_start) / (seg.t_end - seg.t_start);
|
let t_local = (ball.track_progress - seg.t_start) / (seg.t_end - seg.t_start);
|
||||||
|
|
||||||
let mut pos = Vec2::ZERO;
|
let mut pos = Vec2::ZERO;
|
||||||
match seg.segment_type{
|
match seg.segment_type {
|
||||||
SegementType::Line {} => {
|
SegementType::Line {} => {
|
||||||
pos = seg.start_pos + seg.direction * seg.length * t_local;
|
pos = seg.start_pos + seg.direction * seg.length * t_local;
|
||||||
// transform.translation = pos.extend(ROUND_BALL_Z);
|
// transform.translation = pos.extend(ROUND_BALL_Z);
|
||||||
|
|
@ -72,3 +72,86 @@ pub fn move_round_balls(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn count_matching_balls(
|
||||||
|
mut commands: Commands,
|
||||||
|
start_point: Query<(Entity, &RoundBall), With<HitMarker>>,
|
||||||
|
balls: Query<(Entity, &RoundBall)>,
|
||||||
|
) {
|
||||||
|
// если хит маркеров нет, сразу выходим
|
||||||
|
if start_point.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Проверка на группу начата");
|
||||||
|
|
||||||
|
//собираем все шарики на треке
|
||||||
|
let mut balls_sorted: Vec<(Entity, RoundBall)> = balls.iter().map(|(e, b)| (e, *b)).collect();
|
||||||
|
|
||||||
|
if balls_sorted.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// сортируем по прогрессу
|
||||||
|
balls_sorted.sort_by(|a, b| a.1.track_progress.total_cmp(&b.1.track_progress));
|
||||||
|
|
||||||
|
// принимаем шарик снаряд как точку отсчета
|
||||||
|
for (start_entity, start_round) in start_point.iter() {
|
||||||
|
// сразу снимаем маркер попадания с бывшего шарика-снаряда, который был встроен в трек
|
||||||
|
commands.entity(start_entity).remove::<HitMarker>();
|
||||||
|
|
||||||
|
// берем прогресс и тип шарика в точке попадания
|
||||||
|
let start_progress = start_round.track_progress;
|
||||||
|
let hit_ball_type = start_round.ball_type;
|
||||||
|
|
||||||
|
// будем итерировать по индексам
|
||||||
|
let mut hit_index = 0;
|
||||||
|
for (index, ball) in balls_sorted.iter().enumerate() {
|
||||||
|
if ball.1.track_progress == start_progress {
|
||||||
|
hit_index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut left_threshold = hit_index;
|
||||||
|
let mut right_threshold = hit_index;
|
||||||
|
|
||||||
|
// ищем крайнего соседа слева
|
||||||
|
for li in (0..=hit_index).rev() {
|
||||||
|
//
|
||||||
|
if balls_sorted[li].1.ball_type == hit_ball_type {
|
||||||
|
// записываем индекс как порог
|
||||||
|
left_threshold = li;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// иначе прерываем
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// то же самое для правого
|
||||||
|
for ri in hit_index..=balls_sorted.len() {
|
||||||
|
if balls_sorted[ri].1.ball_type == hit_ball_type {
|
||||||
|
right_threshold = ri;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// считаем размер группы
|
||||||
|
let group_size = right_threshold - left_threshold + 1;
|
||||||
|
if group_size < 3 {
|
||||||
|
continue; // не return, так как может быть несколько хит маркеров
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Группа из 3+ шариков! Размер: {}", group_size);
|
||||||
|
|
||||||
|
// маркируем группу по порогам на удаление
|
||||||
|
for entity in balls_sorted[left_threshold..=right_threshold]
|
||||||
|
.iter()
|
||||||
|
.map(|(e, _)| *e)
|
||||||
|
{
|
||||||
|
commands.entity(entity).insert(ToRemoveMarker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue