零基础入门Python游戏
上QQ阅读APP看书,第一时间看更新

2.11 Rect对象

前文多次提到了Rect对象,本节将详细介绍有关Rect对象的使用。

负责支持Rect对象的模块是pygame.Rect,这是一个相对独立于其他模块的小模块,但也是Pygame中的一个常用功能,Rect对象可以使许多工作变得更加简单。类似于pygame.Surface模块与Surface对象,pygame.Rect既是一个模块,也是一个类,Rect对象指该类的实例对象。

1. Rect对象定义

从意义上来说,Rect对象是指用类的形式表示的一个矩形区域,它具有一系列属性和方法可供使用。

Rect对象就是如图2-11所示的一个矩形区域,其左上角坐标为(left,top),宽度为width,高度为height。看得出来,这4个关键参数完全可以决定一个矩形区域。

图2-11 Rect示意图

2. 创建Rect对象

创建Rect对象的方法很简单,只需要利用以上4个关键参数即可。

该函数返回的是一个Rect对象,即利用Rect类的构造函数创建一个Rect类的实例。

除了主动调用构造函数创建Rect对象以外,还有一种更为常用的方法可以获取Rect对象。

该方法调用Surface对象的get_rect()方法,以获取Surface所在的矩形区域,从而可以进一步对该矩形区域进行控制和操作,其返回的Rect对象天然继承了Surface的宽、高、尺寸等信息。在前面的Hello World示例程序中,我们也看到了它的用法。

不过,这两种创建Rect对象的方法各有千秋,前者适用于创建一个新的独立Rect对象,后者适用于获取与Surface相关的Rect对象。

这里顺便介绍一下Rect对象的作用。大多数时候,Rect对象是作为其他模块中的函数的参数使用的,如pygame.Surface.blit()、pygame.draw.rect()、pygame.draw.ellipse()等函数中的参数。

注意:当Rect对象作为参数时,无论是使用Rect对象还是使用(left,top,width,height)四元组,都是可以接受的。

由于Rect实际上是一个类,因此Rect对象有许多属性和方法可供使用,它们可以使矩形区域的操作变得更加简单。

3. Rect对象的属性

Rect对象的全部属性及其意义如下。

·x:左上角x坐标。

·y:左上角y坐标。

·w:宽度。

·h:高度。

·width:宽度,等同于w。

·height:高度,等同于h。

·size:矩形尺寸,(width,height)二元组。

·top:左上角y坐标,等同于y。

·left:左上角x坐标,等同于x。

·bottom:右下角y坐标。

·right:右下角x坐标。

·centerx:中心点x坐标。

·centery:中心点y坐标。

·center:中心点坐标,(centerx,centery)二元组。

·topleft:左上角坐标,(x,y)或者(left,top)二元组。

·bottomleft:左下角坐标,(left,bottom)二元组。

·topright:右上角坐标,(right,top)二元组。

·bottomright:右下角坐标,(right,bottom)二元组。

·midtop:上边缘中心点坐标,(centerx,top)二元组。

·midleft:左边缘中心点坐标,(left,centery)二元组。

·midbottom:下边缘中心点坐标,(centerx,bottom)二元组。

·midright:右边缘中心点坐标,(right,centery)二元组。

以上属性都可以自由赋值,但它们必须是整数或者整数对。

注意:当修改了其中任意一个属性值时,其他与之相关的属性值也会随之改变。例如,如果修改了Rect对象的width,则size就会随之改变。除此之外,与之同时发生改变的还有w、right、centerx、center、topright、bottomright、midtop、midbottom、midright。该特性使得Rect对象为矩形区域的控制与操作提供了许多便利。

4. Rect对象的常用方法

Rect对象包含许多方法,其常用的方法如下。

根据指定的偏移量移动矩形。参数x是x方向上的偏移量,如果为正,则表示向右移动;如果为负,则表示向左移动。参数y是y方向上的偏移量,如果为正,则表示向下移动;如果为负,则表示向上移动。这些参数的单位都是像素,且必须为整数。该方法可以返回一个移动后的Rect对象,对原始Rect对象不做修改。

该方法的功能与move()方法类似,只不过其返回值为None,对矩形位置的修改将体现在原始Rect对象上。其中,函数名称中的后缀ip代表in place,即原地操作。

