Created
April 8, 2018 15:18
-
-
Save ufocoder/8536e5112aab11ed9dac8163d7d7d43f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (..) | |
import Collage exposing (Form, collage, filled, move, rect) | |
import Color exposing (Color, rgb) | |
import Element exposing (toHtml) | |
import Html exposing (Html) | |
import Keyboard | |
import Mouse | |
import Random | |
import Time exposing (Time, millisecond) | |
---- MODEL ---- | |
objectSize : Float | |
objectSize = | |
10 | |
velocityY : Float | |
velocityY = | |
5 | |
velocityX : Float | |
velocityX = | |
10 | |
type alias Position = | |
{ x : Float | |
, y : Float | |
} | |
type alias Object = | |
{ position : Position | |
} | |
type alias Model = | |
{ play : Bool | |
, moves : Int | |
, car : Object | |
, obstructions : List Object | |
} | |
init : ( Model, Cmd Msg ) | |
init = | |
( { play = False | |
, moves = 0 | |
, car = { position = { x = 0, y = -140 } } | |
, obstructions = [] | |
} | |
, Cmd.none | |
) | |
---- UPDATE ---- | |
type Msg | |
= KeyMsg Keyboard.KeyCode | |
| NewObctruction Float | |
| NewCarPositionX Float | |
| Tick Time | |
setObjectX : Float -> Object -> Object | |
setObjectX x object = | |
let | |
oldPosition = | |
object.position | |
newPosition = | |
{ oldPosition | x = x } | |
in | |
{ object | position = newPosition } | |
moveObjectX : Float -> Object -> Object | |
moveObjectX offset object = | |
let | |
oldPosition = | |
object.position | |
newPosition = | |
{ oldPosition | x = oldPosition.x + offset } | |
in | |
{ object | position = newPosition } | |
moveObjectY : Float -> Object -> Object | |
moveObjectY offset object = | |
let | |
oldPosition = | |
object.position | |
newPosition = | |
{ oldPosition | y = oldPosition.y + offset } | |
in | |
{ object | position = newPosition } | |
moveLeft : Object -> Object | |
moveLeft = | |
moveObjectX -velocityX | |
moveRight : Object -> Object | |
moveRight = | |
moveObjectX velocityX | |
moveDown : Object -> Object | |
moveDown = | |
moveObjectY -velocityY | |
crossPosition : Position -> Position -> Bool | |
crossPosition a b = | |
abs (a.x - b.x) < objectSize && abs (a.y - b.y) < objectSize | |
isCarAlive : Object -> List Object -> Bool | |
isCarAlive car obstructions = | |
not (List.any (\obstruction -> crossPosition car.position obstruction.position) obstructions) | |
isObjectVisible : Object -> Bool | |
isObjectVisible object = | |
let | |
position = | |
object.position | |
in | |
position.y < 180 && position.y > -180 | |
updateObstructions : Model -> Float -> Model | |
updateObstructions model x = | |
let | |
newObstruction = | |
{ position = { x = x, y = 0 } } | |
movedObstructions = | |
List.map (moveObjectY -velocityY) model.obstructions | |
|> List.filter isObjectVisible | |
isAlive = | |
isCarAlive model.car movedObstructions | |
in | |
{ model | |
| play = isAlive | |
, obstructions = newObstruction :: movedObstructions | |
} | |
updateModel : Model -> Model -> Model | |
updateModel model newModel = | |
if model.play == True then | |
newModel | |
else | |
model | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
NewCarPositionX x -> | |
( updateModel model { model | car = setObjectX x model.car } | |
, Cmd.none | |
) | |
KeyMsg code -> | |
case code of | |
37 -> | |
( updateModel model { model | car = moveLeft model.car } | |
, Cmd.none | |
) | |
39 -> | |
( updateModel model { model | car = moveRight model.car } | |
, Cmd.none | |
) | |
32 -> | |
( { model | |
| play = True | |
, obstructions = [] | |
} | |
, Cmd.none | |
) | |
_ -> | |
( model, Cmd.none ) | |
Tick newTime -> | |
( model | |
, if model.play == True then | |
Random.generate NewObctruction (Random.float 0 290) | |
else | |
Cmd.none | |
) | |
NewObctruction newPositionX -> | |
( updateObstructions model newPositionX | |
, Cmd.none | |
) | |
---- VIEW ---- | |
drawCar : Object -> Form | |
drawCar = | |
drawObject (rgb 255 50 50) | |
drawObstruction : Object -> Form | |
drawObstruction = | |
drawObject (rgb 74 167 43) | |
drawObject : Color -> Object -> Form | |
drawObject color object = | |
let | |
position = | |
object.position | |
in | |
rect objectSize objectSize | |
|> filled color | |
|> move ( position.x, position.y ) | |
view : Model -> Html Msg | |
view model = | |
let | |
car = | |
drawCar model.car | |
obstructions = | |
List.map drawObstruction model.obstructions | |
in | |
collage 300 300 (car :: obstructions) | |
|> toHtml | |
-- SUBSCRIPTIONS | |
subscriptions : Model -> Sub Msg | |
subscriptions model = | |
Sub.batch | |
[ Time.every 100 Tick | |
, Keyboard.downs KeyMsg | |
, Mouse.moves (\{ x, y } -> NewCarPositionX (toFloat x)) | |
] | |
---- PROGRAM ---- | |
main : Program Never Model Msg | |
main = | |
Html.program | |
{ view = view | |
, init = init | |
, update = update | |
, subscriptions = subscriptions | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment