aboutsummaryrefslogtreecommitdiff
path: root/src/Update
diff options
context:
space:
mode:
Diffstat (limited to 'src/Update')
-rw-r--r--src/Update/CloudUpdate.elm106
-rw-r--r--src/Update/Update.elm54
2 files changed, 160 insertions, 0 deletions
diff --git a/src/Update/CloudUpdate.elm b/src/Update/CloudUpdate.elm
new file mode 100644
index 0000000..86f7e13
--- /dev/null
+++ b/src/Update/CloudUpdate.elm
@@ -0,0 +1,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
+ }
diff --git a/src/Update/Update.elm b/src/Update/Update.elm
new file mode 100644
index 0000000..0187dcf
--- /dev/null
+++ b/src/Update/Update.elm
@@ -0,0 +1,54 @@
+module Update.Update
+ ( update
+ ) where
+
+import List
+import Keyboard (KeyCode)
+import Char (fromCode, toCode)
+
+import Model.Player (..)
+import Model.Point (pointSpeed, pointMove, pointAwayDist)
+import Model.Vec2 (..)
+import Model.Config (otherConfig)
+import Model.Cloud (..)
+import Model.Game (..)
+
+import Utils.Geometry (..)
+import Utils.Physics (getNewPosAndSpeed)
+
+import Update.CloudUpdate (cloudUpdate)
+
+import Input (Input)
+
+update : Input -> Game -> Game
+update {dir, inputKeysDown, delta} {time, keysDown, score, player, cloud, bestScore, seed} =
+ let hostilePoints = cloud.points (otherConfig player.config)
+ in if(playerPointsCollision time player hostilePoints) then
+ let newBestScore = if(score > bestScore) then score else bestScore
+ in initialGame seed player.pos player.config newBestScore
+ else
+ let newTime = time + delta
+ newPlayer = playerStep delta dir (newKeyCode keysDown inputKeysDown) player
+ (newCloud, addScore, newSeed) = cloudUpdate time seed newPlayer cloud
+ in { time = newTime
+ , keysDown = inputKeysDown
+ , score = score + addScore
+ , player = newPlayer
+ , cloud = newCloud
+ , bestScore = bestScore
+ , seed = newSeed
+ }
+
+playerStep : Float -> Vec2 -> (KeyCode -> Bool) -> Player -> Player
+playerStep dt dir newKey player =
+ let (pos, speed) = getNewPosAndSpeed dt dir playerSpeed (player.pos, player.speed)
+ newConfig = if (newKey 69) then otherConfig player.config else player.config
+ in { pos = inBoard playerSize pos
+ , speed = speed
+ , config = newConfig
+ }
+
+newKeyCode : List KeyCode -> List KeyCode -> KeyCode -> Bool
+newKeyCode lastKeyCodes newKeyCodes keyCode =
+ let contains = not << List.isEmpty << List.filter (\kc -> kc == keyCode)
+ in not (contains lastKeyCodes) && (contains newKeyCodes)