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
|
module CloudStep where
import List
import Random (..)
import Vec2 (..)
import Geometry (..)
import Player (..)
import Board (boardSize, boardDiagonal)
import Point (..)
import Physics (getMove, getWaveMove)
import Cloud (..)
import Config (..)
cloudStep : Float -> Seed -> Player -> Cloud -> (Cloud, Int, Seed)
cloudStep 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
}
|