动画精灵和碰撞检测之动画精灵,,


  动画精灵和碰撞检测

  从上一章我们已经了解到,看似简单的动画实际上并不简单,如果有大量图像在四处移动,要想跟踪每个图像“底下”有些什么,以便在移动图像时能够重绘,这可能要费很大的功夫,在我们的第一个沙滩球例子中,由于背景是白色的,所以更容易一些,不过你也可以想象,倘若背景有上一些图形,这肯定会复杂得多。

  幸运的是,Pygame可以为我们提供额外的帮助,四处移动的单个图像或图像部分称为动画精灵(sprite),Pygame有一个特殊的模块来处理动画精灵,利用这个模块,我们可以更容易地移动图形对象。

  在上一章中,我们让一个沙滩球在屏幕上反弹,如果希望一堆沙滩球都反弹呢?当然可以编写代码来单独地管理各个球,不过我们不会去这样做,而是使用Pygame的sprite模块,这样更简单一些。

  术语箱

  与孩子一起学编程-python教程

  什么是动画精灵

  可以把动画精灵想成一个小图片---一种可以在屏幕上移动的图形对象,并且可以与其他图形对象交互。

  大多数动画精录都有以下两个基本属性。

  图像(image):为动画精灵显示的图片

  矩形区(rect):包含动画精灵的矩形区域

  动画精灵的图像可以是使用Pygame绘制函数绘制的图像(如上一章看到的图像),也可以是原来就有的图像文件。

  Sprite类

  Pygame的Sprite模块提供了一个动画精灵基类,名为Sprite。(还记得几章前讨论过的对象和类吗?)正常情况下,我们不会直接使用基类,而是基于Pygame.sprite.sprite来创建自己的子类,下面将完成这样的一个例子,并把我们的类命名为MyBallClass。创建这个类的代码如下:

  与孩子一起学编程-python教程

  要仔细分析这些代码的最后一行,location是一个【X,Y】位置,这是个包含两个元素的列表。因为=号的一边是包含两个元素的列表(X和Y),所以可以在另一边赋两个值,这里我们为动画精灵矩形的left和top属性赋值。

  既然已经定义了MyBallClass,接下来必须创建它的一些实例。(要记住一,类定义只是一个蓝图,现在必须动手盖房子。)我们仍然需要和上一章同样的代码来创建Pygame窗口,另外还要在屏幕上创建一些球 ,按行列摆放。这要利用一个嵌套循环来完成:

  与孩子一起学编程-python教程

  我们还需要把球块移到显示表面。(还记得那个好玩的词“块移”吗?我们在上一章讨论过的。)

  与孩子一起学编程-python教程

  把所有这些代码放在一起,在构成了我们的程序,见代码清单17-1

  与孩子一起学编程-python教程与孩子一起学编程-python教程

  如果运行这个程序,会看到9个沙滩球出现在Pygame窗口中,就像下图显示的这样:

  与孩子一起学编程-python教程

  稍后,我们就会让它们动起来。

  有没有注意到第10行和第11行有一个小小的变化?(就是设置Pygame窗口大小的那两行代码)我们将代码

  与孩子一起学编程-python教程

  替换为

  与孩子一起学编程-python教程

  这个代码不仅设置了窗口的大小(像前面一样),还定义了两个变量,width和height,后面将会用到这两个变量,这里有一点很棒,我们不仅定义了一个列表size(其中包含两个元素),还定义了两个整型变量width和height,而且所有这些都在一个语句中完成,另外,我们的列表两边没有加中括号,在Python中这是允许的。

  我这样做只是想告诉你:在Python中有时做同样的事情可以有多种不同的方法,这些方法不存在绝对的优劣(只要它们都能工作),不能说哪种方法一定比另一种方法强,你得遵循Python的语法(语言规则),这是必须保证的,尽管如此,自由表述的空间的还是有的,如果你让10个程序员编写同样的程序,可能得不到两个完全相同的代码。

  Move()方法

  因为我们把球创建为MyBallClass的实例,应该可以使用一个类方法来移动这些球,下面就来创建一个新的类方法,名为move():

  与孩子一起学编程-python教程

  动画精灵(实际上是其中的rect)有一个内置方法move()。这个方法需要一个speed参数来告诉它对象要移动多远(也就是移动多快)。因为我们处理的是二维(2D)图形,而speed是一个包含两个数的列表,一个对应X-speed,另一个对应y-speed。我们还要检查球是否碰到窗口的边界,使球能够在屏幕上“反弹”。

  下面修改MyBallClass定义,增加Speed属性和move()方法:

  与孩子一起学编程-python教程

  

  注意第2行(def_init_(self,image_file,location,speed):)中的修改,这里增加了第7行(self.speed=speed),另外第9行到第15行增加了新的move()方法。

  现在创建球的各个实例时,需要告诉它速度,还要指出图像文件以及位置。

  

  与孩子一起学编程-python教程

  

  前面的代码把所有球都创建为相同的速度(相同方向),不过如果球的移动有些随机性可能更有意思,下面使用random.choice()函数来设置速度,如下:

  

  与孩子一起学编程-python教程

  这会为X和Y选择-2或2.

  代码清单17-2给出了完整的程序。

  

  与孩子一起学编程-python教程与孩子一起学编程-python教程

  这个程序使用了一个列表来跟踪所有球,第32行(balls.append(ball))上,创建每个球时会把球增加到这个列表。

  最后5行代码会重绘屏幕,这里我们走了一条捷径,并不是单独地“擦除”(覆盖)各个球,我们直接用白色填充窗口,然后重绘所有球。

  可以试验一下这些代码,看看有更多(或更少)球时会怎么样,可以改变它们的速度,还可以改变它们移动和“反弹”的方式,等待。你会注意到,球会四处移动,而且在窗口四周会反弹,不过它们相互之间还不能反弹!

评论关闭