diff --git a/elm-package.json b/elm-package.json index d73f055..df7a3df 100644 --- a/elm-package.json +++ b/elm-package.json @@ -4,7 +4,8 @@ "repository": "https://github.com/user/project.git", "license": "BSD3", "source-directories": [ - "." + ".", + "./src" ], "exposed-modules": [], "dependencies": { diff --git a/main.elm b/main.elm index 6521f12..b0004dd 100644 --- a/main.elm +++ b/main.elm @@ -1,98 +1,18 @@ -import Html exposing (Html, h1, div, text) -import Time exposing (Time, inMilliseconds) -import Svg exposing (Svg, svg, g, path) -import Svg.Attributes exposing (stroke, fill, strokeLinejoin, strokeWidth, width, height, viewBox, d) -import Svg.Path exposing (pathToString, arcBy, subpath, closed, lineBy, startAt, antiClockwise, clockwise, largestArc) -import AnimationFrame exposing (times) +module Main exposing (..) +import Html +import Init.All +import Subscriptions exposing (subscriptions) +import Updates.All exposing (update) +import Views.Body exposing (view) +import Types exposing (Model, Msg) -mOVE_SPEED = 60 -- pixels per second -cHAR_RAD = 25 --half-width of character -wIDTH = "500" -hEIGHT = "900" main : Program Never Model Msg main = - Html.program - { init = init - , view = view - , update = update - , subscriptions = subscriptions - } - - --- MODEL - -type alias Model = - { time : Time } - -init : (Model, Cmd msg) -init = - ({ time = 0 } - ,Cmd.none - ) - --- UPDATE - -type Msg = Tick Time - -update : Msg -> Model -> (Model, Cmd Msg ) -update msg model = - case msg of - Tick newTime -> - ({ model | time = newTime }, Cmd.none) - --- SUBSCRIPTIONS - -subscriptions : Model -> Sub Msg -subscriptions model = - times Tick - --- VIEW - -type alias Point = (Float, Float) - -render : String -> String -> Model -> Html msg -render w h model = - let - -- Pull this out into a function to calculate a position in a range - -- based off of a cycle time and current number in the cycle. - cycleTime = 500 - maxOpen = 90 - currentCycleRatio = (model.time |> inMilliseconds |> round) % cycleTime - openness = (toFloat currentCycleRatio) / (cycleTime / (2 * maxOpen)) - maxOpen |> abs - in - svg - [ width w, height h, viewBox "0 0 500, 900"] - [pacman (250, 450) (degrees openness)] - -pacman : Point -> Float -> Svg msg -pacman position openness = - let - opp = cHAR_RAD * sin (openness/2) - adj = cHAR_RAD * cos (openness/2) - in - g [] - [ path - [ d <| - pathToString [(subpath (startAt position) closed - [lineBy (adj, opp) - ,arcBy (cHAR_RAD, cHAR_RAD) 0 (largestArc, clockwise) (0, -(opp * 2)) - ,lineBy (-adj, opp) - ] - )] - ,fill "#ffff00" - ] - [] - ] - - -view : Model -> Html Msg -view model = - div [] - [h1 [] [text "ElmMan!"] - ,render wIDTH hEIGHT model - ] - - - + Html.program + { init = ( Init.All.init, Cmd.none ) + , view = view + , update = update + , subscriptions = subscriptions + } diff --git a/src/AnimationHelpers.elm b/src/AnimationHelpers.elm new file mode 100644 index 0000000..d714984 --- /dev/null +++ b/src/AnimationHelpers.elm @@ -0,0 +1,15 @@ +module AnimationHelpers exposing (..) + +import Types exposing (Range) + + +calculateAnimation : Int -> Int -> Range -> Float +calculateAnimation current cycle range = + let + ( start, end ) = + range + + rangeDiff = + end - start + in + (toFloat (current % cycle)) / (toFloat (cycle)) * rangeDiff + start diff --git a/src/GLOBALS.elm b/src/GLOBALS.elm new file mode 100644 index 0000000..a54b603 --- /dev/null +++ b/src/GLOBALS.elm @@ -0,0 +1,13 @@ +module GLOBALS exposing (..) + + +move_speed = + 60 + + +character_radius = + 25 + + +playAreaSize = + ( "500", "900" ) diff --git a/src/Init/All.elm b/src/Init/All.elm new file mode 100644 index 0000000..fc0216a --- /dev/null +++ b/src/Init/All.elm @@ -0,0 +1,11 @@ +module Init.All exposing (..) + +import Types exposing (Model) +import Init.Player + + +init : Model +init = + { time = 0 + , player = Init.Player.init + } diff --git a/src/Init/Player.elm b/src/Init/Player.elm new file mode 100644 index 0000000..8dc3512 --- /dev/null +++ b/src/Init/Player.elm @@ -0,0 +1,10 @@ +module Init.Player exposing (..) + +import Types exposing (PlayerModel, Direction(Right)) + + +init : PlayerModel +init = + { direction = Right + , location = ( 250, 450 ) + } diff --git a/src/Subscriptions.elm b/src/Subscriptions.elm new file mode 100644 index 0000000..96b8d81 --- /dev/null +++ b/src/Subscriptions.elm @@ -0,0 +1,12 @@ +module Subscriptions exposing (..) + +import AnimationFrame exposing (times, diffs) +import Types exposing (Model, Msg(Tick, Tock)) + + +subscriptions : Model -> Sub Msg +subscriptions model = + Sub.batch + [ times Tick + , diffs Tock + ] diff --git a/src/Types.elm b/src/Types.elm new file mode 100644 index 0000000..bd75b22 --- /dev/null +++ b/src/Types.elm @@ -0,0 +1,31 @@ +module Types exposing (..) + +import Time exposing (Time) + + +type Direction + = Up + | Down + | Left + | Right + + +type alias Model = + { time : Time + , player : PlayerModel + } + + +type alias PlayerModel = + { direction : Direction + , location : ( Float, Float ) + } + + +type alias Range = + ( Float, Float ) + + +type Msg + = Tick Time + | Tock Time diff --git a/src/Updates/All.elm b/src/Updates/All.elm new file mode 100644 index 0000000..ee2921a --- /dev/null +++ b/src/Updates/All.elm @@ -0,0 +1,29 @@ +module Updates.All exposing (update) + +import Updates.Player +import Updates.Time +import Types exposing (Msg(Tick, Tock), Model) +import List +import Time exposing (Time) + + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + let + tuples = + { player = Updates.Player.update msg model.player + , time = Updates.Time.update msg model.time + } + + returnModel = + { player = Tuple.first tuples.player + , time = Tuple.first tuples.time + } + + commands = + Cmd.batch + [ Tuple.second tuples.player + , Tuple.second tuples.time + ] + in + ( returnModel, commands ) diff --git a/src/Updates/Player.elm b/src/Updates/Player.elm new file mode 100644 index 0000000..3b0c74f --- /dev/null +++ b/src/Updates/Player.elm @@ -0,0 +1,8 @@ +module Updates.Player exposing (update) + +import Types exposing (PlayerModel, Msg) + + +update : Msg -> PlayerModel -> ( PlayerModel, Cmd Msg ) +update msg model = + ( model, Cmd.none ) diff --git a/src/Updates/Time.elm b/src/Updates/Time.elm new file mode 100644 index 0000000..ef07cda --- /dev/null +++ b/src/Updates/Time.elm @@ -0,0 +1,14 @@ +module Updates.Time exposing (update) + +import Time exposing (Time) +import Types exposing (Msg(Tick, Tock)) + + +update : Msg -> Time -> ( Time, Cmd Msg ) +update msg model = + case msg of + Tick newTime -> + ( newTime, Cmd.none ) + + Tock timeDiff -> + ( model, Cmd.none ) diff --git a/src/Views/Body.elm b/src/Views/Body.elm new file mode 100644 index 0000000..a1d4e0b --- /dev/null +++ b/src/Views/Body.elm @@ -0,0 +1,18 @@ +module Views.Body exposing (..) + +import Html exposing (Html, h1, div, text) +import GLOBALS exposing (playAreaSize) +import Types exposing (Model, Range) +import Views.PlayArea + + +view : Model -> Html msg +view model = + let + ( width, height ) = + playAreaSize + in + div [] + [ h1 [] [ text "ElmMan!" ] + , Views.PlayArea.render width height model + ] diff --git a/src/Views/PlayArea.elm b/src/Views/PlayArea.elm new file mode 100644 index 0000000..69b07e4 --- /dev/null +++ b/src/Views/PlayArea.elm @@ -0,0 +1,14 @@ +module Views.PlayArea exposing (..) + +import Html exposing (Html) +import Svg exposing (svg) +import Svg.Attributes exposing (width, height, viewBox) +import Types exposing (Model) +import Views.Player + + +render : String -> String -> Model -> Html msg +render w h model = + svg + [ width w, height h, viewBox ("0 0 " ++ w ++ " " ++ h) ] + [ Views.Player.render model ] diff --git a/src/Views/Player.elm b/src/Views/Player.elm new file mode 100644 index 0000000..c8f7e48 --- /dev/null +++ b/src/Views/Player.elm @@ -0,0 +1,69 @@ +module Views.Player exposing (..) + +import Time exposing (Time, inMilliseconds) +import Svg exposing (Svg, g, path) +import Svg.Attributes + exposing + ( fill + , d + ) +import Svg.Path + exposing + ( Point + , pathToString + , arcBy + , subpath + , closed + , lineBy + , startAt + , clockwise + , largestArc + ) +import AnimationHelpers exposing (calculateAnimation) +import Types exposing (Model) +import GLOBALS exposing (character_radius) + + +render : Model -> Svg msg +render model = + let + cycleTime = + 500 + + maxOpen = + 90 + + openness = + calculateAnimation (model.time |> inMilliseconds |> round) cycleTime ( 0, maxOpen ) + in + pacman ( 250, 450 ) (degrees openness) + + +pacman : Point -> Float -> Svg msg +pacman position openness = + let + opp = + character_radius * sin (openness / 2) + + adj = + character_radius * cos (openness / 2) + + radiuses = + ( character_radius, character_radius ) + in + g [] + [ path + [ d <| + pathToString + [ (subpath (startAt position) + closed + [ lineBy ( adj, opp ) + , arcBy radiuses 0 ( largestArc, clockwise ) ( 0, -(opp * 2) ) + , lineBy ( -adj, opp ) + ] + ) + ] + , fill "#ffff00" + ] + [] + ]