Как нарисовать каждый объект через определенный промежуток времени (мини-игра JavaScript) - PullRequest
1 голос
/ 17 мая 2019

Я работаю над проектом для Uni и хочу сделать мини-игру на JavaScript с изображением Guitar Heroes (https://www.gameinformer.com/s3/files/styles/body_default/s3/legacy-images/imagefeed/Reunion%20Tour%3A%20The%20Best%20And%20Worst%20Of%20Guitar%20Hero/Gh3_2D00_337_2D00_610.jpg). Я только начал изучать JavaScript месяц назад, но был привлечен библиотекой canvas и решилчтобы сделать мой проект с ним.

Мне удалось создать массив объектов круга, каждый с разной скоростью и y-позицией, и заставить их появляться все вместе на экране.

var canvas = document.getElementById("canvas");
    var g = canvas.getContext("2d");

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    //object
    function Circle(x, y, speed, radius){           this.x=x;
        this.y=y;
        this.speed=speed;
        this.radius=radius;



        //methods for the object


        this.draw = function(){

                g.beginPath();
                g.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
                g.fill();
                g.closePath();

            }

        this.update = function(){

                this.x += this.speed;
                this.draw();
            } 
    }

    var circleArray = [];

    for ( var i=0; i<10; i++){


        var stringA = 100;
        var stringS = 200;
        var stringD = 300;
        var stringF = 400;
        var array = [stringA, stringD, stringF, stringS];



        radius=40;

        var x= innerWidth - radius;
        var y=array[Math.floor(Math.random() * 4)];

        var speed = Math.floor(Math.random() * (10 - 4) ) + 4;  //(max-min) + min
        speed = -speed;


        circleArray.push(new Circle(x, y, speed, radius));
    }




    function animate() {

        requestAnimationFrame(animate);  
        g.clearRect(0, 0, innerWidth, innerHeight);



        //this is where it all went downhill - without setInterval method, it works



        setInterval( function(){
        for ( var i=0; i< circleArray.length; i++ ){
            circleArray[i].update();
        }
        }, 1000);
        //


        //lines
        g.beginPath();
        g.moveTo(0, 100);
        g.lineTo(innerWidth, 100);
        g.strokeStyle = 'red';
        g.stroke();
        g.closePath();

        g.beginPath();
        g.moveTo(0, 200);
        g.lineTo(innerWidth, 200);
        g.strokeStyle = 'red';
        g.stroke();
        g.closePath();

        g.beginPath();
        g.moveTo(0, 300);
        g.lineTo(innerWidth, 300);
        g.strokeStyle = 'red';
        g.stroke();
        g.closePath();

        g.beginPath();
        g.moveTo(0, 400);
        g.lineTo(innerWidth, 400);
        g.strokeStyle = 'red';
        g.stroke();
        g.closePath();
        //


    }

    animate();

Что я хочу сделать дальше, так это сделать так, чтобы объекты круга появлялись на экране один за другим. Желательно после случайного интервала. Но я не могу разобраться с методом setInterval. Моя идея быласделать другой метод setInterval внутри, но это, похоже, не работает. Может кто-нибудь показать мне, как или указать мне учебник? Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Чтобы добиться этого, я объявляю новую переменную: frames, и кадры увеличивают ее значение с каждым animate() кадром.

Я создаю круги внутри animate() и толькоесли

if(frames % 27 == 0 && //you can choose a different number
   Math.random() < .5 && // for randomness
   circleArray.length <= 10){//limiting the total number of circles at 10
   circleArray.push(new Circle());}

Надеюсь, это то, чего вы хотели достичь.

var canvas = document.getElementById("canvas");
var g = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var frames = 0;

//object
function Circle() {
  this.array = [100, 300, 400, 200];
  this.radius = 40;
  this.x = innerWidth + this.radius;
  this.y = this.array[Math.floor(Math.random() * 4)];
  this.speed = -Math.floor(Math.random() * (20 - 4)) + 4;
  

  //methods for the object

  this.draw = function() {
    g.beginPath();
    g.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    g.closePath();
    g.fill();
    
  };

  this.update = function() {
    this.x += this.speed;
    // if the circle goes out of the canvas put it back 
    if(this.x < -this.radius){this.x = innerWidth + this.radius;}
    this.draw();
  };
}

var circleArray = [];


function animate() {
  requestAnimationFrame(animate);
  
  g.clearRect(0, 0, innerWidth, innerHeight);
  
  
  if(frames % 27 == 0 && 
     Math.random() < .5 && 
     circleArray.length <= 10){circleArray.push(new Circle());}
    for (var i = 0; i < circleArray.length; i++) {
      circleArray[i].update();
    }
  
  
  
  drawLines();
  frames++

 
  
}

animate();




function drawLines(){
   //lines
  g.beginPath();
  g.moveTo(0, 100);
  g.lineTo(innerWidth, 100);
  g.strokeStyle = "red";
  g.stroke();
  g.closePath();

  g.beginPath();
  g.moveTo(0, 200);
  g.lineTo(innerWidth, 200);
  g.strokeStyle = "red";
  g.stroke();
  g.closePath();

  g.beginPath();
  g.moveTo(0, 300);
  g.lineTo(innerWidth, 300);
  g.strokeStyle = "red";
  g.stroke();
  g.closePath();

  g.beginPath();
  g.moveTo(0, 400);
  g.lineTo(innerWidth, 400);
  g.strokeStyle = "red";
  g.stroke();
  g.closePath();
}
<canvas id="canvas"></canvas>
0 голосов
/ 17 мая 2019

setInterval может быть не тем, что вы хотите использовать, если вы хотите случайное количество времени между розыгрышами. Попробуйте сделать что-то вроде этого:

let randomDelay
for(int i = 0; i < circleArray.length; i++){
    randomDelay = Math.random() * 100 //maximum number of milliseconds to wait
    setTimeout(() => {
         circleArray[i].update()
    }, randomDelay)
}

Причина, по которой ваш код не выполняет то, что вы ожидаете, заключается в том, что ваш цикл for находится внутри интервала, то есть все они обновляются "одновременно" каждую 1 секунду

...