aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2016-10-02 15:34:27 +0200
committerJoris2016-10-02 15:34:27 +0200
commit3a1cbfe23a3d06c3c30828c623a089868cff0670 (patch)
tree2c81f1f218f92656fdb2026ffedb423d9d06b76a
parentfbab0129f902bf2c3ef07c92deb7674384c18424 (diff)
Add saw-tooth move and multiple moves per level
-rw-r--r--elm-package.json3
-rw-r--r--src/Model/Color.elm22
-rw-r--r--src/Model/Level.elm105
-rw-r--r--src/Model/Player.elm2
-rw-r--r--src/Update/CloudUpdate.elm11
-rw-r--r--src/Utils/Color.elm23
-rw-r--r--src/Utils/Physics.elm24
-rw-r--r--src/View.elm9
8 files changed, 106 insertions, 93 deletions
diff --git a/elm-package.json b/elm-package.json
index 3552bc1..35c1e52 100644
--- a/elm-package.json
+++ b/elm-package.json
@@ -11,7 +11,8 @@
"elm-lang/html": "1.1.0 <= v < 2.0.0",
"elm-lang/svg": "1.1.1 <= v < 2.0.0",
"elm-lang/keyboard": "1.0.0 <= v < 2.0.0",
- "mgold/elm-random-pcg": "3.0.1 <= v < 4.0.0",
+ "mgold/elm-random-pcg": "3.0.4 <= v < 4.0.0",
+ "mgold/elm-nonempty-list": "2.0.1 <= v < 3.0.0",
"ohanhi/keyboard-extra": "1.1.0 <= v < 2.0.0"
}
}
diff --git a/src/Model/Color.elm b/src/Model/Color.elm
deleted file mode 100644
index 49ece2b..0000000
--- a/src/Model/Color.elm
+++ /dev/null
@@ -1,22 +0,0 @@
-module Model.Color exposing
- ( Color
- , htmlOutput
- , mergeColors
- )
-
-type alias Color =
- { red : Int
- , green : Int
- , blue : Int
- }
-
-htmlOutput : Color -> String
-htmlOutput color = "rgb(" ++ (toString color.red) ++ ", " ++ (toString color.green) ++ ", " ++ (toString color.blue) ++ ")"
-
-mergeColors : Float -> Color -> Color -> Color
-mergeColors ratio c1 c2 =
- let mergePart x y = truncate (ratio * (toFloat x) + (1 - ratio) * (toFloat y))
- in { red = mergePart c1.red c2.red
- , green = mergePart c1.green c2.green
- , blue = mergePart c1.blue c2.blue
- }
diff --git a/src/Model/Level.elm b/src/Model/Level.elm
index 9a60b9a..9daa60a 100644
--- a/src/Model/Level.elm
+++ b/src/Model/Level.elm
@@ -1,26 +1,27 @@
module Model.Level exposing
- ( currentLevel
+ ( levelScoreDuration
+ , currentLevel
, currentLevelScore
, currentLevelNumber
, progressiveColor
- , levelScoreDuration
)
import Time exposing (Time)
-import Debug
+import Color as Color exposing (Color)
+import List.Nonempty as NE exposing (Nonempty(..), (:::))
-import Model.Color exposing (..)
-import Model.Vec2 exposing (..)
-import Model.Point exposing (pointSpeed)
+import Model.Vec2 as Vec2 exposing (Vec2)
-import Utils.Physics exposing (getMove, getWaveMove)
+import Utils.Physics as Physics
+import Utils.Color as Color
levelScoreDuration : Int
levelScoreDuration = 20
+type alias Move = Vec2 -> Vec2 -> Time -> Vec2
+
type alias Level =
- { color : Color
- , move : Vec2 -> Vec2 -> Time -> Vec2
+ { moves : Nonempty Move
}
currentLevelScore : Int -> Int
@@ -28,17 +29,10 @@ currentLevelScore currentScore =
currentScore - (currentLevelNumber currentScore - 1) * levelScoreDuration
currentLevelNumber : Int -> Int
-currentLevelNumber currentScore =
- min
- (List.length levels + 1)
- (currentScore // levelScoreDuration + 1)
+currentLevelNumber currentScore = currentScore // levelScoreDuration + 1
currentLevel : Int -> Level
-currentLevel currentScore =
- levels
- |> List.drop (currentScore // levelScoreDuration)
- |> List.head
- |> Maybe.withDefault lastLevel
+currentLevel currentScore = NE.get (currentScore // levelScoreDuration) levels
nextLevel : Int -> Level
nextLevel currentScore = currentLevel (currentScore + levelScoreDuration)
@@ -47,50 +41,41 @@ progressiveColor : Int -> Color
progressiveColor currentScore =
let reminder = currentScore `rem` levelScoreDuration
ratio = progressiveRatio reminder levelScoreDuration
- currentColor = (currentLevel currentScore).color
- nextColor = (nextLevel currentScore).color
- in mergeColors ratio nextColor currentColor
+ currentColor = color currentScore
+ nextColor = color (currentScore + levelScoreDuration)
+ in Color.merge ratio nextColor currentColor
progressiveRatio : Int -> Int -> Float
progressiveRatio a b = (toFloat a ^ 7) / (toFloat b ^ 7)
--- Hue + 35 with gimp each time from the first color
-levels : List Level
-levels =
- [ { color = { red = 156, green = 168, blue = 233 }
- , move = \initPos initDest delta -> getMove (delta / 20) (initDest `sub` initPos)
- }
- , { color = { red = 190, green = 156, blue = 233 }
- , move = \initPos initDest delta -> getWaveMove (delta / 20) (initDest `sub` initPos) 10 10
- }
- , { color = { red = 233, green = 156, blue = 232 }
- , move = \initPos initDest delta -> getMove (delta / 18) (initDest `sub` initPos)
- }
- , { color = { red = 233, green = 156, blue = 187 }
- , move = \initPos initDest delta -> getWaveMove (delta / 18) (initDest `sub` initPos) 20 20
- }
- , { color = { red = 233, green = 171, blue = 156 }
- , move = \initPos initDest delta -> getMove (delta / 13) (initDest `sub` initPos)
- }
- , { color = { red = 233, green = 215, blue = 156 }
- , move = \initPos initDest delta -> getWaveMove (delta / 16) (initDest `sub` initPos) 10 50
- }
- , { color = { red = 206, green = 233, blue = 156 }
- , move = \initPos initDest delta -> getMove (delta / 11) (initDest `sub` initPos)
- }
- , { color = { red = 162, green = 233, blue = 156 }
- , move = \initPos initDest delta -> getWaveMove (delta / 14) (initDest `sub` initPos) 30 15
- }
- , { color = { red = 156, green = 233, blue = 196 }
- , move = \initPos initDest delta -> getMove (delta / 8) (initDest `sub` initPos)
- }
- , { color = { red = 156, green = 225, blue = 233 }
- , move = \initPos initDest delta -> getWaveMove (delta / 12) (initDest `sub` initPos) 30 30
- }
- ]
+initialColor : Color
+initialColor = Color.rgb 156 168 233
-lastLevel : Level
-lastLevel =
- { color = { red = 156, green = 225, blue = 233 }
- , move = \initPos initDest delta -> getWaveMove (delta / 5) (initDest `sub` initPos) 30 30
- }
+color : Int -> Color
+color score = Color.spin (toFloat <| 20 * (score // levelScoreDuration)) initialColor
+
+levels : Nonempty Level
+levels =
+ let ma1 = \initPos initDest delta -> Physics.getMove (delta / 20) (initDest `Vec2.sub` initPos)
+ ma2 = \initPos initDest delta -> Physics.getWaveMove (delta / 20) (initDest `Vec2.sub` initPos) 10 10
+ ma3 = \initPos initDest delta -> Physics.getSawToothMove (delta / 25) (initDest `Vec2.sub` initPos) 30 10
+ mb1 = \initPos initDest delta -> Physics.getMove (delta / 18) (initDest `Vec2.sub` initPos)
+ mb2 = \initPos initDest delta -> Physics.getWaveMove (delta / 18) (initDest `Vec2.sub` initPos) 20 20
+ mb3 = \initPos initDest delta -> Physics.getSawToothMove (delta / 20) (initDest `Vec2.sub` initPos) 30 15
+ mc1 = \initPos initDest delta -> Physics.getMove (delta / 13) (initDest `Vec2.sub` initPos)
+ mc2 = \initPos initDest delta -> Physics.getWaveMove (delta / 16) (initDest `Vec2.sub` initPos) 10 50
+ mc3 = \initPos initDest delta -> Physics.getSawToothMove (delta / 25) (initDest `Vec2.sub` initPos) 100 15
+ in Nonempty
+ { moves = NE.fromElement ma1 }
+ [ { moves = NE.fromElement ma2 }
+ , { moves = NE.fromElement ma3 }
+ , { moves = Nonempty ma1 [ ma2, ma3 ] }
+ , { moves = NE.fromElement mb1 }
+ , { moves = NE.fromElement mb2 }
+ , { moves = NE.fromElement mb3 }
+ , { moves = Nonempty mb1 [ mb2, mb3 ] }
+ , { moves = NE.fromElement mc1 }
+ , { moves = NE.fromElement mc2 }
+ , { moves = NE.fromElement mc3 }
+ , { moves = Nonempty mc1 [ mc2, mc3 ] }
+ ]
diff --git a/src/Model/Player.elm b/src/Model/Player.elm
index 37a1a7f..50efb4b 100644
--- a/src/Model/Player.elm
+++ b/src/Model/Player.elm
@@ -24,7 +24,7 @@ initPlayer =
getPlayerSize : Int -> Float
getPlayerSize score =
- (levelCurve Level.levelScoreDuration 15 (Level.currentLevelScore score)) + 15
+ 15 + (levelCurve Level.levelScoreDuration 15 (Level.currentLevelScore score))
levelCurve : Int -> Int -> Int -> Float
levelCurve maxAbs maxOrd x =
diff --git a/src/Update/CloudUpdate.elm b/src/Update/CloudUpdate.elm
index 559acc9..d8ccf36 100644
--- a/src/Update/CloudUpdate.elm
+++ b/src/Update/CloudUpdate.elm
@@ -3,6 +3,7 @@ module Update.CloudUpdate exposing
)
import List
+import List.Nonempty as NE exposing (Nonempty(..), (:::))
import Random.Pcg as Random exposing (Seed, Generator)
import Model.Vec2 exposing (..)
@@ -58,17 +59,23 @@ getNewPoint : Float -> Vec2 -> Seed -> Int -> (Point, Seed)
getNewPoint elapsedTime boardSize seed currentScore =
let (initPos, seed') = pointInitPos boardSize seed
(initDest, seed'') = pointDestination boardSize seed'
+ (randomMove, seed''') = Random.step (nonemptySample << .moves <| currentLevel currentScore) seed''
in ( { initTime = elapsedTime
, initPos = initPos
, initDest = initDest
, move = \initTime initPos initDest elapsedTime ->
let delta = elapsedTime - initTime
- move = (currentLevel currentScore).move initPos initDest delta
+ move = randomMove initPos initDest delta
in initPos `add` move
}
- , seed''
+ , seed'''
)
+nonemptySample : Nonempty a -> Random.Generator a
+nonemptySample nonempty =
+ Random.int 0 (NE.length nonempty - 1)
+ |> Random.map (\i -> NE.get i nonempty)
+
pointInitPos : Vec2 -> Seed -> (Vec2, Seed)
pointInitPos boardSize seed =
let (rand, seed') = Random.step (Random.float 0 1) seed
diff --git a/src/Utils/Color.elm b/src/Utils/Color.elm
new file mode 100644
index 0000000..f9e344f
--- /dev/null
+++ b/src/Utils/Color.elm
@@ -0,0 +1,23 @@
+module Utils.Color exposing
+ ( merge
+ , spin
+ )
+
+import Color as Color exposing (Color)
+
+merge : Float -> Color -> Color -> Color
+merge ratio c1 c2 =
+ let rgb1 = Color.toRgb c1
+ rgb2 = Color.toRgb c2
+ mergePartFloat x y = ratio * x + (1 - ratio) * y
+ mergePartInt x y = truncate <| ratio * (toFloat x) + (1 - ratio) * (toFloat y)
+ in Color.rgba
+ (mergePartInt rgb1.red rgb2.red)
+ (mergePartInt rgb1.green rgb2.green)
+ (mergePartInt rgb1.blue rgb2.blue)
+ (mergePartFloat rgb1.alpha rgb2.alpha)
+
+spin : Float -> Color -> Color
+spin d color =
+ let { hue, saturation, lightness, alpha } = Color.toHsl color
+ in Color.hsla (hue + degrees d) saturation lightness alpha
diff --git a/src/Utils/Physics.elm b/src/Utils/Physics.elm
index 5da3737..88a4434 100644
--- a/src/Utils/Physics.elm
+++ b/src/Utils/Physics.elm
@@ -2,6 +2,7 @@ module Utils.Physics exposing
( getNewPosAndSpeed
, getMove
, getWaveMove
+ , getSawToothMove
)
import Model.Vec2 exposing (..)
@@ -17,24 +18,37 @@ getNewPosAndSpeed dt dir computeSpeed (pos, speed) =
)
getMove : Float -> Vec2 -> Vec2
-getMove speed dir =
+getMove dist dir =
if (isNull dir)
then {x = 0, y = 0}
else
let angle = atan2 dir.y dir.x
- in { x = speed * cos angle
- , y = speed * sin angle
+ in { x = dist * cos angle
+ , y = dist * sin angle
}
getWaveMove : Float -> Vec2 -> Float -> Float -> Vec2
-getWaveMove speed dir amplitude period =
- let move = getMove speed dir
+getWaveMove dist dir amplitude period =
+ let move = getMove dist dir
perpendMove =
getMove
(amplitude * (sin ((norm move) / period)))
(clockwiseRotate90 move)
in move `add` perpendMove
+getSawToothMove : Float -> Vec2 -> Float -> Float -> Vec2
+getSawToothMove dist dir amplitude period =
+ let move = getMove dist dir
+ perpendMove =
+ getMove
+ ( let max = 1000 / period
+ middle = max / 2
+ modulo = toFloat <| round (norm move) % round max
+ in amplitude * (if modulo < middle then modulo else max - modulo) / middle
+ )
+ (clockwiseRotate90 move)
+ in move `add` perpendMove
+
getAcc : Vec2 -> Vec2 -> Vec2
getAcc move speed = (move `div` 300) `sub` (speed `div` 300)
diff --git a/src/View.elm b/src/View.elm
index 822c2d2..d6265f6 100644
--- a/src/View.elm
+++ b/src/View.elm
@@ -6,6 +6,7 @@ import Html exposing (Html)
import Svg exposing (..)
import Svg.Attributes exposing (..)
import List
+import Color as Color exposing (Color)
import Time exposing (Time)
@@ -16,7 +17,6 @@ import Model.Point exposing (..)
import Model.Config exposing (..)
import Model.Round exposing (..)
import Model.Level exposing (..)
-import Model.Color exposing (htmlOutput)
import View.Round exposing (roundView)
@@ -103,10 +103,15 @@ renderBoard currentScore =
[ y (toString headerHeight)
, width "100%"
, height "100%"
- , fill (htmlOutput (progressiveColor currentScore))
+ , fill (colorRgba (progressiveColor currentScore))
]
[]
+colorRgba : Color -> String
+colorRgba color =
+ let c = Color.toRgb color
+ in "rgba(" ++ (toString c.red) ++ ", " ++ (toString c.green) ++ ", " ++ (toString c.blue) ++ "," ++ (toString c.alpha) ++ ")"
+
renderPlayer : Vec2 -> Player -> Float -> Svg msg
renderPlayer boardSize player playerSize =
renderCircle boardSize player.pos playerSize (playerColor player.config)