Skip to content

Latest commit

 

History

History
104 lines (77 loc) · 4.48 KB

chapter5.md

File metadata and controls

104 lines (77 loc) · 4.48 KB

Chapter 5: Making It a Game

In this chapter, we’ll turn your WebXR experience into a simple game by adding a proximity-based hit test for the targets and implementing a scoreboard to track the player’s score. These additions will make your scene more interactive and engaging, providing immediate feedback when a target is hit.

Setting Up the Scoreboard

To display the score, we’ll use the troika-three-text library, which allows us to render high-quality text in Three.js. The score will be displayed on a monitor in the space station scene, giving the player a clear view of their progress.

Scoreboard Setup

First, we define the score text and an updateScoreDisplay function to manage the scoreboard:

import { Text } from 'troika-three-text';
let score = 0;
const scoreText = new Text();
scoreText.fontSize = 0.52;
scoreText.font = 'assets/SpaceMono-Bold.ttf';
scoreText.position.z = -2;
scoreText.color = 0xffa276;
scoreText.anchorX = 'center';
scoreText.anchorY = 'middle';

function updateScoreDisplay() {
	const clampedScore = Math.max(0, Math.min(9999, score));
	const displayScore = clampedScore.toString().padStart(4, '0');
	scoreText.text = displayScore;
	scoreText.sync();
}

Explanation:

  • Score Text Setup: The Text object is used to display the score. We configure its font size, color, and position, ensuring it fits well within the scene.
  • updateScoreDisplay Function: This function updates the score text whenever the score changes. It clamps the score between 0 and 9999 and formats it to be a four-digit number, which is then displayed on the monitor.

Adding the Scoreboard to the Scene

Next, we add the score text to the scene in setupScene:

function setupScene({ scene, camera, renderer, player, controllers }) {
	// Other setup code...

	// Add the score text to the scene
	scene.add(scoreText);
	scoreText.position.set(0, 0.67, -1.44);
	scoreText.rotateX(-Math.PI / 3.3);
	updateScoreDisplay();
}

Explanation:

  • Score Text Positioning: The score text is positioned and rotated to align with a monitor in the space station scene, making it look like the monitor is displaying the player's score. You will need to adjust it if you are using a different environment.

Implementing Proximity-Based Hit Test

To determine whether a bullet hits a target, we use a proximity-based hit test. This method checks the distance between the bullet and each target, and if they’re close enough, the target is considered “hit”:

function onFrame() {
	// ... unchanged params
	Object.values(bullets).forEach((bullet) => {
		// ... unchanged logic
		targets
			.filter((target) => target.visible)
			.forEach((target) => {
				const distance = target.position.distanceTo(bullet.position);
				if (distance < 1) {
					delete bullets[bullet.uuid];
					scene.remove(bullet);

					// make target disappear, and then reappear at a different place after 2 seconds
					target.visible = false;
					setTimeout(() => {
						target.visible = true;
						target.position.x = Math.random() * 10 - 5;
						target.position.z = -Math.random() * 5 - 5;
					}, 2000);

					score += 10; // Update the score when a target is hit
					updateScoreDisplay(); // Update the rendered troika-three-text object
				}
			});
	});
}

Explanation:

  • Proximity-Based Hit Test: This method checks if the distance between the bullet and a target is less than 1 unit. If it is, the bullet is removed from the scene, and the target is temporarily hidden.

  • Updating the Score: Each time a target is hit, the score is increased by 10 points, and the updateScoreDisplay function is called to refresh the displayed score.

  • Respawning Targets: After 2 seconds, the target becomes visible again and is repositioned randomly within the scene.

  • Why Proximity-Based?: This approach is simple and effective for our scenario because the targets are round and facing the player. However, for more advanced and reliable hit detection, especially with irregularly shaped objects or targets that aren’t facing the player, you would need to look into using raycasting.

Summary

In this chapter, you’ve transformed your WebXR scene into a simple game by adding hit detection and a scoreboard. The proximity-based hit test provides a straightforward way to register hits, while the scoreboard keeps track of the player’s score, making the game more engaging and interactive.

Here’s what your game looks like now:

Gameplay Screenshot