Проектная работа
пример с состояниями
This commit is contained in:
@@ -4,3 +4,5 @@
|
|||||||
|
|
||||||
Отчетные проекты:
|
Отчетные проекты:
|
||||||
- [Умный дом](smart-house/README.md)
|
- [Умный дом](smart-house/README.md)
|
||||||
|
- [Умный дом WEB](smart-house-web/README.md)
|
||||||
|
- [Игра "Змейка"](snake-game/README.md) -- проектная работа
|
||||||
|
|||||||
Generated
+1405
-31
File diff suppressed because it is too large
Load Diff
+11
-2
@@ -5,8 +5,7 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.18", default-features = false, features = ["2d_bevy_render", "bevy_log", "bevy_winit", "bevy_text", "bevy_ui", "debug"] }
|
bevy = "0.18"
|
||||||
# bevy = { version = "0.18" }
|
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
rand = "0.10"
|
rand = "0.10"
|
||||||
@@ -14,6 +13,13 @@ rand = "0.10"
|
|||||||
# for examples
|
# for examples
|
||||||
rand_chacha = "0.10"
|
rand_chacha = "0.10"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 0
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
debug = false
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
@@ -23,3 +29,6 @@ panic = "abort"
|
|||||||
overflow-checks = false
|
overflow-checks = false
|
||||||
incremental = false
|
incremental = false
|
||||||
strip = "symbols"
|
strip = "symbols"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["bevy/dynamic_linking"]
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
//! This example illustrates how to use [`States`] for high-level app control flow.
|
||||||
|
//! States are a powerful but intuitive tool for controlling which logic runs when.
|
||||||
|
//! You can have multiple independent states, and the [`OnEnter`] and [`OnExit`] schedules
|
||||||
|
//! can be used to great effect to ensure that you handle setup and teardown appropriately.
|
||||||
|
//!
|
||||||
|
//! In this case, we're transitioning from a `Menu` state to an `InGame` state.
|
||||||
|
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut app = App::new();
|
||||||
|
app.add_plugins(DefaultPlugins)
|
||||||
|
.init_state::<AppState>() // Alternatively we could use .insert_state(AppState::Menu)
|
||||||
|
.add_systems(Startup, setup)
|
||||||
|
// This system runs when we enter `AppState::Menu`, during the `StateTransition` schedule.
|
||||||
|
// All systems from the exit schedule of the state we're leaving are run first,
|
||||||
|
// and then all systems from the enter schedule of the state we're entering are run second.
|
||||||
|
.add_systems(OnEnter(AppState::Menu), setup_menu)
|
||||||
|
// By contrast, update systems are stored in the `Update` schedule. They simply
|
||||||
|
// check the value of the `State<T>` resource to see if they should run each frame.
|
||||||
|
.add_systems(Update, menu.run_if(in_state(AppState::Menu)))
|
||||||
|
.add_systems(OnExit(AppState::Menu), cleanup_menu)
|
||||||
|
.add_systems(OnEnter(AppState::InGame), setup_game)
|
||||||
|
.add_systems(Update, (movement, change_color).run_if(in_state(AppState::InGame)));
|
||||||
|
|
||||||
|
// #[cfg(feature = "bevy_dev_tools")]
|
||||||
|
// app.add_systems(Update, bevy::dev_tools::states::log_transitions::<AppState>);
|
||||||
|
// #[cfg(not(feature = "bevy_dev_tools"))]
|
||||||
|
// warn!("Enable feature bevy_dev_tools to log state transitions");
|
||||||
|
|
||||||
|
app.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Hash, States)]
|
||||||
|
enum AppState {
|
||||||
|
#[default]
|
||||||
|
Menu,
|
||||||
|
InGame,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct MenuData {
|
||||||
|
button_entity: Entity,
|
||||||
|
}
|
||||||
|
|
||||||
|
const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15);
|
||||||
|
const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25);
|
||||||
|
const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands) {
|
||||||
|
commands.spawn(Camera2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_menu(mut commands: Commands) {
|
||||||
|
let button_entity = commands
|
||||||
|
.spawn((
|
||||||
|
Node {
|
||||||
|
// center button
|
||||||
|
width: percent(100),
|
||||||
|
height: percent(100),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
children![(
|
||||||
|
Button,
|
||||||
|
Node {
|
||||||
|
width: px(150),
|
||||||
|
height: px(65),
|
||||||
|
// horizontally center child text
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
// vertically center child text
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
|
children![(
|
||||||
|
Text::new("Play"),
|
||||||
|
TextFont { font_size: 33.0, ..default() },
|
||||||
|
TextColor(Color::srgb(0.9, 0.9, 0.9)),
|
||||||
|
)],
|
||||||
|
)],
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
commands.insert_resource(MenuData { button_entity });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn menu(mut next_state: ResMut<NextState<AppState>>, mut interaction_query: Query<(&Interaction, &mut BackgroundColor), (Changed<Interaction>, With<Button>)>) {
|
||||||
|
for (interaction, mut color) in &mut interaction_query {
|
||||||
|
match *interaction {
|
||||||
|
Interaction::Pressed => {
|
||||||
|
*color = PRESSED_BUTTON.into();
|
||||||
|
next_state.set(AppState::InGame);
|
||||||
|
}
|
||||||
|
Interaction::Hovered => {
|
||||||
|
*color = HOVERED_BUTTON.into();
|
||||||
|
}
|
||||||
|
Interaction::None => {
|
||||||
|
*color = NORMAL_BUTTON.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cleanup_menu(mut commands: Commands, menu_data: Res<MenuData>) {
|
||||||
|
commands.entity(menu_data.button_entity).despawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_game(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
commands.spawn(Sprite::from_image(asset_server.load("branding/icon.png")));
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPEED: f32 = 100.0;
|
||||||
|
fn movement(time: Res<Time>, input: Res<ButtonInput<KeyCode>>, mut query: Query<&mut Transform, With<Sprite>>) {
|
||||||
|
for mut transform in &mut query {
|
||||||
|
let mut direction = Vec3::ZERO;
|
||||||
|
if input.pressed(KeyCode::ArrowLeft) {
|
||||||
|
direction.x -= 1.0;
|
||||||
|
}
|
||||||
|
if input.pressed(KeyCode::ArrowRight) {
|
||||||
|
direction.x += 1.0;
|
||||||
|
}
|
||||||
|
if input.pressed(KeyCode::ArrowUp) {
|
||||||
|
direction.y += 1.0;
|
||||||
|
}
|
||||||
|
if input.pressed(KeyCode::ArrowDown) {
|
||||||
|
direction.y -= 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if direction != Vec3::ZERO {
|
||||||
|
transform.translation += direction.normalize() * SPEED * time.delta_secs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_color(time: Res<Time>, mut query: Query<&mut Sprite>) {
|
||||||
|
for mut sprite in &mut query {
|
||||||
|
let new_color = LinearRgba {
|
||||||
|
blue: ops::sin(time.elapsed_secs() * 0.5) + 2.0,
|
||||||
|
..LinearRgba::from(sprite.color)
|
||||||
|
};
|
||||||
|
|
||||||
|
sprite.color = new_color.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user