Files
EightBittr/docs/walkthrough/8. Collisions.md
T

3.2 KiB

Collisions

Our collision detection logic will have player Actors check for touching any square Actors and kill off the player if so.

That will involve three areas of work:

  1. Selection: Having Actors know which Actors they share quadrants with.
  2. Detection: Determining whether a collision is happening.
  3. Handling: Reacting to a collision taking place.

Quadrant Selection

Create a new Quadrants section declaring "Players" and "Squares" as active groups to have quadrants determined:

import { Quadrants as QuadrantsBase } from "eightbittr";

import { FullScreenSaver } from "../FullScreenSaver";

/**
 * Arranges game physics quadrants.
 */
export class Quadrants<Game extends FullScreenSaver> extends QuadrantsBase<Game> {
    /**
     * Groups that should have their quadrants updated.
     */
    public readonly activeGroupNames: string[] = ["Players", "Squares"];
}

Add a quadrants member to the FullScreenSaver class:

/**
 * Arranges game physics quadrants.
 */
@member(Quadrants)
public readonly quadrants: Quadrants<this>;

Player and square Actors will now know their game quadrants, but not how to check for collisions with each other.

Collision Detection

Create a new src/sections/Collisions.ts with an inheriting Collisions section. Its first member should be a collidingGroupNames array that just includes "Players", to indicate they should check for collisions against other Actors:

import { Actor, Collisions as CollisionsBase } from "eightbittr";

import { FullScreenSaver } from "../FullScreenSaver";

/**
 * Checkers and callbacks for Actor collisions.
 */
export class Collisions<Game extends FullScreenSaver> extends CollisionsBase<Game> {
    /**
     * Names of groups that should be checked for collisions.
     */
    public readonly collidingGroupNames = ["Players"];
}

Next, create a hitCheckGenerators object containing a function to check whether a player touches a solid:

/**
 * Function generators for checking whether two Actors are colliding.
 */
public readonly hitCheckGenerators = {
    Players: {
        Squares: () =>
            (player: Actor, solid: Actor) =>
                player.right >= solid.left
                && player.left <= solid.right
                && player.bottom >= solid.top
                && player.top <= solid.bottom
    }
};

Add this as a collisions member to the FullScreenSaver class:

/**
 * Checkers and callbacks for Actor collisions.
 */
@member(Collisions)
public readonly collisions: Collisions<this>;

The game will now know when a player is touching a solid, but it won't know what to do about it.

Collision Handling

Add an equivalent hitCallbackGenerators later in the Collisions class to kill the player:

/**
 * Function generators for reacting to two Actors colliding.
 */
public readonly hitCallbackGenerators = {
    Players: {
        Squares: () => (player: Actor) => {
            this.game.death.kill(player);
        },
    },
};

Now, whenever a player touches a square, it'll be "killed" and removed from its group.

Next up, let's staying alive a little more difficult over time.

👉 9. Events