Skip to content
A multiplayer game to test your typing speed
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
frontend
models
routes/api
validation
.gitignore
README.md
app.js
package-lock.json
package.json

README.md

rocket typer logo

View live

Rocket Typer

Rocket Typer was designed to test your typing speed and see how you stack up against other users. It was build using the following technologies:

  • Frontend: React.js with Redux, socket.io
  • Backend: Node.js with a MongoDB database
  • Other: SCSS, Express.js, Heroku, Socket.io

Features


Multiplayer

Socket.io allows for management of individual multiplayer games. Upon joining the waiting room, a connection to the waiting room websocket is opened and as soon as 3 players have joined, a game can start. By broadcasting each individual user's typing progress through Socket.io, React's local state will render a rocket for each user in the game.

Once the game has been completed, all scores are submitted via an API endpoint and the statistics for the game can be found on each user's profile or on the "Recent Games" tab of the homepage.

rocket typer

  io.on('connection', (socket) => {
    socket.on('send_progress', (data) => {
      data.playerId = socket.id;
      socket.broadcast.emit('receive_progress', data);
      socket.emit('receive_progress', data);
    });

    socket.on('playerDisconnect', (data) => {
      data.playerId = socket.id;
      socket.broadcast.emit('playerLeft', data);
    });
    
    socket.on('joined', (data) => {
      data.playerId = socket.id;
      socket.broadcast.emit('newPlayer', data);
      data.username = data.username + ` (You)`;
      socket.emit('newPlayer', data);
    });

    socket.on('startGame', (data) => {
      socket.broadcast.emit('playGame', data);
      socket.emit('playGame', data);
    });

    socket.on('disconnect', () => {
      let data = {};
      data.playerId = socket.id;
      socket.broadcast.emit('playerLeft', data);
      io.emit('disconnect', socket.id);
    });
  });


Speed Test

Utilizing keypress event listeners and React's local state, Rocket Typer is able to keep track of correctly typed letters, while calculating words per minute, and accuracy. Upon completion of the given phrase, an API call automatically saves the race, so that it can be posted to the global leaderboard and the user's profile page will reflect the most recent stats.

With React, we're able the user's progress in the game as local state to other components which allow for rendering of the rocket's trip from Earth to Mars.

rocket typer



User profiles

When visiting a user's profile, Rocket Typer presents a plethora of statistics about that user, including signup date, number of races, average speed, and top 10 fastest races.

rocket typer



Global Leaderboard

The homepage for Rocket Typer shows the global top 10 fastest races and 10 latest races via custom SQL queries to the MongoDB database.

rocket typer

  router.get('/recent', (req, res) => {
      Race
          .aggregate([
                      {$match: { 
                          }
                      },
                      {$sort: {
                          "date": -1,
                          }
                      },
                      {$sort: {
                          "averageSpeed": 1,
                          }
                      },
                      {$group: { 
                              _id: "$raceId",
                              numRaces: { $sum: 1},
                              topSpeed: { $max: "$averageSpeed" },
                              date: { $last: "$date" },
                              winner: { $last: "$username" },
                          }
                      },
                      {$sort: {
                          "date": -1,
                          }
                      },
                  ])
          .limit(10)
          .then(races => res.json(races))
          .catch(err => 
              res.status(404).json({ noracesfound: 'No races found'})
          );
  });


You can’t perform that action at this time.