除了该方法以外,Rect对象还有一些其他方法都有其对应的ip版本和非ip版本,下面两种方法也是其中之一。

根据指定的偏移量缩放矩形。参数x是x方向上的偏移量,如果为正,则表示宽度增加;如果为负,则表示宽度减小。参数y是y方向上的偏移量,如果为正,则表示高度增加;如果为负,则表示高度减小。缩放时,中心点保持不变。该方法可以返回一个缩放后的Rect对象,对原始Rect对象不做修改。

该方法的功能与inflate()方法类似,只不过它进行的是“原地操作”,对矩形尺寸的修改将体现在原始Rect对象上,返回的是None。

检测调用者Rect对象的矩形区域是否完全包含参数Rect对象的矩形区域。如果完全包含,则返回True,否则返回False。这里的参数Rect既可以是Rect对象,也可以是(left,top,width,height)四元组。如同前面提及的其他函数一样,在Pygame中,凡是接收Rect矩形区域作为参数的函数,都可以利用这种方式传递参数。

检测点(x,y)是否在调用者Rect对象的矩形区域内。如果是,则返回True;如果否,则返回False。注意:Rect对象的右边缘和下边缘一般不属于矩形区域,因此如果该点刚好位于矩形的右边缘或者下边缘,则该方法返回的依然是False。另外,该方法也可以接收(x,y)二元组作为参数,即可以这样使用:collidepoint((x,y))。

检测调用者Rect对象的矩形区域与参数Rect对象的矩形区域是否重叠。如果是,则返回True;如果否,则返回False。

检测调用者Rect对象的矩形区域与参数列表中的Rect对象的矩形区域是否重叠。这里,参数p_list为多个Rect对象的列表。该函数返回第一个发生重叠的Rect对象在p_list列表中的index,如果没有Rect对象与调用者发生重叠,则该方法返回-1。

该方法与collidelist()方法的功能类似,也是判断调用者Rect对象的矩形区域与参数列表中的Rect对象的矩形区域是否重叠,只不过该方法返回的是由p_list列表中所有发生重叠的Rect对象的index所组成的列表,而不是第一个发生重叠的index。如果列表中没有Rect对象与调用者发生重叠,则该方法返回一个空列表。

除了以上方法以外,Rect对象还有许多其他方法,这里不再赘述,有兴趣的读者可以阅读Pygame官方文档。

5. 具体示例

下面给出一个具体示例,供读者参考和学习Rect对象的用法,完整代码如下。

简单介绍一下上面这段代码,这里涉及的矩形有以下4个。

rect0只是一个(left,top,width,height)四元组,它并不是Rect对象,所以它只能被用作函数参数传递,并不拥有Rect对象的众多属性和方法。

rect1是通过Rect构造函数创建的一个矩形,所以它是一个名正言顺的Rect对象,有着许多的属性和方法可以使用。

rect2是通过调用rect1的inflate()方法而获得的相对于rect1收缩后的矩形,它也是一个Rect对象。

rect3则是dogsurface所在的矩形,它同样也是一个Rect对象。

然后,我们分别在rect0、rect1、rect2处绘制了三个不同颜色的矩形区域,而rect3的作用则是用来移动小狗,使小狗在屏幕范围内左右移动。

此外,这里还使用了Rect对象的众多方法,代码中的3个print函数打印出来的值分别为1,0,1。

最后说明一下clock.tick(60)这句代码,它用来限定画面的帧率,使游戏的最大帧率不超过60fps。只有这样,我们才可以看到小狗在屏幕上缓慢移动,否则会因为刷新频率太快而导致小狗疯狂地在屏幕上左右移动。

该示例程序的执行效果如图2-12所示。

图2-12 Rect对象示例程序

窗口中除了有3个矩形框,我们还可以看到小狗在屏幕范围内左右移动,只不过小狗并不会调头,所以你经常会看到它倒着走,那么该如何处理小狗的调头呢?其实此时只要把小狗所在的image surface水平翻转一下就可以了。Surface的翻转、缩放、旋转等变换操作都是在pygame.transform模块中定义的,本书不做讲解,有兴趣的读者可以自行参考Pygame官方文档中关于pygame.transform模块的介绍。