HomeAboutMailing ListList Chatter /0/0

Python coding question

2023-03-13 by: "Robert A. Kelly III
From: "Robert A. Kelly III" 

My son has been learning some python coding  and wanting to expand a very 
simple game to something a bit more complex. Currently it has simple game play 
where projectiles fly in from the right and you move a character around to 
dodge them. It tracks the time you have been playing and a high score for the 
longest time and when you get hit, you blow up and the game exists. He wants 
to extend this to have a home screen that lets you see high scores and 
possibly change settings for the game and either start game play or exit; then 
the regular game play; and also an end screen when the character blows up that 
shows your score compared to the high scores, asks for you your name if you 
set a new high score, and gives an option to play again, etc.

So, I am looking for advice on how to structure this code. We are thinking to 
set it up as different modes of game play with a flag that tells it which mode 
is currently active and determines the behavior of the main game loop. 
Additionally, we thought we should create functions that set up each mode. In 
order to create an object in the set up function that will be used outside of 
the function until the mode changes, they need to be declared as globals, 
right? Is this a good way to structure this sort of application? Or am I 
completely off? 

Additionally, if anyone could recommend resources on learning more about how 
to structure more complex programs like this, I would appreciate it. I find 
that there are many very basic tutorials available for free, but how to move 
beyond that to more complex applications seems to be a bit harder to find.

Thanks in advance.

=============================================================== From: Dan Mailman ------------------------------------------------------ These are two different potential resources for your son and you: https://subscription.packtpub.com/book/game+development/9781785281532/1/ch0= 1lvl1sec10/the-basic-gui-layout https://www.pygame.org/wiki/gui o g . e .

=============================================================== From: Dan Lyke ------------------------------------------------------ On Mon, Mar 13, 2023 at 11:40=E2=80=AFAM Robert A. Kelly III wrote: g to mode Congratulations, you've just reinvented object-oriented dynamic dispatch, only with a case or if statement! Sorry, I don't mean to sound as snarky as that came off, but this is *exactly* where object orientation makes a lot of sense: each mode is an object (because you're sending it messages from the run loop, and those messages of different types all go to one thing that understands the context), the main runloop dispatches as appropriately to. And, yeah, then somewhere in setup you'll create a class+object for each of these states (or your main menu control item will create a game item and push that on the main runloop state), until that object decides that it's done, and pops back to the main menu state, And maybe to manage the object the main runloop is pointing at, you'll have a "push" option (eg: main menu pushes the gameplay on, if you go into like a configuration menu from gameplay, that pushes the configuration interaction thing on to that stack) and a "replace" option (eg: the splash screen replaces itself with the main menu, maybe even the game interaction controller replaces itself with the cut scene controller which replaces itself again with the game interaction controller). how nd ove . Following this thread closely because... well... 4 decades of immersing myself in code and thinking about this, and I don't have a current modern "how to structure things" suggestion, and it seems like every project is recreating a whole lot of this in the context of whatever windowing/view/mouse/keyboard management framework is being used at any particular time.

=============================================================== From: Tia Lobo ------------------------------------------------------ The challenge you now face is not a Python Coding Question but a code design problem. One way you could fake it and Python likes faking it, is to make all the options into the game command-line parameters. That way you can launch the game from the command line in the different modes available. Two popular modules for dealing with command line arguments are getopt and argparse (google them). Knowing how to find a python module, install it, and use it, is about 60% of professional Python programming. Hint make sure pip is setup properly (that's another 5 -10% of being a professional developer). Another 25% is putting the code into GitHub. So you could send us a link to the project and we could comment on the code directly. Once you have the command-line arguments, you can make a "launcher" program that manages options and starts the game with os.system (or something like that). Or you can get "fancy" and put the entire game into a module that is imported into the launcher (https://www.w3schools.com/python/python_modules.asp). -Erica -=3D--=3D---=3D----=3D----=3D---=3D--=3D-=3D--=3D---=3D----=3D---=3D--=3D-= =3D- Erica Wolf (she/her) On Mon, Mar 13, 2023 at 2:40=E2=80=AFPM Robert A. Kelly III wrote: play o the nts then that ou g to mode . In e of how nd ove .

=============================================================== From: Peter Goss ------------------------------------------------------ One possible approach might be something like this: 1) create functions for each of the screens and have a return value that would indicate which screen should be next. 2) have a section in your main loop that would use that return value on the next run around the loop. (start pseudocode) START_SCREEN =3D 0 GAME_SCREEN =3D 1 GAME_OVER_SCREEN =3D 2 EXIT =3D 3 def start_screen(what_it_needs_to_do_its_job): # handle input #draw the screen if start_game_selected: return GAME_SCREEN elif exit_game_selected: return EXIT else: return START_SCREEN def game_screen(what_it_needs_to_do_its_job): #handle input #draw screen if dead: return GAME_OVER_SCREEN else: return GAME_SCREEN def end_game_screen(what_it_needs_to_do_its_job): #handle input #draw screen if return_to_start_screen: return START_SCREEN else: return GAME_OVER_SCREEN close_game =3D False screen =3D START_SCREEN while(not close_game): # Do stuff that you do every time at the beginning of the loop if screen =3D=3D START_SCREEN: screen =3D start_screen(what_it_needs_to_do_its_job) elif screen =3D=3D GAME_SCREEN: screen =3D game_screen(what_it_needs_to_do_its_job) elif screen =3D=3D GAME_OVER_SCREEN: screen =3D game_over_screen(what_it_needs_to_do_its_job) # Do stuff that you do every time at the end of the loop if screen =3D=3D EXIT: close_game =3D True (end pseudocode) Hopefully that is understandable. ~Peter o g . e .

