aboutsummaryrefslogtreecommitdiff
path: root/src/Update/CloudUpdate.elm
blob: 86f7e135b30bf1b442fa2a46a40d00010b392300 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
module Update.CloudUpdate
  ( cloudUpdate
  ) where

import List
import Random (..)

import Model.Vec2 (..)
import Model.Player (..)
import Model.Board (boardSize, boardDiagonal)
import Model.Point (..)
import Model.Cloud (..)
import Model.Config (..)

import Utils.Geometry (..)
import Utils.Physics (getMove, getWaveMove)

cloudUpdate : Float -> Seed -> Player -> Cloud -> (Cloud, Int, Seed)
cloudUpdate time seed player {points, spawn, lastSpawn} =
  let pointsToCatch = presentPoints time (points player.config)
      presentAndNotCaughtPoints = List.filter (not << (playerPointCollision time player)) pointsToCatch
      addScore = (List.length pointsToCatch) - (List.length presentAndNotCaughtPoints)
      presentOtherPoints = presentPoints time (points (otherConfig player.config))
      (newCloud, seed''') =
        if time > lastSpawn + spawn then
          let (newPoint1, seed') = getNewPoint time seed
              (newPoint2, seed'') = getNewPoint time seed'
          in  ( { points config =
                    if(config == player.config)
                      then
                        newPoint1 :: presentAndNotCaughtPoints
                      else
                        newPoint2 :: presentOtherPoints
                , spawn = spawn - sqrt(spawn) / 50
                , lastSpawn = time
                }
              , seed''
              )
        else
          ( { points config =
                if(config == player.config) then
                  presentAndNotCaughtPoints
                else
                  presentOtherPoints
            , spawn = spawn
            , lastSpawn = lastSpawn
            }
          , seed
          )
  in  (newCloud, addScore, seed''')

presentPoints : Float -> List Point -> List Point
presentPoints time points =
  let isPresent point = (distance (pointMove point time) originVec) < pointAwayDist
  in  List.filter isPresent points


getNewPoint : Float -> Seed -> (Point, Seed)
getNewPoint time seed =
  let (initPos, seed') = pointInitPos seed
      (initDest, seed'') = pointDestination seed'
  in  ( { initTime = time
        , initPos = initPos
        , initDest = initDest
        , move initTime initPos initDest time =
            let delta = time - initTime
                move = getWaveMove (pointSpeed delta) (initDest `sub` initPos) 10 10
            in  initPos `add` move
        }
      , seed''
      )

pointInitPos : Seed -> (Vec2, Seed)
pointInitPos seed =
  let (rand, seed') = generate floatGen seed
      angle = rand * (degrees 360)
      dist = boardDiagonal * 3 / 5
  in  (polarToCartesian angle dist, seed')

pointDestination : Seed -> (Vec2, Seed)
pointDestination seed =
  let ([r1, r2, r3, r4], seed') = generateMany 4 floatGen seed
  in  ( randomBoardPosition (r1, r2) (r3, r4)
      , seed'
      )

generateMany : Int -> Generator a -> Seed -> (List a, Seed)
generateMany count gen seed =
  if count == 0
    then
      ([], seed)
    else
      let (rand, seed') = generate gen seed
          (randList, seed'') = generateMany (count - 1) gen seed'
      in  (rand :: randList, seed'')

floatGen : Generator Float
floatGen = float 0 1

randomBoardPosition : (Float, Float) -> (Float, Float) -> Vec2
randomBoardPosition (randomX, randomY) (percentX, percentY) =
  let width = boardSize.x * percentX
      height = boardSize.y * percentY
  in  { x = width * randomX - width / 2
      , y = height * randomY - height / 2
      }