Запуск оператора if только один раз в Pygame - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть беговая игра, в которой вы можете перемещаться и собирать монеты.Для каждой монеты у меня есть оператор if:

if cn1+25 < x and cn1 + 50 > x:
        cn1 = -1000
        if cn1 < -3:
            coincount += 1
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)

Этот оператор if повторяется снова и снова, добавляя сотни монет к переменной coincount.Позже в моем коде я сбрасываю количество монет в совпадении на экране.

Есть ли способ убедиться, что это выполняется только один раз?

(Вот остальная часть моего кода, но может быть полезным)

import pygame,sys,random
pygame.init()

width = 900
height = 300
screenDim = (width,height)
green=(0,255,0)
yellow=(255,255,0)
red=(255,0,0)
WHITE = (0,0,0)
BLACK = (255,255,255)
screen = pygame.display.set_mode(screenDim)

placePlatformX = 0
placePlatformY = 275
coin = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Desktop\\coin.png').convert_alpha()
coin = pygame.transform.scale(coin, (25,25))
background = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Desktop\\background.jpg').convert_alpha()
background = pygame.transform.scale(background, (width,height))
guy = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Desktop\\guy.png').convert_alpha()
guy = pygame.transform.rotate(guy,90)
cloud1 = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Downloads\\cloud.png').convert_alpha()
cloud1 = pygame.transform.scale(cloud1,(156,88))
cloud2 = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Downloads\\cloud.png').convert_alpha()
cloud2 = pygame.transform.scale(cloud1,(131,53))
cloud3 = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Downloads\\cloud.png').convert_alpha()
cloud3 = pygame.transform.scale(cloud1,(200,100))
cloud4 = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Downloads\\cloud.png').convert_alpha()
cloud4 = pygame.transform.scale(cloud1,(39,20))


bplatform = pygame.image.load('C:\\Users\\eliya_s1suf2x\\Desktop\\platform.jpg').convert_alpha()
coincount = 0    
x = 450
y = -20
block = 1000
cn1 = 100
cn2 = 100
cn3 = 100
cn4 = 100
cn5 = 100
cloudmove = 20

INVFONT = pygame.font.Font('C:\\Users\\eliya_s1suf2x\\Desktop\\MINECRAFT\\Raleway-ExtraBold.ttf', 18)
textObj = INVFONT.render(str(coincount), True, WHITE, BLACK)

def update():


    screen.blit(background,(0,0))

    screen.blit(textObj,(860,0))
    screen.blit(cloud1,(cloudmove,0))
    screen.blit(cloud2,(cloudmove+120,30))
    screen.blit(cloud3, (cloudmove+500,10))
    screen.blit(cloud4, (cloudmove + 340,20))

    screen.blit(bplatform,(placePlatformX,placePlatformY))
    screen.blit(bplatform,(placePlatformX+190,placePlatformY))
    screen.blit(bplatform,(placePlatformX+380,placePlatformY))
    screen.blit(bplatform,(placePlatformX+570,placePlatformY))
    screen.blit(bplatform,(placePlatformX+760,placePlatformY))
    screen.blit(bplatform,(placePlatformX+1760,placePlatformY+100))
    #block list update
    screen.blit(bplatform,(block-500,190))
    screen.blit(bplatform,(block,100))
    screen.blit(bplatform,(block+250,200))
    screen.blit(bplatform,(block+500,210))
    screen.blit(bplatform,(block+830,190))
    screen.blit(bplatform,(block+1000,140))

    screen.blit(coin,(cn1 + 40,245))
    screen.blit(coin,(cn2 + 80,245))
    screen.blit(coin,(cn3 + 120,245))
    screen.blit(coin,(cn4+ 160,245))
    screen.blit(coin,(cn5 + 200,245))
    screen.blit(coin,(830,0))
    screen.blit(guy,(x,y))

#pygame.sprite.spritecollide()




