2017-11-29 08:44:14

Hello, friends!
Guys! My question is for any of the programming languages. I'm studying C++, C#, and Python, but I'll be programming more in C#.
The question is, how in the code to separate the menu from the game?
There is an idea to create a variable "status", in which to enter the status values. But how good is this idea?
Thanks in advance!

2017-11-29 10:15:15

Something like that I think is usually referred to as state handling, and is not uncommon. This touches abit on the principles of Object Oriented Programming (OOP), where you could keep your menus and game logic in separate classes and use your main loop to switch state and update each as needed. Keeping objects, your menus and game in this case, separate and encapsulated from each other can make it alot easier to drop in or remove menus or other parts of your game as needed, mitigating "spahgetti code".

Python example:

import pyglet
from pyglet.window import key


class Example(pyglet.window.Window):
    def __init__(self):
        super(Example, self).__init__(640, 480, resizable=False, fullscreen=False, caption="Example")
        self.clear()

        self.key_input = []

    #initialize menu's and main game class
        self.menus = {'title':title(),'game':game()}
    #the current state
        self.state = 'title'
    #regularly call the update function
        pyglet.clock.schedule_interval(self.update, .01)

    def update(self,dt):
    #update menus/game, whatever they return is set as the new state
        self.state = self.menus[self.state].update(self.key_input,self.state)

    #if the close option is triggered, exit game.
        if self.state == 'quit':
            self.close()

    #clear key buffer
        if len(self.key_input) > 0:
            self.key_input = []

    #draw screen
        self.draw()

    def draw(self):
        self.clear()
       
    def on_key_press(self,symbol,modifiers):
        self.key_input.append(key.symbol_string(symbol) + " press")

    def on_key_release(self,symbol,modifiers):
        self.key_input.append(key.symbol_string(symbol) + " release")



#titlescreen class
class title(object):
    def update(self,key,state):
    #if space is pressed, switch state to the game loop
        if 'SPACE press' in key:
            print 'Starting game loop'
            return 'game'
    #if escape is pressed, switch state to exit the game
        elif 'ESCAPE press' in key:
            return 'quit'
    #otherwise return the current state to stay on the title screen
        else:
            return state



#main game logic class
class game(object):
    def update(self,key,state):
    #if space is pressed return to the title screen
        if 'SPACE press' in key:
            print 'Returning to title screen'
            return 'title'
    #otherwise return the current state to keep updating the game loop
        else:
            return state



if __name__ == '__main__':
    window = Example()
    pyglet.app.run()
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2017-11-29 11:01:18

Pyglet is complicated for me, I need at least an algorithm

2017-11-30 03:51:26 (edited by magurp244 2017-11-30 03:55:33)

Sure, here's an example only using classes:

#Main class
class main(object):
    def __init__(self):
    #initialize menu's and main game class
        self.menus = {'title':title(),'game':game()}
    #the current state
        self.state = 'title'

    def update(self):
    #update menus/game, whatever they return is set as the new state
        self.state = self.menus[self.state].update(self.state)
        if self.state != 'quit':
            self.update()

#titlescreen menu class
class title(object):
    def update(self,state):
        box = raw_input('Titlescreen\n\nEnter Option:\n1. Start Game\n2. Quit\n>')
    #if 1 is pressed, switch state to the game loop
        if box == '1':
            print 'Starting game loop'
            return 'game'
    #if 2 is pressed, switch state to exit the game
        elif box == '2':
            return 'quit'
    #otherwise return the current state to stay on the title screen
        else:
            return state

#game logic class
class game(object):
    def update(self,state):
        box = raw_input('Game\n\nEnter Option:\n1. Titlescreen\n>')
    #if 1 is pressed return to the title screen
        if box == '1':
            print 'Returning to title screen'
            return 'title'
    #otherwise return the current state to keep updating the game loop
        else:
            return state

a = main()
a.update()

And here's an example using a single function:

def example():
    state = 'title'

#main loop
    while True:

    #title screen menu
        if state == 'title':
            box = raw_input('Titlescreen\n\nEnter Option:\n1. Start Game\n2. Quit\n>')
        #if 1 is pressed, switch state to the game loop
            if box == '1':
                print 'Starting game loop'
                state = 'game'
        #if 2 is pressed, switch state to exit the game
            elif box == '2':
                state = 'quit'

    #game logic
        elif state == 'game':
            box = raw_input('Game\n\nEnter Option:\n1. Titlescreen\n>')
        #if 1 is pressed return to the title screen
            if box == '1':
                print 'Returning to title screen'
                state = 'title'

    #quit
        elif state == 'quit':
            break

example()
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2017-11-30 22:35:21

@magurp244: I'm going to go with the OP may need something really down to basics here.

The way I'd do it is to have a menu class, and have the members, choices of that menu, within each menu you set up. Then you'd want something responsible for getting a user's input from that menu, you might call it a menu manager, or similar. You could probably shove them in the same class, but there's a good Object Oriented Programming Principal known as "Single Responsibility", which is often really good advice.

So, have two classes, here's some psudo code, in a C# ish fashion, but it should apply to any other language.

public class Menu
{
    List<string> Choices = new List<string>();

    public Menu(List<string> choices)
    {
        this.Choices = choices;
    }
}

public class MenuManager
{
    public void Render(Menu menu)
    {
        foreach (var menuItem of menu.Choices)
        {
            // render this menuItem on screen for the user somehow
        }
    }

    public void Close()
    {
        // remove any onscreen menu however you'd like
    }
}

How you then choose to handle that user picking an option is up to you. You may either have an event, or store a chosen value and periodically check for a choice in the game loop, or a callback function, etc. Usage may look like this with the first option, an event based approach.

// you'd probably only want one of these in your whole app, even if you have many menus
var menuManager = new MenuManager();
var menu = new Menu(new List<string> { "New game", "Load game", "Cheat menu", "Quit" });
menuManager.Render(menu);
// you'll have to add this event to the menu manager. You may choose not to, so I didn't provide this in the code
menuManager.OnMenuChoice += (menu, choice) =>
{
    // determine what you're doing somehow
};

There's lots of ways you can do it. I do recommend separating it from the game code though! You're absolutely on the right lines there. Good luck. I hope I've helped rather than hindered here