I do not understand how the script gets the next room, and generally how the "Engine" and "Map" classes work. Here's an excerpt:
我不明白脚本如何获得下一个房间,以及“引擎”和“地图”类的工作原理。这是一段摘录:
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
def next_scene(self, scene_name):
return Map.scenes.get(scene_name)
def opening_scene(self):
return self.next_scene(self.start_scene)
class Engine(object):
def __init__(self, scene_map):
self.scene_map = scene_map
def play(self):
current_scene = self.scene_map.opening_scene()
while True:
print "\n--------"
next_scene_name = current_scene.enter()
current_scene = self.scene_map.next_scene(next_scene_name)
I simply don't understand how these portions work. I know how classes and object instances and attributes and all that other OOP stuff works, but for some reason this portion of the code I don't get. Mainly the Map class. If someone could explain it it would be awesome.
我根本不明白这些部分是如何工作的。我知道类和对象实例和属性以及所有其他OOP的工作原理,但由于某种原因,这部分代码我没有得到。主要是Map类。如果有人能够解释它会很棒。
Also (this may require reading the exercise), why is it required to have these two classes anyway? Couldn't you just do it with class methods instead (i.e. methods without self as a param.)? Then you could just call, for example, CentralCorridor.enter(). In fact, that is how I solved it before reading the answer, and it worked out fine.
另外(这可能需要阅读练习),为什么还需要这两个课程呢?难道你不能用类方法代替它(即没有自我作为参数的方法)。然后你可以调用,例如,CentralCorridor.enter()。事实上,这就是我在阅读答案之前解决它的方法,并且结果很好。
Sorry, my main question is how the Engine and Map classes work. The other thing is secondary.
对不起,我的主要问题是引擎和地图类的工作原理。另一件事是次要的。
Thanks in advance!
提前致谢!
2 个解决方案
#1
7
The Map
object is a Class which maps your scenes. It has some scenes saved in an array.
Map对象是一个映射场景的Class。它有一些场景保存在一个数组中。
scenes = {
'central_corridor': CentralCorridor(),
'laser_weapon_armory': LaserWeaponArmory(),
'the_bridge': TheBridge(),
'escape_pod': EscapePod(),
'death': Death()
}
When an object of Map is made you also give it an opening scene as seen in the constructor
当制作一个Map对象时,你也会给它一个开头场景,如构造函数中所示
def __init__(self, start_scene):
self.start_scene = start_scene
This creates a variable in Map
called start_scene
containing your opening scene.
这会在Map中创建一个名为start_scene的变量,其中包含您的开场景。
Furthermore Map
has 2 methods
此外,Map有2种方法
# This one returns a scene based on its name or key in the scenes array
def next_scene(self, scene_name):
return Map.scenes.get(scene_name)
# And this one returns the opening scene which is set when you create the map.
def opening_scene(self):
return self.next_scene(self.start_scene)
The Engine
seems to be controlling the scenes when to play and what to play.
引擎似乎在控制场景何时播放以及播放什么。
# When creating an Engine object you give the map containing scenes to its constructor
def __init__(self, scene_map):
self.scene_map = scene_map
# The method which starts playing the scenes
def play(self):
# the opening scene from the map is selected as the current scene
current_scene = self.scene_map.opening_scene()
# You loop all the scenes probably, conditions of this loop are unknown because you haven't posted it entirely.
while True:
print "\n--------"
# It seems the next scene name is known in the current scene
next_scene_name = current_scene.enter()
# It replaces current scene with the next scene from the map
current_scene = self.scene_map.next_scene(next_scene_name)
why is it required to have these two classes anyway?
为什么要这两个课程呢?
It isn't, unless it's required according to your assignment
除非根据您的任务要求,否则不是
Like you said it's possible to do it without, BUT there are good reasons to do so.
就像你说过没有可能做到这一点,但有充分的理由这样做。
This way you make 2 separate classes with their own responsibilities. This way code is more readable when the application gets bigger and bigger. And it's easy to navigate through the application. You can easily change parts of your app etc etc. My advice is to keep practicing and reading about OOP, you will notice why you do the things you see.
通过这种方式,您可以使用自己的职责制作2个单独这种方式代码在应用程序变得越来越大时更具可读性。并且可以轻松浏览应用程序。您可以轻松更改应用程序的部分内容等。我的建议是继续练习和阅读有关OOP的内容,您会注意到为什么要执行您所看到的内容。
#2
6
The Map class has a dictionary of scene names that are keys, and instances of different classes as the values. To retrieve one of the instances, you call a method passing in a string that is the scene name. The Map class then returns an instance of the corresponding class.
Map类具有作为键的场景名称字典,以及作为值的不同类的实例。要检索其中一个实例,请调用传入字符串的方法,该字符串是场景名称。然后,Map类返回相应类的实例。
Couldn't you just do it with class methods instead (i.e. methods without self as a param.)? Then you could just call, for example, CentralCorridor.enter().
难道你不能用类方法代替它(即没有自我作为参数的方法)。然后你可以调用,例如,CentralCorridor.enter()。
Yes, you could. The downside is that now you have hard coded the names of your scene classes in your code. If you later decide to rewrite your program to remove some scenes or add other scenes, you have to change all the places in your code where you hard coded the names. If you employ the Map class, then changes only have to be made to the dictionary. Although, you would still have to eliminate method calls that try to retrieve class instances that you've removed. Or, you could have the next_scene() method deal with attempts to retrieve scenes you've removed from the dictionary.
是的,你可以。缺点是现在您已经在代码中硬编码了场景类的名称。如果您以后决定重写程序以删除某些场景或添加其他场景,则必须更改代码中硬编码名称的所有位置。如果使用Map类,则只需对字典进行更改。虽然,您仍然必须消除尝试检索已删除的类实例的方法调用。或者,您可以使用next_scene()方法处理尝试检索已从字典中删除的场景。
Another consideration with class methods is: will you need to store 'state'? Like, how many players are currently in the scene. And, will you need to create more than one scene of that type?
类方法的另一个考虑因素是:你需要存储'状态'吗?比如,目前有多少玩家在场。而且,您需要创建多个该类型的场景吗?
#1
7
The Map
object is a Class which maps your scenes. It has some scenes saved in an array.
Map对象是一个映射场景的Class。它有一些场景保存在一个数组中。
scenes = {
'central_corridor': CentralCorridor(),
'laser_weapon_armory': LaserWeaponArmory(),
'the_bridge': TheBridge(),
'escape_pod': EscapePod(),
'death': Death()
}
When an object of Map is made you also give it an opening scene as seen in the constructor
当制作一个Map对象时,你也会给它一个开头场景,如构造函数中所示
def __init__(self, start_scene):
self.start_scene = start_scene
This creates a variable in Map
called start_scene
containing your opening scene.
这会在Map中创建一个名为start_scene的变量,其中包含您的开场景。
Furthermore Map
has 2 methods
此外,Map有2种方法
# This one returns a scene based on its name or key in the scenes array
def next_scene(self, scene_name):
return Map.scenes.get(scene_name)
# And this one returns the opening scene which is set when you create the map.
def opening_scene(self):
return self.next_scene(self.start_scene)
The Engine
seems to be controlling the scenes when to play and what to play.
引擎似乎在控制场景何时播放以及播放什么。
# When creating an Engine object you give the map containing scenes to its constructor
def __init__(self, scene_map):
self.scene_map = scene_map
# The method which starts playing the scenes
def play(self):
# the opening scene from the map is selected as the current scene
current_scene = self.scene_map.opening_scene()
# You loop all the scenes probably, conditions of this loop are unknown because you haven't posted it entirely.
while True:
print "\n--------"
# It seems the next scene name is known in the current scene
next_scene_name = current_scene.enter()
# It replaces current scene with the next scene from the map
current_scene = self.scene_map.next_scene(next_scene_name)
why is it required to have these two classes anyway?
为什么要这两个课程呢?
It isn't, unless it's required according to your assignment
除非根据您的任务要求,否则不是
Like you said it's possible to do it without, BUT there are good reasons to do so.
就像你说过没有可能做到这一点,但有充分的理由这样做。
This way you make 2 separate classes with their own responsibilities. This way code is more readable when the application gets bigger and bigger. And it's easy to navigate through the application. You can easily change parts of your app etc etc. My advice is to keep practicing and reading about OOP, you will notice why you do the things you see.
通过这种方式,您可以使用自己的职责制作2个单独这种方式代码在应用程序变得越来越大时更具可读性。并且可以轻松浏览应用程序。您可以轻松更改应用程序的部分内容等。我的建议是继续练习和阅读有关OOP的内容,您会注意到为什么要执行您所看到的内容。
#2
6
The Map class has a dictionary of scene names that are keys, and instances of different classes as the values. To retrieve one of the instances, you call a method passing in a string that is the scene name. The Map class then returns an instance of the corresponding class.
Map类具有作为键的场景名称字典,以及作为值的不同类的实例。要检索其中一个实例,请调用传入字符串的方法,该字符串是场景名称。然后,Map类返回相应类的实例。
Couldn't you just do it with class methods instead (i.e. methods without self as a param.)? Then you could just call, for example, CentralCorridor.enter().
难道你不能用类方法代替它(即没有自我作为参数的方法)。然后你可以调用,例如,CentralCorridor.enter()。
Yes, you could. The downside is that now you have hard coded the names of your scene classes in your code. If you later decide to rewrite your program to remove some scenes or add other scenes, you have to change all the places in your code where you hard coded the names. If you employ the Map class, then changes only have to be made to the dictionary. Although, you would still have to eliminate method calls that try to retrieve class instances that you've removed. Or, you could have the next_scene() method deal with attempts to retrieve scenes you've removed from the dictionary.
是的,你可以。缺点是现在您已经在代码中硬编码了场景类的名称。如果您以后决定重写程序以删除某些场景或添加其他场景,则必须更改代码中硬编码名称的所有位置。如果使用Map类,则只需对字典进行更改。虽然,您仍然必须消除尝试检索已删除的类实例的方法调用。或者,您可以使用next_scene()方法处理尝试检索已从字典中删除的场景。
Another consideration with class methods is: will you need to store 'state'? Like, how many players are currently in the scene. And, will you need to create more than one scene of that type?
类方法的另一个考虑因素是:你需要存储'状态'吗?比如,目前有多少玩家在场。而且,您需要创建多个该类型的场景吗?