Skip to content
Snippets Groups Projects
Select Git revision
  • ad42dbb8148f97318a2f6505d28454b11f9db869
  • master default protected
  • refactor
3 results

main.rs

Blame
  • main.rs 8.24 KiB
    #![allow(unused)]
    use bevy::{
        core::FixedTimestep,
        prelude::*,
        render::{camera::Camera, texture::FilterMode},
    };
    use bevy_ecs_tilemap::{prelude::*, MapQuery};
    use std::f32::consts::PI;
    
    const PLAYER_SHEET: &str = "character_zombie_sheet.png";
    fn main() {
        env_logger::Builder::from_default_env()
            .filter_level(log::LevelFilter::Info)
            .init();
    
        App::build()
            .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
            .insert_resource(WindowDescriptor {
                title: "My Little Zombie".to_string(),
                width: 1920.,
                height: 1080.,
                vsync: true,
                cursor_visible: false,
                // resizable: false,
                ..Default::default()
            })
            .add_plugins(DefaultPlugins)
            .add_plugin(TilemapPlugin)
            .add_plugin(TiledMapPlugin)
            .add_startup_system(setup.system())
            .add_system_set(
                SystemSet::new()
                    .with_run_criteria(FixedTimestep::step(1.0 / 60.0))
                    .with_system(player_movement.system())
                    .with_system(camera.system())
                    .with_system(parallax.system()),
            )
            .add_system(set_texture_filters_to_nearest.system())
            .run();
    }
    
    fn set_texture_filters_to_nearest(
        mut texture_events: EventReader<AssetEvent<Texture>>,
        mut textures: ResMut<Assets<Texture>>,
    ) {
        // quick and dirty, run this for all textures anytime a texture is created.
        for event in texture_events.iter() {
            match event {
                AssetEvent::Created { handle } => {
                    if let Some(mut texture) = textures.get_mut(handle) {
                        texture.sampler.min_filter = FilterMode::Nearest;
                    }
                }
                _ => (),
            }
        }
    }
    
    fn setup(
        mut commands: Commands,
        asset_server: Res<AssetServer>,
        mut materials: ResMut<Assets<ColorMaterial>>,
        mut texture_atlases: ResMut<Assets<TextureAtlas>>,
        mut windows: ResMut<Windows>,
    ) {
        let mut window = windows.get_primary_mut().unwrap();
        commands.spawn_bundle(OrthographicCameraBundle::new_2d());
        let bottom = -window.height() / 2.0;
    
        // load the tile map
        let handle: Handle<TiledMap> = asset_server.load("tmap.tmx");
        let map_entity = commands.spawn().id();
        commands.entity(map_entity).insert_bundle(TiledMapBundle {
            tiled_map: handle,
            map: Map::new(0u16, map_entity),
    
            transform: Transform {
                translation: Vec3::new(0., bottom, 1.0),
                scale: Vec3::new(4.0, 4.0, 1.0),
                ..Default::default()
            },
    
            ..Default::default()
        });
    
        let texture_handle = asset_server.load(PLAYER_SHEET);
        let texture_atlas = TextureAtlas::from_grid(texture_handle, Vec2::new(96.0, 128.0), 9, 5);
        let atlas_handle = texture_atlases.add(texture_atlas);
        commands
            .spawn_bundle(SpriteSheetBundle {
                texture_atlas: atlas_handle,
    
                transform: Transform {
                    translation: Vec3::new(0., bottom / 2.0, 10.0),
                    scale: Vec3::new(1., 1., 1.0),
                    ..Default::default()
                },
                ..Default::default()
            })
            .insert(Player {
                y: bottom / 2.,
                ..Player::default()
            });
    }
    
    #[derive(Copy, Clone)]
    enum Direction {
        Right,
        Left,
        Idle,
    }
    pub struct Player {
        direction: Direction,
        jump: bool,
        index: u32,
        y: f32,
    }
    
    impl Default for Player {
        fn default() -> Self {
            Player {
                direction: Direction::Idle,
                jump: false,
                index: 3,
                y: 0.,
            }
        }
    }
    
    // run each frame (60Hz)
    fn player_movement(
        mut query: Query<(&mut Player, &mut Transform, &mut TextureAtlasSprite)>,
        keyboard_input: Res<Input<KeyCode>>,
    ) {
        if let Ok((mut player, mut transform, mut sprite)) = query.single_mut() {
            let (index, state, dir) = if player.jump {
                // already in jump
                let mut index = player.index + 1;
                match index {
                    4 => {
                        sprite.index = 7;
                    }
                    8 => {
                        sprite.index = 8;
                    }
                    60 => {
                        sprite.index = 3;
                    }
                    _ => {}
                };
                if index == 64 {
                    index = 0;
                    player.jump = false
                };
    
                if index > 8 && index < (60) {
                    transform.translation.y =
                        player.y + (((index - 8) as f32) * PI / (60.0 - 8.0)).sin() * 200.0;
                } else {
                    transform.translation.y = player.y
                }
    
                (index, player.direction, 0.)
            } else if keyboard_input.pressed(KeyCode::Space) {
                // start jump
                player.jump = true;
                sprite.index = 3;
                let index = 0;
                (index, player.direction, 0.)
            } else if keyboard_input.pressed(KeyCode::Right) {
                sprite.flip_x = false;
                match player.direction {
                    // already walking
                    Direction::Right => {
                        let index = (player.index + 1) % 32;
                        sprite.index = (4 * 9) + index / 4;
                        (index, Direction::Right, 2.)
                    }
                    // starting walking
                    _ => {
                        let index = 3 * 4;
                        sprite.index = (4 * 9) + index / 4;
                        (index, Direction::Right, 2.)
                    }
                }
            } else if keyboard_input.pressed(KeyCode::Left) {
                sprite.flip_x = true;
                match player.direction {
                    // already walking
                    Direction::Left => {
                        let index = (player.index + 1) % 32;
                        sprite.index = (4 * 9) + index / 4;
                        (index, Direction::Left, -2.)
                    }
                    // starting walking
                    _ => {
                        let index = 3 * 4;
                        sprite.index = (4 * 9) + index / 4;
                        (index, Direction::Left, -2.)
                    }
                }
            } else {
                match player.direction {
                    // already idle
                    Direction::Idle => {
                        let index = (player.index + 1) % 256;
                        sprite.index = if index > 224 { 0 } else { 9 * 1 + 6 };
                        (index, Direction::Idle, 0.)
                    }
                    // start idle
                    _ => {
                        player.index = 0;
                        sprite.index = 0;
                        (0, Direction::Idle, 0.)
                    }
                }
            };
    
            player.direction = state;
            player.index = index;
            transform.translation.x += dir;
        }
    }
    
    // A simple camera system for moving and zooming the camera.
    pub fn camera(
        time: Res<Time>,
        keyboard_input: Res<Input<KeyCode>>,
        mut query: Query<&mut Transform, With<Camera>>,
    ) {
        // println!("camera");
        for mut transform in query.iter_mut() {
            // print!("-");
            let mut direction = Vec3::ZERO;
            let scale = transform.scale.x;
    
            if keyboard_input.pressed(KeyCode::A) {
                direction -= Vec3::new(1.0, 0.0, 0.0);
            }
    
            if keyboard_input.pressed(KeyCode::D) {
                direction += Vec3::new(1.0, 0.0, 0.0);
            }
    
            if keyboard_input.pressed(KeyCode::W) {
                direction += Vec3::new(0.0, 1.0, 0.0);
            }
    
            if keyboard_input.pressed(KeyCode::S) {
                direction -= Vec3::new(0.0, 1.0, 0.0);
            }
    
            if keyboard_input.pressed(KeyCode::Z) {
                let scale = scale + 0.1;
                transform.scale = Vec3::splat(scale);
            }
    
            if keyboard_input.pressed(KeyCode::X) {
                let scale = scale - 0.1;
                transform.scale = Vec3::splat(scale);
            }
    
            if transform.scale.x < 1.0 {
                transform.scale = Vec3::splat(1.0)
            }
    
            transform.translation += time.delta_seconds() * direction * 500.;
        }
    }
    
    // parallaxing
    pub fn parallax(mut query: Query<(&mut Transform, &Layer)>) {
        println!("parallax");
        for (mut _transform, layer) in query.iter_mut() {
            print!(
                "layer_id {:?}, map_id {:?}",
                layer.settings.layer_id, layer.settings.map_id
            );
        }
    }