Last active
August 29, 2015 14:10
-
-
Save emhoracek/a35b4937f6ade4146eb3 to your computer and use it in GitHub Desktop.
Now I can't figure out math
This file contains hidden or 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
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