2013-02-13 3 views
2

그래서 나는 위로 움직이는 원을 만들어내는이 미니 입자 효과를 가지고 있습니다. 연기처럼 보이게하고 싶습니다. 나는 많은 문제를 겪고있다.파이 게임 입자 효과

  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의 단순한 감소입니다. 내가 추가 한 변화는 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 

새로운 입자 생성해야합니다 코드 : 그 새로운 클래스가 추가 나는 A의 300을 권 해드립니다 (

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이다 변수를, B는 Y의 값이됩니다)

새 코드는 입자가 시작 위치에 스폰되게하고 중단없이 계속 상승합니다. 희망을 즐기세요.

0

나는 특히 Particle 클래스에서 코드를 많이 변경했다.
이 코드에는 수수께끼 같은 것들이 있지만 현재 코드보다 더 유연합니다.

여기에서
저는 문자 그대로 Particle 클래스를 다시 작성했습니다. __init__을 변경 이외의
이 많은 인수를 위해 (7 정확한 예정),
나는 쉽게 관리 할 수, 삼각법 및 movemath 모듈 입자를 사용했다 (당신이 수학을 잘하는 경우!). 또한 Particlebouncedraw 메서드를 추가하여 코드를보다 읽기 쉽게 만들었습니다.
@PygameNerd처럼 시계를 추가하여 최대 fps를 제한했습니다. 이벤트 처리를 변경하지 않았지만 for p in particles: 루프에 bouncedraw 기능을 사용했습니다.

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

+0

@PygameNerd 네, 동의합니다. 이것은 연기와 같은 방식은 아닙니다. 그러나 방향에 중력을 적용하여 (업데이트가 올라옴), 나는 당신과 비슷한 결과를 얻을 수 있습니다. 그건 그렇고, 내 의견으로는 무슨 뜻이야? 그의 질문을 자세히 읽지는 않았지만 그것을 지적하기 위해 코드를 변경해야합니다. – pradyunsg

+0

@PygameNerd 그래, 내가 완전히 틀렸어. 이건 그의 문제를 해결하는 방법이 아니야. – pradyunsg