From 25fd373278a78b276738d85121125ab4f831278a Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 14:42:04 +0200 Subject: [PATCH 01/37] delete whitespace --- src/Hexagon.elm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 33e0648..8268a28 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -9,7 +9,6 @@ import Color exposing (..) -- MODEL - type alias Player = { angle: Float } @@ -23,8 +22,6 @@ type alias Game = player : Player } - - (gameWidth, gameHeight) = (1024, 576) -- 16:9 (halfWidth, halfHeight) = (gameWidth/2, gameHeight/2) (iHalfWidth, iHalfHeight) = (gameWidth//2, gameHeight//2) @@ -42,7 +39,6 @@ defaultGame = -- UPDATE - updatePlayerAngle: Float -> Int -> Float updatePlayerAngle angle dir = let From 5977bf1cdb17a82c5ba29531c5686d478614502d Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 14:56:21 +0200 Subject: [PATCH 02/37] added State and progress --- src/Hexagon.elm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 8268a28..4ff4d90 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -6,8 +6,10 @@ import Window import Graphics.Collage exposing (..) import Graphics.Element exposing (..) import Color exposing (..) +import Debug -- MODEL +type State = NewGame | Play | GameOver type alias Player = { angle: Float } @@ -20,6 +22,8 @@ type alias Input = type alias Game = { player : Player + , state : State + , progress : Int } (gameWidth, gameHeight) = (1024, 576) -- 16:9 @@ -35,6 +39,8 @@ defaultGame : Game defaultGame = { player = Player (degrees 30) + , state = NewGame + , progress = 0 } -- UPDATE @@ -51,6 +57,20 @@ updatePlayerAngle angle dir = else newAngle +updateState: Input -> Game -> State +updateState input game = + case game.state of + NewGame -> Play + Play -> Play + GameOver -> NewGame + +updateProgress: Game -> Int +updateProgress {state,progress} = + case state of + NewGame -> 0 + Play -> progress + 1 + _ -> progress + updatePlayer: Input -> Game -> Player updatePlayer {dir} {player} = let @@ -64,6 +84,8 @@ update (timestamp, input) game = { game | player = updatePlayer input game + , state = updateState input game + , progress = Debug.watch "progress" (updateProgress game) } -- VIEW From 0c0950ad1426369a3ca5c363c4620736d4c6662d Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 14:56:59 +0200 Subject: [PATCH 03/37] add state debug --- src/Hexagon.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 4ff4d90..4222a01 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -84,7 +84,7 @@ update (timestamp, input) game = { game | player = updatePlayer input game - , state = updateState input game + , state = Debug.watch "state" (updateState input game) , progress = Debug.watch "progress" (updateProgress game) } From 5f39e70a0aaa5516bfcfd1dfc230e0f1c33f3998 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 15:09:58 +0200 Subject: [PATCH 04/37] background autorotates --- src/Hexagon.elm | 97 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 4222a01..0b5fc3b 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -1,5 +1,6 @@ module Game where -import Time exposing ( .. ) +import Time exposing (..) +import List exposing (..) import AnimationFrame import Keyboard import Window @@ -24,6 +25,14 @@ type alias Game = player : Player , state : State , progress : Int + , autoRotateAngle : Float + , autoRotateSpeed : Float + } + +type alias Colors = + { dark : Color + , medium: Color + , bright : Color } (gameWidth, gameHeight) = (1024, 576) -- 16:9 @@ -41,6 +50,8 @@ defaultGame = player = Player (degrees 30) , state = NewGame , progress = 0 + , autoRotateAngle = 0.0 + , autoRotateSpeed = 0.0 } -- UPDATE @@ -71,6 +82,16 @@ updateProgress {state,progress} = Play -> progress + 1 _ -> progress +updateAutoRotateAngle: Game -> Float +updateAutoRotateAngle {autoRotateAngle, autoRotateSpeed} = + autoRotateAngle + autoRotateSpeed + +updateAutoRotateSpeed: Game -> Float +updateAutoRotateSpeed {progress, autoRotateSpeed} = + 0.02 * sin (toFloat progress * 0.005 |> Debug.watch "φ") + |> Debug.watch "autoRotateSpeed" + + updatePlayer: Input -> Game -> Player updatePlayer {dir} {player} = let @@ -86,6 +107,8 @@ update (timestamp, input) game = player = updatePlayer input game , state = Debug.watch "state" (updateState input game) , progress = Debug.watch "progress" (updateProgress game) + , autoRotateAngle = updateAutoRotateAngle game + , autoRotateSpeed = updateAutoRotateSpeed game } -- VIEW @@ -108,14 +131,74 @@ makePlayer player = |> moveRadial angle (playerRadius - 10) |> rotate angle +hexagonElement: Int -> List((Float, Float)) +hexagonElement i = + let + radius = halfWidth * sqrt 2 + angle0 = 60 * i |> toFloat |> degrees + angle1 = 60 * (i+1) |> toFloat |> degrees + in + [(0.0, 0.0) + , (sin angle0 * radius, cos angle0 * radius) + , (sin angle1 * radius, cos angle1 * radius) + ] + +makeField: Colors -> Form +makeField colors = + let + color i = + if i % 2 == 0 then + colors.dark + else + colors.medium + poly i = + polygon (hexagonElement i) + |> filled (color i) + in + group (map poly [0..5]) + +-- the polygon in the center: this is just decoration, so it has no own state +makeCenterHole : Colors -> Game -> List Form +makeCenterHole colors game = + let + shape = ngon 6 60 + line = solid colors.bright + in + [ shape + |> filled colors.dark + |> rotate (degrees 90) + , shape + |> (outlined {line | width = 4.0}) + |> rotate (degrees 90) + ] + +makeColors : Int -> Colors +makeColors progress = + let + hue = degrees 0.1 * (toFloat <| progress % 3600) + in + { dark = (hsl hue 0.6 0.2) + , medium = (hsl hue 0.6 0.3) + , bright = (hsla hue 0.6 0.6 0.8) + } + view : (Int,Int) -> Game -> Element view (w, h) game = - container w h middle <| - collage gameWidth gameHeight - [ rect gameWidth gameHeight - |> filled bgBlack - , makePlayer game.player - ] + let + colors = makeColors game.progress + in + container w h middle <| + collage gameWidth gameHeight + [ rect gameWidth gameHeight + |> filled bgBlack + , group (append + [ makeField colors + , makePlayer game.player + ] + (makeCenterHole colors game) + ) + |> rotate game.autoRotateAngle + ] -- SIGNALS From ce9aed04590e1641a2f78dae92b297c7dea7d4cd Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 15:22:10 +0200 Subject: [PATCH 05/37] added enemies --- src/Hexagon.elm | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 0b5fc3b..888668f 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -15,14 +15,22 @@ type State = NewGame | Play | GameOver type alias Player = { angle: Float } +type alias Enemy = + { radius : Float + , parts : List(Bool) + } + type alias Input = { space : Bool , dir : Int } + type alias Game = { player : Player + , enemies: List(Enemy) + , enemySpeed: Float , state : State , progress : Int , autoRotateAngle : Float @@ -42,12 +50,16 @@ type alias Colors = playerRadius : Float playerRadius = gameWidth / 10.0 +enemyThickness = 30 + -- The global game state defaultGame : Game defaultGame = { player = Player (degrees 30) + , enemies = [] + , enemySpeed = 0.0 , state = NewGame , progress = 0 , autoRotateAngle = 0.0 @@ -99,12 +111,41 @@ updatePlayer {dir} {player} = in { player | angle = newAngle } +updateEnemies: Game -> List(Enemy) +updateEnemies game = + let + enemyDistance = 300 + partsFor index = + case index of + 0 -> [True, True, True, False, True, True] + 1 -> [True, True, True, False, True, True] + 2 -> [False, True, False, True, True, True] + 3 -> [False, True, True, True, True, True] + _ -> [True, False, True, True, True, True] + radiusFor index = + toFloat (enemyThickness + (iHalfWidth + round (( enemyDistance * (toFloat index)) - (toFloat game.progress) * game.enemySpeed)) % (enemyDistance * 5)) + in + [ + {parts = partsFor 0, radius = radiusFor 0} + , {parts = partsFor 1, radius = radiusFor 1} + , {parts = partsFor 2, radius = radiusFor 2} + , {parts = partsFor 3, radius = radiusFor 3} + , {parts = partsFor 4, radius = radiusFor 4} + ] + +updateEnemySpeed: Game -> Float +updateEnemySpeed game = + 2 + (toFloat game.progress)/1000 + + -- Game loop: Transition from one state to the next. update : (Time, Input) -> Game -> Game update (timestamp, input) game = { game | player = updatePlayer input game + , enemies = updateEnemies game + , enemySpeed = updateEnemySpeed game , state = Debug.watch "state" (updateState input game) , progress = Debug.watch "progress" (updateProgress game) , autoRotateAngle = updateAutoRotateAngle game @@ -131,6 +172,37 @@ makePlayer player = |> moveRadial angle (playerRadius - 10) |> rotate angle +trapezoid: Float -> Float -> Color -> Form +trapezoid base height color = + let + s = height/(tan <| degrees 60) + in + filled color <| polygon [ + (-base/2, 0), (base/2, 0), (base/2-s, height), (-base/2+s, height) + ] + + +makeEnemy : Color -> Enemy -> Form +makeEnemy color enemy = + let + base = 2.0 * (enemy.radius +enemyThickness) / (sqrt 3) + makeEnemyPart : Int -> Form + makeEnemyPart index = + trapezoid base enemyThickness color + |> rotate (degrees <| toFloat (90 + index * 60)) + |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius +enemyThickness) + + -- color = (hsl (radius/100) 1 0.5) + in + group + (indexedMap (,) enemy.parts |> filter snd |> map fst |> map makeEnemyPart) + +makeEnemies : Color -> List(Enemy) -> List(Form) +makeEnemies color enemys = + map (makeEnemy color) enemys + + + hexagonElement: Int -> List((Float, Float)) hexagonElement i = let @@ -194,6 +266,7 @@ view (w, h) game = , group (append [ makeField colors , makePlayer game.player + , group <| makeEnemies colors.bright game.enemies ] (makeCenterHole colors game) ) From 28a1b7e6e616ca3a9de5efbf6d20f44db2314853 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 15:24:41 +0200 Subject: [PATCH 06/37] added watch --- src/Hexagon.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 888668f..082f9f3 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -135,7 +135,7 @@ updateEnemies game = updateEnemySpeed: Game -> Float updateEnemySpeed game = - 2 + (toFloat game.progress)/1000 + Debug.watch "enemy speed" (2 + (toFloat game.progress)/1000) -- Game loop: Transition from one state to the next. From 6a32e3b331025a3da1a9cb323a2c6020959e299d Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 16:12:42 +0200 Subject: [PATCH 07/37] added times --- src/Hexagon.elm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 4222a01..da36afa 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -24,6 +24,8 @@ type alias Game = player : Player , state : State , progress : Int + , timeStart : Time + , timeRunning : Time } (gameWidth, gameHeight) = (1024, 576) -- 16:9 @@ -41,6 +43,8 @@ defaultGame = player = Player (degrees 30) , state = NewGame , progress = 0 + , timeStart = 0.0 + , timeRunning = 0.0 } -- UPDATE @@ -71,6 +75,13 @@ updateProgress {state,progress} = Play -> progress + 1 _ -> progress +updateTimeRunning: Time -> Game -> Time +updateTimeRunning timestamp game = + case game.state of + Play -> (timestamp - game.timeStart) + GameOver -> game.timeRunning + _ -> 0.0 + updatePlayer: Input -> Game -> Player updatePlayer {dir} {player} = let @@ -78,14 +89,16 @@ updatePlayer {dir} {player} = in { player | angle = newAngle } + -- Game loop: Transition from one state to the next. update : (Time, Input) -> Game -> Game update (timestamp, input) game = - { game | player = updatePlayer input game , state = Debug.watch "state" (updateState input game) , progress = Debug.watch "progress" (updateProgress game) + , timeStart = Debug.watch "timeStart" (if game.state == NewGame then timestamp else game.timeStart) + , timeRunning = Debug.watch "timeRunning" (updateTimeRunning timestamp game) } -- VIEW From 4b2b61510d836736aea016814a14562866dc28cd Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 16:36:50 +0200 Subject: [PATCH 08/37] update --- src/Hexagon.elm | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index da36afa..10184db 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -25,7 +25,8 @@ type alias Game = , state : State , progress : Int , timeStart : Time - , timeRunning : Time + , timeTick : Time + , msRunning : Float } (gameWidth, gameHeight) = (1024, 576) -- 16:9 @@ -44,7 +45,8 @@ defaultGame = , state = NewGame , progress = 0 , timeStart = 0.0 - , timeRunning = 0.0 + , timeTick = 0.0 + , msRunning = 0.0 } -- UPDATE @@ -75,12 +77,12 @@ updateProgress {state,progress} = Play -> progress + 1 _ -> progress -updateTimeRunning: Time -> Game -> Time -updateTimeRunning timestamp game = +updateMsRunning: Time -> Game -> Time +updateMsRunning timestamp game = case game.state of - Play -> (timestamp - game.timeStart) - GameOver -> game.timeRunning - _ -> 0.0 + Play -> game.msRunning + timestamp - game.timeTick + NewGame -> 0.0 + _ -> game.msRunning updatePlayer: Input -> Game -> Player updatePlayer {dir} {player} = @@ -98,7 +100,8 @@ update (timestamp, input) game = , state = Debug.watch "state" (updateState input game) , progress = Debug.watch "progress" (updateProgress game) , timeStart = Debug.watch "timeStart" (if game.state == NewGame then timestamp else game.timeStart) - , timeRunning = Debug.watch "timeRunning" (updateTimeRunning timestamp game) + , timeTick = timestamp + , msRunning = Debug.watch "msRunning" (updateMsRunning timestamp game) } -- VIEW From 9c602875a8040d8896c01e4334ff354cedbb724e Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 4 Jun 2016 16:45:36 +0200 Subject: [PATCH 09/37] removed --- src/Hexagon.elm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 0afadf5..941b429 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -56,7 +56,6 @@ defaultGame = , timeStart = 0.0 , timeTick = 0.0 , msRunning = 0.0 - , timeRunning = 0.0 , autoRotateAngle = 0.0 , autoRotateSpeed = 0.0 } From 3a366ba017490bc83157a5f739daa00d4567ba5c Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 17:55:49 +0200 Subject: [PATCH 10/37] wip --- elm-package.json | 34 ++++++----- package.json | 8 +-- src/Hexagon.elm | 146 ++++++++++++++++++++++++++++++----------------- 3 files changed, 116 insertions(+), 72 deletions(-) diff --git a/elm-package.json b/elm-package.json index c3c1aa6..5f36e8f 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,17 +1,21 @@ { - "version": "1.0.0", - "summary": "A functional reactive implementation of Terry Cavanagh's game Hexagon in Elm", - "repository": "https://github.com/sbaechler/polygon.git", - "license": "BSD3", - "source-directories": [ - "src", - "../elm-audio" - ], - "native-modules": true, - "exposed-modules": [], - "dependencies": { - "elm-lang/core": "3.0.0 <= v < 4.0.0", - "jwmerrill/elm-animation-frame": "1.0.5 <= v < 2.0.0" - }, - "elm-version": "0.16.0 <= v < 0.17.0" + "version": "1.0.0", + "summary": "A functional reactive implementation of Terry Cavanagh's game Hexagon in Elm", + "repository": "https://github.com/sbaechler/polygon.git", + "license": "All rights reserved", + "source-directories": [ + "src", + "lib/elm-audio/src" + ], + "exposed-modules": [], + "native-modules": true, + "dependencies": { + "elm-lang/animation-frame": "1.0.0 <= v < 2.0.0", + "elm-lang/core": "4.0.0 <= v < 5.0.0", + "elm-lang/html": "1.0.0 <= v < 2.0.0", + "elm-lang/window": "1.0.0 <= v < 2.0.0", + "evancz/elm-graphics": "1.0.0 <= v < 2.0.0", + "ohanhi/keyboard-extra": "1.0.1 <= v < 2.0.0" + }, + "elm-version": "0.17.0 <= v < 0.18.0" } diff --git a/package.json b/package.json index dca8aa2..c82682b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "private": true, "scripts": { - "build": "elm-make --yes src/Game.elm --output=./elm.js && cp index.template.html index.html", - "watch": "node watch.js", - "server": "python -m SimpleHTTPServer 5000" + "build": "elm-make src/Hexagon.elm --output=public/index.html", + "server": "elm-reactor", + "setup": "elm-package install && git submodule update --init" }, "dependencies": { - "watch": "^0.16.0" + "elm": "^0.17.0" } } diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 8268a28..877b02d 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -1,25 +1,30 @@ -module Game where -import Time exposing ( .. ) +import Time exposing (..) +import List exposing (..) import AnimationFrame -import Keyboard +import Keyboard.Extra as Keyboard import Window -import Graphics.Collage exposing (..) -import Graphics.Element exposing (..) +import Collage exposing (..) +import Element exposing (..) import Color exposing (..) - +import Html.App as App +import Html -- MODEL + + +type Msg + = Step Time + | KeyboardExtraMsg Keyboard.Msg + | Noop + type alias Player = { angle: Float } -type alias Input = - { space : Bool - , dir : Int - } - type alias Game = { player : Player + , direction : Int + , keyboardModel : Keyboard.Model } (gameWidth, gameHeight) = (1024, 576) -- 16:9 @@ -29,13 +34,6 @@ type alias Game = playerRadius : Float playerRadius = gameWidth / 10.0 --- The global game state - -defaultGame : Game -defaultGame = - { - player = Player (degrees 30) - } -- UPDATE @@ -51,20 +49,45 @@ updatePlayerAngle angle dir = else newAngle -updatePlayer: Input -> Game -> Player -updatePlayer {dir} {player} = +updatePlayer: Int -> Game -> Player +updatePlayer dir {player} = let newAngle = updatePlayerAngle player.angle dir in { player | angle = newAngle } --- Game loop: Transition from one state to the next. -update : (Time, Input) -> Game -> Game -update (timestamp, input) game = - - { game | - player = updatePlayer input game - } + +{-| Updates the game state on a keyboard command -} +onUserInput : Keyboard.Msg -> Game -> (Game, Cmd Msg) +onUserInput keyMsg game = + let + ( keyboardModel, keyboardCmd ) = + Keyboard.update keyMsg game.keyboardModel + in + ( { game | keyboardModel = keyboardModel + , direction = (Keyboard.arrows keyboardModel).x + } + , Cmd.map KeyboardExtraMsg keyboardCmd ) + +{-| Updates the game state on every frame -} +onFrame : Time -> Game -> (Game, Cmd Msg) +onFrame time game = + let + nextCmd = Cmd.none + in + ( { game | + player = updatePlayer game.direction game + }, nextCmd ) + + +{-| Game loop: Transition from one state to the next. -} +update : Msg -> Game -> (Game, Cmd Msg) +update msg game = + case msg of + KeyboardExtraMsg keyMsg -> onUserInput keyMsg game + Step time -> onFrame time game + _ -> (game, Cmd.none) + -- VIEW @@ -86,33 +109,50 @@ makePlayer player = |> moveRadial angle (playerRadius - 10) |> rotate angle -view : (Int,Int) -> Game -> Element -view (w, h) game = - container w h middle <| - collage gameWidth gameHeight - [ rect gameWidth gameHeight - |> filled bgBlack - , makePlayer game.player - ] +view : Game -> Html.Html Msg +view game = + let + bg = rect gameWidth gameHeight |> filled bgBlack + field = makePlayer game.player + in + toHtml <| + container gameWidth gameHeight middle <| + collage gameWidth gameHeight + [ bg + , field + ] + +-- SUBSCRIPTIONS + +subscriptions : Game -> Sub Msg +subscriptions game = + Sub.batch [ + AnimationFrame.times (\time -> Step time), + Sub.map KeyboardExtraMsg Keyboard.subscriptions + ] + + +--INIT + +init : (Game, Cmd Msg) +init = + let + ( keyboardModel, keyboardCmd ) = Keyboard.init + in + ( { player = Player (degrees 30) + , keyboardModel = keyboardModel + , direction = 0 + } + , Cmd.batch + [ Cmd.map KeyboardExtraMsg keyboardCmd + ] + ) --- SIGNALS -main : Signal Element main = - Signal.map2 view Window.dimensions gameState - -gameState : Signal Game -gameState = - Signal.foldp update defaultGame input - --- Creates an event stream from the keyboard inputs and is --- updated by AnimationFrame. -input : Signal (Time, Input) -input = - Signal.map2 Input - Keyboard.space - (Signal.map .x Keyboard.arrows) - -- only update on a new frame - |> Signal.sampleOn AnimationFrame.frame - |> Time.timestamp + App.program + { init = init + , update = update + , view = view + , subscriptions = subscriptions } From fa7f5d3d7d18f89989e02b0588bc0c90b0e0aea6 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 19:24:09 +0200 Subject: [PATCH 11/37] elm17 --- src/Hexagon.elm | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 90b3552..37e0a63 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -59,7 +59,9 @@ updatePlayerAngle angle dir = else newAngle - +isGameOver: Game -> Bool +isGameOver {player} = + False updateProgress: Game -> Int updateProgress {state,progress} = @@ -76,11 +78,15 @@ updateMsRunning timestamp game = _ -> game.msRunning updatePlayer: Int -> Game -> Player -updatePlayer dir {player} = - let - newAngle = updatePlayerAngle player.angle dir - in - { player | angle = newAngle } +updatePlayer dir {player, state} = + if state == Play then + let + newAngle = if state == NewGame then degrees 30 + else updatePlayerAngle player.angle dir + in + { player | angle = newAngle } + else + player {-| Updates the game state on a keyboard command -} onUserInput : Keyboard.Msg -> Game -> (Game, Cmd Msg) @@ -101,6 +107,7 @@ onUserInput keyMsg game = in ( { game | keyboardModel = keyboardModel , direction = (Keyboard.arrows keyboardModel).x + , state = nextState } , Cmd.map KeyboardExtraMsg keyboardCmd ) @@ -109,12 +116,18 @@ onFrame : Time -> Game -> (Game, Cmd Msg) onFrame time game = let nextCmd = Cmd.none + nextState = + case game.state of + Starting -> Pause + Resume -> Play + Play -> if isGameOver game then GameOver else Play + _ -> game.state in ( { game | player = updatePlayer game.direction game - , state = Debug.log "state" (updateState input game) + , state = Debug.log "state" nextState , progress = Debug.log "progress" (updateProgress game) - , timeStart = Debug.log "timeStart" (if game.state == NewGame then time else game.timeStart) + , timeStart = if game.state == NewGame then time else game.timeStart , timeTick = time , msRunning = Debug.log "msRunning" (updateMsRunning time game) }, nextCmd ) @@ -182,6 +195,11 @@ init = ( { player = Player (degrees 30) , keyboardModel = keyboardModel , direction = 0 + , state = Starting + , progress = 0 + , timeStart = 0.0 + , timeTick = 0.0 + , msRunning = 0.0 } , Cmd.batch [ Cmd.map KeyboardExtraMsg keyboardCmd From 3ed2c9cfc619f26057e9bf96ebdaf3191649d672 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 21:32:40 +0200 Subject: [PATCH 12/37] replaced direction with Direciton type --- src/Hexagon.elm | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 877b02d..4df191c 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -8,9 +8,8 @@ import Element exposing (..) import Color exposing (..) import Html.App as App import Html --- MODEL - +-- MODEL type Msg = Step Time @@ -20,10 +19,12 @@ type Msg type alias Player = { angle: Float } +type Direction = Left | Right | Still + type alias Game = { player : Player - , direction : Int + , direction : Direction , keyboardModel : Keyboard.Model } @@ -37,10 +38,14 @@ playerRadius = gameWidth / 10.0 -- UPDATE -updatePlayerAngle: Float -> Int -> Float +updatePlayerAngle: Float -> Direction -> Float updatePlayerAngle angle dir = let - newAngle = (angle + toFloat (-dir * 4) * 0.032) + sign = + if dir == Left then 1 + else if dir == Right then -1 + else 0 + newAngle = (angle + toFloat (sign * 4) * 0.032) in if newAngle < 0 then newAngle + 2 * pi @@ -49,7 +54,7 @@ updatePlayerAngle angle dir = else newAngle -updatePlayer: Int -> Game -> Player +updatePlayer: Direction -> Game -> Player updatePlayer dir {player} = let newAngle = updatePlayerAngle player.angle dir @@ -63,9 +68,13 @@ onUserInput keyMsg game = let ( keyboardModel, keyboardCmd ) = Keyboard.update keyMsg game.keyboardModel + direction = + if (Keyboard.arrows keyboardModel).x < 0 then Left + else if (Keyboard.arrows keyboardModel).x > 0 then Right + else Still in ( { game | keyboardModel = keyboardModel - , direction = (Keyboard.arrows keyboardModel).x + , direction = direction } , Cmd.map KeyboardExtraMsg keyboardCmd ) @@ -141,7 +150,7 @@ init = in ( { player = Player (degrees 30) , keyboardModel = keyboardModel - , direction = 0 + , direction = Still } , Cmd.batch [ Cmd.map KeyboardExtraMsg keyboardCmd From dd6b07a0b02375b64fb0df897fe5a98cdb0a177c Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 21:46:37 +0200 Subject: [PATCH 13/37] change position --- src/Hexagon.elm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 4df191c..2a95033 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -11,11 +11,6 @@ import Html -- MODEL -type Msg - = Step Time - | KeyboardExtraMsg Keyboard.Msg - | Noop - type alias Player = { angle: Float } @@ -28,6 +23,11 @@ type alias Game = , keyboardModel : Keyboard.Model } +type Msg + = Step Time + | KeyboardExtraMsg Keyboard.Msg + | Noop + (gameWidth, gameHeight) = (1024, 576) -- 16:9 (halfWidth, halfHeight) = (gameWidth/2, gameHeight/2) (iHalfWidth, iHalfHeight) = (gameWidth//2, gameHeight//2) From a831ef66c524b8967ac95e1ee11232debd7e7f83 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 22:14:20 +0200 Subject: [PATCH 14/37] removed Starging-state --- src/Hexagon.elm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 47e12a6..6535965 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -13,7 +13,7 @@ import Html -- MODEL -type State = NewGame | Play | GameOver | Starting | Pause | Resume +type State = NewGame | Play | GameOver | Pause | Resume -- MODEL @@ -111,7 +111,7 @@ onUserInput keyMsg game = else Still nextState = case game.state of - NewGame -> if spacebar then Starting else NewGame + NewGame -> if spacebar then Play else NewGame Play -> if spacebar then Pause else Play GameOver -> if spacebar then NewGame else GameOver Pause -> if spacebar then Resume else Pause @@ -130,7 +130,7 @@ onFrame time game = nextCmd = Cmd.none nextState = case game.state of - Starting -> Pause + NewGame -> NewGame Resume -> Play Play -> if isGameOver game then GameOver else Play _ -> game.state @@ -207,7 +207,7 @@ init = ( { player = Player (degrees 30) , keyboardModel = keyboardModel , direction = Still - , state = Starting + , state = NewGame , progress = 0 , timeStart = 0.0 , timeTick = 0.0 From 742108c2ea435e759c6ff21973aa100f7265da27 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 22:38:23 +0200 Subject: [PATCH 15/37] remove extranous type --- src/Hexagon.elm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 0874724..45f6253 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -35,7 +35,6 @@ type alias Game = , msRunning : Float , autoRotateAngle : Float , autoRotateSpeed : Float - , keyboardModel : Keyboard.Model } type alias Colors = From 671e4e4b803c8c6abfe813a66fe889fc98d27924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sat, 18 Jun 2016 22:57:12 +0200 Subject: [PATCH 16/37] cleanup --- src/Hexagon.elm | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 2a95033..7d45a2c 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -17,7 +17,7 @@ type alias Player = type Direction = Left | Right | Still type alias Game = - { + { player : Player , direction : Direction , keyboardModel : Keyboard.Model @@ -26,7 +26,7 @@ type alias Game = type Msg = Step Time | KeyboardExtraMsg Keyboard.Msg - | Noop + (gameWidth, gameHeight) = (1024, 576) -- 16:9 (halfWidth, halfHeight) = (gameWidth/2, gameHeight/2) @@ -41,7 +41,7 @@ playerRadius = gameWidth / 10.0 updatePlayerAngle: Float -> Direction -> Float updatePlayerAngle angle dir = let - sign = + sign = if dir == Left then 1 else if dir == Right then -1 else 0 @@ -68,7 +68,7 @@ onUserInput keyMsg game = let ( keyboardModel, keyboardCmd ) = Keyboard.update keyMsg game.keyboardModel - direction = + direction = if (Keyboard.arrows keyboardModel).x < 0 then Left else if (Keyboard.arrows keyboardModel).x > 0 then Right else Still @@ -95,7 +95,6 @@ update msg game = case msg of KeyboardExtraMsg keyMsg -> onUserInput keyMsg game Step time -> onFrame time game - _ -> (game, Cmd.none) -- VIEW @@ -110,7 +109,7 @@ moveRadial angle radius = makePlayer : Player -> Form makePlayer player = - let + let angle = player.angle - degrees 30 in ngon 3 10 @@ -152,9 +151,7 @@ init = , keyboardModel = keyboardModel , direction = Still } - , Cmd.batch - [ Cmd.map KeyboardExtraMsg keyboardCmd - ] + , Cmd.map KeyboardExtraMsg keyboardCmd ) From ddf9204b13b043b7919e75c2e7183171daf835ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sat, 18 Jun 2016 23:10:57 +0200 Subject: [PATCH 17/37] remove unused resume state --- src/Hexagon.elm | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 0b35598..4513582 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -13,7 +13,7 @@ import Html -- MODEL -type State = NewGame | Play | GameOver | Pause | Resume +type State = NewGame | Play | GameOver | Pause -- MODEL @@ -23,7 +23,7 @@ type alias Player = type Direction = Left | Right | Still -type alias Enemy = +type alias Enemy = { radius : Float , parts : List(Bool) } @@ -125,14 +125,14 @@ updateEnemies: Game -> List(Enemy) updateEnemies game = let enemyDistance = 300 - partsFor index = + partsFor index = case index of 0 -> [True, True, True, False, True, True] 1 -> [True, True, True, False, True, True] 2 -> [False, True, False, True, True, True] 3 -> [False, True, True, True, True, True] _ -> [True, False, True, True, True, True] - radiusFor index = + radiusFor index = toFloat (enemyThickness + (iHalfWidth + round (( enemyDistance * (toFloat index)) - (toFloat game.progress) * game.enemySpeed)) % (enemyDistance * 5)) in [ @@ -144,7 +144,7 @@ updateEnemies game = ] updateEnemySpeed: Game -> Float -updateEnemySpeed game = +updateEnemySpeed game = Debug.log "enemy speed" (2 + (toFloat game.progress)/1000) {-| Updates the game state on a keyboard command -} @@ -165,8 +165,7 @@ onUserInput keyMsg game = NewGame -> if spacebar then Play else NewGame Play -> if spacebar then Pause else Play GameOver -> if spacebar then NewGame else GameOver - Pause -> if spacebar then Resume else Pause - _ -> game.state + Pause -> if spacebar then Play else Pause in ( { game | keyboardModel = keyboardModel , direction = direction @@ -182,7 +181,6 @@ onFrame time game = nextState = case game.state of NewGame -> NewGame - Resume -> Play Play -> if isGameOver game then GameOver else Play _ -> game.state in @@ -244,9 +242,9 @@ makeEnemy color enemy = let base = 2.0 * (enemy.radius +enemyThickness) / (sqrt 3) makeEnemyPart : Int -> Form - makeEnemyPart index = - trapezoid base enemyThickness color - |> rotate (degrees <| toFloat (90 + index * 60)) + makeEnemyPart index = + trapezoid base enemyThickness color + |> rotate (degrees <| toFloat (90 + index * 60)) |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius +enemyThickness) -- color = (hsl (radius/100) 1 0.5) @@ -256,7 +254,7 @@ makeEnemy color enemy = makeEnemies : Color -> List(Enemy) -> List(Form) makeEnemies color enemys = - map (makeEnemy color) enemys + map (makeEnemy color) enemys @@ -319,7 +317,7 @@ view game = field = append [ makeField colors , makePlayer game.player - , group <| makeEnemies colors.bright game.enemies + , group <| makeEnemies colors.bright game.enemies ] (makeCenterHole colors game) |> group From fd7215361ccc8060cb90910ba02f34862320a5f9 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 18 Jun 2016 23:18:19 +0200 Subject: [PATCH 18/37] refactor enemies --- src/Hexagon.elm | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index ca4f922..1a88720 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -125,23 +125,28 @@ updateEnemies: Game -> List(Enemy) updateEnemies game = let enemyDistance = 300 - partsFor index = - case index of - 0 -> [True, True, True, False, True, True] - 1 -> [True, True, True, False, True, True] - 2 -> [False, True, False, True, True, True] - 3 -> [False, True, True, True, True, True] - _ -> [True, False, True, True, True, True] + enemies = + [ [False, True, False, True, False, True] + , [True, True, True, False, True, True] + , [False, True, False, True, True, True] + , [False, True, True, True, True, True] + , [True, False, True, True, True, True] + , [True, False, True, True, True, False] + , [False, False, False, True, True, True] + , [False, True, True, True, True, True] + ] + numEnemies = List.length enemies + maxDistance = numEnemies * enemyDistance + enemyProgress = (toFloat game.progress) * game.enemySpeed radiusFor index = - toFloat (enemyThickness + (iHalfWidth + round (( enemyDistance * (toFloat index)) - (toFloat game.progress) * game.enemySpeed)) % (enemyDistance * 5)) + enemyThickness + (iHalfWidth + round ( enemyDistance * (toFloat index) - enemyProgress)) % maxDistance + |> toFloat in - [ - {parts = partsFor 0, radius = radiusFor 0} - , {parts = partsFor 1, radius = radiusFor 1} - , {parts = partsFor 2, radius = radiusFor 2} - , {parts = partsFor 3, radius = radiusFor 3} - , {parts = partsFor 4, radius = radiusFor 4} - ] + List.indexedMap (\index parts -> { + parts = parts, + radius = radiusFor index + }) enemies + updateEnemySpeed: Game -> Float updateEnemySpeed game = From 5cf69e8c0a8846b69df116d4cd88b189f5dda91f Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Jun 2016 21:59:40 +0200 Subject: [PATCH 19/37] refactor --- src/Hexagon.elm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 1bb4bb8..5e29d50 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -138,8 +138,10 @@ updateEnemies game = numEnemies = List.length enemies maxDistance = numEnemies * enemyDistance enemyProgress = (toFloat game.progress) * game.enemySpeed + offsetForEnemy index = + round <| enemyDistance * (toFloat index) - enemyProgress radiusFor index = - enemyThickness + (iHalfWidth + round ( enemyDistance * (toFloat index) - enemyProgress)) % maxDistance + enemyThickness + (iHalfWidth + offsetForEnemy index) % maxDistance |> toFloat in List.indexedMap (\index parts -> { From 52d10a3975befc0af42a49d8b77dc87b8727e765 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Jun 2016 22:00:53 +0200 Subject: [PATCH 20/37] removed progress --- src/Hexagon.elm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 7680558..8bdce6c 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -29,7 +29,6 @@ type alias Game = , direction : Direction , keyboardModel : Keyboard.Model , state : State - , progress : Int , timeStart : Time , timeTick : Time , msRunning : Float @@ -82,12 +81,6 @@ isGameOver: Game -> Bool isGameOver {player} = False -updateProgress: Game -> Int -updateProgress {state,progress} = - case state of - NewGame -> 0 - Play -> progress + 1 - _ -> progress updateMsRunning: Time -> Game -> Time updateMsRunning timestamp game = @@ -138,7 +131,6 @@ onFrame time game = ( { game | player = updatePlayer game.direction game , state = Debug.log "state" nextState - , progress = Debug.log "progress" (updateProgress game) , timeStart = if game.state == NewGame then time else game.timeStart , timeTick = time , msRunning = Debug.log "msRunning" (updateMsRunning time game) @@ -207,7 +199,6 @@ init = , keyboardModel = keyboardModel , direction = Still , state = NewGame - , progress = 0 , timeStart = 0.0 , timeTick = 0.0 , msRunning = 0.0 From 6ace3235c9deac9d9026f77acd88230ea1bcc167 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Jun 2016 22:09:41 +0200 Subject: [PATCH 21/37] remove progress --- src/Hexagon.elm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 71e1b2d..73224cf 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -102,8 +102,8 @@ updateAutoRotateAngle {autoRotateAngle, autoRotateSpeed} = autoRotateAngle + autoRotateSpeed updateAutoRotateSpeed: Game -> Float -updateAutoRotateSpeed {progress, autoRotateSpeed} = - 0.02 * sin (toFloat progress * 0.005 |> Debug.log "φ") +updateAutoRotateSpeed {msRunning, autoRotateSpeed} = + 0.02 * sin (msRunning * 0.0003 |> Debug.log "φ") |> Debug.log "autoRotateSpeed" @@ -226,10 +226,10 @@ makeCenterHole colors game = |> rotate (degrees 90) ] -makeColors : Int -> Colors -makeColors progress = +makeColors : Float -> Colors +makeColors msRunning = let - hue = degrees 0.1 * (toFloat <| progress % 3600) + hue = degrees 0.01 * (toFloat <| round msRunning % 36000) in { dark = (hsl hue 0.6 0.2) , medium = (hsl hue 0.6 0.3) @@ -240,7 +240,7 @@ view : Game -> Html.Html Msg view game = let bg = rect gameWidth gameHeight |> filled bgBlack - colors = makeColors game.progress + colors = makeColors game.msRunning field = append [ makeField colors , makePlayer game.player From f33d3a405ff1181b0adadc1f5a6dcdb24712caec Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Jun 2016 23:33:26 +0200 Subject: [PATCH 22/37] refactor --- src/Hexagon.elm | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 255ecf1..59d0647 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -62,6 +62,18 @@ playerRadius : Float playerRadius = gameWidth / 10.0 enemyThickness = 30 +enemyDistance = 300 + +enemies = + [ [False, True, False, True, False, True] + , [True, True, True, False, True, True] + , [False, True, False, True, True, True] + , [False, True, True, True, True, True] + , [True, False, True, True, True, True] + , [True, False, True, True, True, False] + , [False, False, False, True, True, True] + , [False, True, True, True, True, True] + ] -- UPDATE @@ -114,34 +126,26 @@ updateAutoRotateSpeed {msRunning, autoRotateSpeed} = 0.02 * sin (msRunning * 0.0003 |> Debug.log "φ") |> Debug.log "autoRotateSpeed" + updateEnemies: Game -> List(Enemy) updateEnemies game = let - enemyDistance = 300 - enemies = - [ [False, True, False, True, False, True] - , [True, True, True, False, True, True] - , [False, True, False, True, True, True] - , [False, True, True, True, True, True] - , [True, False, True, True, True, True] - , [True, False, True, True, True, False] - , [False, False, False, True, True, True] - , [False, True, True, True, True, True] - ] + enemyProgress = game.msRunning * game.enemySpeed numEnemies = List.length enemies maxDistance = numEnemies * enemyDistance - enemyProgress = game.msRunning * game.enemySpeed + offsetForEnemy index = round <| enemyDistance * (toFloat index) - enemyProgress + radiusFor index = - enemyThickness + (iHalfWidth + offsetForEnemy index) % maxDistance + (offsetForEnemy index) % maxDistance |> toFloat in List.indexedMap (\index parts -> { parts = parts, radius = radiusFor index }) enemies - + updateEnemySpeed: Game -> Float updateEnemySpeed game = From b7c8c1b75c951d7e766d53f14266d25f2d41a143 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 22 Jun 2016 23:42:09 +0200 Subject: [PATCH 23/37] changed enemies --- src/Hexagon.elm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 59d0647..5a1a26c 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -62,17 +62,17 @@ playerRadius : Float playerRadius = gameWidth / 10.0 enemyThickness = 30 -enemyDistance = 300 +enemyDistance = 350 enemies = [ [False, True, False, True, False, True] - , [True, True, True, False, True, True] - , [False, True, False, True, True, True] , [False, True, True, True, True, True] , [True, False, True, True, True, True] - , [True, False, True, True, True, False] - , [False, False, False, True, True, True] - , [False, True, True, True, True, True] + , [True, True, True, True, False, True] + , [True, True, True, False, True, True] + , [False, True, False, True, False, True] + , [True, False, True, False, True, False] + , [True, True, True, True, True, False] ] From d4c29b21332f70352422ba615317cbd3a3d47819 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 23 Jun 2016 00:07:23 +0200 Subject: [PATCH 24/37] remove resume --- src/Hexagon.elm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 6535965..1ea560a 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -13,7 +13,7 @@ import Html -- MODEL -type State = NewGame | Play | GameOver | Pause | Resume +type State = NewGame | Play | GameOver | Pause -- MODEL @@ -114,8 +114,7 @@ onUserInput keyMsg game = NewGame -> if spacebar then Play else NewGame Play -> if spacebar then Pause else Play GameOver -> if spacebar then NewGame else GameOver - Pause -> if spacebar then Resume else Pause - _ -> game.state + Pause -> if spacebar then Play else Pause in ( { game | keyboardModel = keyboardModel , direction = direction @@ -131,7 +130,6 @@ onFrame time game = nextState = case game.state of NewGame -> NewGame - Resume -> Play Play -> if isGameOver game then GameOver else Play _ -> game.state in From 5a4a6df4be40621b9d4f6d003f3c293789391d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Thu, 23 Jun 2016 15:59:32 +0200 Subject: [PATCH 25/37] move bgBlack definition to Model section --- .editorconfig | 1 + src/Hexagon.elm | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index 3b281f2..7d370f6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,3 +9,4 @@ end_of_line = lf insert_final_newline = true indent_style = space indent_size = 2 +max_line_length = 80 diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 7d45a2c..51642a6 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -35,6 +35,10 @@ type Msg playerRadius : Float playerRadius = gameWidth / 10.0 +bgBlack : Color +bgBlack = + rgb 20 20 20 + -- UPDATE @@ -99,10 +103,6 @@ update msg game = -- VIEW -bgBlack : Color -bgBlack = - rgb 20 20 20 - moveRadial : Float -> Float -> Form -> Form moveRadial angle radius = move (radius * cos angle, radius * sin angle) From 35a7ebdb0b96f255f2ed7c19c9417243dfc564b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Thu, 23 Jun 2016 16:10:12 +0200 Subject: [PATCH 26/37] use constant for player speed --- src/Hexagon.elm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 51642a6..f98b9d1 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -35,6 +35,9 @@ type Msg playerRadius : Float playerRadius = gameWidth / 10.0 +playerSpeed : Float +playerSpeed = 0.12 + bgBlack : Color bgBlack = rgb 20 20 20 @@ -49,7 +52,7 @@ updatePlayerAngle angle dir = if dir == Left then 1 else if dir == Right then -1 else 0 - newAngle = (angle + toFloat (sign * 4) * 0.032) + newAngle = angle + toFloat sign * playerSpeed in if newAngle < 0 then newAngle + 2 * pi From a46d164ddeb724e5afbd8dadfbb15334ffdd8edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Thu, 23 Jun 2016 16:21:33 +0200 Subject: [PATCH 27/37] simplify hue value --- src/Hexagon.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index ec874fd..6bcf87b 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -230,7 +230,7 @@ makeCenterHole colors game = makeColors : Float -> Colors makeColors msRunning = let - hue = degrees 0.01 * (toFloat <| round msRunning % 36000) + hue = 0.00005 * msRunning in { dark = (hsl hue 0.6 0.2) , medium = (hsl hue 0.6 0.3) From 3a07708bf9ac94766c6376a61999c969dee5915e Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 25 Jun 2016 17:11:38 +0200 Subject: [PATCH 28/37] removed --- src/Hexagon.elm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 5a1a26c..f021fe3 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -249,8 +249,7 @@ makeEnemy color enemy = trapezoid base enemyThickness color |> rotate (degrees <| toFloat (90 + index * 60)) |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius +enemyThickness) - - -- color = (hsl (radius/100) 1 0.5) + in group (indexedMap (,) enemy.parts |> filter snd |> map fst |> map makeEnemyPart) From 4507fad98b0d87aecfaa9a350854933599378b13 Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 26 Jun 2016 16:33:45 +0200 Subject: [PATCH 29/37] add player size --- src/Hexagon.elm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index f98b9d1..65d9c07 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -34,10 +34,10 @@ type Msg playerRadius : Float playerRadius = gameWidth / 10.0 - +playerSize: Float +playerSize = 10.0 playerSpeed : Float playerSpeed = 0.12 - bgBlack : Color bgBlack = rgb 20 20 20 @@ -115,9 +115,9 @@ makePlayer player = let angle = player.angle - degrees 30 in - ngon 3 10 + ngon 3 playerSize |> filled (hsl angle 1 0.5) - |> moveRadial angle (playerRadius - 10) + |> moveRadial angle (playerRadius - playerSize) |> rotate angle view : Game -> Html.Html Msg From ede4295820b12e5ef04ad745902c2654b3726f97 Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 26 Jun 2016 16:46:35 +0200 Subject: [PATCH 30/37] removed line --- src/Hexagon.elm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 0d9edbb..653998c 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -81,7 +81,6 @@ enemies = , [True, True, True, True, True, False] ] - bgBlack : Color bgBlack = rgb 20 20 20 From c683d519cd0ca239f0242e505c2380415b03bb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sun, 26 Jun 2016 21:03:45 +0200 Subject: [PATCH 31/37] Remove empty line --- src/Hexagon.elm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 653998c..a007bf0 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -255,8 +255,7 @@ makeEnemy color enemy = makeEnemyPart index = trapezoid base enemyThickness color |> rotate (degrees <| toFloat (90 + index * 60)) - |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius +enemyThickness) - + |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius + enemyThickness) in group (indexedMap (,) enemy.parts |> filter snd |> map fst |> map makeEnemyPart) From 983b706a3be83a5f817875646a2891c93745693b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sun, 26 Jun 2016 21:06:24 +0200 Subject: [PATCH 32/37] Add another line to keep the numbers --- src/Hexagon.elm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index a007bf0..6909cea 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -260,6 +260,7 @@ makeEnemy color enemy = group (indexedMap (,) enemy.parts |> filter snd |> map fst |> map makeEnemyPart) + makeEnemies : Color -> List(Enemy) -> List(Form) makeEnemies color enemies = map (makeEnemy color) enemies From d7df5bcc028c0d74a51b3fe1716fbbe46e3dc891 Mon Sep 17 00:00:00 2001 From: Santiago Andaluz Date: Mon, 20 Nov 2017 16:47:17 -0600 Subject: [PATCH 33/37] update App.program for 0.18 --- src/Hexagon.elm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 65d9c07..d57a8e8 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -6,8 +6,7 @@ import Window import Collage exposing (..) import Element exposing (..) import Color exposing (..) -import Html.App as App -import Html +import Html exposing (Html) -- MODEL @@ -159,7 +158,7 @@ init = main = - App.program + Html.program { init = init , update = update , view = view From 24e23617783b2ac23ee0e6e308a5a9adb656a151 Mon Sep 17 00:00:00 2001 From: Santiago Andaluz Date: Mon, 20 Nov 2017 16:52:45 -0600 Subject: [PATCH 34/37] Update Hexagon.elm --- src/Hexagon.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index f1ebade..08185ed 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -210,7 +210,7 @@ makeField colors = polygon (hexagonElement i) |> filled (color i) in - group (map poly [0..5]) + group (map poly (List.range 0 5)) -- the polygon in the center: this is just decoration, so it has no own state makeCenterHole : Colors -> Game -> List Form From 423554133922aac3f71e7d69493c5a83399fbae0 Mon Sep 17 00:00:00 2001 From: Santiago Andaluz Date: Mon, 20 Nov 2017 16:57:45 -0600 Subject: [PATCH 35/37] Update fst and snd for 0.18 This will change the line numbers. **Causing issues with the gitbook** --- src/Hexagon.elm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 6909cea..70fd12a 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -1,5 +1,6 @@ import Time exposing (..) import List exposing (..) +import Tuple exposing (..) import AnimationFrame import Keyboard.Extra as Keyboard import Window @@ -258,7 +259,7 @@ makeEnemy color enemy = |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius + enemyThickness) in group - (indexedMap (,) enemy.parts |> filter snd |> map fst |> map makeEnemyPart) + (indexedMap (,) enemy.parts |> filter Tuple.second |> map Tuple.first |> map makeEnemyPart) makeEnemies : Color -> List(Enemy) -> List(Form) From df1017a5142a596cc859d51e760a7964a9d3a9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sun, 26 Nov 2017 16:23:17 +0100 Subject: [PATCH 36/37] Update Dependencies, match Keyboard.Extra syntax with documentation, use elm-format --- .editorconfig | 2 +- elm-package.json | 10 +- package.json | 2 +- src/Hexagon.elm | 270 +++++++++++++++++++++++++++++------------------ 4 files changed, 173 insertions(+), 111 deletions(-) diff --git a/.editorconfig b/.editorconfig index 7d370f6..f1196bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,5 +8,5 @@ root = true end_of_line = lf insert_final_newline = true indent_style = space -indent_size = 2 +indent_size = 4 max_line_length = 80 diff --git a/elm-package.json b/elm-package.json index 5f36e8f..4528a3f 100644 --- a/elm-package.json +++ b/elm-package.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "1.1.0", "summary": "A functional reactive implementation of Terry Cavanagh's game Hexagon in Elm", "repository": "https://github.com/sbaechler/polygon.git", "license": "All rights reserved", @@ -11,11 +11,11 @@ "native-modules": true, "dependencies": { "elm-lang/animation-frame": "1.0.0 <= v < 2.0.0", - "elm-lang/core": "4.0.0 <= v < 5.0.0", - "elm-lang/html": "1.0.0 <= v < 2.0.0", + "elm-lang/core": "5.0.0 <= v < 6.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0", "elm-lang/window": "1.0.0 <= v < 2.0.0", "evancz/elm-graphics": "1.0.0 <= v < 2.0.0", - "ohanhi/keyboard-extra": "1.0.1 <= v < 2.0.0" + "ohanhi/keyboard-extra": "3.0.4 <= v < 4.0.0" }, - "elm-version": "0.17.0 <= v < 0.18.0" + "elm-version": "0.18.0 <= v < 0.19.0" } diff --git a/package.json b/package.json index c82682b..ad771dc 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,6 @@ "setup": "elm-package install && git submodule update --init" }, "dependencies": { - "elm": "^0.17.0" + "elm": "^0.18.0" } } diff --git a/src/Hexagon.elm b/src/Hexagon.elm index d57a8e8..0c43d8e 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -1,166 +1,228 @@ +module Main exposing (..) + import Time exposing (..) import List exposing (..) import AnimationFrame -import Keyboard.Extra as Keyboard +import Keyboard.Extra exposing (Key(..)) import Window import Collage exposing (..) import Element exposing (..) import Color exposing (..) import Html exposing (Html) + -- MODEL + type alias Player = - { angle: Float } + { angle : Float } + + +type Direction + = Left + | Right + | Still -type Direction = Left | Right | Still type alias Game = - { - player : Player - , direction : Direction - , keyboardModel : Keyboard.Model - } + { player : Player + , direction : Direction + , pressedKeys : List Key + } + type Msg - = Step Time - | KeyboardExtraMsg Keyboard.Msg + = Step Time + | KeyboardMsg Keyboard.Extra.Msg + + +( gameWidth, gameHeight ) = + ( 1024, 576 ) -(gameWidth, gameHeight) = (1024, 576) -- 16:9 -(halfWidth, halfHeight) = (gameWidth/2, gameHeight/2) -(iHalfWidth, iHalfHeight) = (gameWidth//2, gameHeight//2) +-- 16:9 + + +( halfWidth, halfHeight ) = + ( gameWidth / 2, gameHeight / 2 ) +( iHalfWidth, iHalfHeight ) = + ( gameWidth // 2, gameHeight // 2 ) playerRadius : Float -playerRadius = gameWidth / 10.0 -playerSize: Float -playerSize = 10.0 +playerRadius = + gameWidth / 10.0 + + +playerSize : Float +playerSize = + 10.0 + + playerSpeed : Float -playerSpeed = 0.12 +playerSpeed = + 0.12 + + bgBlack : Color bgBlack = - rgb 20 20 20 + rgb 20 20 20 + -- UPDATE -updatePlayerAngle: Float -> Direction -> Float + +updatePlayerAngle : Float -> Direction -> Float updatePlayerAngle angle dir = - let - sign = - if dir == Left then 1 - else if dir == Right then -1 - else 0 - newAngle = angle + toFloat sign * playerSpeed - in - if newAngle < 0 then - newAngle + 2 * pi - else if newAngle > 2 * pi then - newAngle - 2 * pi - else - newAngle - -updatePlayer: Direction -> Game -> Player -updatePlayer dir {player} = - let - newAngle = updatePlayerAngle player.angle dir - in - { player | angle = newAngle } - - -{-| Updates the game state on a keyboard command -} -onUserInput : Keyboard.Msg -> Game -> (Game, Cmd Msg) + let + sign = + if dir == Left then + 1 + else if dir == Right then + -1 + else + 0 + + newAngle = + angle + toFloat sign * playerSpeed + in + if newAngle < 0 then + newAngle + 2 * pi + else if newAngle > 2 * pi then + newAngle - 2 * pi + else + newAngle + + +updatePlayer : Direction -> Game -> Player +updatePlayer dir { player } = + let + newAngle = + updatePlayerAngle player.angle dir + in + { player | angle = newAngle } + + +{-| Updates the game state on a keyboard command +-} +onUserInput : Keyboard.Extra.Msg -> Game -> ( Game, Cmd Msg ) onUserInput keyMsg game = - let - ( keyboardModel, keyboardCmd ) = - Keyboard.update keyMsg game.keyboardModel - direction = - if (Keyboard.arrows keyboardModel).x < 0 then Left - else if (Keyboard.arrows keyboardModel).x > 0 then Right - else Still - in - ( { game | keyboardModel = keyboardModel - , direction = direction - } - , Cmd.map KeyboardExtraMsg keyboardCmd ) - -{-| Updates the game state on every frame -} -onFrame : Time -> Game -> (Game, Cmd Msg) + let + pressedKeys = + Keyboard.Extra.update keyMsg game.pressedKeys + + direction = + if (Keyboard.Extra.arrows pressedKeys).x < 0 then + Left + else if (Keyboard.Extra.arrows pressedKeys).x > 0 then + Right + else + Still + in + ( { game + | pressedKeys = pressedKeys + , direction = direction + } + , Cmd.none + ) + + +{-| Updates the game state on every frame +-} +onFrame : Time -> Game -> ( Game, Cmd Msg ) onFrame time game = - let - nextCmd = Cmd.none - in - ( { game | - player = updatePlayer game.direction game - }, nextCmd ) + let + nextCmd = + Cmd.none + in + ( { game + | player = updatePlayer game.direction game + } + , nextCmd + ) + + +{-| Game loop: Transition from one state to the next. +-} +update : Msg -> Game -> ( Game, Cmd Msg ) +update msg game = + case msg of + KeyboardMsg keyMsg -> + onUserInput keyMsg game + Step time -> + onFrame time game -{-| Game loop: Transition from one state to the next. -} -update : Msg -> Game -> (Game, Cmd Msg) -update msg game = - case msg of - KeyboardExtraMsg keyMsg -> onUserInput keyMsg game - Step time -> onFrame time game -- VIEW + moveRadial : Float -> Float -> Form -> Form moveRadial angle radius = - move (radius * cos angle, radius * sin angle) + move ( radius * cos angle, radius * sin angle ) + makePlayer : Player -> Form makePlayer player = - let - angle = player.angle - degrees 30 - in - ngon 3 playerSize - |> filled (hsl angle 1 0.5) - |> moveRadial angle (playerRadius - playerSize) - |> rotate angle + let + angle = + player.angle - degrees 30 + in + ngon 3 playerSize + |> filled (hsl angle 1 0.5) + |> moveRadial angle (playerRadius - playerSize) + |> rotate angle + view : Game -> Html.Html Msg view game = - let - bg = rect gameWidth gameHeight |> filled bgBlack - field = makePlayer game.player - in - toHtml <| - container gameWidth gameHeight middle <| - collage gameWidth gameHeight - [ bg - , field - ] + let + bg = + rect gameWidth gameHeight |> filled bgBlack + + field = + makePlayer game.player + in + toHtml + <| container gameWidth gameHeight middle + <| collage gameWidth + gameHeight + [ bg + , field + ] + + -- SUBSCRIPTIONS + subscriptions : Game -> Sub Msg subscriptions game = - Sub.batch [ - AnimationFrame.times (\time -> Step time), - Sub.map KeyboardExtraMsg Keyboard.subscriptions - ] + Sub.batch + [ AnimationFrame.times (\time -> Step time) + , Sub.map KeyboardMsg Keyboard.Extra.subscriptions + ] + --INIT -init : (Game, Cmd Msg) + +init : ( Game, Cmd Msg ) init = - let - ( keyboardModel, keyboardCmd ) = Keyboard.init - in ( { player = Player (degrees 30) - , keyboardModel = keyboardModel + , pressedKeys = [] , direction = Still } - , Cmd.map KeyboardExtraMsg keyboardCmd + , Cmd.none ) main = - Html.program - { init = init - , update = update - , view = view - , subscriptions = subscriptions } - + Html.program + { init = init + , update = update + , view = view + , subscriptions = subscriptions + } From 81bde14168a74b16b54ba6608594a2d49449cb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=A4chler?= Date: Sun, 26 Nov 2017 17:47:17 +0100 Subject: [PATCH 37/37] Format --- src/Hexagon.elm | 149 +++++++++++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 59 deletions(-) diff --git a/src/Hexagon.elm b/src/Hexagon.elm index 332a899..c84e0dc 100644 --- a/src/Hexagon.elm +++ b/src/Hexagon.elm @@ -38,15 +38,16 @@ type Direction type alias Enemy = - { radius : Float - , parts : List(Bool) - } + { radius : Float + , parts : List (Bool) + } + type alias Game = { player : Player , direction : Direction - , enemies: List(Enemy) - , enemySpeed: Float + , enemies : List (Enemy) + , enemySpeed : Float , pressedKeys : List Key , state : State , timeStart : Time @@ -86,23 +87,37 @@ playerSize = playerSpeed : Float -playerSpeed = 0.12 +playerSpeed = + 0.12 + + +enemyThickness = + 30 + + +enemyDistance = + 350 + + +enemyInitialSpeed = + 0.25 + + +enemyAcceleration = + 0.000002 -enemyThickness = 30 -enemyDistance = 350 -enemyInitialSpeed = 0.25 -enemyAcceleration = 0.000002 enemies = - [ [False, True, False, True, False, True] - , [False, True, True, True, True, True] - , [True, False, True, True, True, True] - , [True, True, True, True, False, True] - , [True, True, True, False, True, True] - , [False, True, False, True, False, True] - , [True, False, True, False, True, False] - , [True, True, True, True, True, False] - ] + [ [ False, True, False, True, False, True ] + , [ False, True, True, True, True, True ] + , [ True, False, True, True, True, True ] + , [ True, True, True, True, False, True ] + , [ True, True, True, False, True, True ] + , [ False, True, False, True, False, True ] + , [ True, False, True, False, True, False ] + , [ True, True, True, True, True, False ] + ] + bgBlack : Color bgBlack = @@ -180,33 +195,43 @@ updateAutoRotateSpeed { msRunning, autoRotateSpeed } = |> Debug.log "autoRotateSpeed" -updateEnemies: Game -> List(Enemy) +updateEnemies : Game -> List (Enemy) updateEnemies game = - let - enemyProgress = game.msRunning * game.enemySpeed - numEnemies = List.length enemies - maxDistance = numEnemies * enemyDistance + let + enemyProgress = + game.msRunning * game.enemySpeed - offsetForEnemy index = - round <| enemyDistance * (toFloat index) - enemyProgress + numEnemies = + List.length enemies - radiusFor index = - (offsetForEnemy index) % maxDistance - |> toFloat - in - List.indexedMap (\index parts -> { - parts = parts, - radius = radiusFor index - }) enemies + maxDistance = + numEnemies * enemyDistance + offsetForEnemy index = + round <| enemyDistance * (toFloat index) - enemyProgress -updateEnemySpeed: Game -> Float + radiusFor index = + (offsetForEnemy index) + % maxDistance + |> toFloat + in + List.indexedMap + (\index parts -> + { parts = parts + , radius = radiusFor index + } + ) + enemies + + +updateEnemySpeed : Game -> Float updateEnemySpeed game = - Debug.log "enemy speed" (enemyInitialSpeed + game.msRunning * enemyAcceleration) + Debug.log "enemy speed" (enemyInitialSpeed + game.msRunning * enemyAcceleration) -{-| Updates the game state on a keyboard command -} -onUserInput : Keyboard.Extra.Msg -> Game -> (Game, Cmd Msg) +{-| Updates the game state on a keyboard command +-} +onUserInput : Keyboard.Extra.Msg -> Game -> ( Game, Cmd Msg ) onUserInput keyMsg game = let pressedKeys = @@ -333,33 +358,39 @@ makePlayer player = |> rotate angle -trapezoid: Float -> Float -> Color -> Form +trapezoid : Float -> Float -> Color -> Form trapezoid base height color = - let - s = height/(tan <| degrees 60) - in - filled color <| polygon [ - (-base/2, 0), (base/2, 0), (base/2-s, height), (-base/2+s, height) - ] + let + s = + height / (tan <| degrees 60) + in + filled color + <| polygon + [ ( -base / 2, 0 ) + , ( base / 2, 0 ) + , ( base / 2 - s, height ) + , ( -base / 2 + s, height ) + ] makeEnemy : Color -> Enemy -> Form makeEnemy color enemy = - let - base = 2.0 * (enemy.radius +enemyThickness) / (sqrt 3) - makeEnemyPart : Int -> Form - makeEnemyPart index = - trapezoid base enemyThickness color - |> rotate (degrees <| toFloat (90 + index * 60)) - |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius + enemyThickness) - in - group - (indexedMap (,) enemy.parts |> filter Tuple.second |> map Tuple.first |> map makeEnemyPart) - - -makeEnemies : Color -> List(Enemy) -> List(Form) + let + base = + 2.0 * (enemy.radius + enemyThickness) / (sqrt 3) + + makeEnemyPart : Int -> Form + makeEnemyPart index = + trapezoid base enemyThickness color + |> rotate (degrees <| toFloat (90 + index * 60)) + |> moveRadial (degrees <| toFloat (index * 60)) (enemy.radius + enemyThickness) + in + group (indexedMap (,) enemy.parts |> filter Tuple.second |> map Tuple.first |> map makeEnemyPart) + + +makeEnemies : Color -> List (Enemy) -> List (Form) makeEnemies color enemies = - map (makeEnemy color) enemies + map (makeEnemy color) enemies hexagonElement : Int -> List ( Float, Float )