2013-02-13 61 views
2

所以我有这个迷你粒子效应,产生向上移动的圆圈。我想让它看起来像烟。虽然我遇到了很多问题。Pygame粒子效应

  1. 首先,我希望把它递归这样,当粒子到达顶部就 返回其原始点,并再次开始,我有什么工作一点,但不完全是。
  2. 另一件事是我不觉得它真的看起来像烟雾任何人都可以建议更改,使其看起来更好?
  3. 另外我想添加到我的游戏中,我将如何使这个可调用的游戏,所以我可以称为粒子,并给它一个位置,它出现在那里。任何人都可以帮忙吗?

我的代码

import pygame,random 
from pygame.locals import * 

xmax = 1000 #width of window 
ymax = 600  #height of window 

class Particle(): 
    def __init__(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 move(self): 
     if self.y >= 10: 
      if self.dy < 0: 
       self.dy = -self.dy 

     self.ry -= self.dy 
     self.y = int(self.ry + 0.5) 

     self.dy -= .1 
     if self.y < 1: 
      self.y += 500 

def main(): 
    pygame.init() 
    screen = pygame.display.set_mode((xmax,ymax)) 
    white = (255, 255, 255) 
    black = (0,0,0) 
    grey = (128,128,128) 

    particles = [] 
    for part in range(25): 
     if part % 2 > 0: col = black 
     else: col = grey 
     particles.append(Particle(random.randint(500, 530), random.randint(0, 500), 0, 0, 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), 8) 

     pygame.display.flip() 
    pygame.quit() 

if __name__ == "__main__": 
    main() 

回答

3

我已经取得了一些重大的修改你的代码。对于初学者来说,我会很好地清理你的课程。让我们从参数和__init__函数开始。

首先,粒子不是去往500重置,而是去设置为起点的位置。它开始的位置现在是在__init__函数中随机选择的,而不是在游戏中。我摆脱了一些不必要的争论。

在你的班级的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() 

更新

为了增加颗粒进入你的代码,只是做你的代码做了什么上面。它工作正常。如果你想做一些事情来显示烟雾开始的时间,只需将暂停时间放入你的论点中,并禁止烟雾的移动,直到经过这段时间。

class Particle(): 
    def __init__(self, startx, starty, col, pause): 
     self.x = startx 
     self.y = starty 
     self.col = col 
     self.sx = startx 
     self.sy = starty 
     self.pause = pause 

    def move(self): 
     if self.pause==0: 
      if self.y < 0: 
       self.x=self.sx 
       self.y=self.sy 

      else: 
       self.y-=1 

      self.x+=random.randint(-2, 2) 

     else: 
      self.pause-=1 

,您将需要创建新的粒子代码:在添加新的类

for part in range(1, A): 
    if part % 2 > 0: col = black 
    else: col = grey 
    particles.append(Particle(515, B, col, round(B*part/A))) 

A和B是变量(我建议约300对A,B将是Y值)

新的代码将使粒子在起始位置产生,并且连续上升而没有中断。希望你喜欢。

0

我已经对您的代码进行了很多更改,特别是在Particle类中。
虽然在这段代码中有些令人费解的事情,但它会比你当前的代码更加灵活。

这里,
我已经很文雅地改写了你的Particle类。
除了改变__init__,采取许多争论(7确切),
我用三角和math模块move颗粒,使其更易于管理(如果你的数学很好!)。我还将bouncedraw方法添加到Particle,并使代码更具可读性。
就像@PygameNerd,我添加了一个时钟,用于限制最大fps。 我没有改变任何事件处理,但在for p in particles:循环中使用了bouncedraw funcs。

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

在我看来,这看上去一点也不像烟。这有点像一大片烟雾,但是如果你把它放进一个带有火焰的程序中,它看起来并不像真正的烟雾;它只会看起来像一堆弹跳球。但是,您可以有自己的看法,对此我没有太多可以做的。 – PygameNerd 2013-02-14 22:50:07

+0

@PygameNerd是的,我同意你的意见,这是没有办法像烟。但是通过在一个方向上应用重力,(更新即将来临),我可以得到与你的结果非常相似的结果。顺便说一下,我的意见是什么意思?我没有详细阅读他的问题,但是要指出它的问题,我需要更改我的代码。 – pradyunsg 2013-02-15 05:28:27

+0

@PygameNerd是的,我明白了我完全错了,这不是解决他的问题的方法... – pradyunsg 2013-02-15 05:55:27