这个是给孩子们讲如何编写粒子程序时,用到的案例,不废话,上代码。
代码分三部分, 文末有动图可以看看程序的效果。
# firework.pyfrom particle import Particlefrom base import *import timeW,H = 1920,1080g= 0.1 # 重力balls = [] # 存放烟花粒子def Bang(n=100,pos = (W/2,H/4)): '''烟花爆炸''' for i in range(n): ball = Particle(pos,(4,4),(255,255,255),(0,0),(0,0),5) ball.color = ctx.hsv_to_rgb(random.randint(0,360),100,100) r = random.randint(2,12) ball.size = (r,r) ball.r = r speed = Vector2(random.random()*15,0).rotate(random.randint(0,360)) ball.vel = speed balls.append(ball)def setup(): size(W,H)last_time = 0 # 上次爆炸时间def draw(): global last_time for event in ctx.events: if event.type == KEYDOWN: if event.key == K_SPACE: pos = random.randint(50,W-100),random.randint(100,H/2) Bang(200,pos) if event.type == MOUSEBUTTONDOWN: Bang(200,event.pos) if time.time() - last_time > random.randint(30,100)/10: # 每隔一段时间爆炸一次(3 - 10秒) pos = random.randint(50,W-100),random.randint(100,H/2) Bang(random.randint(50,300),pos) last_time = time.time() ctx.screen.fill((0,0,0,100)) # 先清屏,alpha = 100 留残影 for ball in balls[:]: # 有删除操作,所以用 balls 的副本遍历 if not ball.alive: balls.remove(ball) else: ball.applyForce(Vector2(0,g)) ball.draw(ctx.screen)run()
particle.py 粒子程序的实现:
import pygamefrom pygame.math import Vector2import random,timeclass Particle(): def __init__(self,pos,size,color=(255,255,255),vel=(0,0),acc = (0,0),mass = 1): self.pos = Vector2(pos) self.size = size self.color = color self.vel = Vector2(vel) self.acc = Vector2(acc) self.r = size[0]/2 self.mass = mass self.borth_time = time.time() self.life = random.random()*10 self.alive = True def applyForce(self,force): f = force / self.mass self.acc += f def is_OutOfEdges(self,canvas): rect = canvas.get_rect() w,h = self.size if self.pos.x - w/2 >= rect.width: return True elif self.pos.x +w/2<= 0: return True if self.pos.y-h/2 >= rect.height: return True elif self.pos.y +h/2<= 0: return True def checkLife(self): if self.life <= time.time() - self.borth_time: self.alive = False def update(self): self.vel += self.acc self.pos += self.vel self.acc *= 0 self.checkLife() def draw(self,canvas): self.update() if not self.is_OutOfEdges(canvas): pygame.draw.circle(canvas,self.color,self.pos,self.r) else: self.alive = False
base.py 用来简单封装 pygame
# base.pyimport pygamefrom pygame.locals import *from pygame.math import Vector2import sys,random,math,oswidth,height = 1920,1080pygame.init()window = Nonepygame.display.set_caption('测试')clock = pygame.time.Clock()running = Trueclass real_contex(): def __init__(self): self.screen = None x,y = pygame.mouse.get_pos() self.mouseX = x self.mouseY = y self.fps = 60 def fill(self,color): self.window.fill(0) if self.screen is not None: self.screen.fill(color) def hsv_to_rgb(self,h,s,v,a=100): '''颜色转换''' c = pygame.Color(0,0,0,a) c.hsva = (h,s,v,a) return c def setup(self): pass def draw(self): passctx = real_contex()def size(w,h): global width,height,window width,height = w,h if w >= 1920 and h >= 1080: window = pygame.display.set_mode((0,0),FULLSCREEN) else: window = pygame.display.set_mode((width,height)) ctx.window = window ctx.screen = pygame.Surface((w,h), pygame.SRCALPHA) ctx.size = window.get_size() ctx.width = ctx.size[0] ctx.height = ctx.size[1] ctx.rect = window.get_rect() ctx.center = ctx.rect.centerdef run(): global running,window # 获取调用 run 函数的文件名 m_name = sys._getframe(1).f_code.co_filename f_name = os.path.basename(m_name) module_name = os.path.splitext(f_name)[0] # 通过文件名加载为模块,并动态获取 setup 和 draw 方法 app_module = __import__(module_name) m_dir = dir(app_module) if 'setup' in m_dir: ctx.setup = app_module.setup if 'draw' in m_dir: ctx.draw = app_module.draw del m_dir ctx.setup() if window is None: size(800,600) while running: ctx.events = pygame.event.get() ctx.mouseX,ctx.mouseY = pygame.mouse.get_pos() for evt in ctx.events: if evt.type == QUIT: pygame.quit() sys.exit() if evt.type == KEYDOWN: if evt.key == K_ESCAPE: pygame.quit() sys.exit() ctx.draw() window.blit(ctx.screen,(0,0)) pygame.display.update() clock.tick(ctx.fps)
只截了小部分屏,全屏好看
标签: ctx
②文章观点仅代表原作者本人不代表本站立场,并不完全代表本站赞同其观点和对其真实性负责。
③文章版权归原作者所有,部分转载文章仅为传播更多信息、受益服务用户之目的,如信息标记有误,请联系站长修正。
④本站一律禁止以任何方式发布或转载任何违法违规的相关信息,如发现本站上有涉嫌侵权/违规及任何不妥的内容,请第一时间反馈。发送邮件到 88667178@qq.com,经核实立即修正或删除。