Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • 9562850/fp-asteroids
1 result
Show changes
Commits on Source (3)
......@@ -16,8 +16,8 @@ step secs gstate@(GameState{screen = MainMenu}) = do -- retrieve highscores
scores <- highscoresFromFile
return gstate {highscores = scores}
step secs gstate
= -- Normal tick
checkDeath $ checkPowerupCollision $ applyKeys $ tickNotification $ tickPowerup $ tickMeteors secs $ tick secs gstate
= -- Normal tick
checkDeath $ checkPowerupCollision $ applyKeys $ tickNotification $ tickPowerup $ tickMeteors secs $ checkBulletCollision $ tick secs gstate
-- Handle all the logic not directly influenced by the user
tick :: Float -> GameState -> GameState
......@@ -305,6 +305,33 @@ updateBullet secs (Bullet (x,y) angle speed) = do
let (rx, ry) = (cos angle, sin angle)
let (x', y') = (x + secs * speed * rx, y + secs * speed * ry)
Bullet (x', y') angle speed
-- Function to get the collision radius based on meteor size
collisionRadius :: Int -> Float
collisionRadius size = case size of
1 -> 20
2 -> 40
3 -> 60
_ -> 20 -- Default case, assuming size 1 if size is not 1, 2, or 3
checkBulletCollision :: GameState -> GameState
checkBulletCollision gstate@(GameState {spaceShip, meteors, player}) =
let shipBullets = bullets spaceShip
playerScore = score player
(newMeteors, remainingBullets, newScore) = foldl handleCollision ([], shipBullets, playerScore) meteors
in gstate { meteors = newMeteors, spaceShip = spaceShip { bullets = remainingBullets }, player = (player { score = newScore }) }
handleCollision :: ([Meteor], [Bullet], Score) -> Meteor -> ([Meteor], [Bullet], Score)
handleCollision (remainingMeteors, remainingBullets, score) meteor =
let (collidedBullets, nonCollidedBullets) = partition (\(Bullet loc _ _) -> collidesWith (collisionRadius (size meteor)) loc (coordinates meteor)) remainingBullets
in if null collidedBullets
then (meteor : remainingMeteors, remainingBullets, score)
else case size meteor of
1 -> (remainingMeteors, nonCollidedBullets, score + 100)
2 -> (meteor { size = size meteor - 1 } : remainingMeteors, nonCollidedBullets, score + 50)
3 -> (meteor { size = size meteor - 1 } : remainingMeteors, nonCollidedBullets, score + 20)
anyBulletCollides :: [Bullet] -> Meteor -> Bool
anyBulletCollides bullets meteor = any (\(Bullet loc _ _) -> collidesWith (collisionRadius (size meteor)) loc (coordinates meteor)) bullets
translateMeteor :: Float -> Meteor -> Meteor
translateMeteor secs (Meteor (x,y) angle speed lives) = do
......
......@@ -30,7 +30,7 @@ data Specifications = Specs {
}
type Size = Int
data Meteor = Meteor Location Orientation Velocity Size
data Meteor = Meteor { coordinates :: Location, directoin :: Orientation, pace :: Velocity, size :: Size}
data UFO = UFO Location Orientation Velocity Bullet
type Score = Int
type Name = String
......
("Player", 410)
("Player", 10)
("Gerda", 9)
("Billy", 2)