what is problem?
I think you can figure this out on your own. Hints:
- The error tells you that in line 18 of managerGame.py
current_scene
isNone
. You need to find out why. Print, print, print… - I can see the error somewhere in your screenshots, so you don’t need to search any other files.
Happy debugging. Ask again if you feel that you’re completely stuck.
I didn’t figure it out ? i don’t know the enter () where come from
Your map maps strings to scenes. You query the next scene with the key that the enter method of the previous scene returns. So all the enter methods must return strings, not scenes. But your weapon scene returns scenes in most cases.
so you tell me I can’t add find enter because I use function direct in managerGame.py
and this is way def enter null, i must go to map to make def enter work ? am I right?
No. This is the problem with object oriented programming: it generates a lot of confusing indirection…
Your bug surfaces somewhere in the engine code where you move to the next scene. So let’s see how that works:
- Your engine has-a
Map
which is basically a thin wrapper around a dictionary that maps string keys toScene
objects, like"death" -> Death()
. The engine callsMap.next_scene(key)
to get the next scene. - Every
Scene
has-aenter
method. When theEngine
has obtained the next scene from theMap
it calls that method on the scene to run it. - When a scene is finished, its
enter
method returns the key of the next scene to theEngine
. - The
Engine
uses that key to fetch the next scene from theMap
. Go back to 1.
Now let’s look at the error message:
current_scene.enter(): 'NoneType' object has no attribute 'enter'
This means that at this point (line 18 in managerGame.py) you are calling enter
on an object that doesn’t have that method.
Okay, which is the object? current_scene
. You expect current_scene
to be a Scene
object, but the message says it’s None
(NoneType
), and None
doesn’t have enter
.
Why is it None
? You need to go, find out where current_scene
gets its current value. That’s in the line above:
current_scene = self.scene_map.next_scene(next_scene_name)
We’ve seen that current_scene
ends up being None
and that the map is just a dictionary. Whenever you get None
from a dictionary it’s usually a sign that the requested key doesn’t exist. So we need to look at the key: next_scene_name
.
Where does next_scene_name
get its value? The line above:
next_scene_name = current_scene.enter()
We know that enter
should return strings, but it seems this one returns something, maybe a string, maybe something else that’s not a valid key for the map. Let’s look at the offending scene. From your screenshots it’s Weapon
.
And here we see what’s going on: In the if
block at the end of Weapon.enter()
you return Sword()
and Gun()
and so on, but it must be "sword"
and "gun"
, respectively. You need to return the exact keys that are used in the map, not the values. Otherwise the map says "sorry, I don’t have a key Sword()
", and returns None
.
Does this make sense?
What you would usually do is print out current_scene
and next_scene_name
to see what the values are and then compare to what you expect.
yes make sense, and this what I understand
I run map and add sense (romeDevel
) to map then map call (Engine) so go to it and run (__init__
)
and then back to map and run (a_amp.play) then go to (Engine) and run def (play) inside def play var (current_scene) = romeDevel.
.opening_scene()
=>back to map to run this def ,and
this opening_scene()
=>call def next_scene()
and next_scene() get key from dict , and dict return it if exist , and before to go to var ( next_scene_name
) if user solve the romeDevel will return him to weapon
and this scene go to var ( next_scene_name
)
and so on
Yeah that sounds about right.
Just nitpicking: when you say “run this def”, the correct word for “def” would be “function”. “def” is a shorthand for “define [a function]” in Python. I had to read your post twice to get what you were saying.