Используя javascript/jQuery, подождите 3 секунды до щелчка, затем продолжите

Я пытался понять, как запустить бесконечный цикл во время паузы для щелчка пользователя, а затем разрешить перерыв.

Когда цикл начинается, пользователю предоставляется изображение, и он должен выбрать идентичное изображение из одного из 4 отображаемых. Если они успешно нажимают на совпадение в течение 5 секунд, им предоставляется другое изображение, и игра продолжается. Если они либо выберут неправильное изображение, либо истечет 5 секунд, игра заканчивается.

У меня проработан весь функционал, кроме вот этой паузы в ожидании клика или истечения времени.

В идеале я также хотел бы, чтобы время настраивалось на каждой итерации. Скажем, начните с 5 секунд, затем немного сократите время (10 мс) на каждом цикле.

Я считаю, что это должно быть решаемо с помощью setTimeout() или setInterval(), но просто не могу обдумать это.

Вот минимальная концепция того, чего я пытаюсь достичь.

$('#playnow').on('click',function(){
    var speed = 5000;
    var speed_reduce = 10;
    var game_running = true;

    /* create array of images */
    var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];

    var runnow = setInterval(
        function(){

            //get random image from loaded theme
            rand_img = imgs[Math.floor(Math.random() * imgs.length) ];

            //display chosen image
            $('#goal_image').html('<img src="'+theme_dir+rand_img+'" />');

            // wait up to 5 seconds for user to click or time to expire
            if(*clicked and matched*){
                //get new random image and reset timer (less 10ms)
            }
            if(*time expired*){
                //bail out and game ends
            }   

            /* reduce time */
            speed -= speed_reduce;
        },
    speed);

});

person bluedenham    schedule 08.01.2016    source источник


Ответы (4)


Я думаю, вам понадобится что-то вроде этого:

var speed = 5000, // the initial time
    currentimage,
    timer,
    gamerunning;
function newimage(){
    var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];
    currentimage=Math.floor(Math.random() * imgs.length);
    $('#goal_image').html('<img src="'+theme_dir+imgs[currentimage]+'" />');
    timer = setTimeout(speed, lost)
}
function answer(id){
    if(!gamerunning){return}
    clearTimeout(timer)
    if(id==currentimage){
        speed -= 10; // time decrease every time.
        newimage();
    }else{
        lost()
    }
}
function lost(){
    gamerunning=0;
    speed=5000;
    // what to do when lost.
}
$("#puppy").on("click",function(){answer(0)}); // here #puppy is the id of the answer image, and 0 the index in the imgs array.
$("#kitten").on("click",function(){answer(1)});
$("#bunny").on("click",function(){answer(2)});
$("#fish").on("click",function(){answer(3)});
$("#gamestartbutton").on("click",function(){gamerunning=1})
person Ewoud    schedule 09.01.2016
comment
Спасибо всем, кто вставил свои пять копеек. Я смог достичь своей цели, используя комбинацию всех ответов, но, поскольку я могу официально поблагодарить только одного, я выбрал Ewoud, поскольку их ответ был наиболее полезным, и в конечном итоге мои собственные умственные соки текли больше всего. @Ewoud: создал функции nweimage и lost @Michael Saunders: создал runNow @fken: создал gameover @Araymer: заставил меня увидеть необходимость clearInterval (в итоге использовал set/clearTimeout) - person bluedenham; 09.01.2016

Один из способов решить эту проблему — использовать setTimeout() и clearTimeout() вместо setInterval. Кроме того, вам нужно какое-то событие для успешного нажатия кнопки (я сделал вид, что у вас есть специальная кнопка «#successfulmatch»):

var speed = 5000;
var speed_reduce = 10;
var game_running = true;
var imgs = ['puppy.png','kitten.png','bunny.png','goldfish.png'];
var myTimeout;

function runNow(speed){
  rand_img = imgs[Math.floor(Math.random() * imgs.length) ];
  $('#goal_image').html('<img src="'+theme_dir+rand_img+'" />');
  
  // Keep track of the timeout so we can cancel it later if the user clicks fast enough.
  myTimeout = window.setTimeout(function(){
    game_running = false;
    gameEnds();
  },speed);
}

$('#successfulmatch').on('click',function(){
  if(game_running){
    
    // Cancel the timeout because the user was fast enough
    window.clearTimeout(myTimeout);
  
    // Give the user less time than before
    runNow(speed - speed_reduce);
  }
  else{
    // Throw an error: you forgot to hide the clickable buttons when the game ended.  
  }
}

$('#playnow').on('click',function(){
    runNow(speed);
}
                 
           

person Michael Saunders    schedule 09.01.2016

Похоже, вы смешиваете логику для проверки «щелкнул ли пользователь изображение? Это было правильно?» с одним для проверки "истекло ли время?"

Вы можете прослушивать события onclick на изображениях и устанавливать событие тайм-аута для окончания игры, поэтому пользователь должен отменить этот таймер, чтобы отменить неизбежное окончание игры, щелкнув изображения, если щелкнуть правильное изображение, таймер сбрасывается, если нет , игра окончена, вы можете отменить событие тайм-аута до его запуска с помощью cancelTimeout(), см. W3C здесь для справки.

here is a quick prototype:

$('#playnow').on('click', function() {
  var speed = 5000;
  var speed_reduce = 10;
  var game_running = true;

  /* create array of images */
  var imgs = ['puppy.png', 'kitten.png', 'bunny.png', 'goldfish.png'];

  // function that ends the game if it's called
  function gameover() {
    alert("GAME OVER");
    game_running = false;
  }

  // in order to use clearTimeout() you must store the timer in a global variable
  // setting a timeout that will end the game if it's not cleared before
  window.timer = setTimeout(gameover, speed);

  // function that is called whenever the user clicks on a image
  function onclickimage(event) {

    if (!game_running) return;

    if ( /*clicked right img*/ ) {

      // get random image from loaded theme
      var rand_img = imgs[Math.floor(Math.random() * imgs.length)];

      // display chosen image
      $('#goal_image').html('<img src="' + theme_dir + rand_img + '" />');

      // delete timer, user now has one more opportunity
      clearTimeout(timer);

      // speed is less 10ms
      speed -= speed_reduce;

      // launch timer again
      window.gametimer = setTimeout(loop, speed);
    } else { // if click did not match correct image
      gameover();
    }
  }

});

person fken    schedule 09.01.2016

Ну, во-первых, вам нужно clearInterval(), когда они либо щелкают, либо терпят неудачу, чтобы остановить текущий интервал. Затем вы можете перезапустить интервал с новой скоростью. Интервал вроде рабочий.

Каждые 5 секунд отображается новая картинка. Итак, вам нужно событие onclick для изображения, которое очищает интервал и запускает новый. Таким образом, вы можете использовать setTimeout вместо setInterval, так как это только одна итерация за раз.

Я полагаю, вы могли бы использовать setInterval, но в этом нет никакой реальной пользы. Этот способ также позволяет относительно легко снижать скорость каждый раз.

person Araymer    schedule 09.01.2016