Как мне подключить страницу к кнопке - Pygame? - PullRequest
0 голосов
/ 17 января 2020

У меня есть меню с 3 кнопками. Я хочу, чтобы одна из кнопок подключилась к моей странице игры, но я не уверен, как это сделать. Поэтому я хочу, чтобы кнопка «игра» выводила на экран, на котором находится настоящая игра (например, экран, на котором вы играете). Я пытаюсь выяснить, как подключить страницу к кнопке в этой игре. Спасибо

# import images
background = pygame.image.load('background.png')
backgroundX = 0
backgroundX2 = background.get_width()
homeScreen = pygame.image.load('home_screen.png')
obstacle = pygame.image.load('obstacle.png')
obstacleX = 0
obstacleX2 = obstacle.get_width()
instructions = pygame.image.load('instructions.png')

# frame rate
clock = pygame.time.Clock()


# use procedure for game window rather than using it within loop
def redrawGameWindow():
    # background images for right to left moving screen
    screen.blit(background, (backgroundX, 0))
    screen.blit(background, (backgroundX2, 0))
    man.draw(screen)
    screen.blit(obstacle, (obstacleX, 400))
    screen.blit(obstacle, (obstacleX2, 400))
    pygame.display.update()


# create class for character (object)
class player(object):
    def __init__(self, x, y, width, height):  # initialize attributes
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.left = True
        self.right = True
        self.isJump = False
        self.stepCount = 0
        self.jumpCount = 10
        self.standing = True

    def draw(self, screen):
        if self.stepCount + 1 >= 27:  # 9 sprites, with 3 frames - above 27 goes out of range
            self.stepCount = 0

        if not self.standing:
            if self.left:
                screen.blit(leftDirection[self.stepCount // 5], (self.x, self.y), )
                self.stepCount += 1
            elif self.right:
                screen.blit(rightDirection[self.stepCount // 5], (self.x, self.y), )
                self.stepCount += 1
        else:
            if self.right:
                screen.blit(rightDirection[0], (self.x, self.y))  # using index, include right faced photo
            else:
                screen.blit(leftDirection[0], (self.x, self.y))


class enlargement(object):
    def __init__(self, x, y, radius, color, facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius, 1)


man = player(200, 313, 64, 64)

font = pygame.font.Font(None, 75)  # font for home screen
instructionsFont = pygame.font.Font(None, 30)  # font for instructions page

# HOME SCREEN
WHITE = (255,255,255)
BLACK = (  0,  0,  0)

RED   = (255,  0,  0)
GREEN = (  0,255,  0)
BLUE  = (  0,  0,255)

YELLOW = (255,255, 0)

def button_create(text, rect, inactive_color, active_color, action):

    font = pygame.font.Font(None, 40)

    button_rect = pygame.Rect(rect)

    text = font.render(text, True, BLACK)
    text_rect = text.get_rect(center=button_rect.center)

    return [text, text_rect, button_rect, inactive_color, active_color, action, False]


def button_check(info, event):

    text, text_rect, rect, inactive_color, active_color, action, hover = info

    if event.type == pygame.MOUSEMOTION:
        # hover = True/False
        info[-1] = rect.collidepoint(event.pos)

    elif event.type == pygame.MOUSEBUTTONDOWN:
        if hover and action:
            action()


def button_draw(screen, info):

    text, text_rect, rect, inactive_color, active_color, action, hover = info

    if hover:
        color = active_color
    else:
        color = inactive_color

    pygame.draw.rect(screen, color, rect)
    screen.blit(text, text_rect)

# ---

def on_click_button_1():
    global stage
    stage = 'game'
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)

    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)

    YELLOW = (255, 255, 0)

    # --- classes --- (CamelCaseNanes)

    # empty

    # --- functions --- (lower_case_names_

    def button_create(text, rect, inactive_color, active_color, action):

        font = pygame.font.Font(None, 40)

        button_rect = pygame.Rect(rect)

        text = font.render(text, True, BLACK)
        text_rect = text.get_rect(center=button_rect.center)

        return [text, text_rect, button_rect, inactive_color, active_color, action, False]

    def button_check(info, event):

        text, text_rect, rect, inactive_color, active_color, action, hover = info

        if event.type == pygame.MOUSEMOTION:
            # hover = True/False
            info[-1] = rect.collidepoint(event.pos)

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if hover and action:
                action()

    def button_draw(screen, info):

        text, text_rect, rect, inactive_color, active_color, action, hover = info

        if hover:
            color = active_color
        else:
            color = inactive_color

        pygame.draw.rect(screen, color, rect)
        screen.blit(text, text_rect)

    # ---

    def on_click_button_1():
        global stage
        stage = 'game'

        print('You clicked Button 1')

    def on_click_button_2():
        global stage
        stage = 'options'

        print('You clicked Button 2')

    def on_click_button_3():
        global stage
        global running

        stage = 'exit'
        running = False

        print('You clicked Button 3')

    def on_click_button_return():
        global stage
        stage = 'menu'

        print('You clicked Button Return')

    # --- main ---  (lower_case_names)

    # - init -

        pygame.init()
        screen = pygame.display.set_mode((800, 600))
        screen_rect = screen.get_rect()

        # - objects -

        stage = 'menu'

        button_1 = button_create("GAME", (300, 100, 200, 75), RED, GREEN, on_click_button_1)
        button_2 = button_create("OPTIONS", (300, 200, 200, 75), RED, GREEN, on_click_button_2)
        button_3 = button_create("EXIT", (300, 300, 200, 75), RED, GREEN, on_click_button_3)

        button_return = button_create("RETURN", (300, 400, 200, 75), RED, GREEN, on_click_button_return)

        # - mainloop -

        running = True

        while running:

            # - events -

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

                if stage == 'menu':
                    button_check(button_1, event)
                    button_check(button_2, event)
                    button_check(button_3, event)
                elif stage == 'game':
                    button_check(button_return, event)
                elif stage == 'options':
                    button_check(button_return, event)
                # elif stage == 'exit':
                #    pass

            # - draws -

            screen.fill(BLACK)

            if stage == 'menu':
                button_draw(screen, button_1)
                button_draw(screen, button_2)
                button_draw(screen, button_3)
            elif stage == 'game':
                button_draw(screen, button_return)
            elif stage == 'options':
                button_draw(screen, button_return)
            # elif stage == 'exit':
            #    pass

            pygame.display.update()


            print('You clicked Button 1')

def on_click_button_2():
    global stage
    stage = 'options'

    print('You clicked Button 2')

def on_click_button_3():
    global stage
    global running

    stage = 'exit'
    running = False

    print('You clicked Button 3')

def on_click_button_return():
    global stage
    stage = 'menu'

    print('You clicked Button Return')

# --- main ---  (lower_case_names)

# - init -

pygame.init()
screen = pygame.display.set_mode((800,600))
screen_rect = screen.get_rect()

# - objects -

stage = 'menu'

button_1 = button_create("GAME", (300, 100, 200, 75), RED, GREEN, on_click_button_1)
button_2 = button_create("OPTIONS", (300, 200, 200, 75), RED, GREEN, on_click_button_2)
button_3 = button_create("EXIT", (300, 300, 200, 75), RED, GREEN, on_click_button_3)

button_return = button_create("RETURN", (300, 400, 200, 75), RED, GREEN, on_click_button_return)

# - mainloop -

running = True

while running:

    # - events -

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if stage == 'menu':
            button_check(button_1, event)
            button_check(button_2, event)
            button_check(button_3, event)
        elif stage == 'game':
            button_check(button_return, event)
        elif stage == 'options':
            button_check(button_return, event)
        #elif stage == 'exit':
        #    pass

    # - draws -

    screen.fill(BLACK)

    if stage == 'menu':
        button_draw(screen, button_1)
        button_draw(screen, button_2)
        button_draw(screen, button_3)
    elif stage == 'game':
        button_draw(screen, button_return)
    elif stage == 'options':
        button_draw(screen, button_return)
    #elif stage == 'exit':
    #    pass

    pygame.display.update()

# - end -

pygame.quit()



run = True
while run:
        clock.tick(30)
        pygame.display.update()
        redrawGameWindow()  # call procedure

        backgroundX -= 1.4  # Move both background images back
        backgroundX2 -= 1.4
        obstacleX -= 1.4
        obstacleX2 -= 1.4

        if backgroundX < background.get_width() * -1:  # If our background is at the -width then reset its position
            backgroundX = background.get_width()

        if backgroundX2 < background.get_width() * -1:
            backgroundX2 = background.get_width()

        if obstacleX < obstacle.get_width() * -10:
            obstacleX = obstacle.get_width

        if obstacleX2 < obstacle.get_width() * -10:
            obstacleX2 = obstacle.get_width()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                quit()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            man.left = True
            man.right = False
            man.standing = False  # false, because man is walking
        # verify that character is within window parameters
        elif keys[pygame.K_RIGHT]:
            man.right = True
            man.left = False
            man.standing = False  # false, because man is walking
        else:
            man.standing = True
            man.stepCount = 0

        if not man.isJump:
            if keys[pygame.K_SPACE]:
                man.isJump = True  # when jumping, man shouldn't move directly left or right
                man.right = False
                man.left = False
                man.stepCount = 0
        else:
            if man.jumpCount >= -10:
                neg = 1
                if man.jumpCount < 0:
                    neg = -1
                man.y -= (man.jumpCount ** 2) * .5 * neg  # to jump use parabola
                man.jumpCount -= 1
            else:
                man.isJump = False
                man.jumpCount = 10



pygame.quit()

1 Ответ

1 голос
/ 17 января 2020

Каждый page или stage имеет похожие элементы - создавать элементы, рисовать, обновлять, обрабатывать события, mainl oop - которые вы можете поместить в класс, чтобы отделить один этап от другого.

При запуске создайте MenuStage и запустите его mainloop(). Когда вы нажимаете кнопку в MenuStage, затем создаете GameStage и запускаете ее mainloop(). Чтобы go вернуться от GameStage к MenuStage, используйте кнопку (или другое событие), чтобы установить self.running = False для остановки GameStage.mainloop и go обратно на MenuStage.mainloop


Этот пример не использует ваш код, но показывает, как будет работать Stages.

import pygame

# === CONSTANTS === (UPPER_CASE_NAMES)

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

# === CLASSES === (CamelCaseNames)

class Player():

    def __init__(self, screen, config):
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.config = config

        self.direction = 'right'
        self.rect = pygame.Rect(100, 100, 20, 20)
        self.speed = 10

    def draw(self, surface):
        pygame.draw.rect(surface, RED, self.rect)

    def update(self):
        self.rect.x += self.speed
        if self.direction == 'right':
            if self.rect.right > self.screen_rect.right:
                self.rect.right = self.screen_rect.right
                self.speed = -self.speed
                self.direction = 'left'
        elif self.direction == 'left':
            if self.rect.left < self.screen_rect.left:
                self.rect.left = self.screen_rect.left
                self.speed = -self.speed
                self.direction = 'right'

class Stage():

    # --- (global) variables ---

        # empty

    # --- init ---

    def __init__(self, screen, config):

        self.screen = screen
        self.config = config

        self.screen_rect = screen.get_rect()

        self.clock = pygame.time.Clock()
        self.is_running = False

        self.widgets = []

        self.create_objects()

    def quit(self):

        pass

    # --- objects ---

    def create_objects(self):

        '''
        self.player = Player()
        '''

        '''
        btn = Button(...)
        self.widgets.append(btn)
        '''

    # --- functions ---

    def handle_event(self, event):

        '''
        self.player.handle_event(event)
        '''

        '''
        for widget in self.widgets:
            widget.handle_event(event)
        '''

    def update(self, ):

        '''
        self.player.update()
        '''

        '''
        for widget in self.widgets:
            widget.update()
        '''

    def draw(self, surface):

        #surface.fill(BLACK)

        '''
        self.player.draw(surface)
        '''

        '''
        for widget in self.widgets:
            widget.draw(surface)
        '''

        #pygame.display.update()    

    def exit(self):
        self.is_running = False

    # --- mainloop --- (don't change it)

    def mainloop(self):

        self.is_running = True

        while self.is_running:

            # --- events ---

            for event in pygame.event.get():

                # --- global events ---

                if event.type == pygame.QUIT:
                    self.is_running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.is_running = False

                # --- objects events ---

                self.handle_event(event)

            # --- updates ---

            self.update()

            # --- draws ---

            self.screen.fill(BLACK)

            self.draw(self.screen)

            pygame.display.update()

            # --- FPS ---

            self.clock.tick(25)

        # --- the end ---

        self.quit()


class IntroStage(Stage):

    def create_objects(self):
        self.font = pygame.font.Font(None, 40)
        self.text = self.font.render("INTRO STAGE (Press ESC or Click Mouse)", True, BLACK)
        self.text_rect = self.text.get_rect(center=self.screen_rect.center)

    def draw(self, surface):
        surface.fill(GREEN)
        surface.blit(self.text, self.text_rect)

    def handle_event(self, event):
        # close on mouse click
        if event.type == pygame.MOUSEBUTTONDOWN:
            #self.is_running = False
            self.exit()

class MenuStage(Stage):

    def create_objects(self):
        self.font = pygame.font.Font(None, 40)
        self.text = self.font.render("MENU STAGE (Press ESC)", True, BLACK)
        self.text_rect = self.text.get_rect(center=self.screen_rect.center)
        self.text_rect.top = 10

        self.stage_game = GameStage(self.screen, self.config)
        self.stage_options = OptionsStage(self.screen, self.config)

        self.button1 = button_create("GAME", (300, 200, 200, 50), GREEN, BLUE, self.stage_game.mainloop)
        self.button2 = button_create("OPTIONS", (300, 300, 200, 50), GREEN, BLUE, self.stage_options.mainloop)
        self.button3 = button_create("EXIT", (300, 400, 200, 50), GREEN, BLUE, self.exit)

    def draw(self, surface):
        surface.fill(RED)
        surface.blit(self.text, self.text_rect)

        button_draw(surface, self.button1)
        button_draw(surface, self.button2)
        button_draw(surface, self.button3)

    def handle_event(self, event):
        button_check(self.button1, event)
        button_check(self.button2, event)
        button_check(self.button3, event)

class OptionsStage(Stage):

    def create_objects(self):
        self.font = pygame.font.Font(None, 40)
        self.text = self.font.render("OPTIONS STAGE (Press ESC)", True, BLACK)
        self.text_rect = self.text.get_rect(center=self.screen_rect.center)

    def draw(self, surface):
        surface.fill(RED)
        surface.blit(self.text, self.text_rect)


class ExitStage(Stage):

    def create_objects(self):
        self.font = pygame.font.Font(None, 40)
        self.text = self.font.render("EXIT STAGE (Press ESC or Click Mouse)", True, BLACK)
        self.text_rect = self.text.get_rect(center=self.screen_rect.center)

    def draw(self, surface):
        surface.fill(GREEN)
        surface.blit(self.text, self.text_rect)

    def handle_event(self, event):
        # close on mouse click
        if event.type == pygame.MOUSEBUTTONDOWN:
            #self.is_running = False
            self.exit()

class GameStage(Stage):

    def create_objects(self):
        self.font = pygame.font.Font(None, 40)
        self.text = self.font.render("GAME STAGE (Press ESC)", True, BLACK)
        self.text_rect = self.text.get_rect(center=self.screen_rect.center)

        self.player = Player(self.screen, self.config)

    def draw(self, surface):
        surface.fill(BLUE)
        surface.blit(self.text, self.text_rect)
        self.player.draw(surface)

    def update(self):
        self.player.update()

# === FUNCTIONS === (lower_case_names)
# TODO: create class Button()

def button_create(text, rect, inactive_color, active_color, action):

    font = pygame.font.Font(None, 40)

    button_rect = pygame.Rect(rect)

    text = font.render(text, True, BLACK)
    text_rect = text.get_rect(center=button_rect.center)

    return [text, text_rect, button_rect, inactive_color, active_color, action, False]


def button_check(info, event):

    text, text_rect, rect, inactive_color, active_color, action, hover = info

    if event.type == pygame.MOUSEMOTION:
        # hover = True/False
        info[-1] = rect.collidepoint(event.pos)

    elif event.type == pygame.MOUSEBUTTONDOWN:
        if hover and action:
            action()

def button_draw(screen, info):

    text, text_rect, rect, inactive_color, active_color, action, hover = info

    if hover:
        color = active_color
    else:
        color = inactive_color

    pygame.draw.rect(screen, color, rect)
    screen.blit(text, text_rect)

# === MAIN === (lower_case_names)

class App():

    # --- init ---

    def __init__(self):

        pygame.init()

        screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

        config = {}

        stage = IntroStage(screen, config)
        stage.mainloop()

        stage = MenuStage(screen, config)
        stage.mainloop()

        stage = ExitStage(screen, config)
        stage.mainloop()

        pygame.quit()

    #def run(self):

#----------------------------------------------------------------------

if __name__ == '__main__':

    App() #.run()

РЕДАКТИРОВАТЬ: Изображение, которое я сделал долгое время go:

enter image description here

...