Creating a VR drumming game: Part 4(Drum mechanics!)

Katie Van
5 min readMar 11, 2020

--

Screengrab from the VR drumming project

In part 3 of creating a VR drumming game, I made concept art to plan the environment and an early prototype. In this blog post, I’ll show the current progress of drum mechanics. In case you are new, in this series, I will be covering everything from design to coding and implementation of creating a browser-based VR drumming game! Here’s part 1.

Designing the Drum Component

Before coding the drum component, I mentally thought up the systems required to make the drums work, including:

  • Collision detection — Check if the drumstick collides with a drum
  • Drumstick velocity — Determine how fast the tip of the drumstick is moving. This will impact the loudness of the drum, and the sound of certain drums
  • Play sound — Obviously the drum should play a sound file unique to that drum
  • Easy File Input — The sound file name and genre folder location for the drum should be easy to specify straight from the HTML component (will be described later)

Implementation

Screengrab showing the early drum stage, before any fancy drum models

Collision Detection

In looking for a simple way to determine if a drumstick is colliding with a drum, I went searching into A-frame’s documentation. I came across the raycaster and realized this would suit my needs perfectly since it checks for collisions in a straight line, convenient for a drumstick.

To implement this, I created a raycaster entity and parented it to the raycaster in the HTML document. In the raycaster options, I told it to check for collisions with any entity that has a collidable class, which was given to the drum cylinder. Then in my drums.js file, I told it that in the event the drum is intersected by any raycaster, to do stuff.

HTML implementation for collision detection involving a raycaster
Snippet from drums.js

Drumstick velocity

To determine how fast the tip of the drumstick moves, I parented an entity at the tip of the drumstick and created a component to measure how fast it moves at any given time. The velocity component checks it’s position every 100 milliseconds and calculates its current speed by finding the magnitude of the previous location vector subtract the new location vector.

Because the drumstick is parented to the camera which is currently driving all of the movement, simply getting the position from a component will only return the local position of the drumstick, resulting in only getting values of 0. In this case, I instead got the matrix position of the location of the drumstick tip relative to world space. To do this, I used a method included in three.js (the 3D graphics javascript library that a-frame is built on) called setFromMatrixPosition.

velocity.js

Playing Sound

I wanted to implement sound in the simplest way possible, using an only-javascript solution if it would make later programming cleaner.

To do this, I created an audio HTML element using javascript in initialization, set the attributes as follows, and appended the element to the page document:

Creating a sound HTML element using javascript and initializing its attributes.

Then, when the drum component detects it’s been hit by the drumstick’s raycaster, it will play the drum sound based off of the drumstick’s current velocity!

Play the drum sound, yes

Setting the current time to 0 before playing it ensures that the sound will always start from the start, even if the drum has already been hit recently.

Easy File Name Input

Aframe allows programmers to create “schema”s for their components. Here I created data attributes called genre (to specify the genre folder), and a file_name attribute to specify the name of the sound file.

My schema for the drum collision

In the HTML drum entity below, the genre and file name can be easily specified in the drum-collision attributes.

In the drum collision attribute, the Pop folder is specified along with the sound file Hi-Hat-1.wav

Results and Time Spent

The result so far? Cool playable drums. However, right now the drumstick is controlled by moving the camera it is parented to, which definitely needs to change. Probably the worst part was that I experienced motion sickness when programming and testing the app at length. If there’s a case of nauseating extremes then testing games with 3D head movement is sure it! These features took a cumulative 10–12 hours per week for the past 2 weeks to create.

Coming Up Next Week…

In next week’s I will update on my current predicament, which is allowing VR controller movement to the drumsticks so they will no longer need to be parented to the camera in order to move. Ha, no more motion sickness after that! Maybe. (I’m the kind of person who gets carsick all the time so we’ll see).

Thanks for reading.

If you like reading about creative/technical projects, weird experiments, and possibly book reviews/summaries in the future, consider subscribing to my account.

--

--

Katie Van

Artist, web developer, video editor, indie game developer, and aspiring writer. I like experiments, productivity and mindset hacks, how-to, and life lessons.