У меня есть огромный список операторов If и я хочу очистить свой код - PullRequest
3 голосов
/ 25 марта 2019

Это 4-й день обучения кодированию, я все еще немного запутался в некоторых основах. У него есть pygame, pygame.text, так что по сути мой код выглядит следующим образом.

#Mouse click to get mouse Position
    if event.type == pygame.MOUSEBUTTONDOWN:
        if gamestage == 0 and gamestage <= 1:
            gamestage += 1
            mx, my =pygame.mouse.get_pos()
        #Total rectangle dimentions mx>806 and mx<889 and my>890 and my<920
        #Clickable squares for Shots and Team
        #Use print function if bug arises
            if mx>848 and mx<889 and my>890 and my<920:

                #numberonscreen_x=859
                #numberonscreen_y=905
                n+=1
                print(n)
                n=str(n)
                text_surface, rect = gamefont.render(n,(4, 8, 18))
                n=int(n)
                screen.blit(board,(0,0))
                pygame.display.flip()

            if mx>806 and mx<848 and my>890 and my<920:
                print("Pass")
            if mx>764 and mx<806 and my>890 and my<920:
                print("Pass")
            if mx>722 and mx<764 and my>890 and my<920:
                print("Pass")
            if mx>680 and mx<722 and my>890 and my<920:
                print("Pass")
            if mx>638 and mx<680 and my>890 and my<920:
                print("Pass")
            if mx>596 and mx<638 and my>890 and my<920:
                print("Pass")
            if mx>554 and mx<596 and my>890 and my<920:
                print("Pass")
            if mx>512 and mx<554 and my>890 and my<920:
                print("Pass")
            if mx>470 and mx<512 and my>890 and my<920:
                print("Pass")
            if mx>428 and mx<470 and my>890 and my<920:
                print("Pass")
            if mx>386 and mx<428 and my>890 and my<920:
                print("Pass")
            if mx>344 and mx<386 and my>890 and my<920:
                print("Pass")
            if mx>302 and mx<344 and my>890 and my<920:
                print("Pass")
            if mx>260 and mx<302 and my>890 and my<920:
                print("Pass")
            if mx>218 and mx<260 and my>890 and my<920:
                print("Pass")
            if mx>176 and mx<218 and my>890 and my<920:
                print("Pass")
            if mx>134 and mx<176 and my>890 and my<920:
                print("Pass")
    if event.type == pygame.MOUSEBUTTONUP:
        if gamestage != 0:
            gamestage = 0

    #Press 0 set given on screen button to zero
    if event.type == pygame.KEYDOWN and event.key == pygame.K_0:
        mx, my =pygame.mouse.get_pos()
        if mx>848 and mx<889 and my>905 and my<920:
            n=0
            print(n)
        if mx>806 and mx<848 and my>905 and my<920:
            print("Pass1")
        if mx>764 and mx<806 and my>905 and my<920:
            print("Pass1")
        if mx>722 and mx<764 and my>905 and my<920:
            print("Pass1")
        if mx>680 and mx<722 and my>905 and my<920:
            print("Pass1")
        if mx>638 and mx<680 and my>905 and my<920:
            print("Pass1")
        if mx>596 and mx<638 and my>905 and my<920:
            print("Pass1")
        if mx>554 and mx<596 and my>905 and my<920:
            print("Pass1")
        if mx>512 and mx<554 and my>905 and my<920:
            print("Pass1")
        if mx>470 and mx<512 and my>905 and my<920:
            print("Pass1")
        if mx>428 and mx<470 and my>905 and my<920:
            print("Pass1")
        if mx>386 and mx<428 and my>905 and my<920:
            print("Pass1")
        if mx>344 and mx<386 and my>905 and my<920:
            print("Pass1")
        if mx>302 and mx<344 and my>905 and my<920:
            print("Pass")
        if mx>260 and mx<302 and my>905 and my<920:
            print("Pass1")
        if mx>218 and mx<260 and my>905 and my<920:
            print("Pass1")
        if mx>176 and mx<218 and my>905 and my<920:
            print("Pass1")
        if mx>134 and mx<176 and my>905 and my<920:
            print("Pass1")

