在 pygame 中只运行一次 if 语句 [英] Running a if statement only once in pygame

查看:71
本文介绍了在 pygame 中只运行一次 if 语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个跑步游戏,您可以在其中移动和收集硬币.对于每个硬币,我都有一个 if 语句:

I have a running game where you can move and collect coins. For each coin I have a if statement:

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 中.后来在我的代码中,我将 coincount 中的硬币数量 blit 到屏幕上.

This if statement keeps happening over and over again, adding hundreds of coins to the variable coincount. Later in my code I blit the number of coins in coincount on to the screen.

有没有办法确保这只运行一次?

Is there a way to make sure this only runs once?

(这是我的其余代码,可能会有所帮助)

(Here's the rest of my code, ut might be helpful)

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()

推荐答案

你的代码缺少的是抽象.

不要使用一堆 screen.blit 和许多 if 语句,而是使用列表.
不要使用硬编码值(如 cn1+25 x),而是使用包含他们需要的所有信息的数据结构(在您的情况下为对象).

Instead of a bunch of screen.blit and a lot of if statements, use lists.
Instead of hard-coded values (like cn1+25 < x and cn1 + 50 > x), use data structures (in your case, objects) that contain all information they need.

这是一个简单的例子.

假设我们有一个美好的世界,晴天时云彩会移动:

Let's say we have this nice world where the clouds move on a sunny day:

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)

当然,我们想要更多而不是单一的云.我们想要的是重复代码并提高复杂性.我们可以这样做:

But of course we want more than one single cloud. What we don't want is to duplicate code and raise the complexity. We could do something like this:

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)

如果我们再添加一打对象,您已经可以看到它会在哪里结束.

You can already see where it is going to end if we add a dozen objects more.

所以让我们在这里尝试使用代表云的对象:

So let's try to use objects here that represent the clouds:

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)

(这里没有新图片,因为它看起来基本一样)

(no new image here because it basically looks the same)

好多了!现在,要添加更多云,我们只需将一个新的 Cloud 实例添加到 clouds 列表中即可.看看我们如何在类中不仅存储云的图像,还存储位置.我们已经将云行为(沿着天空移动离开屏幕后从左边开始)进入课堂.

Much better! Now, to add more clouds, we would simply add a new Cloud instance to the clouds list. See how we not only store the image of a cloud in the class, but also the position. And we've put the cloud behaviour (moving along the sky and start from the left once we moved off the screen) into the class.

但我们仍然可以做得更好! Pygame 提供了一些我们可以使用的方便的类和函数.看看下面的代码:

But we can still do better! Pygame offers some handy classes and functions that we can use. Take a look at the following code:

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)

我们使用 pygame 的 GroupSprite 类.

We abstracted drawing and updating our objects away by using pygame's Group and Sprite classes.

看看在我们的小游戏中添加新东西是多么容易.我添加了你可以点击我收集的硬币,硬币的所有行为都位于Coin类中.单击硬币后,将调用 Sprite 类的 kill 方法,该方法只是将对象从其所有组中删除,因此它不再位于 stuff 中 组,并且不再在屏幕上绘制,并有效地从游戏中删除(并回答您的仅运行一次 if 语句"的问题).

And see how easy it is to add new stuff to our little game. I added coins you can click wo collect, and all the behaviour of the coins is located in the Coin class. Once you click a coin, the kill method of the Sprite class is called, which simply removes the object from all its groups, so it's no longer in the stuff group, and there is no longer being drawn on the screen, and effectively removed from the game (and answering your question of "Running a if statement only once").

这篇关于在 pygame 中只运行一次 if 语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