How to load sound files in combination with dynamic text? - javascript

In the following example I try with a next-button that changes the text next to the radio-buttons also to load the corresponding audio files.
The sound later corresponds to a question. The user answers with the radio-button and clicksNext. The next question should be played and at the same time the answers next to the radio-buttons change. The selection of the answers (radio-buttons) should be transferred to an external script in a second step.
At the moment, the dynamic lyrics work well, but the sound can not yet be loaded properly to match the text array. clip1 to arr1, clip2 to arr2 and clip3 to arr3
Does anyone have a better solution for that? Many Thanks
//////////Text Array1//////////
var arr1 = [
"Argument arr1,1",
"Argument arr1,2",
"Argument arr1,3",
"Argument arr1,4",
];
var i1 = -1;
function nextItem1() {
i1 = i1 + 1; // increase i by one
i1 = i1 % arr1.length
return arr1[i1]
}
function prevItem1() {
if (i1 === 0) { // i would become 0
i1 = arr1.length
}
i1 = i1 - 1; // decrease by one
return arr1[i1];
}
window.addEventListener('load', function () {
document.getElementById.textContent = arr1[0]; // initial value
document.getElementById('prev_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr1').textContent = prevItem1();
}
);
document.getElementById('next_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr1').textContent = nextItem1();
//document.querySelector('#clip1').click;
}
);
});
//////////Text Array2//////////
var arr2 = [
"Argument arr2,1",
"Argument arr2,2",
"Argument arr2,3",
"Argument arr2,4",
];
var i2 = -1;
function nextItem2() {
i2 = i2 + 1;
i2 = i2 % arr2.length
return arr2[i2];
}
function prevItem2() {
if (i2 === 0) { // i would become 0
i2 = arr2.length
}
i2 = i2 - 1; // decrease by one
return arr2[i2];
}
window.addEventListener('load', function () {
document.getElementById.textContent = arr2[0]; // initial value
document.getElementById('prev_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr2').textContent = prevItem2();
}
);
document.getElementById('next_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr2').textContent = nextItem2();
}
);
});
//////////Text Array3//////////
var arr3 = [
"Argument arr3,1",
"Argument arr3,2",
"Argument arr3,3",
"Argument arr3,4",
];
var i3 = -1;
function nextItem3() {
i3 = i3 + 1;
i3 = i3 % arr3.length
return arr3[i3];
}
function prevItem3() {
if (i3 === 0) { // i would become 0
i3 = arr3.length
}
i3 = i3 - 1; // decrease by one
return arr3[i3];
}
window.addEventListener('load', function () {
document.getElementById.textContent = arr3[0]; // initial value
document.getElementById('prev_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr3').textContent = prevItem3();
}
);
document.getElementById('next_button').addEventListener(
'click', // we want to listen for a click
function (e) { // the e here is the event itself
document.getElementById('arr3').textContent = nextItem3();
}
);
});
//////////Load Sound Clips//////////
var listener = new THREE.AudioListener();
var audioLoader = new THREE.AudioLoader();
var clip1 = document.querySelector('#clip1');
clip1.addEventListener('click', function () {
loadClip('https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/358232_j_s_song.mp3');
});
var clip2 = document.querySelector('#clip2');
clip2.addEventListener('click', function () {
loadClip('https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3');
});
var clip3 = document.querySelector('#clip3');
clip3.addEventListener('click', function () {
loadClip('https://cdn.rawgit.com/mrdoob/three.js/master/examples/sounds/358232_j_s_song.mp3');
});
//////////End Sound Clips//////////
var audioLoaded = false,
result
function loadClip( audioUrl ) {
audioLoaded = false
console.log(`\nLoading sound...`);
audioLoader.load( audioUrl, function( buffer ) {
sound = new THREE.PositionalAudio( listener );
sound.setBuffer( buffer );
sound.setRefDistance( 20 );
sound.setLoop(false);
sound.setVolume(5);
console.log(`\nAudio finished loading!`);
audioLoaded = true
});
play.onclick = function playClip() {
console.log( `\nplayClip()` );
play.style.background = "#92ddb8";
reset.disabled = false;
play.disabled = true;
paused.disabled = false;
sound.play();
}
reset.onclick = function resetClip() {
console.log( `\nresetClip()` );
play.style.background = "";
play.style.color = "";
stop.disabled = true;
play.disabled = false;
paused.disabled = false;
sound.stop()
document.getElementById('radio1').checked = false;
document.getElementById('radio2').checked = false;
document.getElementById('radio3').checked = false;
console.clear()
}
paused.onclick = function pausedClip() {
console.log( `\npausedClip()` );
play.style.background = "";
play.style.color = "";
stop.disabled = false;
play.disabled = false;
paused.disabled = true;
sound.pause();
}
}
#arr1 {
font-family:Arial,sans-serif;
font-size: 1em;
color:black;
margin-top: -20px;
margin-left: 30px;
}
#arr2 {
font-family:Arial,sans-serif;
font-size: 1em;
color:black;
margin-top: -20px;
margin-left: 30px;
}
#arr3 {
font-family:Arial,sans-serif;
font-size: 1em;
color:black;
margin-top: -20px;
margin-left: 30px;
}
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<input type="radio" id="radio1" name="myCheckbox" autocomplete="off" onclick="myCheckbox"/>
<p id="arr1">load audio 1 for test</p>
<input type="radio" id="radio2" name="myCheckbox" autocomplete="off" onclick="myCheckbox"/>
<p id="arr2">load audio 2 for test</p>
<input type="radio" id="radio3" name="myCheckbox" autocomplete="off" onclick="myCheckbox"/>
<p id="arr3">load audio 3 for test</p>
<button id="play" class="play">Play</button>
<button id="paused" class="paused">Pause</button>
<button id="reset" class="reset">Reset</button>
<input type="button" id="prev_button" value="<< Prev" onclick="prev_button">
<input type="button" id="next_button" value="Next >>" onclick="next_button">
<p id="clip1"></p>
<p id="clip2"></p>
<p id="clip3"></p>

