Learn Angular.js with a noob

Count Down

Our app is based on infinite looping, we think that the best way to memorize new words is just repeating and repeating, untile you can react to a word within 0.5 second.

0.5 second?

We can let the user adjust this threshold, like that 1 second at first and then 0.8s, 0.5s. In our code, we can set it to 0.5s since it's just a number, and we can create some setting page to enable customization.

If 0.5s is passed and user has no interaction like keypressing or mouse clicking, then it is thought to be failed , we show the explanation and mark it as failed; otherwise this word is passed.

The Failed word will come again, let's say, randomly.

Until all words are reacted within 0.5 seconds, the looping will not end with a green mark.

the timer

so there should a timer to count down, and every time flip() is called, timer should be reset(). As this timer, it updates numbers every 10ms, and if over than 0.5s, it should set this round to fail();

Firstly, we update our html template.

<div class="battle-field">
    <div class="count-down">00:00</div>
    <div class="content">
        <h2 class="word">Japnese Words</h2>
        <p class="desc">Click or Press spacebar</p>
    </div>
</div>

Now we define the methods metioned above.

//whole battle field
var $battleField = $(".battle-field");

//battle field content
var $battleFieldContent = $(".battle-field .content");

//the timer in DOM
var $countDown = $(".battle-field .count-down");

//the timer in script
var timerCountDown = null;

//whether current word is failed to react, or not
var failed = false;

var updateTimerText = function(start){
    var diff = +new Date() - start;
    var secs = Math.floor(diff / 1000);
    var milli = diff - secs * 1000;
    $countDown.text("" + secs + ":" + milli);

    if (diff > 500) {
        failed = true;
        $battleField.addClass('failed');
    }
}
//restar the timer
var resetTimer = function() {
    clearInterval(timerCountDown);

    var now = +new Date();
    timerCountDown = setInterval(function(){
        updateTimerText(now);
    }, 10);

    failed = false;
    $battleField.removeClass('failed');
}

when all words are done

If current word is not failed(reacted within 0.5s), we remove this word out of the list, and when all words are removed, the game is over. We use a varible failed to store the state, and end() to clean up the rest.

By the way, the method flip() is not easy to understand, we change it to showNextWord().

// ends when all words are looped
var end = function(){
    clearInterval(timerCountDown);
    var html =  "<h2 class=\"word\">Congrats!</h2>" +
                "<p class=\"desc\">You accomplished all words</p>";
    $battleFieldContent.html(html);
};

var showNextWord = function(){
    if (length === 0) {
        $battleField.addClass('ended');
        return;
    }

    if (!failed) {
        hira.splice(index,1);
        kata.splice(index,1);
        pronunciation.splice(index,1);
        length -= 1;
    }

    //if all words are looped
    if (length === 0) {
        end();
        return;
    }

    index = (index + 1) % length;
    var html =  "<h2 class=\"word\">" + hira[index] + " " + kata[index] + "</h2>" +
                "<p class=\"desc\">" + pronunciation[index] + "</p>";

    $battleFieldContent.html(html);
    resetTimer();
};

$(document).on('click', '.battle-field', showNextWord);

$(document).on('keypress', function(e){
    //if it's spacebar
    if (e.which === 32) {
        showNextWord();
    }
});

The app upto now can be accesed from: http://colla.me/public/books/learn_angularjs_with_a_noob/app/1.4/