module View.Game ( gameView , render ) where import List import Graphics.Collage exposing (..) import Graphics.Element exposing (Element) import Color exposing (..) import Text exposing (..) import Text import Time exposing (Time) import Model.Vec2 exposing (Vec2) import Model.Player exposing (..) import Model.Game exposing (Game) import Model.Point exposing (..) import Model.Config exposing (..) import Model.Round exposing (..) import View.Round exposing (roundView) import Html exposing (Html) import Svg import Svg.Attributes gameView : Game -> Element gameView game = let pointsForm color = List.map (pointForm game.time (configColor color)) (game.cloud.points color) |> group forms = [ boardForm game.boardSize , playerForm game.player , pointsForm White , pointsForm Black , scoreForm game.boardSize game.time game.rounds game.currentScore ] in collage (truncate game.boardSize.x) (truncate game.boardSize.y) forms boardForm : Vec2 -> Form boardForm boardSize = filled boardColor (rect boardSize.x boardSize.y) boardColor : Color boardColor = rgb 103 123 244 playerForm : Player -> Form playerForm player = let playerColor = configColor player.config in circleForm player.pos playerSize playerColor pointForm : Float -> Color -> Point -> Form pointForm time color point = let pos = pointMove point time in circleForm pos pointSize color configColor : Config -> Color configColor config = case config of White -> rgb 240 240 240 Black -> rgb 14 17 33 circleForm : Vec2 -> Float -> Color -> Form circleForm pos size color = let outline = circle size |> filled outlineColor inside = circle (size - 1) |> filled color in group [outline, inside] |> move (pos.x, pos.y) outlineColor : Color outlineColor = rgb 34 34 34 scoreForm : Vec2 -> Time -> List Round -> Int -> Form scoreForm boardSize currentRoundTime rounds score = let scorePos = { x = 0.0 , y = boardSize.y / 2 - 35 } in if currentRoundTime < 5000 then case List.head rounds of Just round -> textForm scorePos (roundView round) Nothing -> textForm scorePos (toString score) else textForm scorePos (toString score) textForm : Vec2 -> String -> Form textForm pos content = let textElement = fromString content |> Text.height 24 |> typeface ["calibri", "arial"] |> Text.color textColor |> bold in textElement |> text |> move (pos.x, pos.y) textColor : Color textColor = rgb 14 17 33 render : Game -> Html render game = let renderPoints config = List.map (renderPoint game.time config) (game.cloud.points config) in Svg.svg [ Svg.Attributes.width ((toString game.boardSize.x) ++ "px") , Svg.Attributes.height ((toString game.boardSize.y) ++ "px") ] ( [ renderBoard , renderPlayer game.player ] ++ (renderPoints White) ++ (renderPoints Black) ++ [renderScore game.boardSize game.time game.rounds game.currentScore] ) renderBoard : Svg.Svg renderBoard = Svg.rect [ Svg.Attributes.width "100%" , Svg.Attributes.height "100%" , Svg.Attributes.fill "#677BF4" ] [] renderPlayer : Player -> Svg.Svg renderPlayer player = renderCircle player.pos playerSize (playerColor player.config) playerColor : Config -> String playerColor config = case config of White -> "#F0F0F0" Black -> "#0E1121" renderPoint : Float -> Config -> Point -> Svg.Svg renderPoint time config point = let pos = pointMove point time in renderCircle pos pointSize (playerColor config) pointColor : Config -> String pointColor config = case config of White -> "white" Black -> "black" renderCircle : Vec2 -> Float -> String -> Svg.Svg renderCircle pos size color = Svg.circle [ Svg.Attributes.cx (toString (pos.x + 250)) , Svg.Attributes.cy (toString (-1 * pos.y + 250)) , Svg.Attributes.r (toString size) , Svg.Attributes.fill color , Svg.Attributes.stroke "#222222" , Svg.Attributes.strokeWidth "1" ] [] renderScore : Vec2 -> Time -> List Round -> Int -> Svg.Svg renderScore boardSize currentRoundTime rounds score = let scorePos = { x = 0.0 , y = boardSize.y / 2 - 35 } in if currentRoundTime < 5000 then case List.head rounds of Just round -> renderText scorePos (roundView round) Nothing -> renderText scorePos (toString score) else renderText scorePos (toString score) renderText : Vec2 -> String -> Svg.Svg renderText pos content = Svg.text' [ Svg.Attributes.x (toString (250 + pos.x)) , Svg.Attributes.y (toString (-1 * pos.y + 250)) , Svg.Attributes.fontFamily "calibri" , Svg.Attributes.fontSize "24" , Svg.Attributes.color "#0E1121" , Svg.Attributes.fontWeight "bold" ] [ Svg.tspan [ Svg.Attributes.textAnchor "middle" ] [ Svg.text content ] ]