Learn Rust Coding · Leçon

Collisions et état du jeu

Ajoutez des règles et des conditions de victoire.

Leçon 4 sur 413 étapes

Collisions et état du jeu est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 4 leçons au total.

Bases des collisions AABB

Le test de collision le plus simple est le chevauchement de boîtes englobantes alignées sur les axes (AABB). Deux rectangles entrent en collision lorsqu'ils se chevauchent sur les axes x et y.

Pour les sprites, cette méthode est rapide et suffisamment précise pour de nombreux jeux en 2D avant de recourir à un moteur physique complet.

fn overlaps(a_pos: Vec2, a_size: Vec2, b_pos: Vec2, b_size: Vec2) -> bool {
    (a_pos.x - b_pos.x).abs() < (a_size.x + b_size.x) * 0.5
        && (a_pos.y - b_pos.y).abs() < (a_size.y + b_size.y) * 0.5
}

Un composant Collider

Attachez un composant Collider contenant les demi-dimensions ou les dimensions complètes de chaque entité. Les systèmes lisent ensuite la transformation et le collider pour tester les chevauchements.

Conserver la taille dans son propre composant permet à différentes entités de partager le même système de collision.

#[derive(Component)]
struct Collider {
    size: Vec2,
}

Détecter les collisions dans un système

Pour comparer un joueur à de nombreux obstacles, demandez le joueur une seule fois et parcourez les obstacles. Deux requêtes distinctes évitent d'emprunter deux fois les mêmes données.

En cas de chevauchement, vous réagissez — en infligeant des dégâts, en faisant rebondir l'objet ou en le supprimant — au moyen de Commands ou en modifiant les composants.

fn detect(
    player: Query<(&Transform, &Collider), With<Player>>,
    walls: Query<(&Transform, &Collider), With<Wall>>,
) {
    let (pt, pc) = player.single().unwrap();
    for (wt, wc) in &walls {
        if overlaps(pt.translation.truncate(), pc.size, wt.translation.truncate(), wc.size) {
            info!("hit a wall");
        }
    }
}

Réagir avec des événements

Plutôt que de gérer les conséquences directement, envoyez un Event personnalisé. Un système détecte les collisions et émet des événements ; un autre les lit et applique les effets.

Cela découple la détection de la réaction et permet de conserver des systèmes de petite taille.

#[derive(Event)]
struct CollisionEvent { entity: Entity }

fn emit(mut writer: EventWriter<CollisionEvent>, e: Entity) {
    writer.send(CollisionEvent { entity: e });
}

Lire les événements

Un système lecteur récupère les événements en file avec un EventReader et agit sur chacun d'eux. Les événements restent disponibles pendant deux images, afin que tous les lecteurs puissent les voir.

Ce fonctionnement publication-abonnement passe à l'échelle : de nombreux producteurs et consommateurs peuvent fonctionner sans couplage étroit.

fn on_hit(mut reader: EventReader<CollisionEvent>, mut commands: Commands) {
    for ev in reader.read() {
        commands.entity(ev.entity).despawn();
    }
}

Mettre à jour le score

Lorsque le joueur ramasse un objet, modifiez la ressource globale Score avec ResMut.

Comme les ressources sont uniques, n'importe quel système peut lire ou mettre à jour le score sans devoir le transmettre manuellement.

fn collect(mut score: ResMut<Score>, mut reader: EventReader<PickupEvent>) {
    for _ in reader.read() {
        score.0 += 10;
    }
}

Les états : vue d'ensemble

Les jeux passent d'un mode à l'autre : menu, partie, pause, fin de partie. Bevy les représente au moyen d'une énumération States enregistrée avec init_state.

Un seul état est actif à la fois, et les systèmes peuvent être autorisés à s'exécuter uniquement dans certains états.

#[derive(States, Default, Debug, Clone, PartialEq, Eq, Hash)]
enum GameState {
    #[default]
    Menu,
    Playing,
    GameOver,
}

Enregistrer un état

Ajoutez l'état à l'application avec init_state. Bevy suit alors la valeur actuelle et expose les ressources State et NextState.

Lisez l'état actuel avec Res<State<GameState>> lorsqu'un système doit connaître le mode en cours.

App::new()
    .add_plugins(DefaultPlugins)
    .init_state::<GameState>()
    .run();

Exécuter des systèmes dans un état

Limitez les systèmes à un état avec la condition run_if in_state. Les déplacements et les collisions ne s'exécutent que lorsque l'état est Playing.

C'est ainsi que fonctionne la pause : quittez l'état Playing pour arrêter les systèmes de gameplay, qui cessent alors simplement de s'exécuter.

app.add_systems(
    Update,
    (drive, detect).run_if(in_state(GameState::Playing)),
);

Effectuer une transition d'état

Pour changer d’état, définissez NextState depuis n’importe quel système. Bevy applique la transition à la prochaine limite de trame.

Utilisez les planifications OnEnter et OnExit pour créer l’interface utilisateur lors de l’entrée dans un état ou effectuer le nettoyage lors de sa sortie.

fn lose(mut next: ResMut<NextState<GameState>>, health: Res<Health>) {
    if health.0 == 0 {
        next.set(GameState::GameOver);
    }
}

Nettoyage à la sortie

Lorsque vous quittez Playing, désallouez les entités du jeu afin que la manche suivante démarre proprement. Marquez-les avec un marqueur, puis utilisez despawn pour tout ce qui le porte.

Enregistrez le nettoyage dans OnExit(GameState::Playing) afin qu’il s’exécute exactement une fois par transition.

fn cleanup(mut commands: Commands, q: Query<Entity, With<GameEntity>>) {
    for e in &q {
        commands.entity(e).despawn();
    }
}
// app.add_systems(OnExit(GameState::Playing), cleanup);

Vérification rapide

Réfléchissez à la manière de mettre le jeu en pause proprement.

Récapitulatif : collisions et état du jeu

Les tests AABB associés à un composant Collider détectent les chevauchements ; les événements dissocient la détection de la réaction, et une ressource Score suit la progression. Le système States, avec run_if, NextState et OnEnter/OnExit, structure les menus, le jeu et la fin de partie.

Vous disposez maintenant de la boucle complète : créer, contrôler, entrer en collision et effectuer une transition. Construisez un jeu Bevy complet à partir de ces éléments.

Gratuit pour commencer

Apprends Rust avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
39
Leçons
144

Questions Fréquemment Posées

La leçon « Collisions et état du jeu » est-elle gratuite ?

Oui — le texte complet de « Collisions et état du jeu » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Collisions et état du jeu » ?

Ajoutez des règles et des conditions de victoire. Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Collisions et état du jeu » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. La philosophie ECS
  2. Créer et déplacer des entités
  3. Gérer les entrées et le temps
  4. Collisions et état du jeu
← Retour à Learn Rust Coding