From be0e07cace80b493a547c293b5e3f9c5bd745f9a Mon Sep 17 00:00:00 2001 From: Romans Potasovs Date: Tue, 28 Jan 2020 22:08:51 +0200 Subject: [PATCH 1/2] Add `delta` and `now` --- examples/clock.elm | 35 +++++++++++++++++++++++ src/Playground.elm | 71 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 examples/clock.elm diff --git a/examples/clock.elm b/examples/clock.elm new file mode 100644 index 0000000..e48d5f3 --- /dev/null +++ b/examples/clock.elm @@ -0,0 +1,35 @@ +import Playground exposing (..) + + +main = + animation view + + +view time = + let + h = + remainderBy (24 * 60 * 60) (now time // 1000) // (60 * 60) |> toFloat + + m = + remainderBy (60 * 60) (now time // 1000) // 60 |> toFloat + + s = + remainderBy 60 (now time // 1000) |> toFloat + in + [ [ rectangle red 10 250 |> moveY 125, triangle red 15 |> moveY 250 ] |> group |> rotate (-360 / 60 * s) + , [ rectangle blue 10 180 |> moveY 90, triangle blue 15 |> moveY 180 ] |> group |> rotate (-360 / 60 * m) + , [ rectangle yellow 10 120 |> moveY 60, triangle yellow 15 |> moveY 120 ] |> group |> rotate (-360 / 60 * h) + , circle brown 10 + ] + ++ (List.range 0 11 + |> List.map + (\i -> + [ words black (String.fromInt (12 - i)) + |> scale 3 + |> rotate (-360 / 12 * toFloat i) + |> moveY 250 + ] + |> group + |> rotate (360 / 12 * toFloat i) + ) + ) diff --git a/src/Playground.elm b/src/Playground.elm index d56a3d9..66d9f65 100644 --- a/src/Playground.elm +++ b/src/Playground.elm @@ -19,6 +19,8 @@ module Playground exposing , spin , wave , zigzag + , delta + , now -- , Computer , Mouse @@ -61,7 +63,7 @@ module Playground exposing @docs group # Time -@docs Time, spin, wave, zigzag +@docs Time, spin, wave, zigzag, delta, now # Computer @docs Computer, Mouse, Screen, Keyboard, toX, toY, toXY @@ -393,7 +395,7 @@ type alias Screen = Helpful when making an [`animation`](#animation) with functions like [`spin`](#spin), [`wave`](#wave), and [`zigzag`](#zigzag). -} -type Time = Time Time.Posix +type Time = Time Time.Posix Int {-| Create an angle that cycles from 0 to 360 degrees over time. @@ -462,13 +464,60 @@ zigzag lo hi period time = toFrac : Float -> Time -> Float -toFrac period (Time posix) = +toFrac period (Time posix _) = let ms = Time.posixToMillis posix p = period * 1000 in toFloat (modBy (round p) ms) / p +{-| Time in milliseconds since the previous frame. + +Here is an example of a green square that +just moves to the right precisely 1px per second, +independent from frame rate: + + import Playground exposing (..) + + main = + game view update 0 + + view computer offset = + [ square green 40 + |> moveRight offset + ] + + update computer offset = + offset + 1 * (delta computer.time) +-} +delta : Time -> Int +delta (Time _ d) = + d + + + +{-| Turn a `Time` time into the number of milliseconds since 1970 January 1 at 00:00:00 UTC. It was a Thursday. + +Here is example of text that shows current seconds: + + import Playground exposing (..) + + main = + animation view + + view time = + let + s = + remainderBy (now time // 1000) 60 + |> String.fromInt + in + words black s + + +-} +now : Time -> Int +now (Time posix _) = + Time.posixToMillis posix -- ANIMATION @@ -498,7 +547,7 @@ animation : (Time -> List Shape) -> Program () Animation Msg animation viewFrame = let init () = - ( Animation E.Visible (toScreen 600 600) (Time (Time.millisToPosix 0)) + ( Animation E.Visible (toScreen 600 600) (Time (Time.millisToPosix 0) 0) , Task.perform GotViewport Dom.getViewport ) @@ -542,9 +591,9 @@ animationSubscriptions = animationUpdate : Msg -> Animation -> Animation -animationUpdate msg (Animation v s t as state) = +animationUpdate msg (Animation v s ((Time _ d ) as t) as state) = case msg of - Tick posix -> Animation v s (Time posix) + Tick posix -> Animation v s (Time posix d) VisibilityChanged vis -> Animation vis s t GotViewport {viewport} -> Animation v (toScreen viewport.width viewport.height) t Resized w h -> Animation v (toScreen (toFloat w) (toFloat h)) t @@ -651,7 +700,7 @@ initialComputer = { mouse = Mouse 0 0 False False , keyboard = emptyKeyboard , screen = toScreen 600 600 - , time = Time (Time.millisToPosix 0) + , time = Time (Time.millisToPosix 0) 0 } @@ -697,10 +746,14 @@ gameUpdate : (Computer -> memory -> memory) -> Msg -> Game memory -> Game memory gameUpdate updateMemory msg (Game vis memory computer) = case msg of Tick time -> + let + (Time timeWas _) = computer.time + d = (Time.posixToMillis time) - (Time.posixToMillis timeWas) + in Game vis (updateMemory computer memory) <| if computer.mouse.click - then { computer | time = Time time, mouse = mouseClick False computer.mouse } - else { computer | time = Time time } + then { computer | time = Time time d, mouse = mouseClick False computer.mouse } + else { computer | time = Time time d } GotViewport {viewport} -> Game vis memory { computer | screen = toScreen viewport.width viewport.height } From c957c2362dc0331f74dceae49030d0b040dd9ec5 Mon Sep 17 00:00:00 2001 From: Romans Potasovs Date: Thu, 30 Jan 2020 11:27:26 +0200 Subject: [PATCH 2/2] Fix delta time save in animationUpdate --- src/Playground.elm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Playground.elm b/src/Playground.elm index 66d9f65..46ae21b 100644 --- a/src/Playground.elm +++ b/src/Playground.elm @@ -591,9 +591,9 @@ animationSubscriptions = animationUpdate : Msg -> Animation -> Animation -animationUpdate msg (Animation v s ((Time _ d ) as t) as state) = +animationUpdate msg (Animation v s ((Time timeWas _ ) as t) as state) = case msg of - Tick posix -> Animation v s (Time posix d) + Tick posix -> Animation v s (Time posix ((Time.posixToMillis posix) - (Time.posixToMillis timeWas))) VisibilityChanged vis -> Animation vis s t GotViewport {viewport} -> Animation v (toScreen viewport.width viewport.height) t Resized w h -> Animation v (toScreen (toFloat w) (toFloat h)) t