Skip to content

Instantly share code, notes, and snippets.

@ufocoder
Created April 8, 2018 15:18
Show Gist options
  • Save ufocoder/8536e5112aab11ed9dac8163d7d7d43f to your computer and use it in GitHub Desktop.
Save ufocoder/8536e5112aab11ed9dac8163d7d7d43f to your computer and use it in GitHub Desktop.
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