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