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 exposing (..)
import Model.Vec2 exposing (..)
import Model.Player exposing (..)
import Model.Board exposing (boardDiagonal)
import Model.Point exposing (..)
import Model.Cloud exposing (..)
import Model.Config exposing (..)
import Utils.Geometry exposing (..)
import Utils.Physics exposing (getMove, getWaveMove)
cloudUpdate : Float -> Vec2 -> Seed -> Player -> Cloud -> (Cloud, Int, Seed)
cloudUpdate time boardSize seed player {points, spawn, lastSpawn} =
let pointsToCatch = presentPoints time boardSize (points player.config)
presentAndNotCaughtPoints = List.filter (not << (playerPointCollision time player)) pointsToCatch
addScore = (List.length pointsToCatch) - (List.length presentAndNotCaughtPoints)
presentOtherPoints = presentPoints time boardSize (points (otherConfig player.config))
(newCloud, seed') =
if time > lastSpawn + spawn then
let (newPoint1, seed') = getNewPoint time boardSize seed
(newPoint2, seed'') = getNewPoint time boardSize 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 -> Vec2 -> List Point -> List Point
presentPoints time boardSize points =
let isPresent point = (distance (pointMove point time) originVec) < (pointAwayDist boardSize)
in List.filter isPresent points
getNewPoint : Float -> Vec2 -> Seed -> (Point, Seed)
getNewPoint time boardSize seed =
let (initPos, seed') = pointInitPos boardSize seed
(initDest, seed'') = pointDestination boardSize seed'
in ( { initTime = time
, initPos = initPos
, initDest = initDest
, move initTime initPos initDest time =
let delta = time - initTime
move = getMove (pointSpeed delta) (initDest `sub` initPos)
in initPos `add` move
}
, seed''
)
pointInitPos : Vec2 -> Seed -> (Vec2, Seed)
pointInitPos boardSize seed =
let (rand, seed') = generate floatGen seed
angle = rand * (degrees 360)
dist = (boardDiagonal boardSize) * 3 / 5
in (polarToCartesian angle dist, seed')
pointDestination : Vec2 -> Seed -> (Vec2, Seed)
pointDestination boardSize seed =
let ([r1, r2, r3, r4], seed') = generateMany 4 floatGen seed
in ( randomBoardPosition boardSize (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 : Vec2 -> (Float, Float) -> (Float, Float) -> Vec2
randomBoardPosition boardSize (randomX, randomY) (percentX, percentY) =
let width = boardSize.x * percentX
height = boardSize.y * percentY
in { x = width * randomX - width / 2
, y = height * randomY - height / 2
}
|