面向对象的弹跳球

时间:2014-04-24 19:10:25

标签: javascript oop

自从我用函数式语言编程以来,已经有很长一段时间了。我有这个代码正常运行;但是由于我的OOD偏好,我不喜欢它。

var canvasWidth = 900;
var canvasHeight = 200;

var canvas0;
var context0;
var x0 = 20;
var y0 = 20;
var dx0 = 4;
var dy0 = 4;

function draw() {
    context0.clearRect(0, 0, context0.canvas.width, context0.canvas.height);
    context0.beginPath();
    context0.fillStyle = "red";
    context0.arc(x0, y0, 20, 0, 2 * Math.PI, true);
    context0.closePath();
    context0.fill();

    // Boundary Logic
    if (x0 < 13 || x0 > context0.canvas.width - 13) {
        dx0 = (-dx0);
    }
    if (y0 < 13 || y0 > context0.canvas.height - 13) {
        dy0 = (-dy0);
    }
    x0 += dx0;
    y0 += dy0;
}

function init() {
    'use strict';
    canvas0 = document.getElementById("gfxCanvas");
    context0 =  canvas0.getContext('2d');
    context0.canvas.width  = canvasWidth;
    context0.canvas.height = canvasHeight;
    setInterval(draw, 10);
}

我试图将其重构为更面向对象的设计,但我遇到了图形处理问题。我可以让球出现一次,但我不能让它移动。这是我的重构代码;请注意,它处于重构的中间点,因此随机修改会产生一些明显的错误。

function Ball(x, y, r, color) {
    this.radius = r;
    this.x = x;
    this.y = y;  
    this.color = color;
    console.log("x in creation" + this.x);
    console.log("y in creation" + this.y);
    draw();

}
Ball.prototype.draw = function(){
    context1.beginPath();
    console.log("x in DRAW()" + this.x);
    console.log("y in DRAW()" + this.y);
    context1.fillStyle = this.color;
    context1.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, true);
    context1.closePath();
    context1.fill();
};

Ball.prototype.move = function(dx, dy){
    // Boundary Logic
    if (this.x < 13 || this.x > context1.canvas.width - 13) {
        dx = (-dx);
    }
    if (this.y < 13 || this.y > context1.canvas.height - 13) {
        dy = (-dy);
    }

    this.x += dx;
    this.y += dy;

};

function initialize() {
    canvas1 = document.getElementById("gfxCanvas2");
    context1 =  canvas1.getContext('2d');
    context1.canvas.width  = 900;
    context1.canvas.height = 200;
    ball1 = new Ball(20,20,20, "red");
    setInterval(ball1.move(4,4), 10);
}

我希望这种方法是移动方法。实际方法将采用方向/速度向量。

setInterval(ball1.move(4,4), 10);

3 个答案:

答案 0 :(得分:1)

setInterval(ball1.move(4,4), 10);

这并不像你想象的那样工作:它调用ball1.move(4,4)一次,然后每隔10ms调用一次结果。您希望每隔10毫秒调用move方法,对吧?有两种方法可以做到这一点:

setInterval(function() {
  ball1.move(4,4);
}, 10);

或者像这样(在我看来更优雅):

setInterval(ball1.move.bind(ball1,4,4), 10);

答案 1 :(得分:0)

您可以使用bind

setInterval(ball1.move.bind(ball1, 4, 4), 10);

这相当于在匿名函数中包含对move的调用:

setInterval(function() { ball1.move(4, 4); }, 10);

然后,您还需要更新move,以便它也适当地调用draw

另外,我不会使用全局变量来访问绘图上下文 - 即使我没有完全去OOP,我会确保draw方法和{{1} }方法采用一个上下文(为了简单起见,可以是#34;拥有&#34;由球)。

答案 2 :(得分:0)

感谢所有人的帮助。你澄清了一切,并指出了正确的方向。我怀疑它是以你所表达的方式工作,但我并不完全确定。我知道有几件事我的实施有问题,但不能用我现有的知识这么简洁地说。

但是,我发现了我的问题,您的解决方案正在以更直接的方式进行补救。我不能用OOD范例来对待javascript。我将使用更多功能的设计模式重构代码。不试图将代码强制转换为OO设计将使事情变得相当容易。您的解决方案有所帮助,但边界检查代码是我遇到的下一个问题。

我正在将其用于球对象的模块设计模式,这应该更适合于js范围/闭包和程序工作流。