imj-game-hamazed-0.1.0.2: src/Imj/Game/Hamazed/World/Ship.hs
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE LambdaCase #-}
module Imj.Game.Hamazed.World.Ship
( shipAnims
, createShipPos
) where
import Imj.Prelude
import Data.Char( intToDigit )
import Data.List( foldl' )
import Data.Maybe( isNothing )
import Imj.Game.Hamazed.Loop.Event
import Imj.Game.Hamazed.World.Space
import Imj.Geo.Discrete
import Imj.Geo.Continuous
import Imj.Graphics.Animation
{- | If the ship is colliding and not in "safe time", and the event is a gamestep,
this function creates an animation where the ship and the colliding number explode.
The ship animation will have the initial speed of the number and vice-versa,
to mimic the rebound due to the collision.
-}
shipAnims :: World
-> KeyTime
-> [Animation]
shipAnims world@(World _ (BattleShip (PosSpeed shipCoords shipSpeed) _ safeTime collisions) _ _ _) k =
if not (null collisions) && isNothing safeTime
then
-- when number and ship explode, they exchange speeds
let collidingNumbersAvgSpeed = foldl' sumCoords zeroCoords $ map (\(Number (PosSpeed _ speed) _) -> speed) collisions
numSpeed = scalarProd 0.4 $ speed2vec collidingNumbersAvgSpeed
shipSpeed2 = scalarProd 0.4 $ speed2vec shipSpeed
(Number _ n) = head collisions
interaction = environmentInteraction world WorldFrame
in fragmentsFreeFallThenExplode numSpeed shipCoords interaction (Speed 1) (Right k) '|'
++
fragmentsFreeFallThenExplode shipSpeed2 shipCoords interaction (Speed 1) (Right k) (intToDigit n)
else
[]
createShipPos :: Space -> [Number] -> IO PosSpeed
createShipPos space numbers = do
let numPositions = map (\(Number (PosSpeed pos _) _) -> pos) numbers
candidate@(PosSpeed pos _) <- createRandomNonCollidingPosSpeed space
if pos `notElem` numPositions
then
return candidate
else
createShipPos space numbers