对如何让javascript原型与HTML5画布友好地行动感到困惑

Confused on how to get javascript prototypes to act kindly with HTML5 canvas

本文关键字:布友好 javascript 原型 HTML5      更新时间:2023-09-26

我正在尝试通过开发更多面向对象的JavaScript代码来提高我的JavaScript技能。虽然我对Java OOP语法和概念很流利,但在javascript方面我却迷失了方向。

虽然球初始化得很好,但我不知道如何让东西移动!如果有人能帮忙,将不胜感激。

至少目前,

球应该只是从画布的"墙壁"上反弹。

代码如下:

var canvas = document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var x=canvas.width/2;//x ball position
var y = canvas.height-30;//y ball posi
var dx=2;
var dy=-2;
var ballRadius = 10;
function Ball(){
}
//draws gameball
Ball.prototype.drawBall=function(){
    ctx.beginPath();
    ctx.arc(x,y,ballRadius,0,Math.PI*2);
    this.checkWalls();
    fillStyle="#0095DD";
    ctx.fill();
    ctx.closePath();
}
//dynamically draw balls position
Ball.prototype.draw=function(){
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    this.drawBall();
    x+=dx;
    y+=dy;
    this.checkWalls(x,y,dx,dy);
}
Ball.prototype.refresh=function(){
    setInterval(this.draw(),8);
}
Ball.prototype.checkWalls=function(x,y,dx,dy){
    //reverse direction if ball hits top or bottom
    if(this.y+this.dy> canvas.height-ballRadius || this.y + this.dy <ballRadius){
        this.dy=-dy;
    }
    //reverse direction if ball hits left or right
    if(this.x+this.dx>canvas.width-ballRadius || this.x+this.dx<ballRadius){
        this.dx=-dx;
    }   
}
//instantiate objects
var ball = new Ball();
ball.refresh(); 

这是更新的: JSFIDDLE

当你这样做时,setInterval(this.draw(), 8)你的this.draw()执行并返回未定义,但它必须返回必须调用的setInterval函数。

简单的方法:

Ball.prototype.refresh=function(){
    var self = this;
    setInterval(function () {
        self.draw();
    },8);
}

重要的是this指向自身对象,因此您必须使用设置局部变量self

快速方法:

Ball.prototype.refresh=function(){
    setInterval(this.draw.bind(this),8);
}

bind方法this.draw链接到this上下文并返回函数,如简单示例中所示。

更新的小提琴:https://jsfiddle.net/reko91/d6mce9yq/2/

最近一直在画布上工作,这就是我使用的。

// game loop function
    var loop = function () {
        //update();
        //draw();
    ball.refresh(); 
        window.requestAnimationFrame(loop, canvas);
    };
    window.requestAnimationFrame(loop, canvas);

还要在顶部添加它以使其运行 60fps :

window.requestAnimFrame = function() {
  return (
    window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function( /* function */ callback) {
      window.setTimeout(callback, 1000 / 60);
    }
  );
}();

这是你的工作墙小提琴:https://jsfiddle.net/reko91/d6mce9yq/7/

我改变了很多东西。

在实际球中添加了 x,y,dx,dy:

function Ball() {
  this.x = x;
  this.y = y;
  this.dx = dx;
  this.dy = dy;    
}

然后稍后使用这些值(全部在小提琴中)。您的"检查墙"功能现在如下所示:

Ball.prototype.checkWalls = function(x, y, dx, dy, thisBall) {
  //console.log(thisBall.dx)
  //reverse direction if ball hits top or bottom
  if (this.y > canvas.height - ballRadius || this.y < ballRadius) {
    //this.y-=dy;
    this.dy *= -1;
  }
  //reverse direction if ball hits left or right
  if (this.x > canvas.width - ballRadius || this.x < ballRadius) {
    //this.xdx;
    this.dx *= -1;
  }
}

希望有帮助。