From 4521cdf1bb5725c9d497e5fb0c03943ad03a052f Mon Sep 17 00:00:00 2001 From: Joris Guyonvarch Date: Sun, 5 Oct 2014 23:10:18 +0200 Subject: Adding multiple moving points to catch --- README.md | 2 +- src/Cloud.elm | 31 +++++++++++++++++++++ src/CloudStep.elm | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/Display.elm | 33 +++++++++++------------ src/Enemy.elm | 27 ------------------- src/EnemyState.elm | 29 -------------------- src/Game.elm | 12 ++++----- src/Input.elm | 23 ++++++++++------ src/Main.elm | 2 +- src/Point.elm | 27 +++++++++++++++++++ src/RandomValues.elm | 13 +++++---- src/Step.elm | 76 +++++++++------------------------------------------- src/Target.elm | 24 ----------------- 13 files changed, 183 insertions(+), 184 deletions(-) create mode 100644 src/Cloud.elm create mode 100644 src/CloudStep.elm delete mode 100644 src/Enemy.elm delete mode 100644 src/EnemyState.elm create mode 100644 src/Point.elm delete mode 100644 src/Target.elm diff --git a/README.md b/README.md index 808baf0..a845588 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Avoid ===== -Avoid red enemies and catch the most green targets as possible. +Avoid red points and catch the most green points as possible. You can play at [http://guyonvarch.github.io/avoid](http://guyonvarch.github.io/avoid). diff --git a/src/Cloud.elm b/src/Cloud.elm new file mode 100644 index 0000000..081862c --- /dev/null +++ b/src/Cloud.elm @@ -0,0 +1,31 @@ +module Cloud where + +import Point (..) +import Player (..) +import Geometry (distance) + +type Cloud = + { greenPoints : [Point] + , redPoints : [Point] + , spawn : Float + , lastSpawn : Float + } + +initCloud : Cloud +initCloud = + let spawn = 200 + in { greenPoints = [] + , redPoints = [] + , spawn = spawn + , lastSpawn = -spawn + } + +playerPointsCollision : Float -> Player -> [Point] -> Bool +playerPointsCollision time player points = + let collision = playerPointCollision time player + in length (filter collision points) > 0 + +playerPointCollision : Float -> Player -> Point -> Bool +playerPointCollision time player point = + let pointPos = pointMove point time + in (distance pointPos player.pos) < pointSize + playerSize diff --git a/src/CloudStep.elm b/src/CloudStep.elm new file mode 100644 index 0000000..e33d573 --- /dev/null +++ b/src/CloudStep.elm @@ -0,0 +1,68 @@ +module CloudStep where + +import Vec2 (..) +import Geometry (..) +import Player (..) +import Board (boardSize, boardDiagonal) +import Point (..) +import RandomValues (..) +import Physics (getMove) +import Cloud (..) + +cloudStep : Float -> RandomValues -> Player -> Cloud -> (Cloud, Int) +cloudStep time {greenPoint, redPoint} player {greenPoints, redPoints, spawn, lastSpawn} = + let insideGreenPoints = presentPoints time greenPoints + insideNotCaughtGreenPoints = filter (not . (playerPointCollision time player)) insideGreenPoints + addScore = (length insideGreenPoints) - (length insideNotCaughtGreenPoints) + presentRedPoints = presentPoints time redPoints + newCloud = + if time > lastSpawn + spawn then + let newGreenPoint = newPoint time greenPoint + newRedPoint = newPoint time redPoint + in + { greenPoints = newGreenPoint :: insideNotCaughtGreenPoints + , redPoints = newRedPoint :: presentRedPoints + , spawn = spawn - sqrt(spawn) / 50 + , lastSpawn = time + } + else + { greenPoints = insideNotCaughtGreenPoints + , redPoints = presentRedPoints + , spawn = spawn + , lastSpawn = lastSpawn + } + in (newCloud, addScore) + +presentPoints : Float -> [Point] -> [Point] +presentPoints time points = + let isPresent point = (distance (pointMove point time) originVec) < pointAwayDist + in filter isPresent points + +newPoint : Float -> PointRandomValues -> Point +newPoint time pointRandomValues = + { initTime = time + , initPos = pointInitPos pointRandomValues.angle + , initDest = pointDestination pointRandomValues.x pointRandomValues.y + , move initTime initPos initDest time = + let delta = time - initTime + move = getMove (pointSpeed delta) (initDest `sub` initPos) + in initPos `add` move + } + +pointInitPos : Float -> Vec2 +pointInitPos randomAngle = + let angle = randomAngle * (degrees 360) + dist = boardDiagonal * 3 / 5 + in polarToCartesian angle dist + +pointDestination : Float -> Float -> Vec2 +pointDestination randomX randomY = + randomBoardPosition (randomX, randomY) (1, 1) + +randomBoardPosition : (Float, Float) -> (Float, Float) -> Vec2 +randomBoardPosition (randomX, randomY) (percentX, percentY) = + let width = boardSize.x * percentX + height = boardSize.y * percentY + in { x = width * randomX - width / 2 + , y = height * randomY - height / 2 + } diff --git a/src/Display.elm b/src/Display.elm index b586129..aa4ed51 100644 --- a/src/Display.elm +++ b/src/Display.elm @@ -3,18 +3,18 @@ module Display where import Vec2 (..) import Player (..) import Game (Game) -import Enemy (..) +import Point (..) import Board (boardSize) -import Target (..) display : Game -> Element -display {time, player, target, enemyState, bestScore} = - let enemyForms = map (enemyForm time) enemyState.enemies +display {time, score, player, cloud, bestScore} = + let greenPointForms = map (pointForm time greenPointColor) cloud.greenPoints + redPointForms = map (pointForm time redPointColor) cloud.redPoints forms = boardForms ++ playerForms player - ++ targetForms target.pos - ++ enemyForms - ++ scoreForms target.score + ++ greenPointForms + ++ redPointForms + ++ scoreForms score ++ bestScoreForms bestScore in collage (truncate boardSize.x) (truncate boardSize.y) forms @@ -30,19 +30,16 @@ playerForms player = [circleForm player.pos playerSize playerColor] playerColor : Color playerColor = rgb 224 224 224 -targetForms : Vec2 -> [Form] -targetForms pos = [circleForm pos targetSize targetColor] +pointForm : Float -> Color -> Point -> Form +pointForm time color point = + let pos = pointMove point time + in circleForm pos pointSize color -targetColor : Color -targetColor = rgb 34 85 34 +greenPointColor : Color +greenPointColor = rgb 34 85 34 -enemyForm : Float -> Enemy -> Form -enemyForm time enemy = - let pos = enemyMove enemy time - in circleForm pos enemySize enemyColor - -enemyColor : Color -enemyColor = rgb 170 0 0 +redPointColor : Color +redPointColor = rgb 170 0 0 circleForm : Vec2 -> Float -> Color -> Form circleForm pos size color = diff --git a/src/Enemy.elm b/src/Enemy.elm deleted file mode 100644 index 0f986aa..0000000 --- a/src/Enemy.elm +++ /dev/null @@ -1,27 +0,0 @@ -module Enemy where - -import Vec2 (..) -import Board (boardDiagonal) - -type Enemy = - { initTime : Float - , initPos : Vec2 - , initDest : Vec2 - , move : Float -> Vec2 -> Vec2 -> Float -> Vec2 - } - -enemyMove : Enemy -> Float -> Vec2 -enemyMove enemy time = - enemy.move enemy.initTime enemy.initPos enemy.initDest time - -enemySize : Float -enemySize = 5 - -enemySpeed : Float -> Float -enemySpeed dt = dt / 25 - -enemySpawnDist : Float -enemySpawnDist = boardDiagonal * 3 / 5 - -enemyAwayDist : Float -enemyAwayDist = boardDiagonal diff --git a/src/EnemyState.elm b/src/EnemyState.elm deleted file mode 100644 index fed2981..0000000 --- a/src/EnemyState.elm +++ /dev/null @@ -1,29 +0,0 @@ -module EnemyState where - -import Enemy (..) -import Player (..) -import Geometry (distance) - -type EnemyState = - { enemies : [Enemy] - , spawn : Float - , lastSpawn : Float - } - -initEnemyState : EnemyState -initEnemyState = - let spawn = 200 - in { enemies = [] - , spawn = spawn - , lastSpawn = -spawn - } - -playerEnemiesCollision : Float -> Player -> [Enemy] -> Bool -playerEnemiesCollision time player enemies = - let collision = playerEnemyCollision time player - in length (filter collision enemies) > 0 - -playerEnemyCollision : Float -> Player -> Enemy -> Bool -playerEnemyCollision time player enemy = - let enemyPos = enemyMove enemy time - in (distance enemyPos player.pos) < enemySize + playerSize diff --git a/src/Game.elm b/src/Game.elm index 8de0c40..83d8baa 100644 --- a/src/Game.elm +++ b/src/Game.elm @@ -1,16 +1,14 @@ module Game where import Player (..) -import Enemy (..) -import EnemyState (..) -import Target(..) +import Cloud (..) import Vec2 (Vec2) type Game = { time : Float + , score : Int , player : Player - , target : Target - , enemyState : EnemyState + , cloud : Cloud , bestScore : Int } @@ -22,8 +20,8 @@ initialGame playerPos bestScore = } in { time = 0 + , score = 0 , player = initPlayer - , target = initTarget - , enemyState = initEnemyState + , cloud = initCloud , bestScore = bestScore } diff --git a/src/Input.elm b/src/Input.elm index 69e7503..1015302 100644 --- a/src/Input.elm +++ b/src/Input.elm @@ -16,7 +16,7 @@ getInput : Signal Input getInput = let dtSignal = delta dirSignal = lift recordIntToVec2 Keyboard.arrows - randomFloatsSignal = Random.floatList (lift (\_ -> 5) dtSignal) + randomFloatsSignal = Random.floatList (lift (\_ -> 6) dtSignal) randomValuesSignal = lift floatsToRandomValues randomFloatsSignal in sampleOn dtSignal <| Input <~ dirSignal ~ dtSignal @@ -32,10 +32,17 @@ recordIntToVec2 {x, y} = } floatsToRandomValues : [Float] -> RandomValues -floatsToRandomValues [enemyAngle, enemyX, enemyY, targetX, targetY] = - { enemyAngle = enemyAngle - , enemyX = enemyX - , enemyY = enemyY - , targetX = targetX - , targetY = targetY - } +floatsToRandomValues [angle1, x1, y1, angle2, x2, y2] = + let greenPoint = + { angle = angle1 + , x = x1 + , y = y1 + } + redPoint = + { angle = angle2 + , x = x2 + , y = y2 + } + in { greenPoint = greenPoint + , redPoint = redPoint + } diff --git a/src/Main.elm b/src/Main.elm index c51ddc8..267bb8c 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -7,4 +7,4 @@ import Input (getInput) import Vec2 (originVec) main : Signal Element -main = lift display (foldp step (initialGame { x = -50, y = 0 } 0) getInput) +main = lift display (foldp step (initialGame originVec 0) getInput) diff --git a/src/Point.elm b/src/Point.elm new file mode 100644 index 0000000..90c61c3 --- /dev/null +++ b/src/Point.elm @@ -0,0 +1,27 @@ +module Point where + +import Vec2 (..) +import Board (boardDiagonal) + +type Point = + { initTime : Float + , initPos : Vec2 + , initDest : Vec2 + , move : Float -> Vec2 -> Vec2 -> Float -> Vec2 + } + +pointMove : Point -> Float -> Vec2 +pointMove {initTime, initPos, initDest, move} time = + move initTime initPos initDest time + +pointSize : Float +pointSize = 5 + +pointSpeed : Float -> Float +pointSpeed dt = dt / 25 + +pointSpawnDist : Float +pointSpawnDist = boardDiagonal * 3 / 5 + +pointAwayDist : Float +pointAwayDist = boardDiagonal * 3 / 4 diff --git a/src/RandomValues.elm b/src/RandomValues.elm index 3d389f3..5d45b15 100644 --- a/src/RandomValues.elm +++ b/src/RandomValues.elm @@ -1,9 +1,12 @@ module RandomValues where type RandomValues = - { enemyAngle : Float - , enemyX : Float - , enemyY : Float - , targetX : Float - , targetY : Float + { greenPoint : PointRandomValues + , redPoint : PointRandomValues + } + +type PointRandomValues = + { angle : Float + , x : Float + , y : Float } diff --git a/src/Step.elm b/src/Step.elm index b88740a..72d3ae1 100644 --- a/src/Step.elm +++ b/src/Step.elm @@ -3,30 +3,28 @@ module Step where import Vec2 (..) import Game (..) import Player (..) -import EnemyState (..) +import Cloud (..) +import Geometry (..) import Player (playerSpeed) -import Enemy (enemySpeed, enemyMove, enemyAwayDist) +import Point (pointSpeed, pointMove, pointAwayDist) import Input (Input) -import Physics (getNewPosAndSpeed, getMove) -import Board (boardSize, boardDiagonal) -import Geometry (..) -import RandomValues (RandomValues) -import Target(..) +import Physics (getNewPosAndSpeed) +import RandomValues (..) +import CloudStep (cloudStep) step : Input -> Game -> Game -step {dir, delta, randomValues} {time, player, target, enemyState, bestScore} = - if(playerEnemiesCollision time player enemyState.enemies) then - let newBestScore = if(target.score > bestScore) then target.score else bestScore +step {dir, delta, randomValues} {time, score, player, cloud, bestScore} = + if(playerPointsCollision time player cloud.redPoints) then + let newBestScore = if(score > bestScore) then score else bestScore in initialGame player.pos newBestScore else let newTime = time + delta newPlayer = playerStep delta dir player - newTarget = targetStep player randomValues target - newEnemyState = enemyStep time randomValues enemyState + (newCloud, addScore) = cloudStep time randomValues player cloud in { time = newTime + , score = score + addScore , player = newPlayer - , target = newTarget - , enemyState = newEnemyState + , cloud = newCloud , bestScore = bestScore } @@ -36,53 +34,3 @@ playerStep dt dir player = in { pos = inBoard playerSize pos , speed = speed } - -targetStep : Player -> RandomValues -> Target -> Target -targetStep player randomValues target = - if(targetCollision player target) then - { score = target.score + 1 - , pos = randomBoardPosition (randomValues.targetX, randomValues.targetY) (0.8, 0.8) - } - else - target - -enemyStep : Float -> RandomValues -> EnemyState -> EnemyState -enemyStep time randomValues {enemies, spawn, lastSpawn} = - let isPresent enemy = (distance (enemyMove enemy time) originVec) < enemyAwayDist - presentEnemies = filter isPresent enemies - in if time > lastSpawn + spawn then - let newEnemy = - { initTime = time - , initPos = enemyInitPos randomValues - , initDest = enemyDestination randomValues - , move initTime initPos initDest time = - let delta = time - initTime - move = getMove (enemySpeed delta) (initDest `sub` initPos) - in initPos `add` move - } - in { enemies = newEnemy :: presentEnemies - , spawn = spawn - sqrt(spawn) / 50 - , lastSpawn = time - } - else { enemies = presentEnemies - , spawn = spawn - , lastSpawn = lastSpawn - } - -enemyInitPos : RandomValues -> Vec2 -enemyInitPos randomValues = - let angle = randomValues.enemyAngle * (degrees 360) - dist = boardDiagonal * 3 / 5 - in polarToCartesian angle dist - -enemyDestination : RandomValues -> Vec2 -enemyDestination randomValues = - randomBoardPosition (randomValues.enemyX, randomValues.enemyY) (1, 1) - -randomBoardPosition : (Float, Float) -> (Float, Float) -> Vec2 -randomBoardPosition (randomX, randomY) (percentX, percentY) = - let width = boardSize.x * percentX - height = boardSize.y * percentY - in { x = width * randomX - width / 2 - , y = height * randomY - height / 2 - } diff --git a/src/Target.elm b/src/Target.elm deleted file mode 100644 index 92ab4c2..0000000 --- a/src/Target.elm +++ /dev/null @@ -1,24 +0,0 @@ -module Target where - -import Board (boardSize) -import Geometry (distance) -import Vec2 (Vec2) -import Player (..) - -type Target = - { score : Int - , pos : Vec2 - } - -targetSize : Float -targetSize = 20 - -targetCollision : Player -> Target -> Bool -targetCollision player target = - (distance player.pos target.pos) < playerSize + targetSize - -initTarget : Target -initTarget = - { score = 0 - , pos = { x = 50, y = 0 } - } -- cgit v1.2.3