矩形故障,其余部分不移动

问题描述

import pygame
import sys
from pygame.sprite import Sprite
class Settings:
    def __init__(self):
        self.raindrop_speed = 3
        self.raindrop_direction = -1
        self.raindrop_dropseed = 3
        self.backgroundcolor = (30,30,30)
class Drop(Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("raindrop.png")
        self.rect = self.image.get_rect()
        self.rect.y = self.rect.height
        self.rect.x = self.rect.width
        self.x_cord = self.rect.x
        self.y_cord = self.rect.y

class RainDrop:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((1200,800))
        self.settings = Settings()
        self.backgroundcolor = self.settings.backgroundcolor
        self.raindrops = pygame.sprite.Group()
        self.screen_rect = self.screen.get_rect()
        self._add_raindrops()
    def _add_raindrops(self):
        new_raindrop = Drop()
        drop_height = new_raindrop.rect.height 
        drop_width = new_raindrop.rect.width
        print(drop_width)
        screen_space = self.screen_rect.width
        screen_height_space = self.screen_rect.height
        aviable_row_space = screen_height_space//(drop_height*2)
        avivable_screen_space = screen_space - (drop_width*2)
        amount_of_columns = avivable_screen_space//(drop_width*2)
        self._add_columns(amount_of_columns,aviable_row_space)
        
    def _add_columns(self,amount_of_columns,aviable_row_space):
        for height_of_drops in range(aviable_row_space):
            for number_of_drops in range(amount_of_columns):
                drop = Drop()
                drop.x_cord = (drop.rect.width *2)* number_of_drops
                drop.y_cord =(drop.rect.height *2)* height_of_drops
                drop.rect.x = drop.x_cord
                drop.rect.y = drop.y_cord
                self.raindrops.add(drop)
    def _bring_down_raindrops(self):
        for drop in self.raindrops:
            drop.y_cord += self.settings.raindrop_dropseed
            drop.rect.y = drop.y_cord
    def _update_drops(self):
        height_counter = 1
        self.raindrops.update()
        for drop in self.raindrops.copy():
            drop.x_cord += self.settings.raindrop_direction * self.settings.raindrop_speed  
            drop.rect.x = drop.x_cord
            if drop.rect.right >= self.screen_rect.right:
                self.settings.raindrop_direction = -1
                self._bring_down_raindrops()
            elif drop.rect.left <= 0:
                self.settings.raindrop_direction = 1
                self._bring_down_raindrops()
            #if drop.rect.y >= self.screen_rect.height or drop.rect.y <= 0:
            #    drop.rect.x = drop.rect.width
             #   drop.y_cord = drop.rect.height 
              #  drop.rect.y = drop.y_cord
        print(height_counter)
        print(self.raindrops)
    
    def _update_game(self):
        self.screen.fill(self.backgroundcolor)
        self.raindrops.draw(self.screen)
        pygame.display.flip()
    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    sys.exit()
    def run_game(self):
        while True:
            self._check_events()
            self._update_drops()
            self._update_game()

if __name__ == "__main__":
    rd = RainDrop()
    rd.run_game()

每次我运行这个程序时,矩形(水滴)到达屏幕末端时会出现一个更大的间隙条件在底部,但我不确定我是否弄乱了它并更改了一些值,但它仍然做同样的事情。

解决方法

你的问题在于当你意识到你已经撞到屏幕边缘时你做了什么。当您发现屏幕上有任何掉落时,您会执行此操作,然后您反转方向。问题是,您已经将顶行上的一些水滴向一个方向移动,但是在您识别出屏幕边缘后,您继续在同一次传递中向相反方向移动其余水滴.事情就是这样结束的。

您想要做的是注意您已经击中了屏幕的边缘,但不会立即做任何不同的事情,以便您仍然以相同的方式处理屏幕上的所有掉落。画完所有的水滴后,您就可以改变方向了。

这是一个 _update_drops 版本,可以执行此操作:

def _update_drops(self):
    height_counter = 1
    self.raindrops.update()
    # assume we haven't hit either edge of the screen
    reverse = 0
    for drop in self.raindrops.copy():
        drop.x_cord += self.settings.raindrop_direction * self.settings.raindrop_speed
        drop.rect.x = drop.x_cord
        if drop.rect.right >= self.screen_rect.right:
            # remember that we hit the right edge of the screen
            reverse = -1
        elif drop.rect.left <= 0:
            # remember that we hit the left edge of the screen
            reverse = 1

    # if we hit one of the edges,change directions and drop down
    if reverse != 0:
        self.settings.raindrop_direction = reverse
        self._bring_down_raindrops()