Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.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
OOP Javascript乒乓球游戏中的上下文在哪里?_Javascript_Oop_Pong - Fatal编程技术网

OOP Javascript乒乓球游戏中的上下文在哪里?

OOP Javascript乒乓球游戏中的上下文在哪里?,javascript,oop,pong,Javascript,Oop,Pong,为了练习我的OOP知识,我正在用javascript制作一个乒乓球游戏(我知道,我知道,这就像在吉他店里玩《天堂的阶梯》)。我已经通过实现几种不同的技术,包括基于原型的OOP和功能风格,实现了该游戏的几个功能版本。然而,我这样做不是为了得到一个功能性游戏,我这样做是为了学习 我使用的是html5画布和普通的ol'javascript,没有框架(好的,有一点键盘捕获的jQuery)。我有我的乒乓球对象,代表我的游戏。Pong有一个属性ctx,其中包含对canvas.getContext(“2d”)

为了练习我的OOP知识,我正在用javascript制作一个乒乓球游戏(我知道,我知道,这就像在吉他店里玩《天堂的阶梯》)。我已经通过实现几种不同的技术,包括基于原型的OOP和功能风格,实现了该游戏的几个功能版本。然而,我这样做不是为了得到一个功能性游戏,我这样做是为了学习

我使用的是html5画布和普通的ol'javascript,没有框架(好的,有一点键盘捕获的jQuery)。我有我的乒乓球对象,代表我的游戏。Pong有一个属性
ctx
,其中包含对
canvas.getContext(“2d”)
上下文的引用。它还有一个
player1
player2
ball
属性,用于固定你知道的东西。当球和两名球员被实例化时,上下文被传递给他们的构造函数,这样他们也可以持有对上下文的引用,以便在他们的
draw(ctx)
方法中使用。Pong有一个
draw()
方法,可以使用
setInterval(this.draw,10)
调用该方法。Pong的抽签方法称为两名球员和球的抽签方法

这两个球员和球的属性是上下文,这让我感到不舒服。它们不拥有上下文,因此它不应该是属性。然而,使用javascript和画布的本质似乎是这是最好的方法。在这种情况下,谁或什么应该拥有上下文?理想情况下,我不希望球员和球对象有一个抽签对象。我觉得它们应该具有描述其几何体和位置的属性,并且应该指定一个专用对象将它们渲染到屏幕上。这样,如果将来我决定使用的是,而不是画布,我可以只更改渲染对象,其他一切都将被忽略

我知道我正在使一个javascript乒乓球游戏变得比它需要的更复杂,但我想练习这些技术并真正探索OOP的概念,但每次我认为我已经破解了它,我的“解决方案”就出现了一个全新的问题

编辑:如果你对我的代码有兴趣的话,这是一个(几乎)完全工作的版本:

library.js-

pong.js-


试试看

你把事情弄得太复杂了

一个专用的对象应该负责将它们渲染到屏幕上

当你有一个任务需要做的时候,说“一个对象被赋予了任务”是很奇怪的。函数做事情。对象封装数据。函数应负责将它们呈现到屏幕上

在这种情况下,谁或什么应该拥有上下文

没有任何东西“拥有”上下文。或者,如果你愿意,画布拥有上下文,但我不知道你为什么要把上下文放在某个地方;我认为这比仅仅传递信息更令人困惑


编辑:浏览一下您的代码,您已经使Pong闭包“拥有”(有一个对上下文的引用),这似乎足够合理。我真的看不出这种方法会带来什么问题。但是,我不同意您应该将其传递给
Ball
等的构造函数。我认为将其传递给各种
draw()
方法要简单得多。

不是专门针对pong的,而是这本在线书

有一个构建小游戏的示例。虽然略有不同,但它很好地展示了如何使用面向对象原则


您可以用多种方式编写代码,使用设计模式很容易走得更远。与任何事情一样,要适度。在使用新语言时,我总是使用Nibbles/Snake作为我的goto游戏。

这可能是应用MVC()原则的一个很好的例子

您可以使用一个模型来跟踪每个游戏元素的状态。这些将是球员,桨,球等东西,然后,你可以有渲染器(视图),其中只包含用于绘制当前状态的逻辑。这些视图可以命名为BallCanvasRenderer和PapperCanvasRenderer

由于视图将被很好地封装,因此让它保留对画布上下文的引用可能是有意义的,但您也可以在每次渲染时传入适当的上下文和模型

控制器将负责响应游戏事件并更新模型


请注意,此模式还提供了为任何类型的模型维护多个渲染器的选项。您还可以使用输出文本、ASCII艺术或OpenGL的渲染器。

我认为您使用上下文没有问题。为了实现允许渲染独立于技术的设计目标,您应该为所需的渲染方法编写一个通用接口,并创建一个使用
context
实现此接口的对象。然后你可以用这个对象的另一个版本来代替,例如,让它在InternetExplorerHeh+1中工作,来代替第一句话中的类比“我们不是韦恩的世界”。没关系。我们中的一些人甚至喜欢pong。是的,将上下文传递到各种
draw()
方法中会更干净。我想我的主要问题是,通过使用画布上下文构建整个游戏,我无法决定使用div来实现游戏。如果我从对象本身抽象出实际的渲染,它将产生更多可重用的代码。但我并不是真的想变得实用,只是想学习。我目前正在研究的版本将上下文传递给了抽签方法,但是球有一个
flash
方法,当球碰到任何东西时会产生反弹效果。这个flash方法需要上下文,这就是我的困境开始的地方!关于你的困境,之所以让人困惑是因为把上下文放到
var Pong = (function() {
   var Graphics, graphics, Ball, ball1, ball2, play;
   Graphics = function() {
      this.context = ...
   };
   graphics = new Graphics();
   Ball = function() {
     // do something with graphics
   };
   ball1 = new Ball();
   ball2 = new Ball();
   // ball1 and ball2 will both be able to access graphics

   play =function() {
       // play the game!
   };
   return {
       play: play
   }
}());