Made a duet and a game

Posted by on January 26th, 2018  •  0 Comments  •  Full Article

I learned some filmmaking skills 3 years ago and I like to dust the rust off every now and then. I enjoy the technology and the tools of the trade: DSLR cameras, lenses, lights, clapper boards and double system sound recording.  Editing is also a lot of fun. Making something beautiful that didn’t exist before appeals to the creative side of my personality. Premier is a fine piece of software. I like the challenge of perfectly syncing multiple tracks, and then playing director in the multi-cam window.

In the video below, I set up lights, tripods and cameras, white balanced everything, recruited talent (my wife), performed and recorded 4 video tracks, 2 audio files. Then blended them all together.

The challenging part was syncing the second shoot with the first shoot. They happened a half hour apart, so there was no way to sync with a  clapper board sound. The earpiece I’m wearing is playing the audio from the first take, while I’m recording the second take. I’d never done this before but I think it’s called dubbing. I had to sync the two takes together by looking at the audio waves in Premiere, while listening to the two takes playing simultaneously as layers in the sequence. There were 4 video layers and 6 audio layers. Four of the audio layers would later be deleted as they were from the cameras. But the two Tascam DR-40 digital audio recorder files had to match perfectly with their video files. Long story short, I was able to get the harmonica sound close, then nudge the audio file left and right one frame at a time until it synced, using the keyboard shortcut of Alt + left or right arrow keys.

My other challenge was setting up the multi-cam sequence. It’s too complicated to explain here, but once it’s set up and running, editing  multiple cameras into one final cut is a breeze. A common problem you will face if you try this is that multi-cam window likes to have the audio follow the video. Meaning, if you click camera 3, the sound switches to the audio from camera 3. In double system sound, this doesn’t work, because you delete all the camera audio tracks after syncing, they are low quality.

Instead, you bring in audio from your digital sound recorder, in my case, a Tascam DR-40, which had feed from two real microphones seen in the video below. So I had 4 video tracks, and two audio tracks. When I went to multi-cam window, it would only play the top audio track, which was the guitar and ukulele. It ignored the harp audio track. Even with ‘audio follows video’ unchecked. My solution was to copy the synced audio track from the main layered sequence and paste it into the multi-cam sequence in  a new audio layer. So now I had one video layer and two audio layers, plus I had all 4 videos displaying at the same time, in little thumbnails. All I had to do then was play the video, and click thumbnails in realtime, director style. If you’ve never seen it, go to youtube and search for premiere multi-cam window. It’s awesome.

I also like to listen to music the old fashioned way, by making it myself or with friends. I come from a long line of amateur musicians. Making music was a tradition anytime our family got together for as long as I can remember.  Grandma used to teach piano, but when she became blind in her nineties she still wanted to participate in our sing alongs. Me and my cousin would sit on either side of her. My cousin would sing, and I would play songs on my harmonica, the one in this video. Actually, that 1967 Hohner harmonica got old, so I recently replaced it with a Suzuki SCX-48 Chromatic in the key of C. It is a lovely instrument, but you can be the judge.

 

My Javascript studies are going well. I learned how to build a number guessing game here:

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/A_first_splash

I’ve got it embedded in an iframe, but if that doesn’t work, here is a direct link. Hint: if you turn on developer tools, I console.log out the random number…so you can cheat.

The tutorial was fun, but as I was working it occurred to me that it could form the backbone of an animated hangman game. I don’t play computer games, life seems to short. But I wanted this game to work, and I wanted it to be pretty.  A lot of what I wanted in the game was functionality that I didn’t know how to program. I found the answers with simple google searches. It is 600 lines of code, including the html, css and JavaScript. I wrote every.single.line.

Here is the game on codepen.

While I was programming the game, I fell in love with a new free code editor called Atom. I like it better than both brackets and sublime. I need to get back to studying Javascript. But if you are curious how I built my hangman game, here is the Javascript code:

  document.querySelector('.dropmenu a').addEventListener('click', toggleMenu); 
  
  function toggleMenu(){
    //e.preventDefault;//fixes safari ios bug
    document.querySelector('.leveltwo').classList.toggle('fold');
    //document.querySelector('.boxMinus').style.visibility = 'visible';
    document.querySelector('.boxMinus').classList.toggle('boxHide');
    document.querySelector('.boxPlus').classList.toggle('boxHide');
  }



