Skip to content

Frontend_Logic

Natsu edited this page May 30, 2024 · 7 revisions

Custom Hooks

Custom hooks used in the game:

  1. usePiece manages the state of the current falling tetromino, handles its rotation, updates its position, and resets it when needed. It ensures collision detection and provides flexibility for single and multiplayer modes by adjusting tetromino generation based on the game mode (link).

  2. useStage manages the game stage state. It updates the game stage based on the current falling tetromino, clears filled rows, and handles collision detection. It integrates with the multiplayer game context for synchronization and adjusts gameplay logic based on the game mode (link).

  3. useInterval is designed for handling intervals. It sets up and clears intervals based on the provided callback function and delay duration. This hook utilizes the useRef and useEffect hooks to maintain the latest callback function and manage interval execution. It ensures that the provided callback is invoked at the specified interval, maintaining proper cleanup when the component unmounts or when the delay changes (link).

  4. useGameStatus manages game-related status such as score, rows, and level. It utilizes state variables to track and update these values based on the number of rows cleared and the current game mode. Additionally, it calculates the score based on the number of rows cleared and the current level, updating the score accordingly. This hook also interacts with the useMultiplayerGameContext hook (provided by MultiplayerGameContext) to update the score in multiplayer mode when necessary. It encapsulates the logic for managing game status, providing a clean and reusable solution for components that require access to game-related data and functionality (link).

  5. useTetrominoStage manages the Tetromino stage of the next tetromino to be selected by the user in multiplayer mode. It maintains state variables for the selected Tetromino index, the Tetromino stage, and the currently selected Tetromino shape. This hook provides functions to update the Tetromino stage with a new Tetromino, rotate the currently active Tetromino, and switch between different Tetromino shapes. Additionally, it ensures that the Tetromino stage reflects the changes made to the selected Tetromino shape, facilitating the rendering of Tetrominos in the game stage link.

Single Player Game Logic

The SinglePlayer page manages the game logic for this mode. The stage where the tetrominos fall in GameArea is generated by an array of size:.

export const STAGE_WIDTH = 12;
export const STAGE_HEIGHT = 20;

export const createStage = () =>

Array.from(Array(STAGE_HEIGHT), () =>
new Array(STAGE_WIDTH).fill([0, CLEAR_CELL])
);
  1. Start: Begin with the start of the game.
  2. Initialize Game: Initialize the game by creating an initial game stage, setting up variables, and displaying the game area.
  3. First piece - Automatically generate a random piece using the useInterval() hook.
  4. Game Loop:
    • Check Input: Check for player input to move the Tetromino piece left, right, down, or to rotate.
    • Update Piece Position: Update the position of the Tetromino piece based on player input.
    • Check Collision: Check for collisions between the Tetromino piece and the game stage or other pieces. Then automatically drop the Tetromino piece down the game stage at regular intervals using the useInterval() hook.
    • Check Rows Cleared: Check if any rows are filled with Tetromino pieces and need to be cleared.
    • Update Game Status: Update game status such as score, level, and rows cleared.
    • Check Game Over: Check if the game is over due to reaching the top of the game stage.
  5. Handle Game Over: If the game is over, display the game over message and end the game loop.
  6. Pause/Resume Game: Check for player input to pause or resume the game.
  7. End: End the game.

The diagram is shown below.

Single player game logic diagram

Multiplayer

Multiplayer Game Context

The MultiplayerGameProvider context manages the state and functionality related to a multiplayer game session. It includes state variables for the user-selected tetromino, player information such as name, turns remaining, penalties, and score, as well as the current turn state including whether a penalty was incurred. This context also handles the logic for updating player info, scoring, penalties, and managing turn states throughout the game session.

Key features of this context include:

  • Tracking user-selected tetromino and player information.
  • Managing turn states and handling state transitions based - on game events.
  • Updating player score and penalties.
  • Sending game-related messages over the WebSocket connection.

The context provides a set of functions and state variables to interact with the multiplayer game state, allowing components to access and update game-related data seamlessly.

Turn State Machine

The state machine is encapsulated inside a context - MultiplayerGameContext.

  1. Select Tetromino (SELECT_TETROMINO): Players select which Tetromino to play with; triggers the game to enter the PLAY_TURN state.

  2. Play Turn (PLAY_TURN): Active game state where players can move, rotate, and drop Tetrominoes.

  3. Update Player Info (UPDATE_PLAYER_INFO): Updates necessary player details like score and turns remaining after each move or game event.

  4. Send Message (SEND_MESSAGE): Transmits messages concerning player status or game results to the server.

  5. End Turn (END_TURN): Concludes the player's turn. Resets any turn related state and waits for user's next move until the turn timer expires (30 sec).

WebSocket Context

The WebSocketProvider context manages the WebSocket connection and message handling for communication with a WebSocket server. It includes state variables for tracking connection status, received messages (communication, game, and error messages), and game room details. This context also provides functions for sending messages, setting the current player, updating game room details, and determining the winner of the game.

Key features of this context include:

  • Establishing a WebSocket connection with the server.
  • Handling received messages and categorizing them based on message type.
  • Managing game room details and current player information.
  • Providing functions to interact with the WebSocket connection and game state.

