- HTML Validator
- CSS Validator
- JavaScript
- Compatability
- User Stories
- Bugs
- 1. Bug: Audio is not playing on iOS mobile #55
- 2. Bug: As a user, when I start the game I should not be immediately hit by an asteroid #60
- 3. As a user I should be able to move the ship using swipes or a button keypad when playing the game on mobile #6
- 4. Bug: game is double clicking to zoom on mobile #99
- 5. Unresolved Bug: Chrome: AudioContext was not allowed to start #98
- 6. Unresolved Bug: Audio is delayed when playing on physical Android device #97
Result: No Errors or warnings
Result: No Errors or warnings
Result: No Errors or warnings
Result: No Errors or warnings
Result: No Errors, 36 warnings. Regarding the warnings, the validator found x22 generic warnings related to the use of CSS variables. The W3C validator does not support CSS variables, so these warnings are expected. The validator also warned that deepest possible browser support for stylings such as box-shadow
, transform
and user-select
were "unknown vendor extensions", however the use of webkit
, moz
and ms
prefixes in front of these items is required in order to provide full browser support. In summary, all 36 warnings were noted, but ignored.
It is also worth noting that W3C initially produced a "too few values for the property linear-gradient" error when css variables were used to define the linear-gradient colors i.e.
background: linear-gradient(to bottom, var(--red-controller), var(--maroon-controller));
A number of fixes were tried, including redefining the css variable in :root
by removing references to rgb
and declaring:
background: linear-gradient(to bottom, rgb(var(--red-controller)), rgb(var(--maroon-controller)));
However, the only solution that worked was to remove the css variable within the linear-gradient entirely, and replace with the following:
background: linear-gradient(to bottom, red, maroon);
- File: asteroid.js
Result: No Errors with x13 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
- File: bullet.js
Result: No Errors with x8 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
- File: collision-detection.js
Result: No Errors with x35 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, etc, which link to this file).
Result: No Errors with x65 unused variables, x1 undefined variable (unused variables are ignored as these variables are all used within game-utilities.js, which link to this file. The x1 undefined variable is also ignored for the same reason).
- File: game.js
Result: No Errors with x22 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
- File: game-utilities.js
Result: No Errors with x29 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file)..
- File: ship.js
Result: No Errors with x16 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
- File: local-storage.js
Result: No Errors with x14 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
- File: user-input.js
Result: No Errors with x17 undefined variables (undefined variables are ignored because these variables are all contained and defined within game-utilities.js / game-constants.js, which link to this file).
-
Browser compatability: To ensure a broad range of users can successfully use this site, it was manually tested across the 6 major browsers:
- Chrome v.87
- Edge v.85
- Firefox v.81
- Safari v.12
- Opera v.71
- Internet Explorer v.6-11 (tested via BrowserStack).
- Site responsiveness was tested using Chrome DevTools using profiles for a wide variety of devices.
- Physical Devices tested included:
- iPhone 5 (iOS: 12.4.9)
- iPhone 6 (iOS: 12.4.9)
- Samsung Galaxy A10 (Model SM-A105FN, Build/QP1A, on Android 10)
- MacBook Pro (Retina, 13", Late 2013, OS Catalina)
- Apple iMac 27" (running Windows 10 Pro ver. 2004, OS 19041.630)
Result: Both browser compatability and site responsiveness testing can be summarised in the table below. Responsiveness was good on all of the devices listed, both physical and simulated. Brower compatability was good across all the major browsers, except for Internet Explorer 6-11 where both the canvas
and grid
elements are only partially supported, or not supported at all (reference IE canvas support and IE grid support).
IE browser incompatibility: Lack of support for canvas
, grid
and css variable elements. Screenshot below shows game.html as displayed in IE 11.
TDD was employed on this project when creating and interacting with the Asteroid, Bullet and Ship objects. The TDD cycle followed the red, green, refactor approach (...read more on this methodology via this codecademy article).
Jasmine 3.6.0 was used to automate these tests, and they can be found in the testing/spec folder. To run all of the automated tests use the spec-runner.html file.
Result: 46 specs, 0 failures.
Further automated testing was performed using Chrome Dev Tools - Lighthouse. Lighthouse is an open-source, automated tool for improving the quality of web pages. It performs audits under the following headers:
- Performance
- Accessibility
- Best Practices
- SEO
Result: see summary results below for Desktop game.html
Result: see summary results below for Mobile game.html
Recommendations: Performance improvements are recommended in the following areas:
- Enable text compression: in order to help the page load faster by up to 1.05s, it is recommended to compress the .js and .css files. It is also recommended to minify the .js to reduce payload sizes by up to 0.45s.
- Remove invisible text: there is a flash of invisible text (FOIT) while the game.html page waits on Font-Awesome to load. The game-pad controller briefly displays blank text for the up, left, and right button icons.
- Use passive listeners to improve scrolling performance: the browser does not know if the event listeners on game.html will prevent scrolling, so it waits for the listener to finish executing before scrolling the page. The recommendation is to add a
passive
flag to every event listener e.g.
document.addEventListener('touchstart', onTouchStart, {passive: true});
Conclusion: As the project is sitting at 99% performance on Desktop, and 95% on Mobile, the suggestions are taken under advisement, but are not implemented at this point in time.
Result: All user stories have been successfully implemented, with a ✅ to denote items that have been implemented in this game.
- The full list of user stories with relevant screenshots can be viewed in this document.
"As a user, I ______________________________________________"
- ✅ need to have a responsive game, playable from any device (mobile, tablet, desktop).
- ✅ should have an invincibility shield for a set period of time when game restarts.
- ✅ should see GAME OVER when I lose all my lives.
- ✅ should progress through the game via Levels i.e. Level 1, Level 2, etc.
- ✅ should have a triangular ship to match the original game.
- ✅ should see irregular shaped asteroids.
- ✅ should see an explosion when I shoot an asteroid.
- ✅ should be able to turn soundfx on and off as a menu option.
- ✅ should hear different sound-fx while playing the game.
- ✅ should have a visual cue for the number of lives I have during the game.
- ✅ should be able to shoot the asteroids with bullets.
- ✅ should be able to shoot bullets using keyboard input.
- ✅ should be able to move the ship using keyboard input.
- ✅ should be able to move my ship forwards, backwards, left, and right.
- ✅ should have my ship render onto the centre of the canvas at the start of the game.
- ✅ should feel friction when my ship is no longer moving forward, and my ship should finally stop.
- ✅ should be given 3 lives at the start of the game.
- ✅ should have a visual cue (explosion) when my ship is hit by an asteroid.
- ✅ should have a visual cue (afterburner at back of ship) when my ship is thrust forward.
- ✅ should see my score increment every time I shoot an asteroid. Different asteroids get different points.
- ✅ should see my ship reappear on the opposite side of the screen if I move off-screen.
- ✅ should see the large and medium sized asteroids break up into x2 smaller asteroids when hit by a bullet.
- ✅ should find the game easy to begin with, and as the game progresses it should get increasingly more difficult.
- ✅ should be able to shoot bullets by tapping a "FIRE" button when on mobile.
- ✅ should be able to move the ship using swipes or a button keypad when playing the game on mobile.
- ✅ should be able to click on a HIGH SCORES menu button, and be presented with the highest score.
Using GitHub Projects, a full list of closed bugs can be found here. In this section we will highlight some of the more interesting ones.
Audio was originally added to the game using standard Audio() object instantiation:
let audio = new Audio();
audio.play();
// see original code here
This code worked fine on Desktop, but when testing on a physical mobile device (iPhone 5, iPhone 6), the audio would not play. Research revealed the many issues that can crop up when adding audio to a mobile HTML5 game, mostly due to browser/performance limitations. The solution, in this instance, was to make use of a 3rd party library, namely Howler.js. By linking to the howler.js cdn, and adding code below, mobile audio worked.
const fireSound = new Howl({
src: ["assets/audio/fire.webm",
"assets/audio/fire.mp3"]
});
//see full solution code here
When starting a new game, or restarting with a new life, the ship is placed in the centre of the screen. However, there was always a possibility that an asteroid would immediately collide with the ship, giving the player no time to react. This bug was resolved in 2 parts:
- For a new game, create a collision zone which cannot be entered by an asteroid.
- For a new life, make the ship invincible for a set period of time.
Item 1, new game, was solved by randomly placing the asteroids onto the canvas, provided they do not collide with the ship within a specific radius.
//see full solution code here.
Item 2, new life, was more complicated, and required a 3-second countdown timer SHIP_INVINCIBILITY_TIMEOUT
, as well as ensuring there was no collision detection between asteroids and the ship during this time period, and finally displaying an invincibility cloak for the ship.
//see full solution code here.
3. As a user I should be able to move the ship using swipes or a button keypad when playing the game on mobile #6
On mobile, this game required the development of a gamepad controller. The controller had to be designed for usability, meaning button positioning and size required consideration.
- Initially, I coded a touch controller within a second
canvas
element, resulting in Controller 1.0 :
The issue with Controller 1.0 was that it was difficult to make the buttons mobile responsive across a large number of devices.
- To solve this bug, I moved over to
span
elements, abandoning thecanvas
element. This resulted in Controller 2.0 :
- Controller buttons were now fully mobile responsive, and easier to style, resulting in Controller 3.0 :
- Physical devices tested:
- Samsung Galaxy SM-A105FN Build/QP1A using Chrome 87.0.4280.86 on Android 10.
- iPhone 5 (iOS: 12.4.9, Chrome v.87.0.4280.77)
- iPhone 6 (iOS: 12.4.9 Chrome v.87.0.4280.77)
- This was 2 issues in one:
- Firstly, a user could double tap anywhere on index.html, and the screen would automatically zoom in.
- This was resolved by making use of the
pointer-events
CSS property, ie:
- This was resolved by making use of the
* {
pointer-events: none
}
and then enabling
pointer-events: auto
on the relevant elements that need to be clicked (i.e. menu buttons, and game-pad controller buttons).
- Secondly, while playing the game on iOS mobile, the user could "pinch-to-zoom". This was most noticeable when the user was holding down the thrust key, and trying to shoot or move left/right at the same time, causing the entire screen to zoom in. This is actually an accessibility feature of iOS +10. Every solution suggested was tried from stack overflow from both here and here, until the following code was added to resolve the bug:
document.addEventListener('touchmove', (event) => {
event.preventDefault();
}, {passive: false });
While physically testing, it is worth noting that responsiveness from the controller buttons on iOS mobile was actually better when the above code was not included. However, this enhanced responsiveness had to be balanced with the poor UX of having the screen zoom in/out every time the user pressed more than one controller button at once.
- Device tested: Desktop using Chrome 87.0.4280.88 on Windows 10 Pro, Version 2004, OS build 19041.630.
- This bug was noticed when manually refreshing the browser window on game.html and high-score.html using the Chrome browser. Note: this bug is only applicable to Chrome.
- The following warning was displayed in the console log:
- This warning is directly related to Chrome's Autoplay Policy Changes, which states that it is good practice to wait for user interaction before starting audio playback. As this is a warning, and did not interfere in any way with the game functionality or playability, the warning was ignored. A quick fix would be to redirect the user back to index.html when the browser is refreshed. The following code was tested and worked well:
function checkForReload() {
let evTypep = window.performance.getEntriesByType("navigation")[0].type;
if (evTypep == "reload") {
window.location.replace("index.html");
}}
- Further testing is required to remove the warning entirely.
- Physical device tested: Samsung Galaxy SM-A105FN Build/QP1A using Chrome 87.0.4280.86 on Android 10. Note: bug is only related to Android mobile. iOS has no audio lag issues.
- There is a delay of approx. 300-900ms from the time the shoot button is pressed, to when the audio is heard.
- Initial research pointed to 300ms tap delay, gone away, but this did not resolve the issue. Further testing is required to solve this bug.