packages feed

nyx-game-0.1.0.0: app/Attack.hs

{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE DuplicateRecordFields  #-}
{-# LANGUAGE FlexibleInstances  #-}
{-# LANGUAGE TemplateHaskell #-}

module Attack where

import qualified SDL

import Play.Engine
import Control.Lens
import qualified Data.DList as DL

import Bullet
import qualified Play.Engine.Movement as MV


data Attack
  = Attack
  { _movement :: !MV.Movement
  , _outAngles :: ![Float]
  , _texture :: SDL.Texture
  , _attackTimerInit :: !Int
  , _attackTimer :: !Int
  , _attackUpdate :: IPoint -> IPoint -> Attack -> (DL.DList Bullet, Attack)
  }


makeFieldsNoPrefix ''Attack

make :: MV.Movement -> [Float] -> Int -> SDL.Texture
  -> (IPoint -> IPoint -> Attack -> (DL.DList Bullet, Attack))
  -> Attack
make mv angles every txt updater =
  Attack
    { _movement = mv
    , _outAngles = angles
    , _texture = txt
    , _attackTimerInit = every
    , _attackTimer = 60
    , _attackUpdate = updater
    }

update :: IPoint -> IPoint -> Attack -> (DL.DList Bullet, Attack)
update posi sz attack =
  let
    bullets'
      | attack ^. attackTimer == 0 = addBullets posi sz attack
      | otherwise = DL.empty

    attack' =
      attack
        & over attackTimer (\t -> if t <= 0 then attack ^. attackTimerInit else t - 1)

  in
    ( bullets'
    , attack'
    )


addBullets :: IPoint -> IPoint -> Attack -> DL.DList Bullet 
addBullets posi sz attack =
  let
    Point w h = Point (sz ^. x) (sz ^. y)
    ds = map ((pi / 180) *) (attack ^. outAngles)
    dirs = map (\d -> Point (cos d) (sin d)) ds
  in DL.fromList $ map
    (\dir ->
       mkBullet
         (attack ^. texture)
         dir
         (attack ^. movement
           & over MV.maxSpeed (fmap abs . mulPoint dir)
           & over MV.minSpeed (fmap abs . mulPoint dir)
           & over MV.speed (mulPoint dir)
         )
         5
         230
        $ (posi `addPoint` Point (w `div` 2) (h `div` 2))
          `addPoint` fmap (floor . (*) (fromIntegral $ w `div` 2)) dir
    ) dirs