High-level management of the game
- Oversees the player, obstacles, level timer, text etc
- Most functionality is farmed out to other classes
- License
- GPL-3.0-only
Methods
(static) addScoreForLevel()
Level completed, calculate points scored and add them to the total
- Points are added for every second remaining (so the player is rewarded for finishing quickly)
- Points per second are increased according to how many successive levels have been played during this session
(static) checkPlayerHit(_obstacle)
Check to see if the player is hitting an obstacle
- Simple circular collision detection: check if distance between 2 centre points is lower than the sum of the 2 objects' radii
- If we have a hit, call
Game.playerHitObstacle(_obstacle)
We actually check the squared distance between the points, as it's more efficient (by avoiding Math.sqrt()), and this method gets called hundreds of times per frame. So we must square the distance we use in the comparison too, before passing it to Game.getSquaredObstacleDistanceFromPlayer()
.
Modern CPUs are fast but this (possibly premature) optimisation isn't complicated so seems like low-hanging fruit, might win us a frame or 2 on slower devices.
Parameters
Name | Type | Description |
---|---|---|
_obstacle |
object | Obstacle to check |
(static) clearAllLevelsFromHash()
Clear out any level IDs from the URL hash parameters
(static) damagePlayer(_bounceMagnitude)
Player has collided with an 'avoid' obstacle
- Set the
Player.damagedFramesCounter
above0
to initiate the flashing/animation - Set
Controller.damageAddedSlipperiness
to make the controls more slippery/inaccurate until the above counter has come back down to0
- Play a sound effect
- Check if health has hit zero, in which case end the game
Parameters
Name | Type | Description |
---|---|---|
_bounceMagnitude |
number | Strength of the collision that caused damage |
(static) delayedStartGameplay()
Start a timer, after which gameplay will commence
Also initiate fullscreen mode (unless the player has indicated that they prefer not to).
(static) displayGameOver(_reason)
Show the 'game over' screen
- Set some variables to take the game out of play
- Start listening for a tap to restart
Parameters
Name | Type | Description |
---|---|---|
_reason |
GAMEOVER_REASON | Why the game ended |
(static) doComplete()
Game completed
Tot up final score and inform the player
(static) doLevelCompleted()
Player completed level
- Add level score to the total
- Explode all remaining 'avoid' obstacles
- Show level outro text and start a timer after which the game moves to the next level
(static) end(_reason)
End the game
Parameters
Name | Type | Description |
---|---|---|
_reason |
GAMEOVER_REASON | Why the game ended, used to decide what to display on the game over screen |
(static) getNextLevelIndex() → {number}
Calculate the index number of the next level
Usually this will just be a matter of adding 1, but sometimes levels may wrap (when the session skipped levels at the beginning).
Returns
number |
Index number for next level |
(static) getSquaredObstacleDistanceFromPlayer(_obstacle) → {number}
Find the squared distance between the centre of the player and the centre of an obstacle
Finding the distance usually involves expensive Math.sqrt()
calls, and this function gets called a lot. So remove the square root step, and in comparisons square the distance we want to compare.
Parameters
Name | Type | Description |
---|---|---|
_obstacle |
object |
Returns
number |
The (squared) distance in pixels |
(static) init()
Set up the basics, initialise other modules
(static) initEventHandlers()
Start listening for events:
- Touch / move pointer
- Tap
- Resize
(static) initFpsCounter()
Hide/show the FPS counter based on URL hash parameter
(static) initSound()
Enable/disable sound based on URL hash parameter or default to 'enabled'
(static) nextLevel()
Move to the next level, or if this is the last level the game is completed
(static) onPointerMove(event)
Update the position of the pointer
- Used for mouse pointer movement and also touch/drag movements
- Position may need to be scaled to match the canvas if the canvas is drawn small and scaled up (
GAME.PIXEL_SCALE
)
Parameters
Name | Type | Description |
---|---|---|
event |
Event | Either a |
(static) onResize()
Update layout and measurements when the viewport is resized
(static) onTap(event)
Check to see if the pointer is positioned over an active area
- There are no
HTMLElement
s here as everything is just pixels on a canvas, so we check based on boundaries of rectangles surrounding eg the sound icon, or fullscreen icon - In case this is a touchscreen device, the pointer position needs to be updated before checking the location of the tap, so the event is first passed through
Game.onPointerMove(event)
Parameters
Name | Type | Description |
---|---|---|
event |
Event | Either a |
(static) playerEats(_obstacle)
Player has eaten an obstacle
- Set the
Player.playerEatsFramesCounter
above0
to initiate the flashing/animation - Set
Player.eatenColor
to the colour of the obstacle, to be used in the above animation - Play a sound effect
Parameters
Name | Type | Description |
---|---|---|
_obstacle |
object |
(static) playerHitObstacle(_obstacle)
Player has hit an obstacle, act accordingly depending on _obstacle.type
- 'Avoid' obstacle: bounce and damage the player
- 'Collect' obstacle: eat the obstacle and decrement
Game.collectableRemaining
Parameters
Name | Type | Description |
---|---|---|
_obstacle |
object |
(static) resetAndStartFirstLevel()
Set up and start the first level
- This might not be level 1 as a URL hash parameter may indicate skipping to another level, but it's still the first level of this gameplay session
- This may be happening after a previous game finished and the player wants another go
- Reset score to 0
(static) setSoundEnabledState(_enabled)
Enable/disable audio
- Add a parameter to the URL hash to remember the preference
- Pass the state into
SoundManagerHowler.setMuteState()
Parameters
Name | Type | Description |
---|---|---|
_enabled |
boolean | The desired state |
(static) setupCurrentLevel()
Everything to do with getting the current level ready to play
- Get the ID and data for the level
- Update the URL hash with the level ID
- Call methods in other modules to update them
- Add the (non-interactive) background and floating obstacles
- Add up how many collectable obstacles there are (but don't add them to the game yet)
- Reset the game timer
- Start the level intro
(static) startLevelIntro()
Set up and display the appropriate level intro
- Show the level intro text
- If this is the first level of the session, wait for a tap
- If this is a subsequent level, start a timer, after which play will start auomatically
(static) startLevelOutro()
Start level outro sequence
(static) startPlay()
All intros etc have finished, actually start playing
(static) updateByFrameCount(_frames)
Update the elements which make up the game
Parameters
Name | Type | Description |
---|---|---|
_frames |
number | How many frames have passed since last update - ideally will be 1, but will be more when the engine is struggling to hit the target frame rate |
(static) updateLayout()
Ensure layout is in sync with the viewport
Calls similar methods in other modules.
(static) updateTimer()
Update the gameplay timer
- If time is low, set the
Game.timeIsLow
flag (which will cause the timer to start flashing) - If time is up, end the game