samedi 28 août 2021

How to generate the level after pressing the pygame menu button

I have been coding a maths game with Pygame. The menu is in one file named Menu121.

# Import the required libraries
import pygame
import pygame_menu


# Initialize pygame
pygame.init()
surface = pygame.display.set_mode((600, 400))
pygame.display.set_caption("Projecte MatZanfe")


font = pygame_menu.font.FONT_8BIT
font1 = pygame_menu.font.FONT_NEVIS
font2 = pygame_menu.font.FONT_BEBAS

#Make menu Sumes
menu3 = pygame_menu.Menu('Sums', 600, 400,
                       theme=pygame_menu.themes.THEME_BLUE)

menu3.add.button('Infinite sums', font_name = font1, font_color = 'green')
menu3.add.button('Sums with images', font_name = font1, font_color = 'blue')
menu3.add.button('Sums with audio', font_name = font1,font_color = 'red')

#Make menu Restes
menu4 = pygame_menu.Menu('Subtraction', 600, 400,
                       theme=pygame_menu.themes.THEME_DEFAULT)

menu4.add.button('Infinite subtractions', font_name = font1, font_color = 'green')
menu4.add.button('Subtractions with images', font_name = font1, font_color = 'blue')
menu4.add.button('Subtratcions with audio', font_name = font1,font_color = 'red')

#Make menu Multiplicacions
menu5 = pygame_menu.Menu('Multiplications', 600, 400,
                       theme=pygame_menu.themes.THEME_ORANGE)

menu5.add.button('Infinite multis', font_name = font1, font_color = 'green')
menu5.add.button('Multis with images', font_name = font1, font_color = 'blue')
menu5.add.button('Multis with audio', font_name = font1,font_color = 'red')

#Make menu Divisions
menu6 = pygame_menu.Menu('Divisions', 600, 400,
                       theme=pygame_menu.themes.THEME_GREEN)

menu6.add.button('Infinite divisions', font_name = font1, font_color = 'green')
menu6.add.button('Divisions with images', font_name = font1, font_color = 'blue')
menu6.add.button('Divisions with audio', font_name = font1,font_color = 'red')

# Make menu 2
menu2 = pygame_menu.Menu('Module selection', 600, 400,
                       theme=pygame_menu.themes.THEME_SOLARIZED)


menu2.add.button('Sums',menu3, font_name = font2, font_color = 'green')
menu2.add.button('Subtractions',menu4, font_name = font2, font_color = 'blue')
menu2.add.button('Multiplications',menu5, font_name = font2,font_color = 'red')
menu2.add.button('Divisions',menu6, font_name = font2, font_color = 'purple' )

# Make main menu
menu = pygame_menu.Menu('Projecte MatZanfe', 600, 400,
                       theme=pygame_menu.themes.THEME_SOLARIZED)

user_input = menu.add.text_input('User: ', font_name = font1, font_color = 'blue')
age_input = menu.add.text_input('Age: ', font_name = font1,font_color = 'Black')
menu.add.button('Start', menu2, font_name = font, font_color = 'green')
menu.add.button('Exit', pygame_menu.events.EXIT, font_name = font,font_color = 'red')

# Run the menu
menu.mainloop(surface)

As you can see, you will eventually arrive at the "level selector", which consists in three different exercices related to the mathematical operations. I need to link the buttons to the code that generates the level, but don't really know how to do it. This is an example of the infinite levels, specifically the Subtractions level. The file name is Infinitesubtractions

import pygame
import random
from InputBox import InputBox
from pygame import mixer

pygame.init()

pygame.time.set_timer(pygame.USEREVENT, 1000)
clock = pygame.time.Clock()
surface = pygame.display.set_mode((600, 400))
pygame.display.set_caption("Projecte MatZanfe")
font = pygame.font.SysFont('comicsans', 50)
base_font = pygame.font.Font(None, 32)
user_text = ''
color_active = pygame.Color('lightskyblue3')
running = True
points = 0
t = 60

def start_the_game():
    x = random.randint(5, 10)
    y = random.randint(0, 5)
    is_correct = False
    return x, y

def display_the_game(x, y):
    # Variables
    z = x + y
    surface.fill((70, 90, 255))
    text = font.render(str(x) + " - " + str(y), True, (255, 255, 255))

    text_surface = base_font.render(user_text, True, (255, 255, 255))
    surface.blit(text, (260, 120))
    input_box.draw(surface)
    punts = font.render("Puntuació: " +  str(points),True, (255,255,255))
    surface.blit(punts, (350,30))
    titolresta = font.render("Resta (1)", True, (0, 0, 0))
    surface.blit(titolresta, (10, 20))
    temps = font.render("Temps: " + str(t), True, (255, 255, 51))
    surface.blit(temps, (0, 360))

x, y = start_the_game()
input_box = InputBox(190, 250, 200, 32)

while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.USEREVENT:
            t -= 1
            temps = font.render("Temps:" + str(t), True, (255, 255, 51))
            surface.blit(temps, (0, 360))
            pygame.display.flip()
            if t == 0:
                pygame.QUIT
        else:
            result = input_box.handle_event(event)
            if result != None:
                if int(result) == int(x) - int(y):
                    points = points + 5
                    t = t + 5
                    mixer.music.load('StarPost.wav')
                    mixer.music.play(1)

                # create new random numbers
                x, y = start_the_game()

                # reset input box (just create a new box)
                input_box = InputBox(190, 250, 200, 32)

    display_the_game(x, y)
    pygame.display.update()

pygame.quit()

And finally the imported InputBox:

import pygame


pygame.init()
surface = pygame.display.set_mode((600, 400))
COLOR_INACTIVE = pygame.Color('lightskyblue3')
COLOR_ACTIVE = pygame.Color('black')
FONT = pygame.font.SysFont('comicsans', 32)
base_font = pygame.font.Font(None, 32)
color_active = pygame.Color('lightskyblue3')
user_text = ''


class InputBox:

    def __init__(self, x, y, w, h, text=''):
        self.rect = pygame.Rect(x, y, w, h)
        self.color = COLOR_INACTIVE
        self.text = text
        self.txt_surface = FONT.render(text, True, self.color)
        self.active = False

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            # If the user clicked on the input_box rect.
            if self.rect.collidepoint(event.pos):
                # Toggle the active variable.
                self.active = not self.active
            else:
                self.active = False
            # Change the current color of the input box.
            self.color = COLOR_ACTIVE if self.active else COLOR_INACTIVE
        if event.type == pygame.KEYDOWN:
            if self.active:
                if event.key == pygame.K_RETURN:
                    user_input = self.text
                    self.text = ''
                    self.txt_surface = FONT.render(self.text, True, self.color)
                    return user_input
                elif event.key == pygame.K_BACKSPACE:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode
                # Re-render the text.
                self.txt_surface = FONT.render(self.text, True, self.color)

    def update(self):
        # Resize the box if the text is too long.
        width = max(200, self.txt_surface.get_width()+10)
        self.rect.w = width

    def draw(self, screen):
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))
        # Blit the rect.
        pygame.draw.rect(screen, self.color, self.rect, 2)



def main():
    clock = pygame.time.Clock()
    input_box2 = InputBox(190, 250, 200, 32)
    input_boxes = [input_box2]
    done = False

    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            for box in input_boxes:
                box.handle_event(event)

        for box in input_boxes:
            box.update()

        surface.fill((255, 70, 90))
        for box in input_boxes:
            box.draw(surface)

        pygame.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    main()
    pygame.quit()



Aucun commentaire:

Enregistrer un commentaire