Skip to content
Snippets Groups Projects
Commit f794f6ac authored by Emma's avatar Emma
Browse files

collision gets handled properly for lasers with enemies and asteroids

parent 0016db08
No related branches found
No related tags found
No related merge requests found
......@@ -26,13 +26,13 @@ step secs gstate
= -- update all values
return $ (enemiesCollidePlayer .
asteroidCollidePlayer .
lasersHitEnemies .
lasersHitAsteroids .
lasersHitEnemies .
lasersHitAsteroids .
lasersHitPlayer
)
(gstate { elapsedTime = elapsedTime gstate + secs,
asteroids = updateAsteroids (asteroids gstate),
lasers = updateLasers (lasers gstate),
)
(gstate { elapsedTime = elapsedTime gstate + secs,
asteroids = updateAsteroids (asteroids gstate),
lasers = updateLasers (lasers gstate),
enemies = updateEnemies (spaceship gstate) (enemies gstate)})
-- | Handle user input
......@@ -59,11 +59,99 @@ inputKey _ gstate = gstate
--checks if a laser collides with a list of given enemies, updating both
lasersHitEnemies :: GameState -> GameState
lasersHitEnemies gstate = gstate
lasersHitEnemies gstate@(GameState { lasers = laserlist, enemies = enemylist}) = gstate { lasers = newLasers, enemies = newEnemies}
where
update = lasersCollideEnemies laserlist enemylist
newLasers = fst update
newEnemies = snd update
--returns survivors of colliding lasers and enemies
lasersCollideEnemies :: [Laser] -> [Enemy] -> ([Laser], [Enemy])
lasersCollideEnemies laserlist enemylist = lasersCollideEnemies' laserlist enemylist []
--returns laserlist as normal if there are no enemies
lasersCollideEnemies' (laser:laserlist) [] acc = (laser:laserlist, [])
--when all lasers have been handles, returns survivors of both lists
lasersCollideEnemies' [] enemylist acc = (filteredLasers, filteredEnemies)
where
filteredLasers = filter aliveL acc
filteredEnemies = filter aliveE enemylist
--goes through the laserlist one at a time, storing the handles lasers in the accumulator
lasersCollideEnemies' (laser:laserlist) enemylist acc = lasersCollideEnemies' laserlist newEnemies (newLaser : acc)
where
updates = laserCollideEnemies laser enemylist
newLaser = fst updates
newEnemies = snd updates
--returns a laser and an updated list of enemies
laserCollideEnemies :: Laser -> [Enemy] -> (Laser, [Enemy])
laserCollideEnemies laser@(Laser { badL = True } ) enemies = (laser, enemies)
laserCollideEnemies laser [] = (laser, [])
laserCollideEnemies laser enemylist = (laserUpdate, enemylistUpdated)
where
enemylistUpdated = map (laserCollideEnemy laser) enemylist
survives = map aliveE enemylist == map aliveE enemylistUpdated
laserUpdate = laser { aliveL = survives}
--given a laser and enemy, it returns an enemy as dead if it collides with the laser.
laserCollideEnemy :: Laser -> Enemy -> Enemy
laserCollideEnemy laser@(Laser { positionL = (xL, yL)}) enemy@(Enemy { positionE = (xE, yE)}) = enemy { aliveE = survives}
where
hitX = xL > xE && xL < xE + 16 --width of the enemy?
hitY = yL + 16 > yE && yL < yE + 16 --height of the laser / height of the enemy?
survives = not (hitX && hitY) --if not within bounds in both axes, enemy survives
--checks if a laser collides with a list of given asteroids, updating both
lasersHitAsteroids :: GameState -> GameState
lasersHitAsteroids gstate = gstate
lasersHitAsteroids gstate@(GameState { lasers = laserlist, asteroids = asteroidlist}) = gstate { lasers = newLasers, asteroids = newAsteroids}
where
update = lasersCollideAsteroids laserlist asteroidlist
newLasers = fst update
newAsteroids = snd update
--returns updated tuple with the lists
lasersCollideAsteroids :: [Laser] -> [Asteroid] -> ([Laser], [Asteroid])
lasersCollideAsteroids ls as = lasersCollideAsteroids' ls as []
--returns laserlist as normal if there are no asteroids
lasersCollideAsteroids' lasers [] acc = (lasers , [])
--when all lasers have been handled, returns survivors of both lists
lasersCollideAsteroids' [] asteroids acc = (filteredLasers, filteredAsteroids)
where
filteredLasers = filter aliveL acc
filteredAsteroids = filter aliveA asteroids
--goes through the laserlist one at a time, storing the hadned lasers in the accumulator
lasersCollideAsteroids' (laser:laserlist) asteroids acc = lasersCollideAsteroids' laserlist newAsteroids (newLaser : acc)
where
updates = laserCollideAsteroids laser asteroids
newLaser = fst updates
newAsteroids = snd updates
--returns a laser and an updated list of enemies
laserCollideAsteroids:: Laser -> [Asteroid] -> (Laser, [Asteroid])
laserCollideAsteroids laser@(Laser { badL = True } ) asteroids = (laser, asteroids)
laserCollideAsteroids laser [] = (laser, [])
laserCollideAsteroids laser asteroids = (laserUpdate, asteroidsUpdated)
where
asteroidsUpdated = map (laserCollideAsteroid laser) asteroids
survives = map hitCounter asteroids == map hitCounter asteroidsUpdated
laserUpdate = laser { aliveL = survives}
--given a laser and enemy, it returns an enemy as dead if it collides with the laser.
laserCollideAsteroid :: Laser -> Asteroid -> Asteroid
laserCollideAsteroid laser@(Laser { positionL = (xL, yL)}) asteroid@(Asteroid { positionA = (xA, yA), hitCounter = health, aliveA = lives}) = asteroid { hitCounter = newHealth, aliveA = survives}
where
hitX = xL > xA && xL < xA + 16 --width of the asteroid?
hitY = yL + 16 > yA && yL < yA + 16 --height of the laser / height of the asteroid?
hit = hitX && hitY
newHealth | hit = health - 1
| otherwise = health
survives = lives && (newHealth > 0) --if previously alive and health is above 0, asteroid survives
--checks if a laser collides with the player, updating both
lasersHitPlayer :: GameState -> GameState
......
......@@ -73,5 +73,4 @@ laserPicture laser@(Laser (coord1, coord2) _ False _) =
let x = fromIntegral coord1 in
let y = fromIntegral coord2 in
translate x y $ scale 0.2 0.2 $ color green (text "l")
laserPicture _ = color red (text "uhh")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment