maciekglowka / hike_deck

Bevy Engine rougelike with a tutorial
MIT License
38 stars 1 forks source link

add_system deprecations and OnUpdate has been removed in Bevy 0.11 #5

Open D0ubleD0uble opened 1 year ago

D0ubleD0uble commented 1 year ago

I am attempting to follow along on the tutorial using bevy 0.11 and in part 1 of the series we are utilizing add_system which has been deprecated and specifically in assets.rs we call .add_system(check_asset_loading.in_set(OnUpdate(MainState::LoadAssets))); - which comes up with an error because OnUpdate has been removed. (see https://github.com/bevyengine/bevy/issues/8239).

I'm afraid I'm still trying to figure out the intended alternative but I'm following along as someone new to bevy. Of course I can downgrade my bevy version but I imagine you will want to fix this at some point to take advantage of newer bevy features and to keep the tutorial relevant.

maciekglowka commented 1 year ago

Hi, yeah the API changed a bit again. I think it should be now smth like that:

.add_systems(
       Update,
       check_asset_loading
       .run_if(in_state(MainState::LoadAssets))
)

Unfortunately #1: because the tutorial is already quite lengthy I might not be able to update it :/ Unfortunately #2: I was playing a bit with Bevy 0.11 recently (trying to update an older game) and I am not sure if the scheduling behaviour is exactly the same in this version. But probably it won't make a difference for the tutorial.

I might do in the future some shorter turn-based approach blog post or tutorial for the recent Bevy version, but I'll probably wait a bit till those issues stabilize.

Good thing is that Bevy typically has well done migrations guides: https://bevyengine.org/learn/migration-guides/0.10-0.11/

If you have any further questions (or the above won't work) do not hesitate to keep asking :) (I am also on Mastodon and Twitter: https://maciejglowka.com/contact/)

NFodrea commented 8 months ago

@D0ubleD0uble I know I'm pretty delayed on a reply here, but I've just started this tutorial as well. If you are still interested I got part 1 working with Bevy 0.13 using bevy asset loader and a texture atlas. I switched a couple small things around in thee project:

@maciekglowka Thank you for this tutorial its been really helpful.

If a repo would be easier let me know and I will make one. Here are the relevant file changes

Asset loader

// asset_loader.rs
use bevy::prelude::*;
use bevy_asset_loader::asset_collection::AssetCollection;

#[derive(AssetCollection, Resource)]
pub struct ImageAssets {
    #[asset(key = "sprites.layout")]
    pub layout: Handle<TextureAtlasLayout>,
    #[asset(key = "sprites.image")]
    pub sprites: Handle<Image>,
}

.ron file

// assets/sprites.assets.ron
({
    "sprites.image": File (
        path: "sprites.png",
    ),
    "sprites.layout": TextureAtlasLayout (
        tile_size_x: 16.,
        tile_size_y: 16.,
        columns: 10,
        rows: 40,
    ),
})

Main

use asset_loader::ImageAssets;
use bevy::{input::common_conditions::input_toggle_active, prelude::*};
use bevy_asset_loader::prelude::*;
use bevy_inspector_egui::quick::WorldInspectorPlugin;
use globals::{ASSET_SCALE, TILE_SIZE, WINDOW_HEIGHT, WINDOW_WIDTH};
mod asset_loader;
mod globals;
mod graphics;
mod map;
mod player;
mod shared;
mod states;
mod utils;

fn main() {
    App::new()
        .init_state::<MainState>()
        .add_plugins(
            DefaultPlugins
                .set(WindowPlugin {
                    primary_window: Some(Window {
                        title: "Bevy Rogue".into(),
                        resolution: (WINDOW_WIDTH, WINDOW_HEIGHT).into(),
                        resizable: false,
                        focused: true,
                        ..default()
                    }),
                    ..default()
                })
                .set(ImagePlugin::default_nearest())
                .build(),
        )
        .add_plugins(WorldInspectorPlugin::default().run_if(input_toggle_active(true, KeyCode::F1)))
        .add_loading_state(
            LoadingState::new(MainState::LoadAssets)
                .continue_to_state(MainState::LoadMap)
                .with_dynamic_assets_file::<StandardDynamicAssetCollection>("sprites.assets.ron")
                .load_collection::<ImageAssets>(),
        )
        .add_plugins(map::MapPlugin)
        .add_systems(Startup, setup)
        .add_loading_state(
            LoadingState::new(MainState::LoadMap).continue_to_state(MainState::LoadTile),
        )
        .add_systems(OnEnter(MainState::Game), spawn_player)
        .add_loading_state(
            LoadingState::new(MainState::LoadTile).continue_to_state(MainState::Game),
        )
        .add_plugins(graphics::GraphicsPlugin)
        .add_loading_state(
            LoadingState::new(MainState::LoadTile).continue_to_state(MainState::Game),
        )
        .add_systems(OnEnter(MainState::Game), spawn_player)
        .add_systems(Update, bevy::window::close_on_esc)
        .run();
}

fn spawn_player(mut commands: Commands, assets: Res<ImageAssets>) {
    commands
        .spawn(SpriteSheetBundle {
            texture: assets.sprites.clone(),
            atlas: TextureAtlas {
                layout: assets.layout.clone(),
                index: 297,
            },
            transform: Transform {
                translation: { Vec3::new(0., 0., 1.) },
                scale: Vec3::splat(ASSET_SCALE),
                ..Default::default()
            },
            ..Default::default()
        })
        .insert(Name::new("Player"));
}

fn setup(mut commands: Commands) {
    // commands.spawn(Camera2dBundle::default());
    let mut camera = Camera2dBundle::default();
    camera.transform.translation = Vec3::new(
        4. * TILE_SIZE * ASSET_SCALE,
        4. * TILE_SIZE * ASSET_SCALE,
        camera.transform.translation.z,
    );
    commands.spawn(camera);
}

Map

//map.mod.rs
use bevy::prelude::*;
use std::collections::HashMap;

use crate::states::MainState;
use crate::utils::Vector2Int;

pub mod systems;

pub struct MapPlugin;

impl Plugin for MapPlugin {
    fn build(&self, app: &mut App) {
        // making a plugin to init the map resource
        app.init_resource::<CurrentMap>()
            .add_systems(OnEnter(MainState::LoadMap), systems::spawn_map);
    }
}

#[derive(Default, Resource)]
pub struct CurrentMap {
    pub tiles: HashMap<Vector2Int, Entity>,
}
// map/systems.rs
use bevy::prelude::*;
use std::collections::HashMap;

use crate::{
    shared::shared_components::{Position, Tile},
    utils::Vector2Int,
};

use super::CurrentMap;

pub fn spawn_map(mut commands: Commands, mut current: ResMut<CurrentMap>) {
    current.tiles = HashMap::new();
    // hard coded size for now for testing
    for x in 0..8 {
        for y in 0..8 {
            let v = Vector2Int::new(x, y);
            let tile = commands.spawn((Position { v }, Tile)).id();
            current.tiles.insert(v, tile);
            // println!("v: {:?}, tile: {:?}", v, tile);
        }
    }
}

Graphics

// graphics/mod.rs
use bevy::prelude::*;

use crate::states::MainState;
pub mod tiles;

pub struct GraphicsPlugin;

impl Plugin for GraphicsPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(OnEnter(MainState::LoadTile), tiles::spawn_tile_renderer);
    }
}
// tiles.rs
use bevy::prelude::*;