//create variables from svg id elements
  var skyBlue = document.getElementById('skyBlue');
  var niteSky = document.getElementById('niteSky');

  var base1 = document.getElementById('base1');
  var base2 = document.getElementById('base2');
  var base3 = document.getElementById('base3');
  var base4 = document.getElementById('base4');
  var base5 = document.getElementById('base5');//mans face
  var base6 = document.getElementById('base6');//mans spine
  var base7 = document.getElementById('base7');
  var base8 = document.getElementById('base8');
  var base9 = document.getElementById('base9');
  var base10 = document.getElementById('base10');
  var man = document.getElementById('man');
//group of the entire hanging man
  var happy = document.getElementById('happy');// hidden group 
  /*
make an array from the svg parts variables so they 
can be called numerically via hangman[0], hangman[1], etc
   hangman[0] = base1 ; hangman[9] = base10 ; hangman.length = 10
*/
  var hangman = [
base1, base2, base3, base4, base5, base6, base7, base8, base9, base10
];
  //console.log(hangman);
  /*******************
    below = create variables from each keyPadButton
  *****************/
  var k1 = document.getElementById('k1');
  var k2 = document.getElementById('k2');
  var k3 = document.getElementById('k3');
  var k4 = document.getElementById('k4');
  var k5 = document.getElementById('k5');
  var k6 = document.getElementById('k6');
  var k7 = document.getElementById('k7');
  var k8 = document.getElementById('k8');
  var k9 = document.getElementById('k9');
  var k0 = document.getElementById('k0');
  var backUp = document.getElementById('backUp');
  /***** begin number pad function ******/
  var keyPad = [k1, k2, k3, k4, k5, k6, k7, k8, k9, k0]
//make keyPad array from keyPad buttons
/************* 
create eventListeners for each keyPad button that fire 
the keyPadPress function 
**************/
  for (var kp = 0; kp < keyPad.length; kp++){
    keyPad[kp].addEventListener('click', keyPadPress);
  }
  /**************
capture number on button and put it into guessField
******/
  function keyPadPress(mw) {
   //console.log('button pressed');
    mw.preventDefault();
   guessField.innerHTML += this.textContent;
/*
permits multiple digit numbers using = what it what plus what was added
*/
   var guessFieldLength = guessField.innerHTML.length;
   /*
console.log('total characters in guess field is: ' + guessFieldLength);
*/
  }
  backUp.addEventListener('click', backUpCursor);
  function backUpCursor(bw){
    //console.log ('backup cursor function fired');tag.innerText.length
    bw.preventDefault();
    let totalNumbers = guessField.innerText.length;
    /*
console.log('length of guess field during backup  is ' + totalNumbers);
*/
 guessField.innerHTML = guessField.innerHTML.substring(0,totalNumbers-1);
//strips off last number
  }
/**********end number pad function***********/
  var randomNumber = Math.floor(Math.random() * 100) +1;

  var guesses = document.querySelector('.guesses');
  var guessesRemaining = document.querySelector('.guessesRemaining');
  var lastResult = document.querySelector('.lastResult');
  var lowOrHi = document.querySelector('.lowOrHi');
  var theArrowUp= document.querySelector('.theArrowUp');
  var theArrowDown= document.querySelector('.theArrowDown');
  var guessSubmitButton = document.querySelector('#guessSubmitButton');
//the submit button
  //var guessField = document.querySelector('.guessField');
//the div  where they enter guesses
  //console.log(hangman[9]);//reads base10
  var guessCount = 1;
    //console.log("guessCount before game is = " + guessCount);
  var resetButton;//creates empty variable
  var guessesRemainingCount = 11;

  //button eventListeners:
  guessSubmitButton.addEventListener('click', checkGuess);
//if they click submit button, run the checkGuess()
  //document eventListeners:
  window.addEventListener('keydown', enterKey);
//has to be keydown!!!!!!! 
//https://www.kirupa.com/html5/keyboard_events_in_javascript.htm
  function enterKey(e){
    e.preventDefault();
      if (e.which === 13) { 
    // if they pressed a key...which one? 13 is enter key
          checkGuess();//fire the checkGuess function
         //console.log("enter key fired checkguess");
        }
  }


  function checkGuess(){
    var userGuess = Number(guessField.innerText);
//captures what ever they guess into userGuess, makes sure it's a number
    if (guessCount === 1){
/*is it their first guess? this is true at the point 
they click it first time*/
      guesses.textContent = 'Guesses: ';
//this text only gets written once.
    }
    guesses.textContent += userGuess + ', ';
//add latest userGuess to list of guesses.
    //console.log('non enter key fired checkguess')
    if (userGuess === randomNumber) {//they nailed it!
      lastResult.textContent = 'Correct!';
      lastResult.style.backgroundColor = 'green';
      for(let i = 0; i < hangman.length; i++ ) {//loops 10 times
        hangman[i].style.visibility = "hidden";//hides each
      }
      skyBlue.style.visibility = 'visible';
      happy.style.visibility = 'visible';

      happy.classList.add('happyBounce');
      //lowOrHi.textContent = '';//empty out Previous 'you are too low!'
      setGameOver();
    } else if (guessCount === 11) {
//they played it 11 times...we counted each time
      lastResult.textContent = 'GAME OVER! ' + guessCount + ' guesses.' ;
      man.classList.add('manBounce');
      guessesRemaining.textContent = '0 guesses left.';
      setGameOver();
    } else {//****************** they guessed wrong
      lastResult.textContent = 'Wrong!';
      lastResult.style.backgroundColor = 'red';
      lowOrHi.style.backgroundColor = 'rgb(2, 120, 157)';
      if (userGuess < randomNumber) {//guess was low

        lowOrHi.textContent = 'Too Low';

      } else if (userGuess > randomNumber){// guess was high


        lowOrHi.textContent = 'Too High';
      }
      /*
console.log("guessCount during game 
before incrementing = " + (guessCount));
     */
      guessesRemainingCount--;//incrementing down remaining guesses
      guessesRemaining.textContent =  'Guesses left: ' + guessesRemainingCount;
      guessCount++;//incrementing up the times they guessed

      hangman[guessCount-2].style.visibility = 'visible';
//turns on hangman artwork parts incrementally
      //console.log(hangman[guessCount-2]);
      guessField.innerHTML = '';
      //guessField.focus();//returns blinking cursor to guessField
    }//end if(userGuess ===)
  }


  console.log(randomNumber);


  function setGameOver(){
//gray out functionality so they can't keep playing
    //guessSubmitButton.removeEventListener('click', checkGuess);
    guessField.style.visibility = 'hidden';
    document.querySelector('.guessSubmitButton a').style.visibility = 'hidden';
    //guessField.disabled = true;
    /******** below may not workvc!******/
//console.log ('set game over is running');
    //guessSubmit.disabled = true;
    resetButton = document.createElement('button');
    resetButton.textContent = 'Start new game';
    //resetButton.classList.add('guessSubmit');
    document.querySelector('.guessSubmitButton').appendChild(resetButton);
    resetButton.classList.add('playAgain');
    resetButton.addEventListener('click', resetGame);
  }

  function resetGame(){//put game back to starting condition
    guessCount = 1;
    guessesRemainingCount = 11;
    if(man.classList.contains('manBounce')){
/*
check to see if man is bouncing, if so  remove the manBounce 
class.Note, he may not be bouncing if they won before 10 guesses
*/
      man.classList.remove('manBounce');
    }
    if(happy.classList.contains('happyBounce')){
      happy.classList.remove('happyBounce');
    }

    for(let i = 0; i < hangman.length; i++ ) {//loops 10 times
      hangman[i].style.visibility = 'hidden';//hides each
    }
    happy.style.visibility = 'hidden';
    var resetParas = document.querySelectorAll('.resultParas p');
//creates an array from the 3 <p>s

    for (var i = 0; i < resetParas.length ; i++){
//for f3 loops, go thru th p's [i] and empty them
      resetParas[i].textContent = '';
    }

    resetButton.parentNode.removeChild(resetButton);
//son tells the parent to remove the son, himself
    skyBlue.style.visibility = 'hidden';
    guessField.style.visibility = 'visible';
      guessSubmitButton.style.visibility = 'visible';
    //guessSubmitButton.addEventListener('click', checkGuess);
    guessField.innerHTML = '';
    //guessField.focus();
    lowOrHi.style.backgroundColor = 'rgba(116, 118, 119, 0)';
//make it invisible
    lastResult.style.backgroundColor = 'rgba(255, 255, 255, 0)';
    randomNumber = Math.floor(Math.random() * 100) +1;
    console.log('New reset random number: ' + randomNumber);
  }

 

Great resource for learning JavaScript

Posted by on January 18th, 2018  •  0 Comments  •  Full Article

I worked through an entire JavaScript course at www.lynda.com but didn’t really feel that I had mastered the language. I did some cool stuff, Morten is always good, but I wanted more. One of his links at the end took me here.

I worked through their first tutorial and it made the classic Number Guessing Game.

I think I can get it working here in wordpress…but I will probably have to run it in an iframe. That will be tomorrows task, since it’s almost midnight.

Until I found this tutorial at developer.mozilla.org I was starting to get frustrated. I’d finished Morten’s course…and I didn’t feel any smarter. But once I started doing this Number Guessing Game, I realized I had actually learned a ton from Morten. The for loop was completely logical. Anyway, I’m making progress. Here is the code:

Here is the HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Guessing game</title>
    <style>
      html {
        font-family: sans-serif;
      }
      body {
        width: 50%;
        max-width: 800px;
        min-width: 480px;
        margin: 0 auto;
      }
      .lastResult {
        color: white;
        padding: 3px;
      }
      .guessSubmit {
        background-color: rgb(238, 223, 182);
      }
      .guessSubmit:hover {
        background-color: rgb(11, 198, 41);
        color: white;
      }
      .guessField {
        background-color: rgb(245, 242, 207)
      }
    </style>
  </head>
  <body>
    <h1>Mark's number guessing game</h1>
    <p>
      We have selected a random number between 1 and 100. See if you can guess
      it in 10 turns or fewer. We'll tell you if your guess was too high or too low.
    </p>

    <div class="form">
      <label for="guessField">Enter a guess:</label>
      <input type="text" id="guessField" class="guessField">
      <input type="submit" value="Submit guess" class="guessSubmit">
    </div><!--end class="form"-->

    <div class="resultParas">
      <p class="guesses"></p>
      <p class="lastResult"></p>
      <p class="lowOrHi"></p>
    </div><!--end class.resultParas-->

 

 

and the script:

    <script>
      var randomNumber = Math.floor(Math.random() * 100) +1;

      var guesses = document.querySelector('.guesses');
      var lastResult = document.querySelector('.lastResult');
      var lowOrHi = document.querySelector('.lowOrHi');

      var guessSubmit = document.querySelector('.guessSubmit');
      var guessField = document.querySelector('.guessField');

      var guessCount = 1;
      var resetButton;//creates empty variable
      function checkGuess(){
        var userGuess = Number(guessField.value);
//captures what ever they guess into userGuess, makes sure it's a number
        if (guessCount === 1){//is it their first guess?
          guesses.textContent = 'Previous guesses: ';
        }
        guesses.textContent += userGuess + ', ';
//add latest userGuess to list of guesses.

        if (userGuess === randomNumber) {//they nailed it!
          lastResult.textContent = 'Congratulations! You got it right!';
          lastResult.style.backgroundColor = 'green';
          lowOrHi.textContent = '';//empty out Previous 'you are too low!'
          setGameOver();
        } else if (guessCount === 10) {
//they played it 10 times...we counted each time
          lastResult.textContent = '!!!GAME OVER!!!';
          setGameOver();
        } else {
          lastResult.textContent = 'Wrong!';
          lastResult.style.backgroundColor = 'red';
          if (userGuess < randomNumber) {
            lowOrHi.textContent = 'Last guess was too low!';
          } else if (userGuess > randomNumber){
            lowOrHi.textContent = 'Last guess was too high!';
          }
        }
        guessCount++;//incrementing up the times they guessed
        guessField.value = '';
        guessField.focus();//returns blinking cursor to guessField
      }//end checkGuess function
      guessSubmit.addEventListener('click', checkGuess);
//if they click submit button, run the checkGuess()
      document.addEventListener('keyup', function (event) {
//tell document to listen for a 'keyup event
        if (event.which === 13) { 
// which event is it? 13 is the enter key, if so, fire the checkGuess function
           checkGuess();
         }
       });

      console.log(randomNumber);

      function setGameOver(){
        guessField.disabled = true;
        guessSubmit.disabled = true;
        resetButton = document.createElement('button');
        resetButton.textContent = 'Start new game';
        document.body.appendChild(resetButton);
        resetButton.addEventListener('click', resetGame);
      }

      function resetGame(){
        guessCount = 1;

        var resetParas = document.querySelectorAll('.resultParas p');
//creates an array from the 3 <p>s

        for (var i = 0; i < resetParas.length ; i++){
//for three loops, go thru th p's [i] and empty them
          resetParas[i].textContent = '';
        }

        resetButton.parentNode.removeChild(resetButton);
//son tells the parent to remove the son, himself

        guessField.disabled = false;//makes the guessField active again
        guessSubmit.disabled = false;
        guessField.value = '';
        guessField.focus();

        lastResult.style.backgroundColor = 'white';
        randomNumber = Math.floor(Math.random() * 100) +1;

      }
    </script>

 

Unlocked my 1997 online journal

Posted by on January 12th, 2018  •  0 Comments  •  Full Article

Back in 2002 my dean asked me to lock my online journal. I’d been writing it since 1997. She thought it made me look unprofessional and she was probably right, though it wasn’t anything bizarre or salacious. It was/is just a bunch of daily writing about working as a printer and raising two teenagers. Last century an online journal was a new thing. WordPress hadn’t been invented, so you had to know how to build a website from scratch. Required skills were html, css, ftp and Photoshop…or at least some kind of image editor.

I used that online journal to learn all that stuff as soon as I bought my first computer in ’97. Anyway, since I’m between jobs right now and not working at the college, I’ve decided to unlock it. Here is the link into the old journal website. The navigation is in Flash…but if you don’t have Flash, you can use the links at the bottom of each post to navigate. It’s not responsive. They hadn’t invented smartphones in ’97, so that was not a concern.

I also have paper journals going back to when I first started drawing in 1971. My sketch pads double as my journals. I find that writing clears the mind. Putting my thoughts down on paper makes them easier to understand. Sort of like emptying out my backpack to see why its so heavy.  Once I can see everything in the clear light of day I can move forward.

I’ve been having a lot of fun studying Javascript at www.lynda.com. They have a guy working there called Morton Rand Hendrickson. He teaches a lot of stuff for Lynda. I’ve taken several WordPress classes from him and he’s always great. In the Javascript class he’s taught me how to build an online clock. I used to teach a clock in Flash Actionscript, so it was interesting to see how similar the Javascript programing was to the old Actionscript. He’s also taught me how to build a typing application that measures the speed and accuracy of your typing. I’ve not put that one online yet, but it was some very interesting programming.

PETZL Sirocco broken buckle fix

Posted by on January 12th, 2018  •  0 Comments  •  Full Article

I’ve had a PETZL Sirocco helmet for a year and I like it a lot. But my buckle just broke during my yearly Christmas trip to Joshua Tree. Before the Sirocco I had been wearing a 1993 Joe Brown helmet. It blew a rivet, so this Sirocco looked very attractive. It’s super light, and as long as I stuff something inside it (to protect it from crushing), I can pack my pack normally and it survived until last week. The buckle Petzl uses is very fragile. The plastic snap tabs are ultra small. There is a magnet inside the buckle that helps pull it closed. Unfortunately, the magnet also attracts iron ore, of which there is a lot in Jtree. I was constantly having to scrape and blow out the sand stuck to the magnet before it would snap.

Finally, up on the “Heart of Darkness” route, one side of the buckle broke completely. I had to borrow a helmet that day. When I got back to camp I replaced the buckle with one I bought at the jtree climbing store. To get the old buckles off, I shaved down the plastic with a razor knife until I could slide the nylon out of the old buckles. Then I prusiked on the new buckle, extended the strap with some tubular nylon using a water knot and had a helmet again. The repair job is stronger than the original. Here are the photos:

PETZL Sirocco broken buckle fix

PETZL Sirocco broken buckle fix

~

PETZL Sirocco broken buckle

PETZL Sirocco broken buckle