So I want to update the sprite so my character looks in a different direction each time the player presses left/right, how could I do this? I can't do it in the setup fn, since it's a startup system, appreciate any help
EDIT: changed formating
here is my code:
use bevy::prelude::*;
`fn main() {
App::new()
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
.add_systems(Startup, setup)
.add_systems(Update, animate_sprite)
.add_systems(Update, player_movement_system)
.run();
}
const BOUNDS: Vec2 = Vec2::new(1200.0, 640.0);
static mut FLIP_BOOLEAN: bool = false;
fn set_flip_boolean(boolean: bool) {
unsafe {
FLIP_BOOLEAN = boolean;
}
}
fn get_flip_boolean() -> bool{
unsafe {
FLIP_BOOLEAN
}
}
#[derive(Component)]
struct Player {
movement_speed: f32,
}
#[derive(Component)]
struct AnimationIndices {
first: usize,
last: usize,
}
#[derive(Component, Deref, DerefMut)]
struct AnimationTimer(Timer);
fn animate_sprite(
time: Res<Time>,
mut query: Query<(&AnimationIndices, &mut AnimationTimer, &mut TextureAtlas)>,
) {
for (indices, mut timer, mut atlas) in &mut query {
timer.tick(time.delta());
if timer.just_finished() {
atlas.index = if atlas.index == indices.last {
indices.first
} else {
atlas.index + 1
};
}
}
}
fn setup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
) {
let texture = asset_server.load("sprites/Idle01.png");
let layout = TextureAtlasLayout::from_grid(Vec2::new(64.0, 40.0), 5, 1, None, None);
let texture_atlas_layout = texture_atlas_layouts.add(layout);
let animation_indices = AnimationIndices { first: 0, last: 4 };
let boolean = get_flip_boolean();
commands.spawn(Camera2dBundle::default());
commands.spawn((
SpriteSheetBundle {
texture,
atlas: TextureAtlas {
layout: texture_atlas_layout,
index: animation_indices.first,
},
..default()
},
Player {
movement_speed: 500.0,
},
animation_indices,
AnimationTimer(Timer::from_seconds(0.1, TimerMode::Repeating)),
));
}
fn player_movement_system(
time: Res<Time>,
keyboard_input: Res<ButtonInput<KeyCode>>,
mut query: Query<(&Player, &mut Transform)>,
) {
let (guy, mut transform) = query.single_mut();
let mut movement_factor = 0.0;
let mut movement_direction = Vec3::X;
if keyboard_input.pressed(KeyCode::ArrowLeft) {
movement_factor -= 1.0;
movement_direction = Vec3::X;
set_flip_boolean(true);
}
if keyboard_input.pressed(KeyCode::ArrowRight) {
movement_factor += 1.0;
movement_direction = Vec3::X;
set_flip_boolean(false);
}
if keyboard_input.pressed(KeyCode::ArrowUp) {
movement_factor += 1.0;
movement_direction = Vec3::Y;
}
if keyboard_input.pressed(KeyCode::ArrowDown) {
movement_factor -= 1.0;
movement_direction = Vec3::Y;
}
let movement_distance = movement_factor * guy.movement_speed * time.delta_seconds();
let translation_delta = movement_direction * movement_distance;
transform.translation += translation_delta;
let extents = Vec3::from((BOUNDS / 2.0, 0.0));
transform.translation = transform.translation.min(extents).max(-extents);
}
In your movement system you can change transform.scale.x which will flip your sprite if it's -1.0.
(Also just a note for the future: you don't use static variables with bevy, you would instead use a Resource. Or if it'd data attached to a specific entity, you'd make a Component for it)