Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
FP Asteroids
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Edwin
FP Asteroids
Compare revisions
e1f99fbe628509ab3e31bdbc19531259ec0aa1bf to 71c1598de65bc52c2a21b05c9aa10154e5031490
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
9562850/fp-asteroids
Select target project
No results found
71c1598de65bc52c2a21b05c9aa10154e5031490
Select Git revision
Swap
Target
9562850/fp-asteroids
Select target project
9562850/fp-asteroids
1 result
e1f99fbe628509ab3e31bdbc19531259ec0aa1bf
Select Git revision
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source (8)
meteor is being drawn, but only one
· 5d7a38b5
Boris
authored
4 months ago
5d7a38b5
adds random meteor when m is pressed
· 5af9f6da
Boris
authored
4 months ago
5af9f6da
cleaned up a bit
· cca0609e
Boris
authored
4 months ago
cca0609e
meteors are able to move to the center
· 27dfafb5
Boris
authored
4 months ago
27dfafb5
different sizes meteors spawn outside screen and move inwards
· 5518feea
Boris
authored
4 months ago
5518feea
spawns random meteors on full screen without input
· c8105305
Boris
authored
4 months ago
c8105305
added spaceship to step
· fd2d94a3
Boris
authored
4 months ago
fd2d94a3
Merge meteor branch, meteors now spawn on a separate MeteorTimer
· 71c1598d
Edwin
authored
4 months ago
71c1598d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/Controller.hs
+72
-2
72 additions, 2 deletions
src/Controller.hs
src/Model.hs
+7
-4
7 additions, 4 deletions
src/Model.hs
src/View.hs
+41
-3
41 additions, 3 deletions
src/View.hs
with
120 additions
and
9 deletions
src/Controller.hs
View file @
71c1598d
...
...
@@ -14,7 +14,7 @@ import Data.Ord(comparing)
step
::
Float
->
GameState
->
IO
GameState
step
secs
gstate
=
-- Normal tick
return
$
checkDeath
$
checkPowerupCollision
$
applyKeys
$
tickNotification
$
tickPowerup
$
tick
secs
gstate
return
$
checkDeath
$
checkPowerupCollision
$
applyKeys
$
tickNotification
$
tickPowerup
$
tickMeteors
secs
$
tick
secs
gstate
-- Handle all the logic not directly influenced by the user
tick
::
Float
->
GameState
->
GameState
...
...
@@ -25,6 +25,22 @@ tick secs gstate@(GameState {screen = Game, elapsedTime, powerupTimer}) = gstate
}
tick
_
gstate
=
gstate
-- Don't do anything while the game is not in progress
{-
| elapsedTime gstate + secs > nO_SECS_BETWEEN_CYCLES
= -- add a new meteor
do randomNumber <- randomIO
let location = locationOutsideScreen (randomLocation randomNumber) (randomOrientation randomNumber)
orientation = randomOrientation randomNumber + pi
size = randomSize randomNumber
newMeteor = Meteor location orientation Forward size
newMeteors = newMeteor : meteors gstate
return $ GameState { meteors = map (translateMeteor 10) newMeteors, infoToShow = ShowMeteors newMeteors, elapsedTime = 0, spaceShip = spaceShip gstate }
| otherwise
= -- Just translate the existing meteors and update the elapsed time
return $ gstate {meteors = map (translateMeteor 10) (meteors gstate), infoToShow = ShowMeteors (meteors gstate), elapsedTime = elapsedTime gstate + secs }
>>>>>>> origin/meteor
-}
-- | Handle user input
input
::
Event
->
GameState
->
IO
GameState
input
e
gstate
@
(
GameState
{
screen
=
Game
})
=
return
(
inputKey
e
gstate
)
...
...
@@ -77,6 +93,44 @@ inputDS _ gstate = gstate
-- GAME SECTION :
meteorSpeed
::
Velocity
meteorSpeed
=
100
spawnMeteor
::
StdGen
->
(
Meteor
,
StdGen
)
spawnMeteor
gen
=
do
let
orientation
=
randomOrientation
gen
location
=
locationOutsideScreen
(
randomLocation
gen
)
(
orientation
+
pi
)
size
=
randomSize
gen
((
Meteor
location
orientation
meteorSpeed
size
),
newGen
gen
)
-- | Generate a random location on the y-axis
randomLocation
::
StdGen
->
Location
randomLocation
gen
=
let
(
y
,
_
)
=
randomR
(
-
50
,
50
)
gen
in
(
0
,
y
)
-- | Generate a random orientation for the meteor
randomOrientation
::
StdGen
->
Orientation
randomOrientation
gen
=
let
(
angle
,
_
)
=
randomR
(
0
,
2
*
pi
)
gen
in
angle
-- | Generate a random starting location for the meteor
locationOutsideScreen
::
Location
->
Orientation
->
Location
locationOutsideScreen
(
x
,
y
)
angle
=
do
let
(
rx
,
ry
)
=
(
cos
angle
,
sin
angle
)
let
(
x'
,
y'
)
=
(
x
+
800
*
rx
,
y
+
500
*
ry
)
(
x'
,
y'
)
-- | Generate a random size for the meteor
randomSize
::
StdGen
->
Int
randomSize
gen
=
let
(
size
,
_
)
=
randomR
(
1
,
3
)
gen
in
size
newGen
::
StdGen
->
StdGen
newGen
gen
=
snd
$
split
gen
inputKey
::
Event
->
GameState
->
GameState
inputKey
(
EventKey
(
SpecialKey
KeyEsc
)
_
_
_
)
gstate
=
(
initialState
(
seed
gstate
))
{
player
=
(
player
gstate
)
{
lives
=
3
,
score
=
0
},
highscores
=
highscores
gstate
}
inputKey
(
EventKey
key
Down
_
_
)
gstate
=
gstate
{
keys
=
insert
key
$
keys
gstate
}
...
...
@@ -114,6 +168,16 @@ tickNotification gstate@(GameState {powerupTimer, elapsedTime})
|
powerupTimer
>
0
&&
elapsedTime
>
3
=
gstate
{
notification
=
"You have just claimed a powerup!"
}
|
otherwise
=
gstate
{
notification
=
""
,
tooltip
=
""
}
meteorSpawnDelay
::
Float
meteorSpawnDelay
=
2
tickMeteors
::
Float
->
GameState
->
GameState
tickMeteors
secs
gstate
@
(
GameState
{
meteorTimer
,
seed
})
|
meteorTimer
>
meteorSpawnDelay
=
do
let
(
newMeteor
,
newGen
)
=
spawnMeteor
seed
gstate
{
meteors
=
map
(
translateMeteor
secs
)
$
newMeteor
:
(
meteors
gstate
),
seed
=
newGen
,
meteorTimer
=
0
}
|
otherwise
=
gstate
{
meteors
=
map
(
translateMeteor
secs
)
$
meteors
gstate
,
meteorTimer
=
meteorTimer
+
secs
}
checkDeath
::
GameState
->
GameState
checkDeath
gstate
@
(
GameState
{
screen
=
Game
,
player
=
(
Player
0
score
name
)})
=
gstate
{
screen
=
Death
,
highscores
=
sortHighscores
(
insert
(
name
,
score
)
(
highscores
gstate
))
}
...
...
@@ -199,4 +263,10 @@ updateBullet :: Float -> Bullet -> Bullet
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
\ No newline at end of file
Bullet
(
x'
,
y'
)
angle
speed
translateMeteor
::
Float
->
Meteor
->
Meteor
translateMeteor
secs
(
Meteor
(
x
,
y
)
angle
speed
lives
)
=
do
let
(
rx
,
ry
)
=
(
cos
angle
,
sin
angle
)
let
(
x'
,
y'
)
=
(
x
+
speed
*
secs
*
rx
,
y
+
speed
*
secs
*
ry
)
Meteor
(
x'
,
y'
)
angle
speed
lives
This diff is collapsed.
Click to expand it.
src/Model.hs
View file @
71c1598d
...
...
@@ -10,7 +10,6 @@ type Location = (Float, Float)
type
Orientation
=
Float
data
Bullet
=
Bullet
Location
Orientation
Velocity
type
Lives
=
Int
data
Spaceship
=
Spaceship
{
location
::
Location
,
orientation
::
Orientation
...
...
@@ -27,9 +26,9 @@ data Specifications = Specs {
,
fireRate
::
Float
-- bullets per second
}
data
Meteor
=
Meteor
Location
Velocity
Lives
type
Size
=
Int
data
Meteor
=
Meteor
Location
Orientation
Velocity
Size
data
UFO
=
UFO
Location
Orientation
Velocity
Bullet
type
Score
=
Int
type
Name
=
String
type
Highscore
=
(
Name
,
Score
)
...
...
@@ -49,7 +48,9 @@ data GameState = GameState {
,
tooltip
::
String
-- Small addition to notification
,
elapsedTime
::
Float
,
powerupTimer
::
Float
,
meteorTimer
::
Float
,
spaceShip
::
Spaceship
,
meteors
::
[
Meteor
]
,
powerup
::
Maybe
Powerup
,
seed
::
StdGen
-- Each game has its own 'seed' which allows for pure randomness
}
...
...
@@ -71,11 +72,13 @@ initialState seed = GameState {
,
powerupTimer
=
0
,
spaceShip
=
Spaceship
(
0
,
0
)
0
0
[]
seed
0
defaultSpecs
,
powerup
=
Nothing
,
meteors
=
[]
,
notification
=
""
,
tooltip
=
""
,
seed
=
seed
,
meteorTimer
=
0
,
highscores
=
[
(
"Player1"
,
2
),
(
"Player2"
,
1
)
]
}
\ No newline at end of file
}
This diff is collapsed.
Click to expand it.
src/View.hs
View file @
71c1598d
...
...
@@ -6,12 +6,13 @@ import Model
import
Graphics.Gloss
import
Text.Printf
import
System.Random
view
::
GameState
->
IO
Picture
view
=
return
.
viewPure
viewPure
::
GameState
->
Picture
viewPure
gstate
@
(
GameState
{
screen
,
spaceShip
,
player
,
powerupTimer
,
powerup
,
elapsedTime
,
notification
,
tooltip
,
highscores
})
=
case
screen
of
viewPure
gstate
@
(
GameState
{
screen
,
meteorTimer
,
spaceShip
,
player
,
powerupTimer
,
powerup
,
elapsedTime
,
notification
,
tooltip
,
highscores
})
=
case
screen
of
MainMenu
->
do
let
title
=
color
white
(
textPlus
(
-
200
,
250
)
0.5
"ASTEROIDS"
)
let
playerName
=
color
yellow
(
textPlus
(
-
50
,
150
)
0.3
$
show
(
name
player
))
...
...
@@ -57,10 +58,13 @@ viewPure gstate@(GameState {screen, spaceShip, player, powerupTimer, powerup, el
let
score'
=
color
yellow
(
textPlus
(
textX
,
textY
-
30
)
textSize
$
"score: "
++
show
(
score
player
))
let
velocity'
=
color
green
(
textPlus
(
textX
,
textY
-
60
)
textSize
$
"speed: "
++
show
(
round
$
velocity
spaceShip
)
++
" m/s"
)
let
time
=
color
green
(
textPlus
(
textX
,
textY
-
90
)
textSize
$
"time: "
++
printf
"%.3f"
elapsedTime
++
" s"
)
let
debug
=
color
red
(
textPlus
(
textX
,
textY
-
120
)
textSize
$
"meteortimer: "
++
printf
"%.3f"
meteorTimer
)
let
notif
=
color
white
(
textPlus
(
-
100
,
textY
)
textSize
$
notification
)
let
tooltip'
=
color
(
greyN
0.5
)
(
textPlus
(
-
50
,
textY
-
30
)
(
textSize
-
0.06
)
$
tooltip
)
pictures
(
player'
:
score'
:
tooltip'
:
notif
:
powerup'
:
time
:
velocity'
:
ship
:
bullets'
)
let
meteors'
=
pictures
(
map
drawMeteor
(
meteors
gstate
))
pictures
(
debug
:
player'
:
meteors'
:
score'
:
tooltip'
:
notif
:
powerup'
:
time
:
velocity'
:
ship
:
bullets'
)
where
(
a
,
b
,
c
)
=
makeSpaceship
spaceShip
30
bs
=
map
(
polygon
.
makeBullet
5
)
(
bullets
spaceShip
)
...
...
@@ -98,6 +102,16 @@ makeBullet o (Bullet loc angle _) = do
let
(
a
,
b
,
c
)
=
makeTriangle
o
loc
angle
[
a
,
b
,
c
]
makeMeteor
::
Meteor
->
(
Point
,
Point
,
Point
,
Point
,
Point
,
Point
)
makeMeteor
(
Meteor
loc
angle
_
1
)
=
makeHexagon
20
loc
angle
makeMeteor
(
Meteor
loc
angle
_
2
)
=
makeHexagon
40
loc
angle
makeMeteor
(
Meteor
loc
angle
_
3
)
=
makeHexagon
60
loc
angle
drawMeteor
::
Meteor
->
Picture
drawMeteor
meteor
=
color
white
(
polygon
[
a
,
b
,
c
,
d
,
e
,
f
])
where
(
a
,
b
,
c
,
d
,
e
,
f
)
=
makeMeteor
meteor
-- Creates the 3 points of a triangle which are centered on a Location,
-- The triangle is oriented in a certain way and always has the same size (o)
makeTriangle
::
Float
->
Location
->
Orientation
->
(
Point
,
Point
,
Point
)
...
...
@@ -114,4 +128,28 @@ makeTriangle o (locx, locy) angle = do
let
(
x2'
,
y2'
)
=
translate
$
rotate
(
x2
,
y2
)
let
(
x3'
,
y3'
)
=
translate
$
rotate
(
x3
,
y3
)
((
x1'
,
y1'
),
(
x2'
,
y2'
),
(
x3'
,
y3'
))
\ No newline at end of file
((
x1'
,
y1'
),
(
x2'
,
y2'
),
(
x3'
,
y3'
))
makeHexagon
::
Float
->
Location
->
Orientation
->
(
Point
,
Point
,
Point
,
Point
,
Point
,
Point
)
makeHexagon
o
(
locx
,
locy
)
angle
=
do
let
gen
=
mkStdGen
2024
let
angley
=
fst
(
randomR
(
negate
locy
-
200
,
negate
locy
+
200
)
gen
)
/
100
let
anglex
=
negate
locx
/
100
let
translate
(
x
,
y
)
=
(
x
+
anglex
,
y
+
angley
)
let
(
x1
,
y1
)
=
(
locx
-
o
,
locy
)
--left corner
let
(
x2
,
y2
)
=
(
locx
-
(
o
/
2
),
locy
+
o
)
--left top corner
let
(
x3
,
y3
)
=
(
locx
+
(
o
/
2
),
locy
+
o
)
--right top corner
let
(
x4
,
y4
)
=
(
locx
+
o
,
locy
)
--right corner
let
(
x5
,
y5
)
=
(
locx
+
(
o
/
2
),
locy
-
o
)
--right bottom corner
let
(
x6
,
y6
)
=
(
locx
-
(
o
/
2
),
locy
-
o
)
--left bottom corner
let
(
x1'
,
y1'
)
=
translate
(
x1
,
y1
)
let
(
x2'
,
y2'
)
=
translate
(
x2
,
y2
)
let
(
x3'
,
y3'
)
=
translate
(
x3
,
y3
)
let
(
x4'
,
y4'
)
=
translate
(
x4
,
y4
)
let
(
x5'
,
y5'
)
=
translate
(
x5
,
y5
)
let
(
x6'
,
y6'
)
=
translate
(
x6
,
y6
)
((
x1'
,
y1'
),
(
x2'
,
y2'
),
(
x3'
,
y3'
),
(
x4'
,
y4'
),
(
x5'
,
y5'
),
(
x6'
,
y6'
))
\ No newline at end of file
This diff is collapsed.
Click to expand it.