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
107
108
109
110
|
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 Model.Level exposing (..)
import Utils.Geometry exposing (..)
cloudUpdate : Float -> Vec2 -> Seed -> Player -> Float -> Cloud -> Int -> (Cloud, Int, Seed)
cloudUpdate elapsedTime boardSize seed player playerSize {points, spawn, lastSpawn} currentScore =
let pointsToCatch = presentPoints elapsedTime boardSize (points player.config)
presentAndNotCaughtPoints = List.filter (not << (playerPointCollision elapsedTime player playerSize)) pointsToCatch
addScore = (List.length pointsToCatch) - (List.length presentAndNotCaughtPoints)
presentOtherPoints = presentPoints elapsedTime boardSize (points (otherConfig player.config))
(newCloud, seed') =
if elapsedTime > lastSpawn + spawn then
let (newPoint1, seed') = getNewPoint elapsedTime boardSize seed currentScore
(newPoint2, seed'') = getNewPoint elapsedTime boardSize seed' currentScore
in ( { points = \config ->
if(config == player.config)
then
newPoint1 :: presentAndNotCaughtPoints
else
newPoint2 :: presentOtherPoints
, spawn = spawn - sqrt(spawn) / 50
, lastSpawn = elapsedTime
}
, 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 elapsedTime boardSize points =
let isPresent point = (distance (pointMove point elapsedTime) originVec) < (pointAwayDist boardSize)
in List.filter isPresent points
getNewPoint : Float -> Vec2 -> Seed -> Int -> (Point, Seed)
getNewPoint elapsedTime boardSize seed currentScore =
let (initPos, seed') = pointInitPos boardSize seed
(initDest, seed'') = pointDestination boardSize seed'
in ( { initTime = elapsedTime
, initPos = initPos
, initDest = initDest
, move = \initTime initPos initDest elapsedTime ->
let delta = elapsedTime - initTime
move = (currentLevel currentScore).move initPos initDest delta
in initPos `add` move
}
, seed''
)
pointInitPos : Vec2 -> Seed -> (Vec2, Seed)
pointInitPos boardSize seed =
let (rand, seed') = generate floatGen seed
angle = rand * (degrees 360)
dist = pointSpawnDist boardSize
in (polarToCartesian angle dist, seed')
pointDestination : Vec2 -> Seed -> (Vec2, Seed)
pointDestination boardSize seed =
case generateMany 4 floatGen seed of
([r1, r2, r3, r4], seed') ->
( randomBoardPosition boardSize (r1, r2) (r3, r4)
, seed'
)
_ ->
( randomBoardPosition boardSize (0, 0) (0, 0)
, 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
}
|