首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >吡咯持续降雨

吡咯持续降雨
EN

Stack Overflow用户
提问于 2019-12-15 14:17:36
回答 1查看 414关注 0票数 1

更新12/16

这些代码得到了正确的效果,但我不知道在新条目new_rainnew_rain.y中没有row,我从Group rains中删除了rain,所以为什么当我将new_rain添加到rains中时,仍然有行,因为我只设置了new_rain.y = 0

代码语言:javascript
复制
def check_edge(setting,rains):
        for rain in rains.sprites():
            if rain.rect.y == setting.h:
                new_rain=Rain()
                new_rain.number=rain.number
                new_rain.row=rain.row
                new_rain.rect.x=new_rain.rect.x+rain.rect.width*new_rain.number
                new_rain.y = 0
                new_rain.rect.y=new_rain.y
                rains.add(new_rain)
                rains.remove(rain)

我正在做13-4的连续雨练习,我的想法是检查每一场雨的位置,首先我创建一个名为Grouprains将所有的项目添加到它中,然后在屏幕上blit它。

我还将数字和行存储到Group rains中,因为我可以为其他方法调用它

代码语言:javascript
复制
def create(self,setting,rains):
    spacex=setting.w-2*self.rect.x
    numbers=int(spacex/(2*self.rect.x))
    rows=int(setting.h/(4*self.rect.height))
    for row in range(rows):
        for number in range(numbers):
            rain=Rain()
            rain.number=number
            rain.row=row
            rain.rect.x =rain.rect.x+rain.rect.width*number
            rain.y = rain.rect.y+2*rain.rect.height*row
            rain.rect.y =rain.y
            rains.add(rain)

然后我检查位置,如果rains中的任何项目触及底部,移除该项目,并在其中添加新的项目,即连续下雨

代码语言:javascript
复制
def check_edge(self,setting,rains):
        for rain in rains.sprites():
            if rain.rect.y == setting.h:
                new_rain=Rain()
                new_rain.rect.x=new_rain.rect.x+rain.rect.width*rain.number
                new_rain.y =new_rain.rect.y+2*rain.rect.height*rain.row
                new_rain.rect.y=new_rain.y
                rains.remove(rain)
                rains.add(new_rain) 

我在屏幕上有2行10列,但是当我运行这个脚本时,第一个和第二个循环是正确的,雨真的消失了,然后在屏幕上创建新的。

第三个循环显示一个错误AttributeError: 'Rain' object has no attribute 'number',我多次尝试,但找不到原因,因为我已经在Group中定义了numberrow

这是密码:

代码语言:javascript
复制
#!/usr/bin/python
import sys
import pygame as p
from random import randint

#13-4

class Setting():
    def __init__(self,width,height):
        self.w=width
        self.h=height
        self.screen=p.display.set_mode((self.w,self.h),p.RESIZABLE,0)
        self.speed = 1
        p.display.set_caption("EXE 13-4")

class Rain(p.sprite.Sprite):
    def __init__(self):
        super().__init__()
        pic=p.image.load("../image/rain.jpg").convert_alpha()
        self.image=p.transform.smoothscale(pic,(100,100)).convert_alpha()
        self.rect=self.image.get_rect()
        self.rect.x=(self.rect.width)/2
        self.y=float(self.rect.y)
    def create(self,setting,rains):
        spacex=setting.w-2*self.rect.x
        numbers=int(spacex/(2*self.rect.x))
        rows=int(setting.h/(4*self.rect.height))
        for row in range(rows):
            for number in range(numbers):
                rain=Rain()
                rain.number=number
                rain.row=row
                rain.rect.x =rain.rect.x+rain.rect.width*number
                rain.y = rain.rect.y+2*rain.rect.height*row
                rain.rect.y =rain.y
                rains.add(rain)
        print(spacex)
        print(numbers)
    def check_edge(self,setting,rains):
        for rain in rains.sprites():
            if rain.rect.y == setting.h:
                new_rain=Rain()
                new_rain.rect.x=new_rain.rect.x+rain.rect.width*rain.number
                new_rain.y =new_rain.rect.y+2*rain.rect.height*rain.row
                new_rain.rect.y=new_rain.y
                rains.remove(rain)
                rains.add(new_rain)



    def update(self,setting):
        self.y += setting.speed
        self.rect.y= self.y
    def blit(setting,rains):
        rains.update(setting)
        rains.draw(setting.screen)


def game():
    p.init()
    setting=Setting(1200,800)
    rain=Rain()
    rains=p.sprite.Group()
    rain.create(setting,rains)
    while True:
        for event in p.event.get():
            if event.type == p.QUIT:
                sys.exit()
            elif event.type == p.KEYDOWN:
                if event.key == p.K_ESCAPE:
                    sys.exit()
        setting.screen.fill((0,0,255))

        rain.check_edge(setting,rains)
        Rain.blit(setting,rains)
        p.display.flip()
game()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-15 14:38:37

主要的问题是new_rain从未获得属性.row.number。将属性.number.rowrain复制到new_rain

代码语言:javascript
复制
new_rain=Rain()
new_rain.number = rain.number
new_rain.row = rain.row

把一滴雨滴从回路中移除,把一滴新雨滴放进回路是完全多余的。改变雨滴的坐标就足够了。当雨滴到达地面时,将雨滴移至窗口顶部:

代码语言:javascript
复制
class Rain(p.sprite.Sprite):
    # [...]

    def check_edge(self,setting,rains):
        for rain in rains.sprites():
            if rain.rect.y == setting.h:
                # put the drop at the top of the window
                rain.y = 0
                rain.rect.y = 0

如果您真的想创建全新的雨滴,无论出于什么原因,您都必须将属性.numberrain复制到new_rain。新雨滴的位置总是在0,在窗口的顶部:

代码语言:javascript
复制
class Rain(p.sprite.Sprite):
    # [...]

    def check_edge(self,setting,rains):
        for rain in rains.sprites():
            if rain.rect.y == setting.h:

                new_rain=Rain()
                new_rain.number = rain.number

                new_rain.rect.x=new_rain.rect.x+rain.rect.width*new_rain.number
                new_rain.y = 0
                new_rain.rect.y=new_rain.y

                rain.kill() # or rains.remove(rain)
                rains.add(new_rain) 

对于初始位置,雨滴的行很重要,因为雨滴必须排列在不同的行中。雨滴的y坐标取决于行。

但是,当雨滴开始下降时,第一行对雨滴的y坐标就不再有意义了。雨滴放在哪里是完全不相关的。窗口顶部的y坐标为0,如果雨滴从顶部开始下降,则其y坐标必须设置为0。

注意,如果创建了一个新的雨滴,那么在最上面的一行中,没有任何雨滴,因为它们已经落下。最上面的一排是空的,新的雨滴必须放在那里。

根本不需要属性.row,可以删除该属性。当create创建雨滴时,该行在应用程序开始时只有一个意义。在那之后,雨滴正在落下,并不断地改变着“行”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59344763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档