move round balls system + extended spawn system

This commit is contained in:
nquidox 2026-04-17 16:26:43 +03:00
parent 0c7ceb5d8d
commit 6506955115

View file

@ -1,13 +1,25 @@
use bevy::asset::ErasedAssetLoader; use std::f32::consts::FRAC_PI_2;
use bevy::prelude::*;
use crate::states::linear::*; use crate::states::linear::*;
use bevy::prelude::*;
pub fn spawn_round_ball( pub fn spawn_round_ball(
track: Res<PrecalculatedTrack>, track: Res<PrecalculatedTrack>,
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
balls: Query<&RoundBall>,
) { ) {
// метод all выдаст истину, если все элементы выполняют условие
let spawn_allowed = balls
.iter()
.all(|b| b.track_progress >= track.min_spawn_gap);
let min_progress = balls
.iter()
.map(|b| b.track_progress)
.reduce(f32::min)
.unwrap_or(1.0);
if min_progress >= track.min_spawn_gap {
let ball_type = RoundBallType::random_from_4(); let ball_type = RoundBallType::random_from_4();
let image: Handle<Image> = asset_server.load(ball_type.asset_path()); let image: Handle<Image> = asset_server.load(ball_type.asset_path());
@ -17,11 +29,46 @@ pub fn spawn_round_ball(
custom_size: Some(Vec2::splat(STEP)), custom_size: Some(Vec2::splat(STEP)),
..default() ..default()
}, },
Transform::from_xyz(0.0, 0.0, ROUND_BALL_Z), Transform::from_translation((track.segments[0].start_pos).extend(ROUND_BALL_Z)),
RoundBall { RoundBall {
ball_type, ball_type,
track_progress: 0.0, track_progress: 0.0,
}, },
LinearStateMarker LinearStateMarker,
)); ));
}
}
pub fn move_round_balls(
track: Res<PrecalculatedTrack>,
mut balls: Query<(&mut Transform, &mut RoundBall)>,
time: Res<Time>,
){
// собираем все существующие шарики на треке и их трансформы
for (mut transform, mut ball) in &mut balls {
// сразу обновляем прогресс
ball.track_progress += track.speed_norm * time.delta_secs();
// потом позиционируем визуал
for seg in &track.segments {
if ball.track_progress >= seg.t_start && ball.track_progress < seg.t_end {
// вычисляем локальное нормализованое положение на треке
let t_local = (ball.track_progress - seg.t_start) / (seg.t_end - seg.t_start);
let mut pos = Vec2::ZERO;
match seg.segment_type{
SegementType::Line {} => {
pos = seg.start_pos + seg.direction * seg.length * t_local;
// transform.translation = pos.extend(ROUND_BALL_Z);
}
SegementType::Turn {} => {
let angle = seg.start_angle + FRAC_PI_2 * seg.sweep_sign * t_local;
pos = seg.center + Vec2::from_angle(angle) * seg.radius;
}
}
transform.translation = pos.extend(ROUND_BALL_Z);
}
}
}
} }