Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 面向对象的弹跳球_Javascript_Oop - Fatal编程技术网

Javascript 面向对象的弹跳球

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,

自从我用函数式语言编程以来,已经有很长一段时间了。我的代码运行正常;然而,由于我的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);
}
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);