首页 » 与孩子一起学编程 » 与孩子一起学编程全文在线阅读

《与孩子一起学编程》16.4 单个像素

关灯直达底部

有时我们并不想画一个圆或矩形,而是希望画单个的点或像素。比如,我们要创建数学程序,想画一条正弦曲线。

如果你不知道什么是正弦曲线也不用担心。学习本章的内容,只要知道这是一种波浪形的曲线就可以了。

另外也不用担心后面几个示例程序中的数学公式,按代码清单原样键入这些程序就行。这些公式只是为了保证得到大小合适的波浪形状,能够放入我们的 Pygame 窗口中。

由于没有 pygame.draw.sinewave 这种方法,所以我们必须利用单个的点来画这样一条曲线。一种方法是画很小的圆或矩形(圆或矩形的大小只有一个或两个像素)。代码清单 16-8 显示了用矩形画出来的曲线是什么样的。

代码清单 16-8 用大量很小的矩形画曲线

运行这个程序时会看到如右图所示的结果。

每个点都是宽和高分别为 1 像素的矩形。注意我们使用的线宽为 1,而不是 0。如果使用线宽 0,什么都不会显示,因为这样一个矩形没有“中间部分”可以填充。

连接多个点

如果你看得确实很仔细,可能会注意到,这个正弦曲线并不是连续的,中间的点之间存在空格。这是因为,在正弦曲线比较陡的部分,我们必须上移(或下移)3 个像素而向右只移动 1 个像素。而且由于我们画的是单个的点,而不是线,所以没有什么来填充它们之间的间隔。

下面还是做同样的工作,不过现在要用一条短线把各个点连接起来。Pygame 有一个画线的方法,另外还有一种方法可以在一系列点之间画线(类似于“连接多个点”)。这个方法是 pygame.draw.lines,它需要 5 个参数:

 
  • 画线的表面(surface);

  • 颜色(color);

  • 是否要画一条线将最后一个点与第一个点相连接,使形状闭合(closed)。我们不希望正弦曲线闭合,所以对我们来说,这个参数是 False

  • 要连接的点的列表(list);

  • 线宽(width)。

所以,在我们的正弦曲线例子中,pygame.draw.lines 方法是这样的:

pygame.draw.lines(screen, [0,0,0],False, plotPoints, 1)

在 for 循环中,并没有画出各个点,我们只是创建了 draw.lines 将要连接的点列表。然后在 for 循环之外调用一次 draw.lines。整个程序如代码清单 16-9 所示。

代码清单 16-9 一条完美连接的正弦曲线

现在运行这个程序时,可以看到如右图所示的曲线。

这就好多了,点与点之间不再有间隔。如果把线宽增加到 2,看上去会更好,如右图所示。

再来连接多个点

还记得小时候玩过的连数字画图吗?这里给出一个 Pygame 版本。

代码清单 16-10 中的程序使用了 draw.lines 函数和一个点列表来创建图形。要想看到这个神秘的图片,必须键入代码清单 16-10 中的程序。这一次没有捷径可走!我们没有把这个程序包含在 /examples 文件夹中,如果你想看到这个神秘的图片,就必须自己键入。不过键入所有这些数字可能有点乏味,所以你可以在 /examples 文件夹或网站上的一个文本文件中找到这个 dots 列表。

代码清单 16-10 连连看神秘图片

逐点绘制

下面再来考虑逐点绘制。如果我们只想改变一个像素的颜色,画一个小圆或矩形就会有点傻。你可以不使用 draw 函数,而是利用 Surface.set_at 方法访问一个表面上的单个像素。你要指出希望设置哪个像素,以及要设置成什么颜色:

screen.set_at([x, y], [0, 0, 0])

如果在我们的正弦曲线例子中使用这行代码(放在代码清单 16-8 的第 8 行),看上去与使用 1 个像素宽的矩形画出的结果完全相同。

还可以用 Surface.get_at 方法检查一个像素设置为什么颜色。只需要传入你想要检查的那个像素的坐标,比如:pixel_color = screen.get_at([320, 240])。在这个例子中,screen 是表面的名字。