standOnBrick = 255   
speed = 2
gravity = 3
pygame.display.set_caption("Run")
finished = False
while finished == False:

    #processing all the events
    for event in pygame.event.get(): # event1, event2,..
        if event.type == pygame.QUIT:
            finished = True
            pygame.quit()
            sys.exit()

    if y < standOnBrick:
        y += gravity
        update()

        #where the block   #where the block
        #starts             #ends
    elif cn1+25 < x and cn1 + 50 > x:
        cn1 = -1000
        if cn1 < -3:
            coincount += 1
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)

        #WORK ON THIS
    elif cn2 + 50 < x and cn2 + 100 > x:
        cn2 = -1025
        if cn2 < -3:
            coincount += 1
            print('coincount',coincount)
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)
    elif cn3 + 75 < x and cn3 + 150 > x:
        cn3 = -1050
        if cn3 < -3:
            coincount += 1
            print('coincount',coincount)
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)

    elif cn4 + 100 < x and cn2 + 200 > x:
        cn4 = -1000
        if cn4 < -3:
            coincount += 1
            print('coincount',coincount)
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)

    elif cn5 + 125 < x and cn5 + 230 > x:
        cn5 = -1000
        if cn5 < -3:
            coincount += 1
            print('coincount',coincount)
            print('hello')
            textObj = INVFONT.render(str(coincount+1), True, WHITE, BLACK)

    elif block-525 < x and block-330 > x:
        #how high guy is
        standOnBrick = 167
    elif block-16 < x and block+180 > x:
        standOnBrick = 79
    elif block + 230 < x and block + 426 > x:
        standOnBrick = 179
    elif block + 480 < x and block + 480+196>x:
        standOnBrick = 189
    elif block + 810 < x and block + 1026 > x:
        standOnBrick = 169
    elif block + 980 < x and block +1176 > x:
        standOnBrick = 119

    else:
        standOnBrick = 255
    pressedKeys = pygame.key.get_pressed()
    if pressedKeys[pygame.K_LEFT] == 1:
        x -= speed
        print(x)
        update()



    elif pressedKeys[pygame.K_RIGHT] == 1:
        block -= 0.5
        cn1 -= 0.5
        cn2 -= 0.5
        cn3 -= 0.5
        cn4 -= 0.5
        cn5 -= 0.5
        cloudmove -= 0.2
        update()
        if x < 450:
            cloudmove += 0.25
            x+=speed
            cn1 += 0.5
            cn2 += 0.5
            cn3 += 0.5
            cn4 += 0.5
            cn5 += 0.5
            update()
            print(x)
            block += 0.5
    elif pressedKeys[pygame.K_UP] == 1:
        y -= 5


        print(y)
        update()

#bounderies

    if x < 2:
        x += 2.1

    pygame.display.flip()#Update method/load next frame

#pygame.quit()

Ответы [ 2 ]

0 голосов
/ 27 января 2019

Также можно использовать кортеж для запуска оператора if только один раз.создавая кортеж switch = [0] вне цикла while, этого кода достаточно.

if Your conditions:
    if switch[0] == 0:
        switch[0] += 1

все, что вам нужно отсюда - это то, что работает (или не работает), потому что switch[0] = 1.Имея только 1, вы можете добавить такой же код для отмены.

0 голосов
/ 02 января 2019

В вашем коде отсутствует абстракция .

Вместо набора screen.blit и множества операторов if используйте списки.
Вместо жесткогозакодированные значения (например, cn1+25 < x and cn1 + 50 > x), используют структуры данных (в вашем случае, объекты), которые содержат всю необходимую им информацию.

Вот простой пример.

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

import pygame

screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

cloud = pygame.Surface((50, 20))
cloud.set_colorkey((11, 12, 13))
cloud.fill((11, 12, 13))
pygame.draw.ellipse(cloud, pygame.Color('white'), cloud.get_rect())

cloudmove = 20

while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            quit()
    screen.fill(pygame.Color('lightblue'))
    screen.blit(cloud, (cloudmove+120,30))
    cloudmove += 1
    pygame.display.flip()
    clock.tick(30)

enter image description here

Но, конечно, мы хотим на больше , чем одно облако.Чего мы не хотим, так это дублирования кода и повышения сложности.Мы могли бы сделать что-то вроде этого:

import pygame

screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

cloud = pygame.Surface((50, 20))
cloud.set_colorkey((11, 12, 13))
cloud.fill((11, 12, 13))
pygame.draw.ellipse(cloud, pygame.Color('white'), cloud.get_rect())

