Проектная работа - RELEASE
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
+12
-2
@@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "snake-game"
|
name = "snake-game"
|
||||||
|
description = "Rust implementation of Snake Game"
|
||||||
version = "0.1.0"
|
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"
|
||||||
@@ -13,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"
|
||||||
@@ -22,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,20 @@
|
|||||||
|
# Игра "Змейка"
|
||||||
|
|
||||||
|
Проектная работа по курсу **Rust Developer. Professional** образовательной платформы [OTUS](https://otus.ru/).
|
||||||
|
|
||||||
|
## Запуск
|
||||||
|
Сразу после запуска игра будет на паузе. Чтобы начать игру нужно снять её с паузы клавишей "Пробел".
|
||||||
|
|
||||||
|
## Управление
|
||||||
|
|
||||||
|
| Действие | Клавиша |
|
||||||
|
| --------------------------- | ---------------------- |
|
||||||
|
| Поворот головы вправо | `->` (Стрелка вправо) |
|
||||||
|
| Поворот головы влево | `<-` (Стрелка влево) |
|
||||||
|
| Возврат направления (прямо) | `^` (Стрелка вверх) |
|
||||||
|
| Пауза | `Space` (Пробел) |
|
||||||
|
| Ускорить игру | `=` (Равно) |
|
||||||
|
| Замедлить игру | `-` (Минус) |
|
||||||
|
|
||||||
|
## Правила
|
||||||
|
Нужно следить за тем, чтоб змея не врезалась в границы поля или сама в себя. Поедая жёлтые кубики (еду) змея удлинняется. Цель игры - вырастить змею как можно длиннее.
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
max_width = 160
|
max_width = 160
|
||||||
newline_style = "Unix"
|
newline_style = "Unix"
|
||||||
fn_single_line = true
|
|
||||||
|
|||||||
Reference in New Issue
Block a user