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 = getMove (pointSpeed delta) (initDest `sub` initPos) 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 }