1

In my game I have a startGame() function which initializes all the key functions that start the game. At the beginning, you press the start button to take you to the game. Once the game is complete the restart button appears. When this is clicked it takes you back to the start screen, where the start button is.

Ideally I would like at this point to be able to click the start button for the second time, and a new game appear. The problem is that it brings the old game up. I have tried to use .empty, .queue and .dequeue and reset, but nothing seems to work.

How can I restart all the functions when the restart-button is clicked?

$(document).ready(function () {

successSound = $("#successSound")[0];
failSound = $("#failSound")[0];
moveSound = $("#moveSound")[0];
hitSound = $("#hitSound")[0];
missSound = $("#missSound")[0];
hintSound = $("#hintSound")[0];
hintPic = $("#hintPic")[0];
hintPicTitle = $("#hintPicTitle")[0];
bgMusic = $('#audio-bg')[0];

newGame();

//Click event to start the game
$(".start-btn-wrapper").click(function () {
    startplay();

});
//Click event to restart the game
$(".restart-btn").click(function () {
    restartplay();
});   

Fiddle with script in: http://jsfiddle.net/rVaFs/

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sMilbz
  • 951
  • 7
  • 25
  • That fiddle doesn’t help, there is no markup. Could you please post relevant code for the `startplay()` and `restartplay()` functions? – David Hellsing Nov 26 '12 at 12:27
  • 2
    The simplest way is to refresh the page, but if you don't want to you would need to write the code to manually reset everything (all variables and DOM) to its initial state. – Alvin Wong Nov 26 '12 at 12:28
  • No refresh is not an option. Could I write a function called resetGame() and do it all in there? @AlvinWong – sMilbz Nov 26 '12 at 12:30

3 Answers3

2

It will be much easier if you stop using globals: everything not prefixed with var (including functions). If your startplay depends on initial DOM state, and it’s too difficult (or just takes too much time) to rewrite the code, you can just make a copy of that part of DOM before starting game and delete it on finish.

Wuron
  • 31
  • 5
1

You could use the document.ready callback to reset everything back to it's original state, by naming the callback function:

$(document).ready(function reset()
{
    //your code here
    //note, you must ensure event handlers are unbound:
    $('#reset').unbind('click').bind('click',reset);//<-- call main callback
});

Another thing you have to keep in mind is that you're creating a lot of implied globals, which could cause problems if you were to use the ready callback. To address this, do change these lines: successSound = $("#successSound")[0]; to var successSound = $("#successSound")[0];.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • they are defined as variables at the top so that is not a problem. I have tried your way and nothing has changed. The old grid still comes back when the start button is re-clicked @Elias Van Ootegem – sMilbz Nov 26 '12 at 15:05
  • @sMilbz: That's why the globals aren't the best of idea's: you're using the same references, regardless of their initial state, the way to go would be as @AleksandrChepurnoy says is to "copy" (part of) the dom (use the `.cloneNode` method if you have to) – Elias Van Ootegem Nov 26 '12 at 15:21
  • I'm really new to this and have no idea how I would do that. Can you show me? or even show me a better way to lay out my variables? @Elias Van Ootegem – sMilbz Nov 26 '12 at 15:28
  • @sMilbz: Honestly, I'm currently reading the post [What have you tried](http://mattgemmell.com/2008/12/08/what-have-you-tried/), and I'm compelled _not_ to give you a copy-paste answer, instead, spend some time reading the aforementioned blog post, and subsequently, [bookmark a few MDN pages](https://developer.mozilla.org/en-US/docs/JavaScript/Reference), [like the docs on the cloneNode method](https://developer.mozilla.org/en-US/docs/DOM/Node.cloneNode) – Elias Van Ootegem Nov 26 '12 at 15:31
  • That's fair enough. I'm not asking for a copy paste answer. I would just like an example @Elias Van Ootegem – sMilbz Nov 26 '12 at 15:36
  • @sMilbz: To be honest, I don't feel like going through all of your code, but for a kickoff: your declaring the variables in the global scope (outside of the `document.ready` callback), which is _evil_, keep the global namespace as clean as possible, honestly, you'll be doing yourself an enormous favour in doing so. That way, when the function callback returns the vars can be GC'ed, unlike globals which are never GC'ed, so every DOMNode they reference will stay in memory, regardless, even if the node doesn't exist in the DOM, the memory will never be deallocated. Tip: look into _closures_ – Elias Van Ootegem Nov 26 '12 at 15:55
  • So you are saying to put all my variable in the document.ready? @Elias Van Ootegem – sMilbz Nov 26 '12 at 16:08
  • @sMilbz: at the very least. The ready callback is a function, so it has it's own scope. Thus variables that are declared within that function can be GC'ed when the function returns, globals will always stay in memory. Perhaps [this question](http://stackoverflow.com/questions/1841916/how-to-avoid-global-variables-in-javascript) can help you, it deals with reloading the load event, too, which is what you need – Elias Van Ootegem Nov 27 '12 at 08:06
  • I have tried to put them all in the ready function in the past and I get bombarded by errors saying that things are not defined. @Elias Van Ootegem – sMilbz Nov 27 '12 at 08:35
  • @sMilbz: that's probably because you're declaring a lot of functions globally, that reference those variables, too. Just move the `$(document).ready(function()` line to the very top of the script and wrap all of your code in that callback. So `$(document).ready(function` is on line one, and the closing `});` bit is on the very last line, so all the functions are declared inside the callback's scope. if those function definitions throw errors, try wrapping them in an if statement: `if (!foo instanceof Function){ function foo(){};}`, ensuring functions aren't defined twice – Elias Van Ootegem Nov 27 '12 at 09:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/20157/discussion-between-smilbz-and-elias-van-ootegem) – sMilbz Nov 27 '12 at 09:54
0

I created a function called resetGame() and cleared the DOM:

function resetGame() {
    $(document).ready();
    $('.table-container').empty();
    $('.reveal-wrapper').empty();
    $('.helper').removeClass('inactive');
    $('.tiles-wrapper').removeClass('active');
    $('.hint-container').removeClass('active');
    $('td').addClass('highlight-problem');
    $('.game').removeClass("active").removeClass('game-over').addClass('standby').addClass('transition');
    $('.score').html("");
    $(".next-question").removeClass('move-down');
    $('.reveal-wrapper').removeClass('image' + randomNumber);
    $(bgMusic).unbind();
    score.right = 0;
    score.wrong = 0;
}

function newGame() {
    randomWord = [];
    listOfWords = [];
    attemptNumber = [];
    completionNumber = [];
    populationNumber = [];
    gridSize = [];

    createGrid();
    backGroundImage();
    dragEvent();
    nextQuestion();
    closeMessage();
    replaySound();

    $('.score').html("0/" + completionNumber);
    $('.game').removeClass("standby").addClass('active').addClass('transition');

    $(bgMusic).on('timeupdate', function () {
        var vol = 1,
            interval = 250;
        if (bgMusic.volume == 1) {
            var intervalID = setInterval(function () {
                if (vol > 0) {
                    vol -= 0.05;
                    bgMusic.volume = vol.toFixed(2);
                } else {
                    clearInterval(intervalID);
                }
            }, interval);
        }
    });
}

$(document).ready(function () {
    successSound = $("#successSound")[0];
    failSound = $("#failSound")[0];
    moveSound = $("#moveSound")[0];
    hitSound = $("#hitSound")[0];
    missSound = $("#missSound")[0];
    hintSound = $("#hintSound")[0];
    hintPic = $("#hintPic")[0];
    hintPicTitle = $("#hintPicTitle")[0];
    bgMusic = $('#audio-bg')[0];

    backGroundSound();
    playBackGroundSound();
    keyPress();

    $(".start-btn-wrapper").click(function () {
        newGame();
    });
    $(".restart-btn").click(function () {
        resetGame();
    });
});

I then called it in the restart-btn click event.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sMilbz
  • 951
  • 7
  • 25