cloud2 = pygame.Surface((50, 20))
cloud2.set_colorkey((11, 12, 13))
cloud2.fill((11, 12, 13))
pygame.draw.ellipse(cloud2, pygame.Color('white'), cloud2.get_rect())

cloud3 = pygame.Surface((50, 20))
cloud3.set_colorkey((11, 12, 13))
cloud3.fill((11, 12, 13))
pygame.draw.ellipse(cloud3, pygame.Color('white'), cloud3.get_rect())

cloudmove = 20

while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            quit()
    screen.fill(pygame.Color('lightblue'))
    screen.blit(cloud, (cloudmove-120,30))
    screen.blit(cloud2, (cloudmove-220,40))
    screen.blit(cloud3, (cloudmove-170,50))
    cloudmove += 1
    pygame.display.flip()
    clock.tick(30)

enter image description here

Вы уже можете видеть, где это закончится, если мы добавим еще дюжину объектов.

Итак, давайте попробуем использовать здесь объекты, представляющие облака:

import pygame

screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

class Cloud:
    def __init__(self, x, y):
        self.image = pygame.Surface((50, 20))
        self.image.set_colorkey((11, 12, 13))
        self.image.fill((11, 12, 13))
        pygame.draw.ellipse(self.image, pygame.Color('white'), self.image.get_rect())
        self.x = x
        self.y = y

    def update(self):
        self.x += 1
        if self.x > 300:
            self.x = 0

clouds = [Cloud(0, 30), Cloud(100, 40), Cloud(50, 50)]

while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            quit()
    screen.fill(pygame.Color('lightblue'))
    for cloud in clouds:
        screen.blit(cloud.image, (cloud.x, cloud.y))
        cloud.update()
    pygame.display.flip()
    clock.tick(30)

(здесь нет нового изображения, потому что оно в основном выглядит одинаково)

Намного лучше!Теперь, чтобы добавить больше облаков, мы просто добавили бы новый экземпляр Cloud в список clouds.Посмотрите, как мы храним не только изображение облака в классе, но и положение.И мы поместили облако поведение (двигаясь по небу и начнем слева, как только мы отошли от экрана ) в класс.

Но мы все еще можем сделать лучше! Pygame предлагает несколько удобных классов и функций, которые мы можем использовать.Взгляните на следующий код:

import pygame

screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

class Coin(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((44, 40))
        self.image.set_colorkey((11, 12, 13))
        self.image.fill((11, 12, 13))
        cx, cy = self.image.get_rect().center
        pygame.draw.circle(self.image, pygame.Color('grey'), (cx + 2, cy), 20)
        pygame.draw.circle(self.image, pygame.Color('orange'), (cx - 2, cy), 20)
        self.rect = self.image.get_rect(topleft=(x, y))

    def update(self):
        mouse_pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(mouse_pos) and pygame.mouse.get_pressed()[0]:
            self.kill()

class Cloud(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((50, 20))
        self.image.set_colorkey((11, 12, 13))
        self.image.fill((11, 12, 13))
        pygame.draw.ellipse(self.image, pygame.Color('white'), self.image.get_rect())
        self.rect = self.image.get_rect(topleft=(x, y))

    def update(self):
        self.rect.move_ip(1, 0)
        if not pygame.display.get_surface().get_rect().colliderect(self.rect):
            self.rect.right = 0

stuff = pygame.sprite.Group(Cloud(0, 30), Cloud(100, 40), Cloud(50, 50), 
                             Coin(100, 100), Coin(150, 180), Coin(80, 200))

while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            quit()
    screen.fill(pygame.Color('lightblue'))
    stuff.draw(screen)
    stuff.update()
    pygame.display.flip()
    clock.tick(30)

enter image description here

Мы абстрагировали отрисовку и обновили наши объекты, используя Pygame's Group и Sprite классы.

И посмотрите, как легко добавлять новые вещи в нашу маленькую игру.Я добавил монеты, которые вы можете нажать, чтобы собрать, и все поведение монет находится в классе Coin.Как только вы щелкаете монетку, вызывается метод kill класса Sprite, который просто удаляет объект из всех его групп, поэтому он больше не входит в группу stuff и больше не рисуется наэкран, и фактически удален из игры (и отвечает на ваш вопрос «Выполнение оператора if только один раз»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...