Python Pygame粒子效应

Python Pygame粒子效应,python,recursion,pygame,effects,particles,Python,Recursion,Pygame,Effects,Particles,所以我有一个小粒子效应,它产生了向上移动的圆。我想让它看起来像烟一样。不过我有很多问题 首先,我想让它递归,这样当粒子到达顶部时 回到原来的位置,重新开始,我所做的有点效果,但不完全有效 另一件事是我不觉得它看起来真的像烟雾谁能建议改变,使它看起来更好 我还想把它添加到我的游戏中,我如何使它在我的游戏中可调用,这样我就可以调用粒子并给它一个位置,它就会出现在那里。有人能帮忙吗 我的代码 导入pygame,随机 从pygame.locals导入* xmax=1000#窗宽 ymax=600#窗高

所以我有一个小粒子效应,它产生了向上移动的圆。我想让它看起来像烟一样。不过我有很多问题

  • 首先,我想让它递归,这样当粒子到达顶部时 回到原来的位置,重新开始,我所做的有点效果,但不完全有效
  • 另一件事是我不觉得它看起来真的像烟雾谁能建议改变,使它看起来更好
  • 我还想把它添加到我的游戏中,我如何使它在我的游戏中可调用,这样我就可以调用粒子并给它一个位置,它就会出现在那里。有人能帮忙吗
  • 我的代码

    导入pygame,随机
    从pygame.locals导入*
    xmax=1000#窗宽
    ymax=600#窗高
    类粒子():
    定义初始值(self,x,y,dx,dy,col):
    self.x=x
    self.y=y
    self.col=col
    self.ry=y
    self.rx=x
    self.dx=dx
    self.dy=dy
    def移动(自我):
    如果self.y>=10:
    如果self.dy<0:
    self.dy=-self.dy
    self.ry-=self.dy
    self.y=int(self.ry+0.5)
    self.dy-=.1
    如果self.y<1:
    自身y+=500
    def main():
    pygame.init()
    screen=pygame.display.set_模式((xmax,ymax))
    白色=(255,255,255)
    黑色=(0,0,0)
    灰色=(128128)
    粒子=[]
    对于范围内的零件(25):
    如果零件%2>0:col=黑色
    其他:颜色=灰色
    particles.append(Particle(random.randint(500530)、random.randint(0500)、0、0、col))
    exitflag=False
    虽然没有退出:
    对于pygame.event.get()中的事件:
    如果event.type==退出:
    exitflag=True
    elif event.type==KEYDOWN:
    如果event.key==K_转义:
    exitflag=True
    屏幕填充(白色)
    对于颗粒中的p:
    p、 移动()
    pygame.draw.circle(屏幕,p.col,(p.x,p.y),8)
    pygame.display.flip()
    pygame.quit()
    如果名称=“\uuuuu main\uuuuuuuu”:
    main()
    
    我对您的代码进行了一些主要编辑。首先,我把你们班上的学生都打扫干净了。让我们从参数和
    \uuuu init\uuu
    函数开始

    首先,粒子不是向下移动500以重置,而是移动到设置为起点的位置。它的起始位置现在是在
    \uuuu init\uuuu
    函数中随机选择的,而不是在游戏中。我也摆脱了你一些不必要的争论

    在你的类的
    move
    函数中,我简化了很多。为了让粒子检测它是否应该重置,它只需查看它是否高于0。上升只是简单地将y减少1。我添加的一个变化是x随机变化并向左和向右移动。这将使烟雾看起来更好/更逼真

    我没有对代码的其余部分做太多更改。我更改了您对
    Particle
    类的调用,以适应新的参数。我制造了更多的粒子,再一次为了视觉效果。我还大幅减小了为(你猜得到吗?)视觉效果绘制的圆圈的大小。我还加了一个时钟,以防止粒子以超音速运动

    这是最后的代码。我希望你喜欢

    import pygame,random
    from pygame.locals import *
    
    xmax = 1000    #width of window
    ymax = 600     #height of window
    
    class Particle():
        def __init__(self, startx, starty, col):
            self.x = startx
            self.y = random.randint(0, starty)
            self.col = col
            self.sx = startx
            self.sy = starty
    
        def move(self):
            if self.y < 0:
                self.x=self.sx
                self.y=self.sy
    
            else:
                self.y-=1
    
            self.x+=random.randint(-2, 2)
    
    def main():
        pygame.init()
        screen = pygame.display.set_mode((xmax,ymax))
        white = (255, 255, 255)
        black = (0,0,0)
        grey = (128,128,128)
    
        clock=pygame.time.Clock()
    
        particles = []
        for part in range(300):
            if part % 2 > 0: col = black
            else: col = grey
            particles.append( Particle(515, 500, col) )
    
        exitflag = False
        while not exitflag:
            for event in pygame.event.get():
                if event.type == QUIT:
                    exitflag = True
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        exitflag = True
    
            screen.fill(white)
            for p in particles:
                p.move()
                pygame.draw.circle(screen, p.col, (p.x, p.y), 2)
    
            pygame.display.flip()
            clock.tick(50)
        pygame.quit()
    
    if __name__ == "__main__":
        main()
    
    A和B是变量(我建议A大约300,B将是Y值)


    新代码将使粒子在起始位置繁殖,并持续上升而不间断。希望您喜欢。

    我对您的代码做了很多更改,特别是在
    粒子
    类中。
    尽管这段代码中有一些令人费解的地方,但它比您当前的代码更加灵活

    这里,
    我已经相当熟练地改写了你的
    Particle
    class.
    除了更改
    \uuuuu init\uuuuuu
    以获取许多参数(准确地说是7个参数),
    我使用了三角学和
    数学
    模块来
    移动
    粒子,使其更易于管理(如果你擅长数学!)。我还向
    粒子
    添加了
    反弹
    绘制
    方法,使代码更具可读性。
    就像,我添加了一个时钟,用于限制最大fps。 我没有更改任何事件处理,但是在粒子中的p的
    循环中使用了
    反弹
    绘制
    函数

    import pygame, random, math
    
    def radians(degrees):
        return degrees*math.pi/180
    
    class Particle:
        def __init__(self, (x, y), radius, speed, angle, colour, surface):
            self.x = x
            self.y = y
            self.speed = speed
            self.angle = angle
            self.radius = 3
            self.surface = surface
            self.colour = colour
            self.rect = pygame.draw.circle(surface,(255,255,0),
                               (int(round(x,0)),
                                int(round(y,0))),
                               self.radius)
        def move(self):
            """ Update speed and position based on speed, angle """
            # for constant change in position values.
            self.x += math.sin(self.angle) * self.speed
            self.y -= math.cos(self.angle) * self.speed
            # pygame.rect likes int arguments for x and y
            self.rect.x = int(round(self.x))
            self.rect.y = int(round(self.y))
    
        def draw(self):
            """ Draw the particle on screen"""
            pygame.draw.circle(self.surface,self.colour,self.rect.center,self.radius)
    
        def bounce(self):
            """ Tests whether a particle has hit the boundary of the environment """
    
            if self.x > self.surface.get_width() - self.radius: # right
                self.x = 2*(self.surface.get_width() - self.radius) - self.x
                self.angle = - self.angle
    
            elif self.x < self.radius: # left
                self.x = 2*self.radius - self.x
                self.angle = - self.angle            
    
            if self.y > self.surface.get_height() - self.radius: # bottom
                self.y = 2*(self.surface.get_height() - self.radius) - self.y
                self.angle = math.pi - self.angle
    
            elif self.y < self.radius: # top
                self.y = 2*self.radius - self.y
                self.angle = math.pi - self.angle
    
    def main():
        xmax = 640    #width of window
        ymax = 480     #height of window
        white = (255, 255, 255)
        black = (0,0,0)
        grey = (128,128,128)
    
        pygame.init()
        screen = pygame.display.set_mode((xmax,ymax))
        clock = pygame.time.Clock()
    
        particles = []
    
        for i in range(1000):
            if i % 2:
                colour = black
            else:
                colour = grey
            # for readability
            x = random.randint(0, xmax)
            y = random.randint(0, ymax)
            speed = random.randint(0,20)*0.1
            angle = random.randint(0,360)
            radius = 3
            particles.append( Particle((x, y), radius, speed, angle, colour, screen) )
    
        done = False
        while not done:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done = True
                    break
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        done = True
                        break
            if done:
                break
    
            screen.fill(white)
            for p in particles:
                p.move()
                p.bounce()
                p.draw()
    
            clock.tick(40)
    
            pygame.display.flip()
        pygame.quit()
    
    if __name__ == "__main__":
        main()
    
    导入pygame、random、math
    def弧度(度):
    返回度*math.pi/180
    类粒子:
    定义初始(自,(x,y),半径,速度,角度,颜色,表面):
    self.x=x
    self.y=y
    自身速度=速度
    自我角度=角度
    自半径=3
    self.surface=曲面
    颜色
    self.rect=pygame.draw.circle(曲面,(255255,0),
    (整数(圆形(x,0)),
    整数(圆形(y,0)),
    自身半径)
    def移动(自我):
    “”“根据速度、角度更新速度和位置”“”
    #用于位置值的恒定变化。
    self.x+=数学sin(self.angle)*self.speed
    self.y-=数学cos(self.angle)*self.speed
    #pygame.rect喜欢x和y的int参数
    self.rect.x=int(舍入(self.x))
    self.rect.y=int(舍入(self.y))
    def牵引(自):
    “”“在屏幕上绘制粒子”“”
    pygame.draw.circle(自表面、自颜色、自直线中心、自半径)
    def反弹(自我):
    “”“测试粒子是否已到达环境的边界”“”
    如果self.x>self.surface.get_width()-self.radius:#正确
    self.x=2*(self.surface.get_width()-self.radius)-self.x
    self.angle=-self.angle
    elif self.xfor part in range(1, A):
        if part % 2 > 0: col = black
        else: col = grey
        particles.append( Particle(515, B, col, round(B*part/A)) )
    
    import pygame, random, math
    
    def radians(degrees):
        return degrees*math.pi/180
    
    class Particle:
        def __init__(self, (x, y), radius, speed, angle, colour, surface):
            self.x = x
            self.y = y
            self.speed = speed
            self.angle = angle
            self.radius = 3
            self.surface = surface
            self.colour = colour
            self.rect = pygame.draw.circle(surface,(255,255,0),
                               (int(round(x,0)),
                                int(round(y,0))),
                               self.radius)
        def move(self):
            """ Update speed and position based on speed, angle """
            # for constant change in position values.
            self.x += math.sin(self.angle) * self.speed
            self.y -= math.cos(self.angle) * self.speed
            # pygame.rect likes int arguments for x and y
            self.rect.x = int(round(self.x))
            self.rect.y = int(round(self.y))
    
        def draw(self):
            """ Draw the particle on screen"""
            pygame.draw.circle(self.surface,self.colour,self.rect.center,self.radius)
    
        def bounce(self):
            """ Tests whether a particle has hit the boundary of the environment """
    
            if self.x > self.surface.get_width() - self.radius: # right
                self.x = 2*(self.surface.get_width() - self.radius) - self.x
                self.angle = - self.angle
    
            elif self.x < self.radius: # left
                self.x = 2*self.radius - self.x
                self.angle = - self.angle            
    
            if self.y > self.surface.get_height() - self.radius: # bottom
                self.y = 2*(self.surface.get_height() - self.radius) - self.y
                self.angle = math.pi - self.angle
    
            elif self.y < self.radius: # top
                self.y = 2*self.radius - self.y
                self.angle = math.pi - self.angle
    
    def main():
        xmax = 640    #width of window
        ymax = 480     #height of window
        white = (255, 255, 255)
        black = (0,0,0)
        grey = (128,128,128)
    
        pygame.init()
        screen = pygame.display.set_mode((xmax,ymax))
        clock = pygame.time.Clock()
    
        particles = []
    
        for i in range(1000):
            if i % 2:
                colour = black
            else:
                colour = grey
            # for readability
            x = random.randint(0, xmax)
            y = random.randint(0, ymax)
            speed = random.randint(0,20)*0.1
            angle = random.randint(0,360)
            radius = 3
            particles.append( Particle((x, y), radius, speed, angle, colour, screen) )
    
        done = False
        while not done:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done = True
                    break
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        done = True
                        break
            if done:
                break
    
            screen.fill(white)
            for p in particles:
                p.move()
                p.bounce()
                p.draw()
    
            clock.tick(40)
    
            pygame.display.flip()
        pygame.quit()
    
    if __name__ == "__main__":
        main()