Source: Howling Husky Web Development Blog

Howling Husky Web Development Blog How to Make a VR Game

Introduction:This article walks you through how to create an arcade style virtual reality game using JavaScript and Mozilla's A-Frame library. The game works on Rift, Vive, and Cardboard, as well as any most mobile and PC devices.Play the Game!Step 1: Create your HTMLA-Frame Virtual Reality is built over the internet as web pages. For that reason the first step in the process is to create a basic HTML page.<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Breakout VR Tutorial</title> <meta name="description" content="Breakout VR Tutorial"> </head> <body> </body> </html>Step 2: Add the A-Frame LibrariesA-Frame is a JavaScript library called "aframe.js". This should be added through a <script> tag inside the <head> section of the HTML.We will also use a library called "aframe-text-component", which allows to add text to our VR scene.!-- Basic A-Frame library --> <script src="https://aframe.io/releases/0.2.0/aframe.min.js"></script> <!-- Needed to add Text --> <script src="https://rawgit.com/ngokevin/aframe-text-component/master/dist/aframe-text-component.min.js"></script>Step 3: Set up Static Game ElementsMost of the elements in our game will be dynamic and change as part of the game. However some elements will not move or have very little interaction. We will add those inside the <body> tag of the HTML using special tags specific to the A-Frame library.The a-scene element has to be in the body of the HTML. All of the other A-Frame elements will be placed inside of it.<a-scene> </a-scene> Mixins are a way of defining attributes for a group of objects without declaring the attributes on each of those objects. <!-- Mixins. --> <a-assets> <a-mixin id="red" material="color: red"></a-mixin> <a-mixin id="green" material="color: green"></a-mixin> <a-mixin id="blue" material="color: blue; opacity: 0.5"></a-mixin> <a-mixin id="url-red" material="color: #d63959"></a-mixin> <a-mixin id="cube" geometry="primitive: box"></a-mixin> </a-assets>To help the player see the game area we are going to place flat planes behind and below the game area. <!-- set game background planes. --> <a-plane rotation="-90 0 0" width="4" height="4" color="#a0a0a0"></a-plane> <a-plane position="0 2 -2" rotation="0 0 0" width="4" height="4" color="#bfabce"></a-plane>We could set the scene background to a flat color. I think that it looks more interesting with a 360 degree image, so I added in an example image from Mozilla. <!-- sky color. --> <a-sky src="city.jpg"></a-sky>We need to specify where the camera is at. To do this we add an A-Frame camera tag. The game functionality is based on the player moving their view, so I also added a cursor with lets the player see where their view is centered.Note that wasd-controls is set to disabled. This prevents the player from moving the camera away from the game board. <!-- Set camera starting position. --> <a-entity position="0 0 3.8"> <a-camera look-controls id="myCamera" wasd-controls="enabled: false"> <a-cursor id="cursor" material="color: gray; opacity: 0.5"> </a-cursor> </a-camera> </a-entity>Adding lighting is not strictly required, but I added a couple of lights into the scene to make the game elements easier to see. <!-- Set light position. --> <a-light type="directional" color="#FFF" intensity="0.1" position="-1 1 2"> </a-light> <a-light type="ambient" color="#FFF"> </a-light>Step 4. Add a Window.OnLoad WrapperWe want the HTML to load before running the JavaScript. This is necessary to prevent errors in loading the game elements. The JavaScript is inserted as a <script> tag in the <head> section of the page.<script> //wait until the page loads to perform the following window.onload = function () { } </script>Step 5: Add Dynamic elements through JavaScriptMany elements of the game are dynamic and require heavy interaction. It's possible to declare these in the HTML and then interact with them through JavaScript, but I found it easier to declare them directly through the JavaScript.This is entered inside the window.onload function we declared earlier.Since this is a virtual reality game, every game element will have X, Y, and Z coordinates which define where they are at in cartesian space.The game ball is the ball that will bounce around inside the game area. We are going to create through as an A-Frame sphere.//Create the game ball var gameBall = document.createElement('a-sphere'); var gameBallX = 0; var gameBallY = 1.25; var gameBallZ = -1; var gameBallVelocityX = 0.05; var gameBallVelocityY = 0.1; var gameBallRadius = 0.15; gameBall.setAttribute('color', '#EF2D5E'); gameBall.setAttribute('radius', gameBallRadius); console.log(gameBallX + ' ' + gameBallY + ' ' + gameBallZ); gameBall.setAttribute('position', gameBallX + ' ' + gameBallY + ' ' + gameBallZ); scene.appendChild(gameBall);The paddle is a bar that will move left and right in the game area. We are going to create it as a box. //create the paddle var gamePaddle = document.createElement('a-box'); var gamePaddleX = 0; var gamePaddleY = 0.3; var gamePaddleVelocityX = 0; var gamePaddleZ = -1; var gamePaddleWidth = 1; var gamePaddleHeight = 0.2; var gamePaddleDepth = 0.2; var gamePaddleColor = '#42f4aa'; gamePaddle.setAttribute('width', gamePaddleWidth); gamePaddle.setAttribute('height', gamePaddleHeight); gamePaddle.setAttribute('depth', gamePaddleDepth); gamePaddle.setAttribute('color', gamePaddleColor); scene.appendChild(gamePaddle); gamePaddle.setAttribute('position', gamePaddleX + ' ' + gamePaddleY + ' ' + gamePaddleZ);The blocks are boxes that will disappear when the game ball hits them. We will create these as A-Frame boxes. //create the game blocks //arrays to hold the blocks and their positions var gameBlocks = []; //objects var gameBlocksX = []; //block x positions var gameBlocksY = []; //block y positions var gameBlocksZ = []; //block z positions var gameBlocksActive = []; //whether the block is active var blockWidth = 0.8; var blockHeight = 0.2; var blockDepth = 0.2; var blockColor = '#4CC3D9'; //declare the blocks and their attributes for (i = 0; i < 12; i++) { gameBlocks[i] = document.createElement('a-box'); gameBlocks[i].setAttribute('width', blockWidth); gameBlocks[i].setAttribute('height', blockHeight); gameBlocks[i].setAttribute('depth', blockDepth); gameBlocks[i].setAttribute('color', blockColor); gameBlocksActive[i] = "1"; } //set the position of the blocks //Top row gameBlocksX[0] = -1.5; gameBlocksY[0] = 3.5; gameBlocksZ[0] = -1; gameBlocksX[1] = -0.5; gameBlocksY[1] = 3.5; gameBlocksZ[1] = -1; gameBlocksX[2] = 0.5 gameBlocksY[2] = 3.5; gameBlocksZ[2] = -1; gameBlocksX[3] = 1.5; gameBlocksY[3] = 3.5; gameBlocksZ[3] = -1; //Middle row gameBlocksX[4] = -1.5; gameBlocksY[4] = 3; gameBlocksZ[4] = -1; gameBlocksX[5] = -0.5; gameBlocksY[5] = 3; gameBlocksZ[5] = -1; gameBlocksX[6] = 0.5 gameBlocksY[6] = 3; gameBlocksZ[6] = -1; gameBlocksX[7] = 1.5; gameBlocksY[7] = 3; gameBlocksZ[7] = -1; //Bottom row gameBlocksX[8] = -1.5; gameBlocksY[8] = 2.5; gameBlocksZ[8] = -1; gameBlocksX[9] = -0.5; gameBlocksY[9] = 2.5; gameBlocksZ[9] = -1; gameBlocksX[10] = 0.5 gameBlocksY[10] = 2.5; gameBlocksZ[10] = -1; gameBlocksX[11] = 1.5; gameBlocksY[11] = 2.5; gameBlocksZ[11] = -1; //add the blocks to the scene for (i = 0; i < 12; i++) { scene.appendChild(gameBlocks[i]); gameBlocks[i].setAttribute('position', gameBlocksX[i] + ' ' + gameBlocksY[i] + ' ' + gameBlocksZ[i]); }Step 6. Add Game VariablesIn order for our game to work, we have to keep track of certain types of information. These will be declared as JavaScript variables near the top of our <script> section. //declare variables var gameIsOn = 0; //whether the game is active, controls certain functionality var intervalLength = 25; //determines the speed of the game var topBorder = 3.5; //border of game area var bottomBorder = 0.25; //border of game area var rightBorder = 1.8; //border of game area var leftBorder = -1.8; //border of game area var scene = document.querySelector('a-scene'); //assign a name to the A-Frame sceneStep 7. Create Functions to Reset the Game ElementsWe will want to reset the game elements when the game starts. Let's add these functions into the JavaScript to reset the blocks and the location of the ball. //function to reset the blocks function resetBlocks() { for (i = 0; i < 12; i++) { gameBlocksActive[i] = "1"; gameBlocks[i].setAttribute('opacity', '1'); } } //function to reset the ball position function resetBall() { gameBallX = 0; gameBallY = 1.25; gameBallZ = -1; gameBallVelocityX = 0.05; gameBallVelocityY = 0.1; gameBall.setAttribute('position', gameBallX + ' ' + gameBallY + ' ' + gameBallZ); } //function to check if all blocks are broken, return true if so function checkBlocks() { var returnValue = 1; for (i = 0; i < 12; i++) { if(gameBlocksActive[i] == "1") returnValue = 0; } return returnValue; } Step 8. Adding TextHow fun would a game be if we didn't know what was happening. We are going to add some text into the game environment, so that the game can communicate with the player.The score will keep track of how many blocks the player breaks. //Display the score var scoreValue = 0; var scoreText = document.createElement('a-entity'); scoreText.setAttribute('mixin', 'blue'); scene.appendChild(scoreText); scoreText.setAttribute('text', 'text: Score: ' + scoreValue); scoreText.setAttribute('position', '-3.5 3.8 -0.8'); scoreText.setAttribute('size', '0.75');The player will have a finite number of lives. Everytime the ball touches the bottom of the screen instead of the paddle, we will deduct a life. //Display the player's lives var livesValue = 3; var livesText = document.createElement('a-entity'); livesText.setAttribute('mixin', 'blue'); scene.appendChild(livesText); livesText.setAttribute('text', 'text: Lives: ' + livesValue); livesText.setAttribute('position', '1.4 3.8 -0.8')

Read full article »
Est. Annual Revenue
$5.0-25M
Est. Employees
25-100
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100