After reading Javascript: The Good Parts by Douglas Crockford I decided to make some minor changes to the codebase of the suite:

Instead of using the postfix increment operator ++ use += 1

Instead of using the == comparison operator which uses type coercion , use the more reliable ===. Similarly for !=, use !==.

After making those changes, I screen grabbed each Reactickle to make an icon. Midway through the process I realised that it was difficult to tell the difference between some of the mouse based interactions and the keyboard interactions, so decided to make animated video icons instead of a still.

I used Screeny to be able to grab at a fixed pixel dimension of 256×256, but drawn at 128×128 in the main menu.

After adding the video thumbnails I spotted a bug with the KeyboardFountain – objects were being added to the matter.js simulation, but never removed.

First I made sure that the array holding all the circles was empty before I started adding to it:

Taking each Reactickle one by one, I started with KeyboardScalingCircleGrid.

On line 14 of KeyboardScalingCircleGrid.js, I had a console output, detailing the size of the array that held each of the ScalingCircles, one for each keyboard button I was taking input from. Repeatedly starting the Reactickle and going back to the main menu resulting in the following output:

KeyboardScalingCircleGrid.js:14 The size of the circles array is 216
KeyboardScalingCircleGrid.js:14 The size of the circles array is 252
KeyboardScalingCircleGrid.js:14 The size of the circles array is 288

While testing every Reactickle to confirm that I’d expunged the array bug, I discovered that that both KeyboardSquares.js and KeyboardFountain.js used a centred rectMode() rather than a cornered one. I added a rectMode() change before each of their draw calls, as well as reseting to corner mode in the main sketch.js to ensure that the GUI was drawn correctly.

Next will be creating some icons for the Reactickles, rather than the current placeholder text.

After talking to Wendy, we agreed that the next step was to get all the individual sketches working in a suite.

I created a new folder to contain the suite: Reactickles3, and started by trying to run KeyboardScalingCircleGrid within a larger p5.js sketch.

I created a new sketch.js in the Reactickles3 folder and copied KeyboardScalingCircleGrid.js into the same folder. After making the entire KeyboardScalingCircleGrid a class of its own, I was able to call its setup, draw and keyTyped methods from within my main sketch.js.

With that functioning, I started to test other Reactickles in this new structure, starting with KeyboardWorm, followed by MouseWorm, KeyboardSpringyCircles, MouseSpringyCircles, KeyboardSquares and finally KeyboardFountain.

Once those were working, I created an array of those Reactickles as well as a main menu screen and a return to main menu button. There are still some bugs in the system, but I’m going to save those for the next session.

The original KeyboardSquares can be seen above – on key presses the larger square broke up into smaller squares and flew apart, as well as changing colour. It was a relatively quick port to create, based on previously ported Reactickles. One sticking point was making sure that the larger square was always centred – even if the user changed the size of the window of the browser. Luckily p5.js has a windowResized() function to detect that. I also found some different options for emptying an array in JavaScript. The ported version can be found here.

The next Reactickle was Keyboard Fountain which can be seen from 01:43- 02:20 on the video above.

After creating KeyboardFountain in my local Git repository, I set about creating the “fountain” at the bottom of the screen. Conveniently, p5.js has an existing triangle drawing function, called triangle(). Quoting from the reference:

Description
A triangle is a plane created by connecting three points. The first two arguments specify the first point, the middle two arguments specify the second point, and the last two arguments specify the third point.

However, this meant that the user had to repeatedly press the arrow keys to move, whereas I wanted the Fountain to keep moving as long as I held the key down. I found the keyIsDown function which allowed me to have the Fountain move in the way that I wanted:

In order to get the particles flying out of the fountain in a realistic way, I new I would have to create some kind of 2D physics simulation – at the very least using basic projectile physics. In the spirit of keeping it simple, I looked online to see if there were any existing physics libraries that worked with p5.js. Thanks to the fantastic Coding Train by Daniel Shiffman, I discovered matter.js.

I found this explanation of Robert Penner’s easing equations very useful – the most useful being the idea that one is feeding a timing value between 0 and 1 to the easing function to get back another value how far along the transformation in question you are – and that this value may be greater than 1 or less than zero. This is exactly what I want in my springy circles – for them to overshoot their target and oscillate a few times before settling at the final position.

Starting with KeyboardSpringyCircles, I started adding the logic to allow for non-linear tweens for movement. I got timing working by using the the millis() function of p5.js.

One bug that caused me intense frustration was that my local webserver didn’t seem to be serving the latest code when I made an update. Eventually I tracked it down to Chrome caching files wherever possible – meaning that I had to use Command Shift R to force a reload of all the files being served – not just the HTML.

I also managed to repeated Vector copying values explicitly bug from late November, by doing writing:

this.startPosition = this.position;

Rather than:

