I've just started making this project, so there is nothing much in it. I will use the bevy_ecs_ldtk dependency. I will use any one of these .ldtk file I was also looking for collision setup, is there a automatic way to do it, while using ldtk?
main.rs:
use bevy::{prelude::*, window::PrimaryWindow};
use bevy_ecs_ldtk::prelude::*;
mod components;
mod systems;
const PLAYER_SPEED: f32 = 200.0;
const PLAYER_SIZE: f32 = 24.0;
fn main() {
App::new()
.insert_resource(ClearColor(Color::rgb(0.5, 0.5, 0.9)))
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
.add_systems(Startup, setup)
.add_systems(Startup, systems::spawn_player)
.add_systems(
Update,
systems::player_movement.before(systems::confine_player_movement),
)
.add_systems(Update, systems::confine_player_movement)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(Camera2dBundle::default());
let ldtk_handle = asset_server.load("Typical_2D_platformer_example.ldtk");
commands.spawn(LdtkWorldBundle {
ldtk_handle,
..default()
});
}
systems.rs:
use bevy::{prelude::*, window::PrimaryWindow};
use crate::components::*;
use crate::*;
pub fn spawn_player(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
) {
let texture_handle = asset_server.load("gabe-idle-run.png");
let texture_atlas =
TextureAtlas::from_grid(texture_handle, Vec2::new(24.0, 24.0), 7, 1, None, None);
let texture_atlas_handle = texture_atlases.add(texture_atlas);
// Use only the subset of sprites in the sheet that make up the running animation
commands.spawn((
SpriteSheetBundle {
texture_atlas: texture_atlas_handle,
sprite: TextureAtlasSprite::new(1),
transform: Transform {
scale: Vec3::new(3.0, 3.0, 0.0),
..default()
},
..default()
},
Player,
));
}
pub fn player_movement(
keyboard_input: Res<Input<KeyCode>>,
mut player_query: Query<&mut Transform, With<Player>>,
time: Res<Time>,
) {
if let Ok(mut transform) = player_query.get_single_mut() {
let mut direction = Vec3::ZERO;
if keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A) {
direction += Vec3::new(-1.0, 0.0, 0.0);
}
if keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D) {
direction += Vec3::new(1.0, 0.0, 0.0);
}
if direction.length() > 0.0 {
direction = direction.normalize();
}
transform.translation += direction * PLAYER_SPEED * time.delta_seconds();
}
}
pub fn confine_player_movement(
mut player_query: Query<&mut Transform, With<Player>>,
window_query: Query<&Window, With<PrimaryWindow>>,
) {
if let Ok(mut player_transform) = player_query.get_single_mut() {
let window = window_query.get_single().unwrap();
let half_player_size = PLAYER_SIZE;
let x_min = -window.width() / 2.0 + half_player_size - 2.8;
let x_max = window.width() / 2.0 - half_player_size;
let mut translation = player_transform.translation;
// Bound the player X position
if translation.x < x_min {
translation.x = x_min
} else if translation.x > x_max {
translation.x = x_max
}
player_transform.translation = translation;
}
}
components.rs:
use bevy::prelude::*;
#[derive(Component)]
pub struct Player;
#[derive(Clone, Default, Component)]
pub struct GroundDetection {
on_ground: bool,
}
I've tried looking at their platformer example (which is what I'm trying to make) but I didn't understand it.