use crate::asset_loader::ImageAssets;
use crate::globals::{ASSET_SCALE, TILE_SIZE};
use crate::shared::shared_components::{Position, Tile};

pub fn spawn_tile_renderer(
    mut commands: Commands,
    query: Query<(Entity, &Position), Added<Tile>>,
    assets: Res<ImageAssets>,
) {
    for (entity, position) in query.iter() {
        // print!("entity: {:?}, position: {:?}\n", entity, position);
        let v = Vec3::new(
            (TILE_SIZE * ASSET_SCALE) * position.v.x as f32,
            (TILE_SIZE * ASSET_SCALE) * position.v.y as f32,
            0.,
        );
        commands.entity(entity).insert(SpriteSheetBundle {
            texture: assets.sprites.clone(),
            atlas: TextureAtlas {
                layout: assets.layout.clone(),
                index: 60,
            },
            transform: Transform {
                translation: { v },
                scale: Vec3::splat(ASSET_SCALE),
                ..Default::default()
            },
            ..Default::default()
        });
    }
}

on to part 2 😄

maciekglowka commented 7 months ago

@NFodrea wow, thanks for such a detailed code update ! It surely will be helpful for future releases. Glad that the tutorial is still helpful despite being outdated and not exactly finished :D

I am thinking now though if it wouldn't be easier to start the tutorial from scratch with the latest Bevy version - instead of updating the existing parts. It could be more minimalist and easier to handle. I think I've made a typical too-large-scope mistake (like card mechanics, complex dungeon generation) - that is not needed for the learning process so much.

Perhaps it'd be more beneficial to keep a shorted bare-bones tutorial with only basic mechanic - esp. how to deal with turns in Bevy. And than if resources permit add more stuff on top :) I will see how it goes.

NFodrea commented 7 months ago

A new tutorial would be awesome! I sent you an invite to a repo with everything through part 5 of the old tutorial finished. Since I'm not 100% sure on the license for the assets I'm using and if it allows public redistribution I have the repo set to private for now. If other people end up wanting it I'm more than happy to create a public version with dummy assets

maciekglowka commented 7 months ago

@NFodrea thanks! I have joined it, will take a look. If you are not sure about those specific assets I am pretty confident that you could use ones from Kenney (kenney.nl). He has rather awesome roguelike packs as well. I hope time permits to attempt a simple tutorial again. I'd really like to do it with the new Bevy functionalities.

mcgeestocks commented 1 week ago

Hey @NFodrea & @maciekglowka would live to check out that repo where you bump to 0.13 if you guys every finished it (or got it to a point where you were fine with sharing).

maciekglowka commented 1 week ago

@mcgeestocks thanks for the interest, but I am afraid there is no progress here... I'd have to catch up with Bevy to resurrect this.