在学习《Python编程之道》教程时,我遇到了一些问题,尤其是在理解Zed Shaw(作者)的OOP示例游戏(第43课)时,我遇到了一些困难。我虽然能区分Fish和salmon,car和Honda等类与对象,但对于为什么我们要使用类和对象(而不是按需编写函数)仍然一知半解。我希望理清类与对象、场景切换以及游戏引擎和地图在游戏中所扮演的角色,以便更好地理解该游戏的运作原理。
2、解决方案
1)类与对象:
类是具有相同属性和方法的一组对象的模板,而对象则是类的实例,它包含了该类所定义的属性和方法。我们使用类和对象是为了代码重用,以便能够在不同的场景中使用相同的代码。例如,我们可以创建一个名为“Car”的类,该类定义了汽车的属性(如颜色、型号等)和方法(如行驶、停车等)。然后,我们可以创建多个“Car”对象,每个对象都具有不同的属性值,但它们都具有相同的行为。
2)场景切换:
游戏中的场景切换逻辑由Engine类和Map类共同实现。Engine类通过play()方法启动游戏,并在循环中不断更新当前场景。每次循环,Engine类都会调用当前场景的enter()方法,该方法返回下一个场景的名称。然后,Engine类会调用Map类的next_scene()方法,该方法根据名称返回下一个场景的实例。最后,Engine类会将当前场景更新为下一个场景。
3)Engine类和Map类:
Engine类是游戏的主要控制器,它负责控制游戏流程,包括场景切换、玩家交互和游戏结束等。Engine类通过self.scene_map属性引用Map类实例,以便能够获取场景信息和切换场景。
Map类是游戏的场景管理类,它负责存储和管理游戏中的所有场景。Map类通过一个字典来存储场景信息,字典的键是场景名称,值是场景实例。Map类的next_scene()方法根据场景名称从字典中获取并返回场景实例。
4)代码示例:
class Scene(object):
def enter(self):
print("This scene is not yet configured. Subclass it and implement enter().")
class Engine(object):
def __init__(self, scene_map):
print("Engine __init__ has scene_map", scene_map)
self.scene_map = scene_map
def play(self):
current_scene = self.scene_map.opening_scene()
print("Play's first scene", current_scene)
while True:
print("\n--------")
next_scene_name = current_scene.enter()
print("next scene", next_scene_name)
current_scene = self.scene_map.next_scene(next_scene_name)
print("map returns new scene", current_scene)
class Map(object):
scenes = {
'central_corridor': CentralCorridor(),
'laser_weapon_armory': LaserWeaponArmory(),
'the_bridge': TheBridge(),
'escape_pod': EscapePod(),
'death': Death()
}
def __init__(self, start_scene):
self.start_scene = start_scene
print("start_scene in __init__", self.start_scene)
def next_scene(self, scene_name):
print("start_scene in next_scene")
val = Map.scenes.get(scene_name)
print("next_scene returns", val)
return val
def opening_scene(self):
return self.next_scene(self.start_scene)
a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()
在该示例中,Map类定义了5个场景,分别是CentralCorridor、LaserWeaponArmory、TheBridge、EscapePod和Death。Engine类通过a_map属性引用Map类实例,并通过play()方法启动游戏。在play()方法中,Engine类不断循环,每次循环都会调用当前场景的enter()方法,并根据enter()方法返回的下一个场景名称更新当前场景。游戏会在Death场景中结束。