imj-game-hamazed-0.1.0.2: A game with flying numbers and 8-bit color animations.

Imj.Game.Hamazed.World

Synopsis

# Parameters

When the game starts, the player can chose World parameters:

• WorldShape : square or rectangular World where the width is twice the height
• WallDistribution : Should the World have walls, and what kind of walls.

Displays the configuration UI showing the game creation options, and returns when the player has finished chosing the options.

Constructors

 GameParameters

# Level

There are 12 levels in Hamazed, numbered from 1 to 12.

data Level Source #

Constructors

 Level Fields_levelNumber :: !IntFrom 1 to 12_levelTarget :: !IntThe target number_levelStatus :: !(Maybe LevelFinished)

## Level termination

Target number
Each level has a different target number which represents the sum of shot Numbers that should be reached to finish the Level.

A Level is finished once the sum of shot Numbers amounts to the target number.

Arguments

 :: Int Remaining ammo -> Int The current sum of all shot Numbers -> Int The Level 's target number. -> SystemTime The current time -> Maybe LevelFinished

# World

A World brings together:

• game elements : Space, BattleShip and Numbers,
• rendering elements: Animations,
• terminal-awareness : InTerminal

data World Source #

Constructors

 World Fields_worldNumbers :: ![Number]The remaining Numbers (shot Numbers are removed from the list)_worldShip :: !BattleShipThe player's BattleShip_worldSpace :: !SpaceThe Space in which BattleShip and Numbers evolve_worldAnimations :: ![Animation]Visual animations. They don't have an influence on the game, they are just here for aesthetics._worldEmbedded :: !InTerminalTo know where we should draw the World from, w.r.t terminal frame.

## Create the world

The World size decreases with increasing Level numbers.

worldSizeFromLevel gives the Size of the World based on the Level number and the WorldShape:

Arguments

 :: Int Level number -> WorldShape -> Size

Once we have the Size of the World, we can create it using mkWorld:

Arguments

 :: MonadIO m => InTerminal Tells where to draw the World from -> Size The dimensions -> WallDistribution How the Walls should be constructed -> [Int] The numbers for which we will create Numbers. -> Int Ammunition : how many laser shots are available. -> m World

## Update World

Every gameMotionPeriod seconds, the positions of BattleShip and Numbers are updated according to their speeds:

Arguments

 :: KeyTime The current time -> World -> World

Moves elements of game logic (Numbers, BattleShip).

Note that Animations are not updated.

## World utilities

laserEventAction returns the effect a laser shot it has on the World.

Arguments

 :: Direction The direction of the laser shot -> World -> ([Number], [Number], Maybe (LaserRay Actual), Int) Numbers still alive, Numbers destroyed, maybe an actual laser ray, Ammo left.

Computes the effect of an laser shot on the World.

# InTerminal

InTerminal allows to place the game in the center of the terminal.

Arguments

 :: MonadIO m => Size Measures the dimensions of the inner content of the World, excluding the outer frame. -> m (Either String InTerminal)

Will compute the position of the World so as to display it in the center of the terminal window.

Constructors

 InTerminal Fields_inTerminalSize :: !(Maybe (Window Int))The size of the terminal window_inTerminalUpperLeft :: !(Coords Pos)The World 's RectContainer upper left coordinates, w.r.t terminal frame.

Instances

 Source # MethodsshowList :: [InTerminal] -> ShowS #

# Space

Space describes the environment in which Numbers and the BattleShip live.

It can be composed of Air, where BattleShip and Numbers are free to move, and of Wall.

data Material Source #

Constructors

 Air In it, ship and numbers can move. Wall Ship and numbers rebound on Walls.

Instances

 Source # Methods Source # MethodsshowList :: [Material] -> ShowS #

## Simple creation

Creates a rectangular empty space of size specified in parameters.

Creates a rectangular deterministic space of size specified in parameters.

## Randomized creation

mkRandomlyFilledSpace places Walls at random and discards resulting Spaces which have more than one Air connected component.

This way, the BattleShip is guaranteed to be able to reach any part of the Space, and Numbers.

Generating a big Space with a very small block size can be computationnaly expensive because the probability to have a single Air connected component drops very fast (probably at least exponentially) towards zero with increasing sizes.

