zoukankan      html  css  js  c++  java
  • 粒子动画——Pygame

    你是否也想做出下图这么漂亮的动态效果?想的话就跟着我一起做吧=.=

     

    工具:

              Python——Pygame

    仔细观察上图,你能发现哪些机制呢?再在下面对比一下是否跟你想的一样。

    运行机制:

                1、随机方向,随机速度,随机初始位置的点,在屏幕上面运动,撞到屏幕边缘会"反向”

                2、点与点之间,距离在某一个值内会产生线段,且线段的颜色深浅跟距离有关

                3、鼠标也能产生2的效果,说明鼠标也是一个点,只不过这个点看不见

                4、看似鼠标能把点给拉动,其实是下面的两个机制组合的效果:

                             (1)、在鼠标周围某一个环形区域内,锁定点到鼠标之间的距离,也就是说,点在这个环形区域内点是不能动的

                             (2)、在另一个比较大的环形区域内,点的速度被加快,并且点的方向改为朝着鼠标移动 

    知道上面的机制,我们就可以开始动手实现了。

    流程:

    点类:

      这个效果是以点为基础的,所以我们可以先描述一下点的特性:

                说到点的特性,肯定有横纵坐标、大小对吧 (其实谈到点的大小,你们可能就清楚了,这里的点,其实是很小的圆),而我们这里的点,不仅仅如此,它还能动,所以它应该具有“”这个方法,对于运动的点,你又该怎么去描述呢?运动肯定就得有方向速度(这里不考虑加速度),方向又该怎么去描述呢?你可以用坐标去描述方向,但这里我不推荐,因为后面方向要经常变换,用坐标不方便,所以这里用运动方向与x轴顺时针的角度(弧度制)作为点的方向,而这些只是数据处理层面,还没有显示真正的点。所以还应该有“显示点”这个方法

    综上

         点:

                属性:坐标、方向(弧度)、大小

                方法:运动(根据方向),显示

    import pygame as py
    import math
    import random
    py.init()
    mysize = width,height=800,600
    screen = py.display.set_mode(mysize)
    fullscreen=False                                                      #全屏开关
    py.display.set_caption("游戏测试")
    class Point:
        speed=0
        upspeed=1;
        direction=0
        position=[0,0]
        size=1
        def __init__(self,position,speed,direction,size):
            self.position=position
            self.speed=speed
            self.direction=direction
            self.size=size
            return              #坐标,速度,方向,点大小
        def run(self,):
            if(self.position[0]<=0 or self.position[0]>=width):
                self.direction=-self.direction+math.pi
            if(self.position[1]<=0 or self.position[1]>=height):
                self.direction=-self.direction
            if(self.distance(py.mouse.get_pos())>130 and self.distance(py.mouse.get_pos())<200):
                y=(py.mouse.get_pos()[1]-self.position[1])
                x=(py.mouse.get_pos()[0]-self.position[0])
                if x!=0:
                    self.mouse_direction=math.atan2(y,x)
                self.upspeed=3
                x=self.upspeed*self.speed*math.cos(self.mouse_direction)
                y=self.upspeed*self.speed*math.sin(self.mouse_direction)
                if x!=0 and (self.distance(py.mouse.get_pos())<110 or self.distance(py.mouse.get_pos())>130):
                    self.position[0]+=x/abs(x)*math.ceil(abs(x))
                if y!=0 and (self.distance(py.mouse.get_pos())<110 or self.distance(py.mouse.get_pos())>130):
                    self.position[1]+=y/abs(y)*math.ceil(abs(y))                       
            else :
                self.upspeed=1
                x=self.upspeed*self.speed*math.cos(self.direction)
                y=self.upspeed*self.speed*math.sin(self.direction)
                if x!=0 and (self.distance(py.mouse.get_pos())<110 or self.distance(py.mouse.get_pos())>130):
                    self.position[0]+=x/abs(x)*math.ceil(abs(x))
                if y!=0 and (self.distance(py.mouse.get_pos())<110 or self.distance(py.mouse.get_pos())>130):
                    self.position[1]+=y/abs(y)*math.ceil(abs(y))                                                 #运动
        def show(self):
            self.position=[int(i+0.5) for i in self.position]
            py.draw.circle(screen,(44,67,116),self.position,self.size)                                                #图像变动
        def distance(self,other):                                          #求点距
            return math.sqrt((self.position[0]-other[0])**2+(self.position[1]-other[1])**2)
    class Graph:
        pointlist=[]                                                       #点列表
        def __init__(self,number):
            self.pointlist.append(Point([0,0],0,0,0))
            for i in range(number):
                self.pointlist.append(Point([random.randint(1,width),random.randint(1,height)],random.randint(1,3),i/number*2*math.pi,3))                                     #根据number创建点个数
        def run(self):
            for it in self.pointlist:
                it.run()                                                  #运动
        def show(self):
            for it in self.pointlist:
                it.show()
            self.line()                                                 #图像变动
        def line(self):                                                    #画线
            color=[0,0,0]
            self.pointlist[0].position=py.mouse.get_pos()
            for i in self.pointlist:
                for j in self.pointlist:
                    s=i.distance(j.position)
                    if s<150:
                        color=[int(s*1.6),int(80+s),int(180+s*0.5)]
                        py.draw.aaline(screen,color,i.position,j.position,5)
                        
    mygraph=Graph(40)                                #画线
    while True:
        screen.fill((255,255,255))
        for each in py.event.get():
            if each.type==py.KEYDOWN:
                if each.key==py.K_F11:
                    fullscreen=not fullscreen
                    if fullscreen:
                        mysize=width,height=1920,1080
                        screen = py.display.set_mode((1920,1080),py.FULLSCREEN|py.HWSURFACE)               
                    else:
                        mysize = width,height=800,600
                        screen = py.display.set_mode(mysize)
                        
        mygraph.run()
        mygraph.show()
        py.display.flip()
        py.time.Clock().tick(150)
    
    
    
  • 相关阅读:
    [原创]桓泽学音频编解码(13):AC3 位分配模块算法分析
    白话红黑树系列之一——初识红黑树
    白话红黑树系列之二——红黑树的构建
    数据驱动编程之表驱动法
    每周一算法之六——KMP字符串匹配算法
    HDOJ 1098 Ignatius's puzzle
    HDOJ 1097 A hard puzzle(循环问题)
    HDOJ 1019 Least Common Multiple(最小公倍数问题)
    辗转相除法_欧几里得算法_java的实现(求最大公约数)
    HDOJ 1020 Encoding
  • 原文地址:https://www.cnblogs.com/F-itachi/p/9974321.html
Copyright © 2011-2022 走看看