2013-02-13 78 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