Skip main navigation

Revisit whack-a-mole with position; scale; rotation & colour

Review rotation, position and colour through an example

Reflection on the Whack-a-mole application

Last week we discussed the storyboard for the simple VR experience of whack-a-mole. During this week, we covered position, rotation and colour of the objects. In this step, we will apply these concepts to understand how the details identified in the storyboard come together in the final web-app. To help us with this, we refer back to the second storyboard panel from Step 8 of Week 1 (see Figure 1). Let’s explore the storyboard panel and the web-app in the context of what we learnt this week. We recommend that you download the web-app (the link is available in the ‘See Also’ section below) and view its source code in your preferred editor.

Second Storyboard Panel of Whack-A-Mole showing spatial and colour attributes of the entities Figure 1. Second Storyboard Panel of Whack-A-Mole: Spatial and colour attributes [from Step 1.8]


Let’s start with the simplest entity, the ground. The code referencing the ground is reproduced below:

<a-entity id="ground" geometry="primitive: circle; radius: 100" rotation="90 0 0" position="0 -0.2 0" material="side: double; color:#D2691E; opacity:1.0"></a-entity> 


The position attribute establishes the position of the ground in the virtual world. It is set 0.2 units below the XZ-plane. The ground is the direct child of the scene and thus this position is the same as the virtual world position. The importance and concept of virtual world position and local relative position will become apparent from the next entity, the mole.


The local position of the mole is established using the following line of code:


<a-entity class="mole" rotation="0 0 0" position="0 -2 0" mixin="popup">
 <!-- rest of the mole content-->


Every mole in the running example has the same local position (0, -2, 0). However, the moles appear randomly distributed. This happens because the moles are not direct children of the virtual world. You will notice that the mole is a child entity of the entity “hole”, which comes with its own position and parents leading all the way up to the virtual world. The mole is positioned relatively at (0,-2,0), assuming that the origin is where the parent is located. The advantage of this approach is that we don’t have to calculate the absolute coordinates of the entities each time. All we need to do is to specify the relative position of the child entity with respect to the parent and any repositioning of the parent entity repositions the child entity automatically.


An astute learner may notice that we only see 5 mole-holes in the game, which are added programmatically (using the “moleFactory” function) and the template mole is not visible. This is because the camera is positioned right above the mole. To see this mole, you need to reposition the camera. Try updating the camera position to move it by +5 units along the z-axis to reveal the template mole. Compare your code to our solution below:


<a-entity id="camera" camera="active: true" look-controls wasd-controls position="0  1.6  5"></a-entity> 


Scale and Size


AFrame assumes a default scale and size factor of 1 for any entity that doesn’t contain this as an explicitly defined attribute. However, we can use the associated attributes to create entities that match our needs. For example, the eyes of the mole are spheres but smaller as compared to the mole itself. We size the ‘eye-iris’ spheres down by specifying the radius attribute as shown below:


<a-sphere color="#444444" radius="0.1"></a-sphere> 


The radius attribute uniformly resizes the sphere down to a smaller size. However, in some cases, this is not enough. For example, the ‘eye-cornea’ (white part) of the mole requires a more interesting set of attributes, as shown below:


<a-sphere color="white" scale="0.2 1 1" radius="0.18" rotation="0 10 0"></a-sphere> 


The radius attribute sets the overall size, but then we flatten the sphere along the x-axis using the scale attribute. The two spheres together produce the effect we desire, i.e. an eye-like structure.




In the whack-a-mole example, we use static rotation to position the holes on the ground. We consider this static because the rotation value is fixed and never changes. As mentioned before, the “moleFactory“ function programmatically populates the holes in the scene. This is useful to create random positions for the holes on each run and provides variety to the VR experience. The key lines of interest for positioning of the hole are reproduced below:


//set the rotation to position in a semi-circular arc 
clone.setAttribute("rotation", [0,positions[i].rY,0].join(" ")); 
//set the position to push the mole away from viewer 
clone.firstElementChild.setAttribute("position",[positions[i].dX,0,0].join(" ")); 


A close examination of the two lines will reveal the following:



    • The rotation attribute of the moleTemplate (initial value “0 0 0”) is updated with a new value “0 ry 0”. The exact value of ry is provided by a pre-computation step through a call to the function “getPlacements”. This rotation re-orients the local axes of the entity and thus affects the virtual world position of all the child entities.



    • The next line sets the position of the child entity “dolly” further along the local X-axis. The combined effect of the child position and parent rotation is that the mole appears somewhere in front of the user.



    • The role of the ‘getPlacements’ function is to prevent overlap and clustering of the moles in one location.






The last set of attributes to explore from the storyboard are the colour. We start with the distant sky colour. It is defined using the line below:


<a-sky color="azure"></a-sky> 


Here we use AFrame’s ability to work with named colours. This works fine for the limited set of defined colours. However, in other cases, we define the colour using its hex-triplet representation. For example, in the code below, we set the ground colour to a dark brown shade (#D291E):


<a-entity geometry="primitive: circle; radius: 100" rotation="90 0 0" position="0 -0.2 0" material="side: double; color:#D2691E; opacity:1.0"></a-entity> 


Notice that we didn’t use the attribute ‘color’ and instead provide it as a property-value tuple for the material attribute. This is another way to specify the colour for an entity.


Lastly, we may encounter situations where the colour needs to be defined dynamically. For example, in our case, the first five moles have the same colour attributes as the template mole. However, the final ‘golden’ mole has different colour attributes. We can programmatically change the colour of the mole by setting the correct attribute through Javascript. We achieve this using the following lines of code in the ‘moleFactory’ function.


if(gold){//is this a golden mole? 
 let moleBodies = clone.getElementsByClassName("colorMe"); 

We access the required entity by using the HTML DOM model (HTMLElement, ChildElement) and then set its ‘color’ attribute to the desired values, thus creating the golden mole.


We strongly recommend you explore the code of the simple VR experience of whack-a-mole in detail and in the context of the concepts learnt this week. A good way to evaluate your understanding would be to make changes to the position, scale, rotation and colour attributes and see if the outcome matches your prediction based on those changes. Overall, we hope you have grasped the concepts of position, scale, rotation and colours well enough to be able to explore the next set of advanced concepts we plan to cover next week.

This article is from the free online

Construct a Virtual Reality Experience

Created by
FutureLearn - Learning For Life

Reach your personal and professional goals

Unlock access to hundreds of expert online courses and degrees from top universities and educators to gain accredited qualifications and professional CV-building certificates.

Join over 18 million learners to launch, switch or build upon your career, all at your own pace, across a wide range of topic areas.

Start Learning now