自从我用函数式语言编程以来,已经有很长一段时间了。我有这个代码正常运行;但是由于我的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);
答案 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范围/闭包和程序工作流。