Santiago
Santiago

Reputation: 77

how to return to the main menu from the game

Hy everyone! i'm stuck in a problem since lot of days ago, and i think here you can help me!

my problem: i'm making a game on python usign the pygame library, and now i'm working on the menu, i tried with a script made by me, but it didnt work, so y download a premade script, but is not working neither, the problem here, is how to go back to the menu from the instructions screen or the game, this is the code from de menu:

# -*- coding: utf-8 -*-
#
# autor: Hugo Ruscitti
# web: www.losersjuegos.com.ar
# licencia: GPL 2

import random
import pygame
from pygame.locals import *


class Opcion:

    def __init__(self, fuente, titulo, x, y, paridad, funcion_asignada):
        self.imagen_normal = fuente.render(titulo, 1, (0, 0, 0))
        self.imagen_destacada = fuente.render(titulo, 1, (200, 0, 0))
        self.image = self.imagen_normal
        self.rect = self.image.get_rect()
        self.rect.x = 500 * paridad
        self.rect.y = y
        self.funcion_asignada = funcion_asignada
        self.x = float(self.rect.x)

    def actualizar(self):
        destino_x = 780
        self.x += (destino_x - self.x) / 5.0
        self.rect.x = int(self.x)

    def imprimir(self, screen):
        screen.blit(self.image, self.rect)

    def destacar(self, estado):
        if estado:
            self.image = self.imagen_destacada
        else:
            self.image = self.imagen_normal

    def activar(self):
        self.funcion_asignada()


class Cursor:

    def __init__(self, x, y, dy):
        self.image = pygame.image.load('cursor.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.y_inicial = y
        self.dy = dy
        self.y = 0
        self.seleccionar(0)

    def actualizar(self):
        self.y += (self.to_y - self.y) / 10.0
        self.rect.y = int(self.y)

    def seleccionar(self, indice):
        self.to_y = self.y_inicial + indice * self.dy

    def imprimir(self, screen):
        screen.blit(self.image, self.rect)


class Menu:
    "Representa un menú con opciones para un juego"

    def __init__(self, opciones):
        self.opciones = []
        fuente = pygame.font.Font('dejavu.ttf', 40)
        x = 780
        y = 250
        paridad = 1

        self.cursor = Cursor(x - 95, y, 95)

        for titulo, funcion in opciones:
            self.opciones.append(Opcion(fuente, titulo, x, y, paridad, funcion))
            y += 30
            if paridad == 1:
                paridad = -1
            else:
                paridad = 1

        self.seleccionado = 0
        self.total = len(self.opciones)
        self.mantiene_pulsado = False

    def actualizar(self):
        """Altera el valor de 'self.seleccionado' con los direccionales."""

        k = pygame.key.get_pressed()

        if not self.mantiene_pulsado:
            if k[K_UP]:
                self.seleccionado -= 1
            elif k[K_DOWN]:
                self.seleccionado += 1
            elif k[K_RETURN]:
                # Invoca a la función asociada a la opción.
                self.opciones[self.seleccionado].activar()

        # procura que el cursor esté entre las opciones permitidas
        if self.seleccionado < 0:
            self.seleccionado = 0
        elif self.seleccionado > self.total - 1:
            self.seleccionado = self.total - 1

        self.cursor.seleccionar(self.seleccionado)

        # indica si el usuario mantiene pulsada alguna tecla.
        self.mantiene_pulsado = k[K_UP] or k[K_DOWN] or k[K_RETURN]

        self.cursor.actualizar()

        for o in self.opciones:
            o.actualizar()

    def imprimir(self, screen):
        """Imprime sobre 'screen' el texto de cada opción del menú."""

        self.cursor.imprimir(screen)

        for opcion in self.opciones:
            opcion.imprimir(screen)

def comenzar_nuevo_juego():
    print " Función que muestra un nuevo juego."

def mostrar_opciones():
    print " Función que muestra otro menú de opciones."

def creditos():
    print " Función que muestra los creditos del programa."

def salir_del_programa():
    import sys
    print " Gracias por utilizar este programa."
    sys.exit(0)


if __name__ == '__main__':

    salir = False
    opciones = [
        ("", comenzar_nuevo_juego),
        ("", mostrar_opciones),
        ("", creditos),
        ("", salir_del_programa)
        ]

    pygame.font.init()
    screen = pygame.display.set_mode((1200, 900))
    fondo = pygame.image.load("fondo.jpg").convert()
    menu = Menu(opciones)

    while not salir:

        for e in pygame.event.get():
            if e.type == QUIT:
                salir = True

        screen.blit(fondo, (0, 0))
        menu.actualizar()
        menu.imprimir(screen)

        pygame.display.flip()
        pygame.time.delay(10)

ill be waiting for your answers!

one more detail: in my code i put the menu like: def menu(): and yo go back to the menu i just called the function menu(), but in this case, i cant because menu isnt a function.

Upvotes: 1

Views: 3155

Answers (1)

trevorKirkby
trevorKirkby

Reputation: 1897

To change readily from gameplay and a menu, you will need to make a way to manage both of them cleanly. Menu can have a class, but the part that maintains a menu should be a function, and the same for gameplay. Here is a good structure for it to use:

is_menu = False

def menu():
    pass
    #right here you want the necessary code to maintain the main menu. be sure not to put the code that starts up the menu here, only the code required to run over and over again to keep the menu running

def change_to_menu():
    is_menu = True
    #right here you want the things to do to create a menu, as well as the above line of code that will be used to mark the fact that the menu is to be maintained, not gameplay

def gameplay():
    pass
    #here is where you put code to maintain gameplay. remember this will be called over and over again, multiple times a second

def change_to_gameplay():
    is_menu = False
    #insert the code to resume or initialize gameplay here, along with the above line. you may want to make different functions to initialize and resume gameplay, though it is not nescessary

while not salir:          #this is your mainloop
    if is_menu:
        menu()
    else:
        gameplay()

the above code is structured to have a main loop, code to go in the mainloop to keep the menu running, code to go in the mainloop to keep the gameplay running, and methods to shift from menu to gameplay that you may call anywhere.

If you want to create a new menu, you can just initialize a new menu object and get rid of the old one. Unless it holds important gameplay attributes, this should be fine, and if it does, you could probably store them as globals or in a different object, for example if this one holds an attribute about the game settings, you could instead make that attribute global or make a second object to manage all the settings that is not the menu, which is meant to manage the GUI aspects of this.

Upvotes: 1

Related Questions