Creates a rectangular random space of size specified in parameters, with a one-element border. IO is used for random numbers generation.

Parameters for random walls creation.

Constructors

 RandomParameters Fields_randomWallsBlockSize :: !IntThe size of a square wall block.Note that the smaller the block size, the harder it will be for the algorithm to find a random world with a single component of air._randomWallsStrategy :: !StrategySpace characteristics (only one connected component is available for the moment)

data Strategy Source #

Constructors

 StrictlyOneComponent There should be a single connected component of air.This way, the ship can reach any allowed location without having to go through Walls.

## Collision detection

location is the standard collision detection function that considers that being outside the world means being in collision.

scopedLocation prevides more options with the use of Boundaries to defines the collision detection scopes.

Considers that outside Space, everything is OutsideWorld

Arguments

 :: Space -> Maybe (Window Int) The terminal size -> Coords Pos The world upper left coordinates w.r.t terminal frame. -> Boundaries The scope -> Coords Pos The coordinates to test -> Location

Constructors

 WorldFrame Just the world. TerminalWindow The terminal, not the world. Both The terminal.

Instances

 Source # MethodsshowList :: [Boundaries] -> ShowS #

## Collision detection utilities

Creates a PosSpeed such that its position is not colliding, and moves to precollision and mirrors speed if a collision is detected for the next step (see mirrorSpeedAndMoveToPrecollisionIfNeeded).

## Render

Arguments

 :: (Draw e, MonadReader e m, MonadIO m) => Space -> Coords Pos World upper left coordinates w.r.t terminal frame. -> m (Coords Pos)

# Movable items

A movable item's PosSpeed is updated using updateMovableItem at each MoveFlyingItems event:

Arguments

 :: Space The surrounding Space will be taken into account for collisions. -> PosSpeed The current position and speed of the moving item. -> PosSpeed The updated position and speed.

Updates PosSpeed of a movable item, according to Space.

## BattleShip

Constructors

 BattleShip Fields_shipPosSpeed :: !PosSpeedDiscrete position and speed._shipAmmo :: !IntHow many laser shots are left._shipSafeUntil :: !(Maybe SystemTime)At the beginning of each level, the ship is immune to collisions with Numbers for a given time. This field holds the time at which the immunity ends._shipCollisions :: ![Number]Which Numbers are currently colliding with the BattleShip.

Instances

 Source # MethodsshowList :: [BattleShip] -> ShowS #

### Accelerate BattleShip

The BattleShip is controlled in (discrete) acceleration by the player using the keyboard.

Note that the position of the BattleShip remains unchanged.

## Number

Numbers can be shot by the BattleShip to finish the Level.

Number can collide with the BattleShip, hence triggering colorfull Animation explosions.

Numbers never change speed, except when they rebound on Walls, of course.

data Number Source #

Constructors

 Number Fields_numberPosSpeed :: !PosSpeedDiscrete position and speed._numberNum :: !IntWhich number it represents (1 to 16).

Instances

 Source # Methods(==) :: Number -> Number -> Bool #(/=) :: Number -> Number -> Bool # Source # MethodsshowsPrec :: Int -> Number -> ShowS #showList :: [Number] -> ShowS #

# UI

UI elements around the World are:

• a RectContainer created by mkWorldContainer to visually delimit the World
• ColorString information, placed around the RectContainer:

• Up: Level target
• Left: remaining ammunitions / shot Numbers
• Down: Level number

Helper function to create a RectContainer containing a World.

# Secondary types

How should walls be created?

Constructors

 None No Walls. Deterministic A Rectangular Wall in the middle of the level. Random !RandomParameters Walls are created with an algorithm involving random numbers.

Constructors

 Square Width = Height Rectangle2x1 Width = 2 * Height

Constructors

 LevelFinished Fields_levelFinishedResult :: !GameStopsLost or won_levelFinishedWhen :: !SystemTime _levelFinishedCurrentMessage :: !MessageState

data GameStops Source #

Constructors

 Lost Text Text is the reason why the Level was lost. Won

# Reexports

data ColorString :: * #

Instances

 MethodsshowList :: [ColorString] -> ShowS # Methods Methodsmconcat :: [ColorString] -> ColorString # First interpolating characters, then color. Methods First interpolating characters, then color. Methods