Который выглядит действительно плохо.Я делаю монопольную игру и добавляю 2 экранные кнопки для каждого свойства.Это означает, что будет более 100 различных наборов (mx, my).Это выглядит очень неэффективно, только если посмотреть на код других людей.Поскольку на доске будет так много разных интерактивных разделов, мне нужно найти способ сделать его более эффективным и легким для чтения.

Хотя было бы неплохо, чтобы кто-то "просто сделал это", я "Я предпочел бы получить ответ с большим количеством ссылок.При использовании этого метода мне также потребовалось бы 100 text_surfaces с разными именами, 100 разных переменных n.Мой мыслительный процесс заключается в создании чего-то, чтобы хранить все n, text_surfaces и вызывать это.Однако я действительно не знаю, как это сделать, как это назвать и может ли работать «импорт из».

Ответы [ 2 ]

2 голосов
/ 25 марта 2019

Вам не хватает некоторых уровней абстракции .

Давайте начнем с базового скелета игры-пигмеи:

import pygame

def main():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    screen_rect = screen.get_rect()
    sprites = pygame.sprite.Group()
    clock = pygame.time.Clock()
    rects = []
    dt = 0

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        sprites.update(dt, events)
        screen.fill(pygame.Color('darkgrey'))
        sprites.draw(screen)
        pygame.display.update()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()

Мы хотим достичь Разделение интересов , поэтому давайте сохраним наш основной цикл чистым ипросто.Мы обрабатываем события (и единственные события, о которых заботится основной цикл, это QUIT), мы обновляем наше игровое состояние (которое является Group спрайтов с именем sprites), мы рисуем вещи вэкран, и мы ограничиваем частоту кадров с помощью Clock

Итак, вы говорите, что у вас есть монопольная доска, поэтому давайте подумаем, как это представить.Давайте создадим список свойств, каждое из которых имеет цвет, имя и цену:

properties = (
    ('purple', 100, 'Oriental Avenue'),
    ('purple', 200, 'Vermont Avenue'),
    ('purple', 300, 'Connecticut Avenue'),
    ('white',  400, 'Atlantic Avenue'),
    ('white',  500, 'Ventnor Avenue'),
    ('white',  600, 'Marvin Gardens'),
    ('blue',   700, 'Park Place'),
    ('blue',   800, 'Boadwalk')
)

Обратите внимание, что это просто список некоторых данных (на самом деле это кортеж кортежей), так как мы хотим Разделение данных и кода .

Свойства являются частью игрового состояния.Давайте создадим класс, который будет содержать все игровое состояние и создаст для нас несколько спрайтов , которые мы будем использовать для рисования чего-либо на экране.Этот класс также вычисляет позицию каждого спрайта.

class Board:
    def __init__(self, properties, font):
        self.properties = properties
        self.sprites = []

        side = len(properties) / 4 + 1
        size = (side * PROP_SIZE.width, side * PROP_SIZE.height)

        x, y = 0, 0
        flow = 'r'
        for prop in properties:
            if flow == 'r':
                if x == side - 1:
                    flow = 'd'
                else:
                    x += 1

            if flow == 'd':
                if y == side - 1:
                    flow = 'l'
                else:
                    y += 1

            if flow == 'l':
                if x == 0:
                    flow = 'u'
                else:
                    x -= 1

            if flow == 'u':
                y -= 1

            self.sprites.append(Property(*prop, (x*PROP_SIZE.width, y*PROP_SIZE.height), font))

Мы хотим, чтобы каждое свойство имело две кнопки, поэтому давайте создадим класс спрайта Property, который будет обрабатывать проверку событий для использования:

class Property(pygame.sprite.Sprite):
    def __init__(self, color, price, name, pos, font):
        super().__init__()
        self.image = pygame.Surface(PROP_SIZE.size)
        self.rect = self.image.get_rect()
        pygame.draw.rect(self.image, (0, 0, 0), self.rect)
        pygame.draw.rect(self.image, pygame.Color(color), self.rect.inflate(-2, -2))
        self.color = color
        self.price = price
        self.name = name

        font.render_to(self.image, (11, 21), name, pygame.Color('black'))
        font.render_to(self.image, (10, 20), name, pygame.Color('white'))

        self.buttons = {
            'A': pygame.Rect(10, 100, 100, 20),
            'B': pygame.Rect(10, 125, 100, 20),
        }

        self.rect.topleft = pos

    def update(self, dt, events):
        pos = pygame.mouse.get_pos()
        for button in self.buttons:
            hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
            pygame.draw.rect(self.image, pygame.Color('red' if hovered else 'darkgrey'), self.buttons[button])

        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.buttons:
                    hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
                    if hovered:
                        print(f'{self.name} says: You clicked {button}')

