Skip to content

Instantly share code, notes, and snippets.

@emhoracek
Last active August 29, 2015 14:10
Show Gist options
  • Save emhoracek/a35b4937f6ade4146eb3 to your computer and use it in GitHub Desktop.
Save emhoracek/a35b4937f6ade4146eb3 to your computer and use it in GitHub Desktop.
Now I can't figure out math
import Keyboard
import Window
import Text
import Random
import Debug
-- INPUTS
type Input = { space: Bool, delta: Time, randBalls: [Ball] }
delta : Signal Time
delta = inSeconds <~ fps 35
randBalls : Signal [Ball]
randBalls = lift (map randBall) random
randBall : Float -> Ball
randBall float =
let x' = -97 + (float * 300) in
{ x = x', y = 200, vx = 75, vy = 75,
binId = (ceiling <| numObjects * float) }
random : Signal [Float]
random = Random.floatList (constant numObjects)
input : Signal Input
input = sampleOn delta <| Input <~ Keyboard.space
~ delta
~ randBalls
-- MODEL
type Object a = { a | x:Float, y:Float,
vx:Float, vy:Float }
type Ball = Object { binId : Int }
type Bin = Object {id : Int}
data State = Running | Paused
type Rule = Int
type Sim = { state: State,
ballList: [ Ball ],
binList: [ Bin ],
rules: Rule }
-- UPDATE
-- are n and m near each other?
-- specifically are they within c of each other?
near : Float -> Float -> Float -> Bool
near n c m = m >= n-c && m <= n+c
far x y byZ= not <| near x y byZ
-- is the ball within a paddle?
within : Ball -> Bin -> Bool
within ball bin =
(ball.x |> near bin.x 8) && (ball.y |> near bin.y 20)
--Ick! I don't like this!
matchBin : Ball -> Bin
matchBin ball = head <|
filter (\ x -> x.id == ball.binId) allBins
changeXVelocity : Ball -> Float
changeXVelocity ({x,y,vx,vy,binId} as ball) =
let bin = matchBin ball
debug = Debug.watch "near?" (not <| near x bin.x 50)
in
if (far x bin.x 300)
then vx * 1.1
else if (x > bin.x && vx > 0)
then (-1) * vx
else if ( x < bin.x && vx < 0)
then (-1) * vx
else if ( near x bin.x 100 )
then vx * 0.3
else vx
stepBall : Time -> Ball -> Ball
stepBall t ({x,y,vx,vy,binId} as ball) =
let debugt = Debug.watch "Time" t == t
debugx = Debug.watch "x" x == x
bin = matchBin ball
vx' = changeXVelocity ball
vy' = if (y > bin.y && vy > 0)
then (-1) * vy
else if (y < bin.y)
then 0
else vy
debugvy = Debug.watch "Vy" vy' == vy'
in
if (within ball bin) then ball else
{ ball | x <- x + vx * t
, y <- y + vy * t
, vx <- vx'
, vy <- vy'}
stepSim : Input -> Sim -> Sim
stepSim { space, delta, randBalls}
({state,ballList,binList} as sim) =
let state' = if space then Paused else Running
ballList' = if ((state == Paused) && (space == True) || ballList == []) then
randBalls
else map (stepBall delta) ballList
--debugBalls = Debug.watch "Balls: " ballList' == ballList'
in
{ sim | state <- state'
, ballList <- ballList'
, binList <- binList }
defaultSim : Sim
defaultSim = { state = Paused,
ballList = [],
binList = allBins,
rules = 0}
simState : Signal Sim
simState = foldp stepSim defaultSim input
-- VIEW
ballSize = 15
binHeight = 35
binWidth = 50
numObjects = 5
makeBins num x y = if (num > 0) then
{ id = num, x = x, y = y, vx = 0, vy = 0 } ::
makeBins (num - 1) (x + binWidth + 30) y
else []
allBins : [ Bin ]
allBins = makeBins numObjects -200 -100
msg : [Ball] -> String
msg balls = show <| (map (.binId) balls)
msg2 : [Ball] -> String
msg2 balls = "x: " ++ (show <| (map (.x) balls))
msg3 : [Ball] -> String
msg3 balls = "y: " ++ (show <| (map (.x) balls))
txt: String -> Element
txt f = leftAligned <| Text.color green <| toText f
text f = flow down [ txt <| msg f ]
drawBall : Ball -> Element
drawBall ball = let d = ballSize * 2 in
collage d d [ filled red (circle ballSize),
toForm <| asText <| show ball.binId ]
drawBin : Bin -> Element
drawBin bin =
collage binWidth binHeight
[ outlined defaultLine (rect binWidth binHeight),
toForm <| asText <| show bin.id ]
displayObj : Shape -> Color -> Object a -> Form
displayObj shape color obj =
let debig1 = Debug.watch "display x" obj.x == obj.x
debug2 = Debug.trace "ball" <| move (obj.x, obj.y)(filled color shape)
in
move (obj.x,obj.y) (filled color shape)
display : (Int, Int) -> Sim -> Element
display (w, h) { state, ballList, binList } =
collage 500 500 (
[ filled black (rect 500 500)] ++
map (Debug.trace "ball") (map (displayObj (circle ballSize) red) ballList) ++
map (displayObj (rect binWidth binHeight) blue) binList ++
[toForm (if state == Running then spacer 1 1 else text ballList )
|> move (0, 40 - 500/2)]
)
main = lift2 display Window.dimensions simState
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment