Made a duet and a game
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); }