Related

how to use .addEventListener when clicking an image and counting the clicks (Javascript)

//* I am trying to click on an image and it counts the clicks*//
var addUp = function(counterId) {
var count = 0;
elem.addEventListener('click', function(counterID){
return function () {
var counterEle = document.getElementById(counterId);
if (counterEle)
counterEle.innerHTML = "Picture Clicks: " + ++count;
}
};
var elem = document.getElementById('PicC');
PicC.addEventListener("click", addUp("PicC-counter"), false);
<img id="PicC" src="avatar.png" alt="Avatar" style="width:200px" onclick="addUp()">
function clickCount(element, listener) {
if (!element) throw new Error("No element to listen to");
let clickCountObj = {};
clickCountObj.clickCount = 0;
clickCountObj.clickDelay = 500;
clickCountObj.element = element;
clickCountObj.lastClickTime = 0;
let clickCountListener = function (e) {
if ((e.timeStamp - clickCountObj.clickDelay) < clickCountObj.lastClickTime) {
clickCountObj.clickCount = clickCountObj.clickCount + 1;
}
else {
clickCountObj.clickCount = 1;
}
clickCountObj.lastClickTime = e.timeStamp;
listener.call(element, clickCountObj.clickCount, e);
};
clickCountObj.remove = function () {
element.removeEventListener("click", clickCountListener);
}
element.addEventListener("click", clickCountListener);
return clickCountObj;
}
You've made it much more complex than it needs to be.
const output = document.getElementById("count");
document.getElementById('PicC').addEventListener("click",function(event){
output.textContent = +output.textContent + 1;
});
<img id="PicC" src="avatar.png" alt="Avatar" style="width:200px">
<div>Click count = <span id="count">0</span></div>
Here's what went wrong, as far as I can tell:
addEventListener was inside a function
addEventListener doesn't accept function parameters
count was being reset every click
and more
You can simply hook up the event listener to a function that'll increment clicks and add the value to the click counter.
var clicks = 0;
document.getElementById("clickme").addEventListener("click", addClick);
function addClick() {
clicks++;
document.getElementById("clickCounter").innerHTML = "Picture Clicks: " + clicks;
}
#clickme {
background-color: black;
width: 100px;
height: 100px;
<div id="clickme"></div> <!-- replaced with div for convenience -->
<div id="clickCounter">Picture Clicks: 0</div>
There's no need of addEventListener for such a simple task.
My suggestion (no CSS added):
var i = 1;
PicC.onclick = () => {
counter.innerHTML = i;
i++;
}
<img id="PicC" src="https://via.placeholder.com/150" alt="Avatar">
<br>
<div>Click(s): <span id="counter">0</span></div>

Combination filters + quick search with Isotope

I’m trying to combine two Isotope filtering features (combination filtering via checkbox and quick search) with no luck. My attempt is here: https://codepen.io/anon/pen/WJvmaj, which is a combination of both of the mentioned feature's demos.
At the moment the search is set to return searchResult and checkboxResult, the latter of which isn’t being defined properly in the code I can tell, and there lies my problem: I’m not sure what to set the checkboxResult variable to in order for it to target what’s being returned by the checkbox filtering.
Check if the element includes the text that input in search input or not with .includes() and if the element has any of selected class from checkboxs' value.
BTW, next time please provide a Minimal, Complete, and Verifiable example that demonstrates the problem, not a link to your fiddle or codepen, cause the links would be broken and other users couldn't understand what you asked and the scenario of the question.
$container.isotope({
filter: function() {
var $this = $(this)
var checkText = text == '' ? true : $this.text().includes(text)
var checkClass = inclusives.length == 0 ? true : false;
$.each(inclusives, function(index, c) {
var _class = $this.hasClass(c)
if (_class) {
checkClass = true;
return;
}
})
return checkText && checkClass
}
})
// quick search regex
var qsRegex;
var checkboxFilter;
// templating
var colors = ['red', 'green', 'blue', 'orange'];
var sizes = ['small', 'medium', 'large'];
var prices = [10, 20, 30];
createItems();
// init Isotope
var $container = $('#container')
var $output = $('#output');
// filter with selects and checkboxes
var $checkboxes = $('#form-ui input');
function createItems() {
var $items;
// loop over colors, sizes, prices
// create one item for each
for (var i = 0; i < colors.length; i++) {
for (var j = 0; j < sizes.length; j++) {
for (var k = 0; k < prices.length; k++) {
var color = colors[i];
var size = sizes[j];
var price = prices[k];
var $item = $('<div />', {
'class': 'item ' + color + ' ' + size + ' price' + price
});
$item.append('<p>' + size + '</p><p>$' + price + '</p>');
// add to items
$items = $items ? $items.add($item) : $item;
}
}
}
$items.appendTo($('#container'));
}
var $quicksearch = $('#quicksearch')
// debounce so filtering doesn't happen every millisecond
function debounce(fn, threshold) {
var timeout;
threshold = threshold || 100;
return function debounced() {
clearTimeout(timeout);
var args = arguments;
var _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
}
function Filter() {
// map input values to an array
var inclusives = [];
// inclusive filters from checkboxes
$checkboxes.each(function(i, elem) {
// if checkbox, use value if checked
if (elem.checked) {
inclusives.push(elem.value);
}
});
// combine inclusive filters
var filterValue = inclusives.length ? inclusives.join(', ') : '*';
var text = $quicksearch.val()
$container.isotope({
filter: function() {
var $this = $(this)
var checkText = text == '' ? true : $this.text().includes(text)
var checkClass = inclusives.length == 0 ? true : false;
$.each(inclusives, function(index, c) {
var _class = $this.hasClass(c)
if (_class) {
checkClass = true;
return;
}
})
return checkText && checkClass
}
})
$output.text(filterValue);
}
$quicksearch.on('input', debounce(function() {
Filter()
}));
$checkboxes.change(function() {
Filter()
});
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
.item {
width: 100px;
height: 100px;
float: left;
margin: 5px;
padding: 5px;
}
.item p {
margin: 0;
}
.red {
background: #F33;
}
.blue {
background: #88F;
}
.green {
background: #3A3;
}
.orange {
background: orange;
}
select,
label,
input {
font-size: 20px;
}
label {
margin-right: 10px;
}
#quicksearch {
height: 30px !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//npmcdn.com/isotope-layout#3/dist/isotope.pkgd.js"></script>
<p><input type="text" id="quicksearch" placeholder="Search" /></p>
<div id="form-ui">
<p>
<label><input type="checkbox" value="red" /> red</label>
<label><input type="checkbox" value="green" /> green</label>
<label><input type="checkbox" value="blue" /> blue</label>
<label><input type="checkbox" value="orange" /> orange</label>
</p>
<p id="output">--</p>
</div>
<div id="container">
<!-- items added with JS -->
</div>

button addEventListener does not function

I am having issues getting a button to work. I want something to happen when I click this button:
<button id="pigBtn" value="click">Pig It!</button>
and my JS file has
window.addEventListener('load', function(){
console.log('hello');
let pigBtn = document.querySelector('#pigBtn');
console.log('pigged');
pigBtn.addEventListener('click', function (){
function pigIt(phrase) {
let array = phrase.split(' ');
console.log('array');
for (let i = 0; i < phrase.length; i++) {
let pig = array[i].split('');
let one = pig.shift();
pig.push(one);
pig.push('ay');
let two = pig.join('');
array[i] = two;
}
return array.join(' ');
}
});
});
'hello' and 'pigged' show up but 'array' does not. What am I missing here?
The button has id pigBtn, but you try to select an element with id pigged.
Try this instead:
let pigBtn = document.querySelector('#pigBtn');
window.addEventListener('load', function(){
console.log('hello');
let pigBtn = document.querySelector('#pigBtn');
console.log('pigged');
pigBtn.addEventListener('click', function (){
console.log('clicked');
});
});
<button id="pigBtn" value="click">Pig It!</button>
window.addEventListener('load', function(){
console.log('hello');
let pigBtn = document.querySelector('#pigBtn');
console.log('pigged');
pigBtn.addEventListener('click', function (){
console.log('clicked');
});
});
The ID in your querySelector has to match the ID of the button in your HTML.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
Your pigIt function is never executed. You define it in your event handler, but you never run it.
I think you're going for something like this :
window.addEventListener('load', function(){
var sentence = "This is the phrase I'm pigging";
console.log('hello');
let pigBtn = document.getElementById('pigBtn');
let pigTxt = document.getElementById('phraseTxt');
let pigPhraseTxt = document.getElementById('pigPhraseTxt');
console.log('pigged');
pigBtn.addEventListener('click', function(e) {
let array = pigTxt.value.split(' ');
for (let i = 0; i < array.length; i++) {
let pig = array[i].split('');
let one = pig.shift();
pig.push(one);
pig.push('ay');
let two = pig.join('');
array[i] = two;
}
pigPhraseTxt.value = array.join(' ');
});
});
input {
display : block;
width : 100%;
padding: 0;
border: 1px solid #aaa;
}
input:read-only {
background: #ddd;
}
<input type="text" id="phraseTxt" value="This is the text I'm converting to Pig Latin" />
<input type="text" id="pigPhraseTxt" readonly />
<button id="pigBtn" value="click">Pig It!</button>

Reset counter on spacebar and onclick

I'm trying to make a count-down that counts down from 200 to 0 in steps of 10.
This timer can be stopped and should then be reset to 200, however, I need also the value of the moment is stopped. The countdown fills the div #log with innerHTML. Whenever I "stop" the timer, I take the value of #log and place it in #price and I hide #log. The problem here is that the timer continues in the background, while I want it to reset so it can be started again by clicking on start. However, it just continues counting down and only after it's done, I can start it again.
In the example, it doesn't take so long for it to reach 0, but in the end, it'll take 15-20 seconds to reach 0, which'll be too long to wait for.
So in short: Countdown 200-0, but on click of Start-button or spacebar, it should stop the function running at the moment, so it can be started again.
See this PEN
If you have any suggestions on how to approach it completely different, you're very welcome to share!
HTML
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
JS
var log = document.getElementById("log");
var btn = document.getElementById("btn");
var price = document.getElementById("price");
var counting = false;
var btnClassName = btn.getAttribute("class");
function start(count) {
if (!counting) {
counting = true;
log.innerHTML = count;
var timer = setInterval(function() {
if (count >= 0) {
log.innerHTML = count;
count -= 10;
} else {
clearInterval(timer);
count = arguments[0];
counting = false;
btn.className = "normal";
}
}, 150);
};
};
btn.onclick = function() {
if (btnClassName == "normal") {
start(200);
price.style.display = 'none';
log.style.display = 'block';
btn.className = "counting";
log.innerHTML = "";
} else {
}
};
document.body.onkeyup = function(e){
if(e.keyCode == 32){
price.innerHTML = log.innerHTML;
price.style.display = 'block';
log.style.display = 'none';
}
}
I "re-code" your code because there are several issues there.
Just read the code and tell me if that's you are looking for or if you have any questions..
var log = document.getElementById("log");
var btn = document.getElementById("btn");
var price = document.getElementById("price");
var counting = false;
var timer;
var c = 0;
function start(count) {
btn.blur();
if (!counting) {
c = count;
counting = true;
log.innerHTML = count;
timer = setInterval(tick, 1500);
tick();
};
};
function tick() {
if (c >= 0) {
log.innerHTML = c;
c -= 10;
}
else {
clearInterval(timer);
c = arguments[0];
counting = false;
btn.className = "normal";
}
}
btn.onclick = function() {
resetTimer();
var btnClassName = btn.getAttribute("class");
if (btnClassName == "normal") {
price.style.display = 'none';
log.style.display = 'block';
btn.className = "counting";
log.innerHTML = "";
start(200);
} else {
pause();
}
};
document.body.onkeyup = function(e) {
if(e.keyCode == 32) {
e.preventDefault();
pause();
}
}
function pause() {
resetTimer();
price.innerHTML = log.innerHTML;
price.style.display = 'block';
log.style.display = 'none';
btn.className = 'normal';
counting = false;
}
function resetTimer() {
clearInterval(timer);
}
body { font: 100% "Helvetica Neue", sans-serif; text-align: center; }
/*#outer {
width: 400px;
height: 400px;
border-radius: 100%;
background: #ced899;
margin: auto;
}
#inner {
width: 350px;
height: 350px;
border-radius: 100%;
background: #398dba;
margin: auto;
}*/
#log, #price {
font-size: 500%;
font-weight: bold;
}
<div id="outer">
<div id="inner">
<div id="arrow">
</div>
</div>
</div>
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
Though you have already got your answer, you can try something like this:
Also I have taken liberty to reformat your code, and for demonstration purpose, have kept delay for interval as 1000
JSFiddle
function Counter(obj) {
var _initialVaue = obj.initialValue || 0;
var _interval = null;
var status = "Stopped";
var start = function() {
this.status = "Started";
if (!_interval) {
_interval = setInterval(obj.callback, obj.delay);
}
}
var reset = function() {
stop();
start();
}
var stop = function() {
if (_interval) {
this.status = "Stopped";
window.clearInterval(_interval);
_interval = null;
}
}
return {
start: start,
reset: reset,
stop: stop,
status: status
}
}
function init() {
var counterOption = {}
var count = 200;
counterOption.callback = function() {
if (count >= 0) {
printLog(count);
count -= 10;
} else {
counter.stop();
}
};
counterOption.delay = 1000;
counterOption.initialValue = 200
var counter = new Counter(counterOption);
function registerEvents() {
document.getElementById("btn").onclick = function() {
if (counter.status === "Stopped") {
count = counterOption.initialValue;
counter.start();
printLog("")
toggleDivs(counter.status)
}
};
document.onkeyup = function(e) {
if (e.keyCode === 32) {
printLog(counterOption.initialValue);
counter.stop();
toggleDivs(counter.status)
printPrice(count);
}
}
}
function printLog(str) {
document.getElementById("log").innerHTML = str;
}
function printPrice(str) {
document.getElementById("price").innerHTML = str;
}
function toggleDivs(status) {
document.getElementById("log").className = "";
document.getElementById("price").className = "";
var hideID = (status === "Started") ? "price" : "log";
document.getElementById(hideID).className = "hide";
}
registerEvents();
}
init();
body {
font: 100% "Helvetica Neue", sans-serif;
text-align: center;
}
.hide{
display: none;
}
#log,
#price {
font-size: 500%;
font-weight: bold;
}
<div id="outer">
<div id="inner">
<div id="arrow">
</div>
</div>
</div>
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
Hope it helps!

Undefined index after running function a few times

So I was trying to create my own Blackjack in javascript for learning purposes and even though the code is overall working, I came across a weird bug.
After some clicks on the Deal html button, which calls the function deal(), I will get either a playerHand[i] undefined or dealerHand[i] undefined error on line 114 or 118, respectively, of the code posted below.
I noticed this also happened if I clicked the button very fast for whatever reason.
I suspected it had something to do with memory optimization so I used the delete command to reset those arrays between game turns, but the error persists.
So, why do my arrays break after some use?
Thanks.
JS:
var deck = [];
var dealerHand = [];
var playerHand = [];
var dscore = 0;
var pscore = 0;
var turn = 0;
function Card(suit, src) {
this.src = src;
this.suit = getSuit(suit);
this.value = getValue(src);
};
function getSuit(suit) {
if (suit == 1) return "Clubs";
if (suit == 2) return "Diamonds";
if (suit == 3) return "Hearts";
if (suit == 4) return "Spades";
};
function getValue(src) {
if (src == 1) return 11;
if (src < 10) return src;
else return 10;
};
function createDeck() {
for (i=1; i<=4; i++) {
for(j=1; j<=13; j++) {
var card = new Card(i, j);
deck.push(card);
};
};
};
function getCard() {
var rand = Math.floor(Math.random()*deck.length);
deck.splice(rand,1);
return deck[rand];
};
function deal() {
if(turn == 0) {
dealerHand.push(getCard());
playerHand.push(getCard());
};
dealerHand.push(getCard());
playerHand.push(getCard());
};
function stand() {
dealerHand.push(getCard());
};
function clearBoard () {
$('#player').html("");
$('#dealer').html("");
};
function resetDeck () {
delete deck;
deck = [];
};
function resetHands () {
delete dealerHand;
delete playerHand;
dealerHand = [];
playerHand = [];
};
function resetScore () {
pscore = 0;
dscore = 0;
};
function isAce (arr) {
for(i=0; i<arr.length; i++) {
if (arr[i].src == 1) return true;
else return false;
};
}
function updateScore() {
resetScore();
if (playerHand.length > 0 && dealerHand.length > 0) {
for(i=0; i<playerHand.length; i++) {
pscore += playerHand[i].value;
};
for(i=0; i<dealerHand.length; i++) {
dscore += dealerHand[i].value;
};
//Regra do Às
if(pscore > 21 && isAce(playerHand)) {
pscore -= 10;
};
if(dscore > 21 && isAce(dealerHand)) {
dscore -= 10;
};
} else {
pscore = 0;
dscore = 0;
};
};
function showScore () {
$('#pscore').html("<p>Player Score: " + pscore + "</p>");
$('#dscore').html("<p>Dealer Score: " + dscore + "</p>");
};
function showCards () {
for(i=0; i<playerHand.length; i++) {
var div = $("<div>");
var img = $("<img>");
img.attr('src', 'img/cards/' + playerHand[i].suit + '/' + playerHand[i].src + '.png');
div.append(img);
$('#player').append(div);
};
for(i=0; i<dealerHand.length; i++) {
var div = $("<div>");
var img = $("<img>");
img.attr('src', 'img/cards/' + dealerHand[i].suit + '/' + dealerHand[i].src + '.png');
div.append(img);
$('#dealer').append(div);
};
};
function cleanUp () {
if (pscore == 21) {
alert("Blackjack!");
newGame();
};
if (pscore > 21) {
alert("Bust!");
newGame();
};
if (dscore == 21) {
alert("You lost!");
newGame();
};
if (dscore > 21) {
alert("You won!");
newGame();
};
};
function newGame () {
turn = 0;
clearBoard();
resetHands();
resetScore();
showScore();
resetDeck();
createDeck();
};
function gameTurn () {
clearBoard();
updateScore();
showCards();
showScore();
cleanUp();
turn++;
};
$(document).ready(function() {
newGame();
$('#deal').on('click', function(){
deal();
gameTurn();
});
$('#stand').on('click', function(){
stand();
gameTurn();
});
});
CSS:
body {
background: url(../img/greenbg.png);
}
.holder {
width:800px;
margin:auto;
}
.clearfix {
clear:both;
}
#pscore, #dscore {
color: white;
margin: 10px;
display: block;
font-size: 1.2rem;
text-shadow: 0 0 5px #000;
}
.container {
width: 600px;
height: 300px;
margin: 10px;
}
div img {
float: left;
margin: 10px;
}
div button {
margin: 10px;
}
HTML:
<html>
<head>
<div class="holder clearfix">
<div id="dscore"><p>Dealer Score: 0</p>
</div>
<div id="dealer" class="container">
</div>
<div id="pscore"><p>Player Score: 0</p>
</div>
<div id="player" class="container">
</div>
<div class="">
<button id="deal">Deal</button>
<button id="stand">Stand</button>
</div>
</div>
</body>
</html>
You have a problem in this function, which may be to blame:
function getCard() {
var rand = Math.floor(Math.random()*deck.length);
deck.splice(rand,1);
return deck[rand];
};
As written, it's removing a card, and then returning the card that now has that position in the deck. If rand was the last element in the array then there is no longer a card in that position, so it'll return undefined.
You should be returning the value of the removed card itself, part of the result of the splice call:
function getCard() {
var rand = Math.floor(Math.random() * deck.length);
var pick = deck.splice(rand, 1);
return pick[0];
};
p.s. it's worth learning modern ES5 utility functions for arrays. For example, your isAce function could be rewritten thus, avoiding the bug where you always return after testing the first element:
function isAce(arr) {
return arr.some(function(n) {
return n === 1;
});
};
or, more cleanly:
function isAce(card) {
return card === 1; // test a single card
};
function holdsAce(hand) {
return hand.some(isAce); // test an array (or hand) of cards
};

Categories