=============================================================== From: Deidre Holtsclaw ------------------------------------------------------ I would probably design this with a base class and the modes simply subclasses of this base class. Then drive everything with a main loop that transitions from one to the next. The Python documentation itself is great, but what Tia said is so very true: You have a design problem, not a Python problem. I'm happy to peek at the code on github sometime and comment if you want. I have the advantage of having Bloomberg's Python Infrastructure team available. Our local member, Gus, graduated from GA Tech. Which surprised me because he transferred here from our London office. Small world. On Tue, Mar 14, 2023 at 5:50=E2=80=AFPM Peter Goss wro= te: y e r ; p h , d.

=============================================================== From: "Robert A. Kelly III" ------------------------------------------------------ This looks very much like the approach we had in mind. But here is the part= I=20 am uncertain how to address. Each mode has objects that need to be created= =20 when we enter that mode and reused as long as we are in that mode (eg- the= =20 object that represents the player when in game play mode). If those objects= =20 are created in the function that is called every time the game loop runs, t= hey=20 will be local to that function and not persist from one invocation to the=20 next. Creating them as globals avoids this, but I am not sure this is the=20 right approach.=20 I think it makes sense to have a set up function for each mode, so that eac= h=20 time the mode is changed, a setup function creates the objects that are nee= d=20 in that mode. But what is the correct way to create these objects in such a= =20 way that they persist as the game loop runs? he ry me to or t; up ing ch de. ide s, nd.

=============================================================== From: Dan Danese ------------------------------------------------------ Sounds like a singleton pattern could help here if things like the game state and player are objects. In the case of the player, your initialize function will first check to see if it exists, and if so just return that. If the player object does not exist, it will instantiate one and return that also setting the flag that it exists. If the main program isn't using class based internals like that the next best thing is to manage a data structure for the game with assignments to active objects. This could be done with a python dataclass. If you name it game, instantiate the player and assign it to the dataclass player entry, you could add an accessor of 'get_player' that can implement the singleton pattern. Of course that dataclass would wind up being having to be global, but you would only have the one global declaration to manage rather than a long list of them. As for the mode switching you can manage that with an 'active state' variable identifying which mode is currently active and then use a control statement to determine which screens to display based on mode. I would use a 'display' function that checks the active state variable and call a more specific display function for the active mode. -br Dan d=3D e=3D t e d s if . m I to