Мы используем некоторые приятные вещи в стиле пигмеев, такие как Rect класс, и это inflate , move и collidepoint методы, поэтому мынам не нужно вычислять позиции / столкновения самостоятельно.

Вот полный, работающий код.Вы получите идею:

import pygame
import pygame.freetype

PROP_SIZE = pygame.Rect(0, 0, 120, 180)

class Property(pygame.sprite.Sprite):
    def __init__(self, color, price, name, pos, font):
        super().__init__()
        self.image = pygame.Surface(PROP_SIZE.size)
        self.rect = self.image.get_rect()
        pygame.draw.rect(self.image, (0, 0, 0), self.rect)
        pygame.draw.rect(self.image, pygame.Color(color), self.rect.inflate(-2, -2))
        self.color = color
        self.price = price
        self.name = name

        font.render_to(self.image, (11, 21), name, pygame.Color('black'))
        font.render_to(self.image, (10, 20), name, pygame.Color('white'))

        self.buttons = {
            'A': pygame.Rect(10, 100, 100, 20),
            'B': pygame.Rect(10, 125, 100, 20),
        }

        self.rect.topleft = pos

    def update(self, dt, events):
        pos = pygame.mouse.get_pos()
        for button in self.buttons:
            hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
            pygame.draw.rect(self.image, pygame.Color('red' if hovered else 'darkgrey'), self.buttons[button])

        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN:
                for button in self.buttons:
                    hovered = self.buttons[button].move(*self.rect.topleft).collidepoint(pos)
                    if hovered:
                        print(f'{self.name} says: You clicked {button}')

class Board:
    def __init__(self, properties, font):
        self.properties = properties
        self.sprites = []

        side = len(properties) / 4 + 1
        size = (side * PROP_SIZE.width, side * PROP_SIZE.height)

        x, y = 0, 0
        flow = 'r'
        for prop in properties:
            if flow == 'r':
                if x == side - 1:
                    flow = 'd'
                else:
                    x += 1

            if flow == 'd':
                if y == side - 1:
                    flow = 'l'
                else:
                    y += 1

            if flow == 'l':
                if x == 0:
                    flow = 'u'
                else:
                    x -= 1

            if flow == 'u':
                y -= 1

            self.sprites.append(Property(*prop, (x*PROP_SIZE.width, y*PROP_SIZE.height), font))


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

    font = pygame.freetype.SysFont(None, 14)
    font.origin = True

    properties = (
        ('purple', 100, 'Oriental Avenue'),
        ('purple', 200, 'Vermont Avenue'),
        ('purple', 300, 'Connecticut Avenue'),
        ('white',  400, 'Atlantic Avenue'),
        ('white',  500, 'Ventnor Avenue'),
        ('white',  600, 'Marvin Gardens'),
        ('blue',   700, 'Park Place'),
        ('blue',   800, 'Boadwalk')
    )

    board = Board(properties, font)
    sprites = pygame.sprite.Group(*board.sprites)
    clock = pygame.time.Clock()
    rects = []
    dt = 0

    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        sprites.update(dt, events)
        screen.fill(pygame.Color('darkgrey'))
        sprites.draw(screen)
        pygame.display.update()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()

enter image description here

2 голосов
/ 25 марта 2019

Вы можете инициализировать массив из mx диапазонов:

mx_ranges = [
    (806,848),
    (764,806),
    (722,764),
    (680,722),
    (638,680),
    (596,638),
    (554,596),
    (512,554),
    (470,512),
    (428,470),
    (386,428),
    (344,386),
    (302,344),
    (260,302),
    (218,260),
    (176,218),
    (134,176),
]

И затем использовать эту функцию вместо каждого из этих "больших if кусков":

def check_mx_range(mx, min_my, max_my, result):
    for mx_range in mx_ranges:
        if mx_range[0] < mx < mx_range[1] and min_my < my < max_my:
            print(result)
            return True
    return False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...