你是否也想做出下图这么漂亮的动态效果?想的话就跟着我一起做吧=.=
工具:
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)