diff options
Diffstat (limited to 'src/Update')
-rw-r--r-- | src/Update/CloudUpdate.elm | 106 | ||||
-rw-r--r-- | src/Update/Update.elm | 54 |
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) |