Python 如何在pygame中同时执行两个事件?

Python 如何在pygame中同时执行两个事件?,python,pygame,Python,Pygame,我正在尝试制作一个游戏,玩家可以在3列中左右移动主精灵格兰,避免从天空中掉落雷雨云。这两个组件都可以工作,但不能同时工作,因此我可以移动播放器,也可以让雷雨云从顶部坠落。请有人帮忙,使这两个事件可以同时发生 这是我的密码 import pygame, sys import random import time from pygame.locals import * #sets colours for transparency BLACK = ( 0, 0, 0) #Sets gra

我正在尝试制作一个游戏,玩家可以在3列中左右移动主精灵格兰,避免从天空中掉落雷雨云。这两个组件都可以工作,但不能同时工作,因此我可以移动播放器,也可以让雷雨云从顶部坠落。请有人帮忙,使这两个事件可以同时发生

这是我的密码

import pygame, sys
import random
import time
from pygame.locals import *

#sets colours for transparency
BLACK = (   0,   0,   0)
#Sets gran sprite
class Sprite_maker(pygame.sprite.Sprite): # This class represents gran it derives from the "Sprite" class in Pygame
    def __init__(self, filename):
        super().__init__() # Call the parent class (Sprite) constructor
        self.image = pygame.image.load(filename).convert()# Create an image loaded from the disk
        self.image.set_colorkey(BLACK)#sets transparrency
        self.rect = self.image.get_rect()# Fetchs the object that has the dimensions of the image
#Initilizes pygame game
pygame.init()
pygame.display.set_caption("2nd try")
#sets background
swidth = 360
sheight = 640
sky = pygame.image.load("sky.png")
screen = pygame.display.set_mode([swidth,sheight])
#This is a list of every sprite
all_sprites_list = pygame.sprite.Group()
#Sets thunder list and creates a new thunder cloud and postions it
tcloud_speed = 10
tc_repeat = 0
thunder_list = [0, 120, 240]
for i in range(1):
    tx = random.choice(thunder_list)
    tcloud = Sprite_maker("thundercloud.png")
    tcloud.rect.x = tx
    tcloud.rect.y = 0
    all_sprites_list.add(tcloud)
#Creates the gran sprite
gran = Sprite_maker("gran.png")
all_sprites_list.add(gran)
gran.rect.x = 120
gran.rect.y = 430
#Movement of gran sprite when left/right pressed
def gran_movement(movex):
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_LEFT and gran.rect.x == 0:
            gran.rect.x = 0
        elif event.key == pygame.K_RIGHT and gran.rect.x == 240:
            gran.rect.x = 240
        elif event.key == pygame.K_LEFT:#left key pressed player moves left 1
            gran.rect.x -= 120
        elif event.key == pygame.K_RIGHT:#right key pressed player moves left 1
            gran.rect.x += 120
    return movex
#Main program loop
game_start = True
while game_start == True:
    for event in pygame.event.get():
        tcloud.rect.y += tcloud_speed
        if event.type == pygame.QUIT: #If user clicked close
            game_start = False #Exits loop
        #Clear the screen and sets background
        screen.blit(sky, [0, 0])
        #Displays all the sprites
        all_sprites_list.draw(screen)
        pygame.display.flip()
        #Moves gran by accessing gran 
        gran_movement(gran.rect.x)
        #Moves cloud down screen
        if tc_repeat == 0:
            tcloud.rect.y = 0
            time.sleep(0.25)
            tc_repeat = 1
        else:
            tcloud.rect.y += tcloud_speed

pygame.quit()
实际上,我会创建一些pygame.sprite.sprite子类和sprite组,但由于您不熟悉它们,所以我只使用和pygame.Surfaces

因此,为玩家创建一个矩形,并为云创建一个矩形列表。矩形用作blit位置,图像/曲面在rect.topleft坐标处进行blit,并用于碰撞检测

要移动云,必须使用for循环在cloud_列表上迭代,并增加每个rect的y坐标。这将在while循环的每帧迭代中发生一次,由于clock.tick30,游戏将以每秒30帧的速度运行

事件循环中的玩家移动似乎与云移动同时发生

import random
import pygame


pygame.init()
# Some replacement images/surfaces.
PLAYER_IMG = pygame.Surface((38, 68))
PLAYER_IMG.fill(pygame.Color('dodgerblue1'))
CLOUD_IMG = pygame.Surface((38, 38))
CLOUD_IMG.fill(pygame.Color('gray70'))


def main():
    screen = pygame.display.set_mode((360, 640))
    clock = pygame.time.Clock()
    # You can create a rect with the `pygame.Surface.get_rect` method
    # and pass the desired coordinates directly as an argument.
    player_rect = PLAYER_IMG.get_rect(topleft=(120, 430))
    # Alternatively create pygame.Rect instances in this way.
    cloud_rect = pygame.Rect(120, 0, 38, 38)
    # The clouds are just pygame.Rects in a list.
    cloud_list = [cloud_rect]

    done = False

    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_d:
                    player_rect.x += 120
                elif event.key == pygame.K_a:
                    player_rect.x -= 120

        remaining_clouds = []

        for cloud_rect in cloud_list:
            # Move the cloud downwards.
            cloud_rect.y += 5

            # Collision detection with the player.
            if player_rect.colliderect(cloud_rect):
                print('Collision!')

            # To remove cloud rects that have left the
            # game area, append only the rects above 600 px
            # to the remaining_clouds list.
            if cloud_rect.top < 600:
                remaining_clouds.append(cloud_rect)
            else:
                # I append a new rect to the list when an old one
                # disappears.
                new_rect = pygame.Rect(random.choice((0, 120, 240)), 0, 38, 38)
                remaining_clouds.append(new_rect)

        # Assign the filtered list to the cloud_list variable.
        cloud_list = remaining_clouds

        screen.fill((30, 30, 30))
        # Blit the cloud image at the cloud rects.
        for cloud_rect in cloud_list:
            screen.blit(CLOUD_IMG, cloud_rect)
        screen.blit(PLAYER_IMG, player_rect)

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


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

请发布一个我们可以复制、运行和测试的文件。代码的结构非常奇怪,您不应该在事件循环中移动thunder sprite,而应该在while循环中移动。另外,您是否已经熟悉类、对象,或者您是否使用自定义sprite类型?我使用pygame_函数创建sprite并控制它们,这是预先制作的扩展模块,抱歉,我对pygame类和对象不是很熟悉。如果你需要一个好的教程,我认为最好在开始时使用纯pygame。在pygame_功能模块中有一些东西在我看来并不好,例如,当精灵移动、杀死精灵等情况发生时,屏幕会一直更新。。通常,每帧应该只有一个pygame.display.update调用。如果你愿意的话,我可以给你看一个纯pygame的例子。谢谢你,我会使用纯pygame,如果你不介意的话,我很想看一个纯pygame的例子谢谢你,我接受了你的建议,用纯pygame做的。我已经更新了问题中的代码