no move for orphan balls
This commit is contained in:
parent
0fd5719473
commit
6423764a17
4 changed files with 74 additions and 6 deletions
|
|
@ -3,9 +3,11 @@ use crate::FACTOR;
|
|||
pub const SHIFT: f32 = 1.0; // коэффициент пересчета для слотов
|
||||
pub const SLOT_SIZE: f32 = FACTOR as f32 / SHIFT;
|
||||
|
||||
pub const BALL_MOVEMENT_SPEED: f32 = 60.0; // пикселей в секунду
|
||||
pub const BALL_MOVEMENT_SPEED: f32 = 10.0; // пикселей в секунду, базово 60
|
||||
pub const INITIAL_BALLS_COUNT: usize = 10;
|
||||
pub const WARMUP_BALL_MOVEMENT_MULTIPLIER: f32 = 5.0; // во сколько раз больше BALL_MOVEMENT_SPEED
|
||||
pub const WARMUP_BALL_MOVEMENT_MULTIPLIER: f32 = 30.0; // во сколько раз больше BALL_MOVEMENT_SPEED, базово 5
|
||||
|
||||
pub const HIT_THRESHOLD: f32 = SLOT_SIZE; // для detect_projectile_hit
|
||||
|
||||
// Z-индексы элементов
|
||||
pub const CANNON_Z_INDEX: f32 = 10.0;
|
||||
|
|
@ -13,4 +15,6 @@ pub const PROJECTILE_Z_INDEX: f32 = 11.0;
|
|||
pub const CURRENT_SHOT_Z_INDEX: f32 = 12.0;
|
||||
pub const NEXT_SHOT_Z_INDEX: f32 = 12.0;
|
||||
|
||||
pub const SCORE_Z_INDEX: f32 = 100.0;
|
||||
pub const SCORE_Z_INDEX: f32 = 100.0;
|
||||
|
||||
pub const TRACK_Z_INDEX: f32 = 9.0;
|
||||
|
|
@ -33,6 +33,7 @@ impl Plugin for LevelPlugin {
|
|||
check_and_remove_matches,
|
||||
update_score_text,
|
||||
move_queue_along_track,
|
||||
// sync_ball_visuals,
|
||||
)
|
||||
.chain(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,14 +49,43 @@ pub fn spawn_new_ball(
|
|||
|
||||
pub fn move_queue_along_track(
|
||||
track: Res<TrackPath>,
|
||||
mut balls: Query<(&mut Ball, &mut Transform)>,
|
||||
mut balls: Query<(Entity, &mut Ball, &mut Transform)>,
|
||||
time: Res<Time>,
|
||||
wave: Res<WaveState>,
|
||||
) {
|
||||
// проверяем, не идет ли прогрев трека
|
||||
if wave.is_warming_up { return; }
|
||||
|
||||
//собираем все шары в вектор и сортируем по индексам слотов
|
||||
let mut balls_sorted: Vec<(Entity, Ball)> = balls.iter().map(|(e, b, _)| (e, *b)).collect();
|
||||
balls_sorted.sort_by_key(|(_, b)| b.slot_index);
|
||||
|
||||
if balls_sorted.is_empty() { return; }
|
||||
|
||||
//ищем первый пустой слот для определения разрыва
|
||||
let active_boundary = {
|
||||
let mut current_idx = balls_sorted[0].1.slot_index;
|
||||
|
||||
for (mut ball, mut transform) in balls.iter_mut() {
|
||||
for (_, ball) in balls_sorted.iter().skip(1) {
|
||||
if ball.slot_index == current_idx + 1 {
|
||||
current_idx = ball.slot_index;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
current_idx
|
||||
};
|
||||
|
||||
for (entity, mut ball, mut transform) in balls.iter_mut() {
|
||||
//пропускаем все шары в слотах после слота начала разрыва
|
||||
if ball.slot_index > active_boundary {
|
||||
// но при этом обнуляем прогресс у оторванных шариков
|
||||
if ball.slot_progress > 0.01 {
|
||||
ball.slot_progress = 0.0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Увеличиваем прогресс
|
||||
ball.slot_progress += BALL_MOVEMENT_SPEED * time.delta_secs() / SLOT_SIZE;
|
||||
|
||||
|
|
@ -311,4 +340,24 @@ pub fn check_and_remove_matches(
|
|||
for (entity, mut ball) in balls.p1().iter_mut() {
|
||||
ball.slot_progress = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync_ball_visuals(
|
||||
track: Res<TrackPath>,
|
||||
mut balls: Query<(&Ball, &mut Transform)>,
|
||||
) {
|
||||
for (ball, mut transform) in balls.iter_mut() {
|
||||
// Получаем точку текущего слота
|
||||
if let Some(&curr_pos) = track.points.get(ball.slot_index) {
|
||||
// Если есть следующий слот — интерполируем, иначе — просто центр текущего
|
||||
let visual_pos = if let Some(&next_pos) = track.points.get(ball.slot_index + 1) {
|
||||
curr_pos.lerp(next_pos, ball.slot_progress)
|
||||
} else {
|
||||
curr_pos
|
||||
};
|
||||
|
||||
// 🔥 ПРИНУДИТЕЛЬНО ставим позицию и правильный Z
|
||||
transform.translation = visual_pos.extend(TRACK_Z_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,7 +108,6 @@ pub fn move_projectiles(
|
|||
}
|
||||
}
|
||||
|
||||
const HIT_THRESHOLD: f32 = SLOT_SIZE;
|
||||
pub fn detect_projectile_hit(
|
||||
mut commands: Commands,
|
||||
track: Res<TrackPath>,
|
||||
|
|
@ -186,6 +185,21 @@ pub fn detect_projectile_hit(
|
|||
slot_progress: target_progress,
|
||||
}
|
||||
}).remove::<BallProjectile>();
|
||||
|
||||
if let Some(&curr_pos) = track.points.get(insert_idx) {
|
||||
// Вычисляем позицию: интерполяция или центр слота
|
||||
let visual_pos = if let Some(&next_pos) = track.points.get(insert_idx + 1) {
|
||||
curr_pos.lerp(next_pos, target_progress)
|
||||
} else {
|
||||
curr_pos
|
||||
};
|
||||
|
||||
// Обновляем Transform: ставим на трек и выравниваем Z (10.0),
|
||||
// чтобы шарик не висел «над» очередью (PROJECTILE_Z_INDEX)
|
||||
commands.entity(proj_entity).insert(
|
||||
Transform::from_translation(visual_pos.extend(10.0))
|
||||
);
|
||||
}
|
||||
// запоминаем индекс слота, куда попали
|
||||
wave.last_insert_index = Some(insert_idx);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue