ExPilot.Ball (ExPilot v0.1.1)

Copy Markdown View Source

Treasures and the balls in them, for capture the flag.

Every * on the map is a treasure belonging to the team of the nearest base, and a ball starts in each. A ball is a body of its own: gravity pulls it, it drifts with its velocity and bounces off walls (or goes home from them, with ballswallbounce off). A ship flying within reach of a loose ball picks it up; the ball then hangs on a string of string/0 tiles, and when the string is taut it pulls the ball after the ship and the ship back toward the ball, the ship being the lighter of the two. Stretched past break/0 times its length the string snaps and the ball is loose again; dropping it (:connector) or dying lets it go too. A team's own ball sitting at home is left alone by that team. Flying into one of your own treasures with another team's ball scores it, and the ball goes home. Without teams there is nothing to score, so a map without teamplay has no balls.

ExPilot.Ball.new(arena)
ExPilot.Ball.step(balls, ships, dt, %{grid: grid, fields: fields, size: size, wrap?: false, bounce?: true})

Summary

Functions

How far the string stretches, as a factor of its length, before it snaps.

The ball a ship is carrying, or nil.

A carrier flying into a treasure of its own team with another team's ball scores it: the ball goes home and the carrier's team gains points.

A ball in every treasure of arena, each with its treasure's team.

Move the balls for one tick: a loose ball is picked up by a ship in reach that carries none or drifts on; a carried ball hangs on its string, pulling its carrier when taut, and snaps free when overstretched. Balls fall in fields, bounce off grid or go home when bounce? is off, and wrap in size when wrap?.

The length of the string, in tiles.

Types

ball()

@type ball() :: %{
  id: pos_integer(),
  home: {integer(), integer()},
  team: integer() | nil,
  pos: {float(), float()},
  vel: {float(), float()},
  carrier: term() | nil
}

env()

@type env() :: %{
  grid: Cauldron2D.Collision.grid(),
  fields: [Cauldron2D.Body.field()],
  size: {number(), number()},
  wrap?: boolean(),
  bounce?: boolean()
}

Functions

break()

@spec break() :: float()

How far the string stretches, as a factor of its length, before it snaps.

carried_by(balls, ship_id)

@spec carried_by([ball()], term()) :: ball() | nil

The ball a ship is carrying, or nil.

deliver(balls, ships, arena)

@spec deliver([ball()], %{required(term()) => map()}, ExPilot.Map.t()) ::
  {[ball()], [{term(), integer(), pos_integer(), integer() | nil}]}

A carrier flying into a treasure of its own team with another team's ball scores it: the ball goes home and the carrier's team gains points.

Returns {balls, scored}, each score {carrier_id, team, points, team_scored_against}.

new(arena)

@spec new(ExPilot.Map.t()) :: [ball()]

A ball in every treasure of arena, each with its treasure's team.

step(balls, ships, dt, env)

@spec step([ball()], %{required(term()) => map()}, float(), env()) ::
  {[ball()], %{required(term()) => map()}}

Move the balls for one tick: a loose ball is picked up by a ship in reach that carries none or drifts on; a carried ball hangs on its string, pulling its carrier when taut, and snaps free when overstretched. Balls fall in fields, bounce off grid or go home when bounce? is off, and wrap in size when wrap?.

Returns {balls, ships}, the ships as pulled by their balls and freed of a snapped string.

string()

@spec string() :: float()

The length of the string, in tiles.