The context ensures that components can easily access WebSocket-related functionality and data, enabling seamless integration of real-time communication features into the application.

WebSocket Initialization

Establishes a connection to the WebSocket server when a player enters the lobby. Handles messages received from the server by categorizing them into command messages, game messages, and error messages.

Message Types and Handling

  • Command Messages (COMM_MESSAGE): Used for general commands like joining game rooms, broadcasting codes, or setting up player statuses.

  • Game Messages (GAME_MESSAGE): Related to the gameplay mechanics, such as sending game updates, player turns, or final scores.

  • Error Messages (ERROR_MESSAGE): Communicate errors encountered during the session, such as disconnection issues or game errors.

WebSocket Communication below explains the messages in detail.

Lobby

The MultiplayerLobby component manages the game logic for this mode. The websocket is connection is established as soon as the player enters the lobby. Player one generates a game code and Player Two enters the code. On success, both players join the same game room allotted by the server.

Game Logic

The MultiplayerGameRoom page manages the game logic for this mode.

  1. Initialize Game: Initialize the game room by creating an initial game stage, setting up variables, and displaying the game area for both players. Ensure webSocket connection status is IN_GAME_ROOM to sync game actions between players in real-time.

  2. Game Loop:

    • Select Tetromino - Each player has the option to select a tetromino. If the timer expires, a randomly generated tetromino is drops in the game area and the player incurs a penalty.
    • Check Input: Check for player input to move the Tetromino piece left, right, down, or to rotate.
    • Update Piece Position: Update the position of the Tetromino piece based on player input. -Check Collision: Check for collisions between the Tetromino piece and the game stage or other pieces.
    • Drop Piece: Drop the selected tetromino
    • Check Rows: Check if any rows are filled with Tetromino pieces and need to be cleared. Sync any row clearances and score updates across players.
    • Update Game Status: Update game status such as score, level, and rows cleared. Broadcast these updates to both players.
    • Check Game Over: Check if the game is over for either player due to a collision at the top of the game stage or other game-ending conditions. Communicate the game over state to both players.
  3. Handle Game Over: If the game is over for one or both players send a game over message through WebSocket. Display the game over message and wait for the winner from the websocket server.

  4. End: End the game and close the WebSocket connection and return players to the home page.

The diagram for each player is shown below.

Multiplayer player game logic diagram

WebSocket Communication

As mentioned earlier in WebSocket Context, messages are categorized into Command Messages, Game Messages, and Error Messages. Each message type serves a specific purpose and facilitates different aspects of the multiplayer gaming experience.

Command Messages (COMM_MESSAGE):

  • WAITING_FOR_CODE: Sent by PLAYER_TWO to indicate that they are waiting for a game code to join a game room.
  • BROADCAST_CODE: Sent by PLAYER_ONE to broadcast the game code to be used for joining the game room.
  • READY_TO_JOIN_GAME_ROOM: Sent by PLAYER_TWO to indicate readiness to join a game room.
  • JOINED_GAME_ROOM: Indicates successful joining of a game room.
  • DISCONNECTED: Indicates a disconnection event, which could occur due to various reasons.

Game Messages (GAME_MESSAGE):

  • TURN_INFO: Provides information about a player's turn, including the Tetromino selection and game-related updates.
  • GAME_OVER: Indicates that the game is over, either due to a player winning or the game reaching a certain condition.
  • PLAY_GAME: Instructs a player to start playing the game.
  • WINNER: Communicates the winner of the game.
  • WAITING_PLAYER: Indicates that the game is waiting for another player to join or perform an action.

Error Messages (ERROR_MESSAGE):

  • CLIENT_TIMEOUT_ERROR: Indicates a timeout error on the client side.
  • COMMUNICATION_ERROR: Communicates errors related to communication between client and server.

WebSocket Message Interface

The custom type defined in gameTypes is shown below:

  export interface WebSocketMessage {
     messageType: string;
     messageName: string;
     isConnectedToServer: boolean;
     messageBody: string;
     player: string;
     commStatus: string;
  }

The WebSocketMessage interface defines the structure of messages exchanged between the client and the server via WebSocket communication. Each WebSocket message conforms to this interface, ensuring consistency in the data format and content across the communication channel enabling effective communication and coordination between the client-side and server-side.

Here's a brief description of each property in the WebSocketMessage interface:

  • messageType: Represents the type of the message, indicating whether it's a communication message, a game-related message, or an error message. It helps in categorizing and distinguishing the purpose of the message.

  • messageName: Provides a descriptive name or identifier for the message, specifying its particular purpose or content within the defined message type. For example, in a game-related message, this property might indicate the specific game event or update being conveyed.

  • isConnectedToServer: A boolean flag that indicates whether the client is currently connected to the server. This flag helps in handling connection status and detecting disconnection events.

  • messageBody: Contains the main content or payload of the message, typically in string format. The content of this property varies depending on the message type and purpose. It may include game data, error details, or communication instructions.

  • player: Specifies the player associated with the message or the player to whom the message pertains. This property helps in identifying the sender or recipient of the message within the multiplayer gaming context.

  • commStatus: Represents the communication status associated with the message, indicating the status of the communication process between the client and the server. It may include values such as "success," "failure," or specific status codes to provide additional context about the communication outcome.