Javascript 面向对象的弹跳球
自从我用函数式语言编程以来,已经有很长一段时间了。我的代码运行正常;然而,由于我的OOD偏好,我不喜欢它Javascript 面向对象的弹跳球,javascript,oop,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,
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);
}
var canvasWidth=900;
var canvasHeight=200;
var-canvas0;
var-context0;
var x0=20;
var y0=20;
var dx0=4;
var-dy0=4;
函数绘图(){
clearRect(0,0,context0.canvas.width,context0.canvas.height);
context0.beginPath();
context0.fillStyle=“红色”;
context0.arc(x0,y0,20,0,2*Math.PI,true);
context0.closePath();
context0.fill();
//边界逻辑
如果(x0<13 | | x0>context0.canvas.width-13){
dx0=(-dx0);
}
if(y0<13 | | y0>context0.canvas.height-13){
dy0=(-dy0);
}
x0+=dx0;
y0+=dy0;
}
函数init(){
"严格使用",;
canvas0=document.getElementById(“gfxCanvas”);
context0=canvas0.getContext('2d');
context0.canvas.width=画布宽度;
context0.canvas.height=画布高度;
设置间隔(抽签,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);
}
功能球(x、y、r、颜色){
这个半径=r;
这个.x=x;
这个。y=y;
这个颜色=颜色;
log(“创建中的x”+this.x);
console.log(“创建中的y”+this.y);
draw();
}
Ball.prototype.draw=函数(){
context1.beginPath();
log(“绘图中的x()”+this.x);
log(“DRAW()中的y”+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=函数(dx,dy){
//边界逻辑
if(this.x<13 | | this.x>context1.canvas.width-13){
dx=(-dx);
}
if(this.y<13 | | this.y>context1.canvas.height-13){
dy=(-dy);
}
这个.x+=dx;
y+=dy;
};
函数初始化(){
canvas1=document.getElementById(“gfxCanvas2”);
context1=canvas1.getContext('2d');
context1.canvas.width=900;
context1.canvas.height=200;
ball1=新球(20,20,20,“红色”);
设定间隔(球1.移动(4,4),10);
}
我更希望这个方法是移动方法。实际方法将采用方向/速度矢量
setInterval(ball1.move(4,4),10)代码>您可以使用:
这相当于将调用包装到匿名函数中的move
:
setInterval(function() { ball1.move(4, 4); }, 10);
然后还需要更新move
,以便它也适当地调用draw
此外,我不会使用全局变量访问绘图上下文-即使我不打算完全面向对象,我也会确保draw
方法和move
方法采用上下文(为了简单起见,可以由球“拥有”)
这并不是您想要的方式:它调用ball1.move(4,4)
一次,然后每隔10毫秒调用一次结果。您希望每隔10毫秒调用move
方法,对吗?有两种方法可以做到这一点:
setInterval(function() {
ball1.move(4,4);
}, 10);
或者像这样(在我看来更优雅):
谢谢大家的帮助。你很好地澄清了一切,为我指明了正确的方向。我怀疑它是按照你所说的方式工作的,但我不能完全确定。我知道我的实现有几个地方出了问题,但不能用我目前的知识简明扼要地说出来
然而,我发现了我的问题,你们的解决方案正在以更直接的方式解决。我不能用OOD范式来处理javascript。我将使用更具功能性的设计模式重构代码。不尝试强制代码进入OO设计将使事情变得相当容易。您的解决方案很有帮助,但边界检查代码是我遇到的下一个问题
我将把它应用到ball对象的模块设计模式中,它应该更适合js作用域/闭包和过程工作流。我怀疑这
不是你在move
实际执行时所认为的那样。这就是我所怀疑的,因此我添加了一些console.log,我仍在获取用于功能范围和闭包。我想知道,除了setinterval的问题之外,是否还使用了对象创建的名称空间类型,您只调用过一次draw
,即使在该调用中,它也应该是this.draw
,因为当前它会爆炸,说draw
未定义。您需要在move函数或setInterval中调用draw,这是一个好主意,也是我最初实现的。然而,为了把注意力完全集中在球的物体上,我删除了程序的这一方面。我不确定上下文是否类似于画布上的层。我希望每个ball对象都在其自身的上下文中,因此当清除帧时,它只清除该balls上下文,而不清除其他的。我将尝试一下,但这正是我看到的情况,但我不确定如何解决它。我将合并这个,并尝试一下。
setInterval(ball1.move(4,4), 10);
setInterval(function() {
ball1.move(4,4);
}, 10);
setInterval(ball1.move.bind(ball1,4,4), 10);