TLDR
Built with ReactJS, this project is a connect four game that allows human player vs. human player gameplay (alternating turns on the same computer). The project was a Frontend Mentor challenge to build the game and get it as close to the provided design specs as possible. While the player vs. player version is complete, Player vs. CPU mode will be in version 2 of the project.
MVP features
- - Responsive design
- - Player vs player game mode
- - Visual game piece animation
- - Score updates after each game
- - Starting player alternatives every game
- - View the game rules
Expected behavior
Players start on the main menu screen, where they can select a 'Player vs. Player' game or view the game rules. After selecting 'Player vs. Player,' Player 1 goes first in the first game, with the first turn alternating in subsequent rounds.
When a player wins a round, a winner modal appears, and the winning player's score is incremented by 1. Each player has 30 seconds (real-time) to take their turn. If the timer reaches zero, the other player is declared the winner, increasing their score by 1.
Clicking the 'Menu' button on the game board opens the in-game menu. In the in-game menu, players can 'Quit Game,' which directs them to the 'Main Menu,' or restart the game by clicking the 'Restart' button, resetting both player scores to zero.
Gameboard
Utilizing the CSS pseudo-elements '::before' and '::after' allowed me to create the gameboard, which consists of a shadow layer, a layer of 42 individual cells (one for each board slot), and the top layer. I set the z-index of the top layer to one and pointer events to none. With this in place, users can click on slots on the board even though they are in the middle layer. It also creates the effect of the game pieces displaying behind the top layer of the board. See the code snippet and accompanying figure.
Piece animation
To create the drop animation, I calculated the heights of the unplaced game piece at the top of a column and the height of the first available row. Next, I subtracted those heights to get the difference and used that information to update the game piece's drop animation using the transform and offset properties. I added a little bounce at the end of each drop to make it more realistic. Shout out to Thomas Campbell on Youtube for this animation approach.