this.startPosition = createVector(this.position.x, this.position.y);

At this stage I had the following interaction working:

Which was a good start, but I didn’t like the precise settling animation, so I decided to create a new external JS file with all the easing equations contained in one convenient place. This would allow me to use all the easing equations in other places in my code.

I created easing.p5.jgl.js and keyboard.p5.jgl.js to contain all my easing logic and keyboard logic respectively. After adding both references to my index.html file:

if(distanceBetweenMouseAndCircle < (springyCircles[i].radius)){ //this is resulting in a bug - radius/2 works properly, but why isn't radius alone giving the correct interaction?
//if the mouse is under the springy circle, then spring/move it
springyCircles[i].moveSpring();
}

This fixed all my circle selection code. The next step is to convert all my radius variables to be proportional to the screen size (as my position co-ordinates already are) rather than being pixel based. It’s important to me that Reactickles 3 is resolution independent – i.e. that it looks the same on a variety of different screen sizes and proportions.

As noted in the source code comments, the spring simulation was based on the spring p5.js example. Once I had the circles randomly generating their position, colour and radius, I had to add the interaction – springing if a key was pressed within their area:

After talking things through with Wendy yesterday, I moved on from KeyBoardScalingCircleGrid to KeyboardSnake. Wendy pointed out the multicoloured background wasn’t necessary for this version – so I could concentrate on making the interaction work with a single colour for the snake. I decided to change the name to the slightly more friendly KeyboardWorm.

Drawing the worm was pretty straight forward, after I realised that I had to draw the segments in reverse order so that the “head” of the worm drew last:

function drawWorm(){
//draw the first segment of the worm last so that the shading looks correct
for (var i = (worm.length-1); i > 0; i--) {
worm[i].display();
}
}

Most challenging was updating the worm:

function updateWorm(){
seekWormTowardsKey(key);
//starting at back of the worm, copy the previous worm segments position onto the current segments position
for (var i = (worm.length-1); i > 0; i--) {
worm[i].position.x = worm[i-1].position.x;
worm[i].position.y = worm[i-1].position.y;
//had to copy both values - not the reference, worm[i].position = worm[i-1].position doesn't work
}
}

As I noted in the comments – just setting the position as a reference didn’t work – I had to set each position x and y value manually – this was a nasty bug to track down, after two hours of drawing and redrawing my segment shifting code I finally realised my error.

Wendy forwarded me a video that she had shot of someone using the original version of Reactickles that I am now in the process of porting to the web. I’ve embedded it below:

The three Reactickles that I am aiming to port initially are at the following points in the video:

2:41, which I am calling KeyboardScalingCircleGrid.

3:57, which I am calling KeyboardBouncingCircleGrid.

0:37, which I am calling KeyboardSnake.

So lets start with the development of KeyboardScalingCircleGrid. I began by duplicating the code I wrote yesterday (KeyboardToScreen) and renaming the folder to KeyboardScalingCircleGrid.

I knew that I would have to create an array of ScalingCircles and instantiate them with certain values, so I had a look at the p5.js examples page to see if there were any sketches that might be useful. Sure enough, the Array of Objects example and the Objects 2 example looked perfect.

This resulted in a pleasing scaling animation, but it wasn’t quite as fast as the video, so I altered the easing ratio to 0.3 from 0.1, as well as setting a fixed number for the target radius of each circle – initially 100 pixels, then 200 pixels on keypress. Finally, I changed the colour of the circle to be 50% transparent to match the blending effect that was visible on the Reactickles 1 demonstration video.

However, in the video I could see that the circles not only scale up, but scale back to their original size – and worse than that they don’t scale up in a linear way, but seem to “bounce” around their full size – overshooting initially and then scaling back. From previous experience in Actionscript and C++ I knew of the existence of Robert Penner’s Easing functions, and that it was very likely that they had already been implemented in p5.js. I Googled “easing functions p5.js” and found p5.ijeoma.js:

[Log] p5 had problems creating the global function "frames", possibly because your code is already using that name as a variable. You may want to rename your variable to something else. (p5.js, line 9429)
[Log] p5 had problems creating the global function "stop", possibly because your code is already using that name as a variable. You may want to rename your variable to something else. (p5.js, line 9429)
[Log] The size of the circles array is 36 (sketch.js, line 14)
[Warning] Only numbers, p5.colors and p5.vectors are supported. (p5.ijeoma.js, line 142)
[Error] TypeError: undefined is not an object (evaluating 'this._properties[i].update')
_updateProperties (ijeoma.js:1170)
dispatchChangedEvent (ijeoma.js:1297)
seek (ijeoma.js:194)
play (ijeoma.js:148)
scaleUpAndThenDown (sketch.js:59:122)
keyTyped (sketch.js:31)
_onkeypress (p5.js:16261)
(anonymous function)