diff --git a/Cargo.toml b/Cargo.toml index bdaf09a..5363f0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = "0.14.2" +bevy = "0.15" fastrand = "2.1.1" # ref: https://github.com/bevyengine/bevy/pull/3992 [workspace] diff --git a/src/game/actor/bullet.rs b/src/game/actor/bullet.rs index fc72a04..5183eff 100644 --- a/src/game/actor/bullet.rs +++ b/src/game/actor/bullet.rs @@ -45,7 +45,7 @@ impl AiBulletBundle for StandardBullet { speed: Vec2::new(10.0, 10.0), }, scene_bundle: StarRustSceneBundle { - scene: models.default_bullet.clone(), + scene: SceneRoot(models.default_bullet.clone()), transform: Transform::from_xyz( weapon_data.translation.x, weapon_data.translation.y, @@ -80,7 +80,7 @@ impl AiBulletBundle for StandardEnemyBullet { weapon_data: &WeaponFiredEvent, ) -> BulletActorBundle { let mut bullet = StandardBullet::get_bullet_bundle(models, weapon_data).clone(); - bullet.scene_bundle.scene = models.default_enemy_bullet.clone(); + bullet.scene_bundle.scene = SceneRoot(models.default_enemy_bullet.clone()); return bullet; } } diff --git a/src/game/actor/mod.rs b/src/game/actor/mod.rs index ca93ac9..ae3ca86 100644 --- a/src/game/actor/mod.rs +++ b/src/game/actor/mod.rs @@ -27,7 +27,7 @@ pub trait BundledActor { #[derive(Bundle, Clone, Default)] pub struct StarRustSceneBundle { - pub scene: Handle, + pub scene: SceneRoot, pub transform: Transform, pub global_transform: GlobalTransform, pub visibility: Visibility, diff --git a/src/game/actor/ship.rs b/src/game/actor/ship.rs index a4227e0..afc3159 100644 --- a/src/game/actor/ship.rs +++ b/src/game/actor/ship.rs @@ -28,7 +28,7 @@ impl BundledActor for PlayerShipDefault { speed: Vec2::new(6.0, 6.0), }, scene_bundle: StarRustSceneBundle { - scene: models.default_player.clone(), + scene: SceneRoot(models.default_player.clone()), transform: Transform::from_xyz(spawn_position.x, spawn_position.y, 2.0) .with_scale(Vec3::splat(ASSET_SCALE)) .with_rotation(Quat::from_rotation_y(std::f32::consts::PI * 1.5)), @@ -76,7 +76,7 @@ impl BundledActor for DefaultEnemyShip { speed: Vec2::new(1.5, 1.5), }, scene_bundle: StarRustSceneBundle { - scene: models.default_enemy.clone(), + scene: SceneRoot(models.default_enemy.clone()), transform: Transform::from_xyz(spawn_position.x, spawn_position.y, 2.0) .with_scale(Vec3::splat(23.0)) .with_rotation(Quat::from_rotation_y(std::f32::consts::PI * 0.5)), @@ -131,7 +131,7 @@ impl BundledActor for JetCharger { spawn_position: Vec2, ) -> AiActorBundle { let mut variant = DefaultEnemyShip::get_bundle(audio_clips, models, spawn_position).clone(); - variant.actor_bundle.scene_bundle.scene = models.jet_charger.clone(); + variant.actor_bundle.scene_bundle.scene = SceneRoot(models.jet_charger.clone()); variant.actor_bundle.actor.speed = Vec2::new(8.0, 8.0); variant.ai.mode = AiMode::ChargeForward1; // Disable Weapon @@ -159,7 +159,7 @@ impl BundledActor for SpacePlatformBare { spawn_position: Vec2, ) -> AiActorBundle { let mut variant = DefaultEnemyShip::get_bundle(audio_clips, models, spawn_position).clone(); - variant.actor_bundle.scene_bundle.scene = models.space_platform.clone(); + variant.actor_bundle.scene_bundle.scene = SceneRoot(models.space_platform.clone()); variant.actor_bundle.actor.speed = Vec2::new(2.0, 2.0); variant.actor_bundle.health.hp = 100; variant.actor_bundle.collider.rect = Vec2::new(210.0, 40.0); @@ -190,7 +190,7 @@ impl BundledActor for Star { ) -> AiActorBundle { let mut variant = DefaultEnemyShip::get_bundle(audio_clips, models, spawn_position).clone(); variant.actor_bundle.camera_shake_on_death.magnitude = 0.0; - variant.actor_bundle.scene_bundle.scene = models.powerup_star.clone(); + variant.actor_bundle.scene_bundle.scene = SceneRoot(models.powerup_star.clone()); // FIXME: Make a dedicated hitmask for player bullets and powerups variant.actor_bundle.collider.hitmask = ENEMY_HITMASK; variant.actor_bundle.collider.damage = 0; diff --git a/src/game/ai/mod.rs b/src/game/ai/mod.rs index 95687de..5f49400 100644 --- a/src/game/ai/mod.rs +++ b/src/game/ai/mod.rs @@ -50,6 +50,6 @@ fn sine_charge( frequency: f32, ) { let forward = t.translation + t.forward() * forward_speed; - let up_down = t.up() * amplitude * (time.elapsed_seconds() as f32 * frequency).sin(); + let up_down = t.up() * amplitude * (time.elapsed_secs() * frequency).sin(); t.translation = forward + up_down; } diff --git a/src/game/audio/mod.rs b/src/game/audio/mod.rs index a5cd36e..60de41c 100644 --- a/src/game/audio/mod.rs +++ b/src/game/audio/mod.rs @@ -51,12 +51,6 @@ fn on_audio_event(mut commands: Commands, mut audio_events: EventReader, + transform: Transform, collider: Collider, wall: Wall, } @@ -62,33 +60,15 @@ impl WallBundle { materials: &mut ResMut>, ) -> WallBundle { WallBundle { - /* - sprite_bundle: SpriteBundle { - transform: Transform { - // We need to convert our Vec2 into a Vec3, by giving it a z-coordinate - // This is used to determine the order of our sprites - translation: location.position().extend(0.0), - // The z-scale of 2D objects must always be 1.0, - // or their ordering will be affected in surprising ways. - // See https://github.com/bevyengine/bevy/issues/4149 - scale: location.size().extend(1.0), - ..default() - }, - sprite: Sprite { - color: WALL_COLOR, - ..default() - }, + mesh: Mesh3d(meshes.add(Mesh::from(Cuboid { + half_size: Vec3::new(0.5, 0.5, 0.5), + }))), + material: MeshMaterial3d(materials.add(StandardMaterial { + base_color: WALL_COLOR, ..default() - },*/ - pbr_bundle: PbrBundle { - mesh: meshes.add(Mesh::from(Cuboid { - half_size: Vec3::new(0.5, 0.5, 0.5), - })), - material: materials.add(WALL_COLOR), - transform: Transform::from_translation(location.position().extend(1.0)) - .with_scale(location.size().extend(1.0)), - ..default() - }, + })), + transform: Transform::from_translation(location.position().extend(1.0)) + .with_scale(location.size().extend(1.0)), collider: Collider { rect: location.size(), damage: 0, diff --git a/src/main.rs b/src/main.rs index f1cf7cb..fa63d88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,19 +48,18 @@ fn setup_camera(mut commands: Commands) { ); // FIXME: this does not render at all*/ // Bevy 2d camera is at Z=999.9 commands - .spawn(Camera3dBundle { - camera_3d: Camera3d { ..default() }, - camera: Camera { + .spawn(( + Camera3d::default(), + Camera { order: 0, ..default() }, - projection: Projection::Orthographic(OrthographicProjection { + Projection::from(OrthographicProjection { scale: 1.0, - ..default() + far: CAMERA_FAR, + ..OrthographicProjection::default_3d() }), - transform: Transform::from_xyz(0.0, 0.0, CAMERA_FAR - 0.1) - .looking_at(Vec3::ZERO, Vec3::Y), - ..default() - }) + Transform::from_xyz(0.0, 0.0, CAMERA_FAR - 0.1).looking_at(Vec3::ZERO, Vec3::Y), + )) .insert(CameraShaker { ..default() }); } diff --git a/src/menus/mod.rs b/src/menus/mod.rs index 6bc27f0..22bfe69 100644 --- a/src/menus/mod.rs +++ b/src/menus/mod.rs @@ -128,8 +128,7 @@ fn menu_action( fn main_menu_setup(mut commands: Commands, asset_server: Res) { let font = asset_server.load("fonts/Arame-Bold.ttf"); - // Common style for all buttons on the screen - let button_style = Style { + let button_node = Node { width: Val::Px(250.0), height: Val::Px(65.0), margin: UiRect::all(Val::Px(20.0)), @@ -137,97 +136,80 @@ fn main_menu_setup(mut commands: Commands, asset_server: Res) { align_items: AlignItems::Center, ..default() }; - let button_icon_style = Style { + let button_icon_node = Node { width: Val::Px(30.0), height: Val::Px(30.0), - // This takes the icons out of the flexbox flow, to be positioned exactly position_type: PositionType::Absolute, - // The icon will be close to the left border of the button left: Val::Px(10.0), right: Val::Auto, top: Val::Auto, bottom: Val::Auto, ..default() }; - let button_text_style = TextStyle { + let button_font = TextFont { font: font.clone(), font_size: 40.0, - color: TEXT_COLOR, + ..default() }; commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node { margin: UiRect::all(Val::Auto), flex_direction: FlexDirection::ColumnReverse, align_items: AlignItems::Center, ..default() }, - background_color: BOX_COLOR.into(), - ..default() - }) + BackgroundColor(BOX_COLOR), + )) .insert(OnMainMenuScreen) .with_children(|parent| { parent - .spawn(ButtonBundle { - style: button_style.clone(), - ..default() - }) + .spawn((Button, button_node.clone(), BackgroundColor(NORMAL_BUTTON))) .insert(MenuButtonAction::Quit) .with_children(|parent| { let icon: Handle = asset_server.load("textures/Game Icons/exitRight.png"); - parent.spawn(ImageBundle { - style: button_icon_style.clone(), - image: UiImage { - texture: icon, - ..default() - }, - ..default() - }); - parent.spawn(TextBundle::from_section("Quit", button_text_style.clone())); + parent.spawn((button_icon_node.clone(), ImageNode::new(icon))); + parent.spawn(( + Text::new("Quit"), + button_font.clone(), + TextColor(TEXT_COLOR), + )); }); parent - .spawn(ButtonBundle { - style: button_style.clone(), - ..default() - }) + .spawn((Button, button_node.clone(), BackgroundColor(NORMAL_BUTTON))) .insert(MenuButtonAction::Play) .with_children(|parent| { let icon = asset_server.load("textures/Game Icons/right.png"); - parent.spawn(ImageBundle { - style: button_icon_style.clone(), - image: UiImage { - texture: icon, - ..default() - }, - ..default() - }); - parent.spawn(TextBundle::from_section("Play", button_text_style.clone())); + parent.spawn((button_icon_node.clone(), ImageNode::new(icon))); + parent.spawn(( + Text::new("Play"), + button_font.clone(), + TextColor(TEXT_COLOR), + )); }); - parent.spawn( - TextBundle::from_section( - "Star Rust", - TextStyle { - font: font.clone(), - font_size: 80.0, - color: TEXT_COLOR, - }, - ) - .with_style(Style { + parent.spawn(( + Text::new("Star Rust"), + TextFont { + font: font.clone(), + font_size: 80.0, + ..default() + }, + TextColor(TEXT_COLOR), + Node { margin: UiRect::all(Val::Px(50.0)), ..default() - }), - ); + }, + )); }); } fn level_end_setup(mut commands: Commands, asset_server: Res) { let font = asset_server.load("fonts/Arame-Bold.ttf"); - // Common style for all buttons on the screen - let button_style = Style { + let button_node = Node { width: Val::Px(315.0), height: Val::Px(65.0), margin: UiRect::all(Val::Px(20.0)), @@ -235,55 +217,50 @@ fn level_end_setup(mut commands: Commands, asset_server: Res) { align_items: AlignItems::Center, ..default() }; - - let button_text_style = TextStyle { + let button_font = TextFont { font: font.clone(), font_size: 40.0, - color: TEXT_COLOR, + ..default() }; commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node { margin: UiRect::all(Val::Auto), flex_direction: FlexDirection::ColumnReverse, align_items: AlignItems::Center, ..default() }, - background_color: LEVEL_END_BOX_COLOR.into(), - ..default() - }) + BackgroundColor(LEVEL_END_BOX_COLOR), + )) .insert(OnLevelEndScreen) .with_children(|parent| { // Display the game name - parent.spawn( - TextBundle::from_section( - "LEVEL END", - TextStyle { - font: font.clone(), - font_size: 80.0, - color: TEXT_COLOR, - }, - ) - .with_style(Style { + parent.spawn(( + Text::new("LEVEL END"), + TextFont { + font: font.clone(), + font_size: 80.0, + ..default() + }, + TextColor(TEXT_COLOR), + Node { margin: UiRect::all(Val::Px(50.0)), ..default() - }), - ); + }, + )); // Display // - MAIN MENU // - RESTART parent - .spawn(ButtonBundle { - style: button_style.clone(), - ..default() - }) + .spawn((Button, button_node.clone(), BackgroundColor(NORMAL_BUTTON))) .insert(MenuButtonAction::MainMenu) .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "MAIN MENU", - button_text_style.clone(), + parent.spawn(( + Text::new("MAIN MENU"), + button_font.clone(), + TextColor(TEXT_COLOR), )); }); }); @@ -292,7 +269,7 @@ fn level_end_setup(mut commands: Commands, asset_server: Res) { fn player_death_setup(mut commands: Commands, asset_server: Res) { let font = asset_server.load("fonts/Arame-Bold.ttf"); // Common style for all buttons on the screen - let button_style = Style { + let button_node = Node { width: Val::Px(300.0), height: Val::Px(65.0), margin: UiRect::all(Val::Px(20.0)), @@ -301,98 +278,81 @@ fn player_death_setup(mut commands: Commands, asset_server: Res) { ..default() }; - let button_text_style = TextStyle { + let button_font = TextFont { font: font.clone(), font_size: 40.0, - color: TEXT_COLOR, + ..default() }; commands - .spawn(NodeBundle { - style: Style { + .spawn(( + Node { margin: UiRect::all(Val::Auto), flex_direction: FlexDirection::ColumnReverse, align_items: AlignItems::Center, ..default() }, - background_color: PLAYER_DEATH_BOX_COLOR.into(), - ..default() - }) + BackgroundColor(PLAYER_DEATH_BOX_COLOR), + )) .insert(OnPlayerDeathScreen) .with_children(|parent| { /* parent - .spawn(ButtonBundle { - style: button_style, - ..default() - }) + .spawn((Button, button_node.clone(), BackgroundColor(NORMAL_BUTTON))) .insert(MenuButtonAction::Restart) .with_children(|parent| { let icon = asset_server.load("textures/Game Icons/exitRight.png"); - parent.spawn(ImageBundle { - style: button_icon_style, - image: UiImage(icon), - ..default() - }); - parent.spawn(TextBundle::from_section("RESTART", button_text_style)); + parent.spawn((button_icon_node.clone(), ImageNode::new(icon))); + parent.spawn((Text::new("RESTART"), button_font.clone(), TextColor(TEXT_COLOR))); });*/ parent - .spawn(ButtonBundle { - style: button_style.clone(), - ..default() - }) + .spawn((Button, button_node.clone(), BackgroundColor(NORMAL_BUTTON))) .insert(MenuButtonAction::MainMenu) .with_children(|parent| { /*let icon = asset_server.load("textures/Game Icons/right.png"); - parent.spawn(ImageBundle { - style: button_icon_style.clone(), - image: UiImage(icon), - ..default() - });*/ - parent.spawn(TextBundle::from_section( - "MAIN MENU", - button_text_style.clone(), + parent.spawn((button_icon_node.clone(), ImageNode::new(icon)));*/ + parent.spawn(( + Text::new("MAIN MENU"), + button_font.clone(), + TextColor(TEXT_COLOR), )); }); // Display the game name - parent.spawn( - TextBundle::from_section( - "GAME OVER", - TextStyle { - font: font.clone(), - font_size: 80.0, - color: TEXT_COLOR, - }, - ) - .with_style(Style { + parent.spawn(( + Text::new("GAME OVER"), + TextFont { + font: font.clone(), + font_size: 80.0, + ..default() + }, + TextColor(TEXT_COLOR), + Node { margin: UiRect::all(Val::Px(50.0)), ..default() - }), - ); + }, + )); }); } fn load_background_model(mut commands: Commands, asset_server: ResMut) { commands - .spawn(SceneBundle { - scene: asset_server.load("models/basic_enemy.glb#Scene0"), - transform: Transform::from_xyz(0.0, 210.0, 20.0) + .spawn(( + SceneRoot(asset_server.load("models/basic_enemy.glb#Scene0")), + Transform::from_xyz(0.0, 210.0, 20.0) .with_scale(Vec3::splat(30.0)) .with_rotation(Quat::from_euler(EulerRot::XYZ, 20.0, 95.0, 0.0)), - ..default() - }) + )) .insert(MenuBackground); commands - .spawn(DirectionalLightBundle { - directional_light: DirectionalLight { + .spawn(( + DirectionalLight { illuminance: 25000.0, color: Color::WHITE, ..default() }, - transform: Transform::from_xyz(0.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y), - ..default() - }) + Transform::from_xyz(0.0, 5.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y), + )) .insert(MenuBackground); }