3.开场白¶
代码的第一部分相对简单,一旦编写,通常可以在您随后制作的每一个游戏中重复使用。它们将执行所有乏味的常规任务,如加载模块、加载图像、打开网络连接、播放音乐等。它们还将包括一些简单但有效的错误处理,以及您希望在以下模块提供的功能之上提供的任何定制 sys
和 pygame
。
3.1.第一行和加载模块¶
首先,你需要开始你的游戏并加载你的模块。在主源文件的顶部设置一些内容总是一个好主意,例如文件名、它包含的内容、它所属的许可证以及您可能想要提供给这些Will的任何其他有用的信息都将查看它。然后,您可以加载模块,并进行一些错误检查,这样就不会打印出令人讨厌的回溯,这是非程序员无法理解的。代码相当简单,所以我不会费心去解释它::
#!/usr/bin/env python
#
# Tom's Pong
# A simple pong game with realistic physics and AI
# http://www.tomchance.uklinux.net/projects/pong.shtml
#
# Released under the GNU General Public License
VERSION = "0.4"
try:
import sys
import random
import math
import os
import getopt
import pygame
from socket import *
from pygame.locals import *
except ImportError, err:
print(f"couldn't load module. {err}")
sys.exit(2)
3.2.资源处理功能¶
在 Line By Line Chimp 例如,要编写的第一个代码是用于加载图像和声音的。因为它们完全独立于任何游戏逻辑或游戏对象,所以它们被编写为单独的函数,并且首先被编写,以便以后的代码可以使用它们。我通常将所有这种性质的代码放在它们自己的无类函数中;一般来说,这些函数将是资源处理函数。当然,您可以为这些资源创建类,这样您就可以将它们组合在一起,或许还可以拥有一个可以控制所有资源的对象。与任何好的编程环境一样,开发您自己的最佳实践和风格取决于您。
编写您自己的资源处理函数总是一个好主意,因为尽管PyGame有打开图像和声音的方法,其他模块也有打开其他资源的方法,但这些方法可能会占用多行代码,它们可能需要您进行一致的修改,而且它们通常不能提供令人满意的错误处理。编写资源处理函数为您提供了复杂的、可重用的代码,并使您能够更好地控制资源。以以下图像加载函数为例:
def load_png(name):
""" Load image and return image object"""
fullname = os.path.join("data", name)
try:
image = pygame.image.load(fullname)
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
except FileNotFoundError:
print(f"Cannot load image: {fullname}")
raise SystemExit
return image, image.get_rect()
这里我们制作了一个比提供的更复杂的图像加载函数 pygame.image.load()
load new image from a file (or file-like object) 。请注意,该函数的第一行是一个文档字符串,描述该函数执行的操作以及它返回的对象。该函数假定您的所有图像都位于一个名为data的目录中,因此它采用文件名并创建完整的路径名,例如 data/ball.png
,使用 os 模块,以确保跨平台兼容性。然后,它尝试加载图像,并转换任何Alpha区域,以便您可以实现透明度,如果出现问题,它会返回更易于阅读的错误。最后,它返回图像对象,并且它的 rect
。
您可以使用类似的函数来加载任何其他资源,例如加载声音。您还可以创建资源处理类,以便对更复杂的资源提供更大的灵活性。例如,您可以创建一个音乐类,并使用 __init__
加载声音的函数(可能是从 load_sound()
功能)、暂停音乐的功能和重新开始的功能。另一个方便的资源处理类是用于网络连接的。打开套接字、使用适当的安全性和错误检查传递数据、关闭套接字、手指地址和其他网络任务的函数,可以使编写具有网络功能的游戏相对轻松。
记住,这些函数/类的主要任务是确保当您开始编写游戏对象类和主循环时,几乎没有什么可做的了。类继承可以使这些基本类特别方便。但是不要过分;只由一个类使用的函数应该作为该类的一部分编写,而不是作为全局函数编写。
Edit on GitHub