Skip to content

Files

Latest commit

0d13735 · Apr 21, 2024

History

History
97 lines (75 loc) · 3.11 KB

a_timer_running_repeatedly.md

File metadata and controls

97 lines (75 loc) · 3.11 KB

A Timer Running Repeatedly

Previously, the Timer triggers an event once and then stops. We can make a Timer repeating by TimerMode::Repeating so that it triggers events periodically.

Timer::from_seconds(0.5, TimerMode::Repeating)

In the following example, we rotate a RegularPolygon every 0.5 seconds.

fn polygon_rotates(
    time: Res<Time>,
    mut my_timer: ResMut<MyTimer>,
    mut polygons: Query<&mut Transform, With<Handle<ColorMaterial>>>,
) {
    let mut transform = polygons.single_mut();

    if my_timer.0.tick(time.delta()).just_finished() {
        *transform = Transform::from_rotation(Quat::from_rotation_z(time.elapsed_seconds() / 2.));
    }
}

The method just_finished() of Timer here will be true every 0.5 seconds. We use the method elapsed_seconds() of Time to compute the degree of the rotation.

The full code is as follows:

use bevy::{
    app::{App, Startup, Update},
    asset::{Assets, Handle},
    core_pipeline::core_2d::Camera2dBundle,
    ecs::{
        query::With,
        system::{Commands, Query, Res, ResMut, Resource},
    },
    math::Quat,
    render::mesh::{shape::RegularPolygon, Mesh},
    sprite::{ColorMaterial, ColorMesh2dBundle},
    time::{Time, Timer, TimerMode},
    transform::components::Transform,
    utils::default,
    DefaultPlugins,
};

#[derive(Resource)]
struct MyTimer(Timer);

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(MyTimer(Timer::from_seconds(0.5, TimerMode::Repeating)))
        .add_systems(Startup, setup)
        .add_systems(Update, polygon_rotates)
        .run();
}

fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
    commands.spawn(Camera2dBundle::default());

    commands.spawn(ColorMesh2dBundle {
        mesh: meshes.add(RegularPolygon::new(50., 5).into()).into(),
        ..default()
    });
}

fn polygon_rotates(
    time: Res<Time>,
    mut my_timer: ResMut<MyTimer>,
    mut polygons: Query<&mut Transform, With<Handle<ColorMaterial>>>,
) {
    let mut transform = polygons.single_mut();

    if my_timer.0.tick(time.delta()).just_finished() {
        *transform = Transform::from_rotation(Quat::from_rotation_z(time.elapsed_seconds() / 2.));
    }
}

When the app just started:

A Timer Running Repeatedly 1

After 0.5 seconds:

A Timer Running Repeatedly 2

After 1 second:

A Timer Running Repeatedly 3

➡️ Next: Easing

📘 Back: Table of contents