Visualisation and rendering - SC-SGS/surviving-sarntal GitHub Wiki

This page gives an overview of the visual aspects and the rendering of the game.

Rendering Architecture

The rendering system of our game is managed by a central Renderer class, which oversees all aspects of drawing the game's graphical elements using the Raylib library. This includes not only rendering the world but also managing sub-renderers that handle specific parts of the visual output, such as entities, the terrain, and the Heads-Up Display (HUD) as shown in figure below.

Ingame-Picture

Main Renderer Class

The Renderer class serves as the core component of the game's rendering pipeline. It is initialized with several key objects, including the world, camera, and resource manager, as well as sub-renderers like the EntityRenderer, MountainRenderer, and HudRenderer. These sub-renderers ensure that rendering is handled in a modular and efficient way, keeping different aspects of the world separate yet cohesive. The primary tasks of the Renderer include:

  • Managing the camera view and adjusting its position based on the player's movements.
  • Rendering the game's background dynamically.
  • Delegating the rendering of entities, terrain, and HUD to the respective sub-renderers.

Camera Initialization

One of the first tasks of the Renderer is to initialize the camera. The camera setup takes into account the dimensions of the world, ensuring that the entire world is visible on the screen with the correct zoom level. The following calculations are performed to achieve this:

  • The world boundaries are determined based on the game's unit-to-pixel ratio.
  • The zoom level is calculated to fit the world width within the screen dimensions.
  • The camera's position is centered within the visible portion of the world.

The camera is then updated dynamically during gameplay, adjusting to track the player's movements while maintaining smooth transitions.

Rendering Pipeline

The draw() method is responsible for the main rendering loop. It begins by clearing the screen and then enters the 2D rendering mode with the camera applied. Inside this loop, the Renderer draws the background and calls the sub-renderers to draw the game's visual elements.

Camera Effects and Fullscreen Support

In addition to basic rendering, the Renderer also handles visual effects such as camera shake, used to simulate rumble when certain events occur (e.g., a large rock falling nearby). The shake effect gradually dampens based on a visual constant and adds a layer of immersion to the gameplay experience.

The Renderer also supports fullscreen mode, allowing players to toggle between windowed and fullscreen display. This feature is controlled through the game's configuration settings and cannot be adjusted at runtime, due to visual bugs occurring while toggling.

Sub-Renderers

To ensure a clean and maintainable codebase, the Renderer class delegates specific rendering tasks to various sub-renderers, each responsible for a distinct portion of the graphical output.

MountainRenderer

The MountainRenderer class is responsible for rendering the mountain terrain, one of the primary visual components of the game. It uses triangulation to generate a mesh from the terrain data and applies a repeating texture to simulate a continuous mountainous background. This renderer ensures that the terrain is drawn efficiently and updates only when necessary to minimize computational overhead.

The terrain rendering system loads and applies a repeating mountain texture, adjusting dynamically to camera view and terrain changes. The rendering logic involves determining the visible terrain area, checking for boundary or vertex updates, and recalculating the mesh if needed. The terrain is then rendered by applying the texture to the triangulated mesh.

To generate the mountain surface, the class relies on the terrain's polyline representation. The Renderer can convert the ground points into a series of 2D coordinates, which are then passed to the poly2tri library for triangulation. This process creates a set of triangles that form the visual mesh of the mountain. The generated triangles are stored as vertex data, which are used to draw the mountain with the texture applied.

EntityRenderer

The EntityRenderer class is responsible for rendering dynamic game entities, such as hikers, monsters, rocks, and in-game items. It ensures each entity is drawn accurately to the screen, manages animations, and provides debug capabilities for easier visualization of entity states.

The primary function of this class is to render entities using texture mapping and transformations. Each entity’s attributes, such as position, size, rotation, and texture, are considered during rendering, allowing for accurate placement, scaling, and orientation on the screen.

This class also manages animated entities, like moving characters or objects. Animation data, stored within each entity’s information, is used to update the current frame of the animation according to the elapsed time. The animation is then rendered frame by frame based on the entity's animation properties, such as the number of frames and frame duration.

Certain entities, such as hikers and rocks, have specialized rendering logic. For example, hikers are rendered differently depending on movement states, including jumping, walking, or crouching. Rocks can be rendered as textured polygons in their normal state, while destroyed rocks involve rendering explosions with more complex visual effects.

HudRenderer

The HudRenderer class handles rendering essential HUD elements like the player's health, score, inventory, and altitude, providing real-time feedback during gameplay. It tracks the player's status and environment, updating accordingly.

Debug Mode

The rendering system includes a debug mode that provides developers with additional visual information to aid in debugging and testing. It also removes unnecessary textures that would otherwise clutter the screen. This mode can be toggled on and off, allowing for a clean and unobtrusive gameplay experience when not needed. The debug mode includes the following features:

  • Entity Debugging: Visualizes entity hitboxes and collision shapes, making it easier to identify issues with entity positioning and interactions.
  • Mountain Debugging: Renders the mountain terrain's vertices and triangles, helping developers verify the correctness of the terrain mesh generation.

The debug mode is a valuable tool for identifying rendering issues, verifying game state, and ensuring that the visual elements of the game are functioning as intended.

Debug-Mode

In the figure above, you can see the debug mode visualization of the mountain triangulation, as well as the hitboxes of the entities, for example, the hiker as a diamond shape, rocks as polygons with a centroid, and items as squares with a blue circle around them indicating the collection radius.

Optimizations

The renderer optimizes performance by only updating the terrain mesh when necessary, such as when boundaries shift or vertices change, avoiding unnecessary recalculations during each frame. Additionally, animations are updated only when the time since the last frame exceeds the animation frame time, and entities that are destroyed and have completed their animations are removed from the rendering cycle.

⚠️ **GitHub.com Fallback** ⚠️