简体   繁体   中英

Loop event listener function

I'm trying to initiate an object dropping down on the click of a button but instead of dropping down smoothly it drops down a bit each time the button is clicked. To click the button just click where it says drop, I didn't include the stylesheet so it wont look like a button but it still works. The issue lies in the function this.update . I want the block to drop down fully on one click of the button.

 let canvas = document.getElementById("canvas"); let dist = document.getElementById("Dist"); let m = document.getElementById("Mass"); let meter = 1; let start = document.getElementById("start"); canvas.height = 800; canvas.width = 900; canvas.style.backgroundColor = "rgb(65, 163, 193)"; canvas.style.marginLeft = "500px"; canvas.style.marginTop = "75px"; let c = canvas.getContext('2d'); let x = 400; let y = 200; let h = 40; let w = 20; let xSpeed = 0; let ySpeed = meter; function Thing(x, y, xSpeed, ySpeed, h, w){ this.x = x; this.y = y; this.xSpeed = xSpeed; this.ySpeed = ySpeed; this.h = h; this.w = w; this.draw = function(){ c.beginPath(); c.rect(this.x, this.y, this.w, this.h); c.fillStyle = "black"; c.fill(); c.stroke(); c.closePath(); }; this.update = function(){ start.addEventListener("click", () => { if (this.y + this.h > canvas.height){ this.y -= this.ySpeed; }; this.y += this.ySpeed; this.x += this.xSpeed; this.draw(); }); this.draw() }; }; let obj; function init(){ obj = new Thing(x, y, xSpeed, ySpeed, h, w,); anim(); }; function anim(){ requestAnimationFrame(anim); c.clearRect(0, 0, canvas.width, canvas.height); obj.update(); }; init(); 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Physics Drop</title> <link rel="stylesheet" href="style.css"> </head> <body> <canvas id="canvas"></canvas> <div id="X/Y title"></div> <table> <tc> <tr> <input id="Mass" placeholder="Mass"> </tr> </tc> <tc> <tr> <input id="Dist" placeholder="Height of drop"> </tr> </tc> </table> <div id="start"> <div id="startT">Drop</div> </div> <script src="app.js"></script> </body> </html> 

You need to have a gameloop, which is function which is run on every frame. Typical structure of gameloop is as follows:

while(1) {
    update() // update the state of object
    draw()   // redraw the object based on updated state
}

I've done few things to fix the code

  • Add the event listener on init()

  • update the obj.y in the update method

  • create a game loop which calls obj.update() every 100ms.

  • Initial obj.ySpeed = 0 so it doesn't start falling. Now you can control the fall just by updating the obj.ySpeed , therefore just set obj.ySpeed on click event to make the object start falling, and set it to 0 when it reached end of the canvas.

Try the new code here JSfiddle

let canvas = document.getElementById("canvas");
let dist = document.getElementById("Dist");
let m = document.getElementById("Mass");
let meter = 10;
let start = document.getElementById("start");

canvas.height = 800;
canvas.width = 900;
canvas.style.backgroundColor = "rgb(65, 163, 193)";
canvas.style.marginLeft = "500px";
canvas.style.marginTop = "75px";

let c = canvas.getContext('2d');

let x = 400;
let y = 200;
let h = 40;
let w = 20;
let xSpeed = 0;
let ySpeed = meter;

function Thing(x, y, xSpeed, ySpeed, h, w){
    this.x = x;
    this.y = y;
    this.xSpeed = xSpeed;
    this.ySpeed = 0;
    this.h = h;
    this.w = w;    

    this.draw = function(){
        c.beginPath();
        c.rect(this.x, this.y, this.w, this.h);
        c.fillStyle = "black";
        c.fill();
        c.stroke();
        c.closePath();
    };

    this.update = function(){

        if (this.y + this.h > canvas.height){
          this.y = canvas.height - this.h;
          this.ySpeed = 0;
        };
        this.y += this.ySpeed;
        this.x += this.xSpeed;

        this.draw()
    };
};

let obj;

function init(){
    obj = new Thing(x, y, xSpeed, ySpeed, h, w,);
    anim();
    start.addEventListener('click', () => {
        obj.ySpeed = ySpeed;
    });
    setInterval(() => {
            obj.update();
    }, 100)
};

function anim(){
    requestAnimationFrame(anim);
    c.clearRect(0, 0, canvas.width, canvas.height);
    obj.update();
};

init();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM