这是一个我用来教我7岁小俊马的雨点例程,2022年网络上已经宣传未来小学生都将会python了,那么我们这些爸爸还不赶快学吗?
说句实话我本意是觉得小孩子就是先学好数理化就行了,编程这事有了数理逻辑思维长大之后自然就很快学会了,但是挡不住历史洪流,顺之者昌,我们也只能先顺应了。我们这一辈是快20岁从C、C++学起的,无奈C和C++还是太抽象,库也没有那么多,对7岁的孩子来说一点吸引力都没有,孩子们都喜欢形象和好玩。python横空出世,就让下一辈从面向对象的python游戏开始吧。
这个动画程序主要就是用了pygame这个第三方库,仅用了画线段line和椭圆ellipse两个绘图函数就实现了模拟下雨的动画,最简单基础的雨点类向小朋友形象的说明类的概念。
import pygame, sys, random, math, pygame.locals
import win32api, win32con
import pygame_menu
class raindrop(): #定义一个雨点类,雨点有位置、重量、颜色、是否落到水面、是否存在、绘制线宽等属性
raindrop_max_radius = 15 # 雨滴落到水面后产生涟漪的初始最大圆的默认半径
color_R = 0 #雨滴颜色的默认红色分量
color_G = 255 #雨滴颜色的默认绿色分量
color_B = 255 #雨滴颜色的默认蓝色分量
def __init__(self,screen_width,screen_heght,raindrop_weight): #雨点初始化构造函数
self.raindrop_x = random.choice(range(screen_width)) #雨点落到水面时在窗口中x坐标#随机生成雨点落到水面时在窗口中x坐标,0到窗口最大值
self.raindrop_y = random.choice(range(int(screen_heght/2),screen_heght))#雨点落到水面时在窗口中y坐标#随机生成雨点落到水面时在窗口中y坐标,窗口最大值的一半到窗口最大值,即雨点只落在屏幕的下半屏
self.raindrop_weight=random.choice(range(1,raindrop_weight)) #随机生成雨滴的重量,默认1-8,可在初始化时由调用函数传入
self.raindrop_radius=random.choice(range(1,self.raindrop_max_radius)) #随机生成涟漪的初始最小圆的半径,默认1-5
self.line_width = 1 #绘制雨滴只有线段和椭圆,定义绘制的默认线宽,雨滴比涟漪宽一个像素
# self.color_R = random.choice(range(255)) #随机生成雨滴颜色的红色分量
# self.color_G = random.choice(range(255)) #随机生成雨滴颜色的绿色分量
# self.color_B = random.choice(range(255)) #随机生成雨滴颜色的蓝色分量
self.raindrop_move_x = self.raindrop_x #雨滴下落过程中的x坐标就是前面随机生成的滴落点x坐标
self.raindrop_move_y = 2 #雨滴下落过程中的y坐标初始为2,滴落运行过程中会增大,但不会大于滴落点的y坐标self.raindrop_y
self.raindrop_move_x_dev = 0 # 雨滴下落过程中的x坐标的移动增量
self.raindrop_move_y_dev = 0 # 雨滴下落过程中的y坐标的移动增量
self.raindrop_move_y_dev = random.choice(range(10, 60)) #随机生成雨滴下落的移动速度,这样雨滴就不会整齐划一的落下了
self.rain_transparency = random.choice((255,230,205,180,155)) #定义雨点滴落过程中的透明度
self.raindrop_transparency = 255 #定义雨点滴落后产生涟漪的透明度
self.raindrop_dripped = False #雨滴构造时都是没有滴落到水面的
self.raindrop_over = True # 雨滴是否存在bool变量
def get_x(self):
return self.raindrop_x
def get_y(self):
return self.raindrop_y
def get_weight(self):
return self.raindrop_weight
def get_radius(self):
return self.raindrop_radius
def get_over(self):
return self.raindrop_over
def transparency_Diminishing(self): #涟漪透明度逐渐低减函数
if self.raindrop_transparency>5:
self.raindrop_transparency=self.raindrop_transparency-4
return self.raindrop_transparency
def weight_Diminishing(self): #雨滴重量递减函数
if self.raindrop_weight>0 :
self.raindrop_weight=self.raindrop_weight-1
return self.raindrop_weight
def radius_Increasing(self): #涟漪绘制半径递增函数
if self.raindrop_radius<=30*self.raindrop_weight: #涟漪的最大半径为雨滴重量的20倍
self.raindrop_radius=self.raindrop_radius+2
else:
self.raindrop_over = False #涟漪一旦超过最大半径,则标识雨滴为不存在
return self.raindrop_radius
def move_Increasing(self): #雨滴滴落移动位置递增函数,只定义了y坐标的移动
if (self.raindrop_move_y + self.raindrop_move_y_dev) < self.raindrop_y :
self.raindrop_move_y = self.raindrop_move_y + self.raindrop_move_y_dev
else:
self.raindrop_dripped = True #一旦雨滴滴落到水面就将雨滴标识为“已滴落”
def draw_raindrop(self,raindrop_screen,color=(0, 255, 0,255),line_width=1):
#################################开始####绘制雨滴下落代码####开始#######################################
if self.raindrop_dripped==False:
pygame.draw.line(raindrop_screen,(self.color_R, self.color_G, self.color_B, self.rain_transparency),(self.raindrop_move_x,self.raindrop_move_y),
(self.raindrop_move_x,self.raindrop_move_y+self.raindrop_weight),self.line_width+1)
self.move_Increasing()
#################################结束####绘制雨滴下落代码####结束#######################################
#################################开始####绘制椭圆形雨滴涟漪代码####开始#######################################
if self.raindrop_dripped == True:
pygame.draw.ellipse(raindrop_screen, (self.color_R, self.color_G, self.color_B, self.raindrop_transparency),
(self.raindrop_x - self.raindrop_radius,
self.raindrop_y - self.raindrop_radius / 2, self.raindrop_radius * 2,
self.raindrop_radius), self.line_width)
if self.raindrop_radius-60>0:
pygame.draw.ellipse(raindrop_screen, (self.color_R, self.color_G, self.color_B, min(self.raindrop_transparency+60,255)),
(self.raindrop_x - (self.raindrop_radius-60),
self.raindrop_y - (self.raindrop_radius-60) / 2, (self.raindrop_radius-60) * 2,
(self.raindrop_radius-60)), self.line_width)
if self.raindrop_radius-100>0:
pygame.draw.ellipse(raindrop_screen, (self.color_R, self.color_G, self.color_B, min(self.raindrop_transparency+100,255)),
(self.raindrop_x - (self.raindrop_radius-100),
self.raindrop_y - (self.raindrop_radius-100) / 2, (self.raindrop_radius-100) * 2,
(self.raindrop_radius-100)), self.line_width)
self.radius_Increasing()
self.transparency_Diminishing()
#################################结束####绘制椭圆形雨滴涟漪代码####结束#######################################
return
class Rain_Curtain(): #定义一个雨幕类,雨幕类包含很多雨点raindrops对象
raindrops = []
default_weight = 8
def __init__(self,screen,width,height): #需要绘制屏幕和屏幕的宽和高进行初始化
self.screen =screen
self.width = width
self.height = height
self.alpha_screen = screen.convert_alpha() #用屏幕构造一个相同大小的画板,raindrops先画在这个画板上
def run(self): #让雨幕运行起来的函数
self.raindrops.append(raindrop(self.width, self.height, self.default_weight)) # 构造一个雨滴,追加到雨滴链表
raindrops_len = 1 # 定义雨滴链表长度整型变量
i = 0
print(len(self.raindrops))
while i < raindrops_len:
raindrops_len = len(self.raindrops)
if not self.raindrops[i].get_over():
del self.raindrops[i]
raindrops_len = len(self.raindrops)
i = i + 1
self.alpha_screen.fill(pygame.Color(0, 0, 0,0)) #绘制雨点链表前,先将画板清空
for i in range(len(self.raindrops)):
if self.raindrops[i].get_over():
self.raindrops[i].draw_raindrop(self.alpha_screen)
self.screen.blit(self.alpha_screen, (0, 0))
def get_default_weight(self):
return self.default_weight
def set_default_weight(self,default_weight):
self.default_weight=default_weight
def set_difficulty(screen,width, height):
# Do the job here !
print("已经设置!")
pass
def start_the_game(screen,width,height):
print("已经开始!")
pass
#print(width,height)
FPS = 35
#default_weight = 8 #定义雨滴的最大重量
pygame.display.set_caption("西西设计平台")
new_Rain_Curtain=Rain_Curtain(screen,width,height) # 定义一个雨滴链表,保存了很多个雨滴
while True: # 窗口主循环开始
for event in pygame.event.get(): # 窗口事件监听开始
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
else:
pass
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.key == pygame.K_UP:
FPS = FPS + 10
elif event.key == pygame.K_DOWN:
if FPS > 10:
FPS = FPS - 10
elif event.key == pygame.K_RIGHT:
if new_Rain_Curtain.get_default_weight() < 15:
new_Rain_Curtain.set_default_weight(new_Rain_Curtain.default_weight+1)
elif event.key == pygame.K_LEFT:
if new_Rain_Curtain.get_default_weight() > 3:
new_Rain_Curtain.set_default_weight(new_Rain_Curtain.get_default_weight()-1)
###游戏程序循环代码开始
screen.fill(pygame.Color(0, 0, 0))
new_Rain_Curtain.run()
pygame.time.delay(FPS)
pygame.display.flip() # 更新全部显示
return None
def main():
width = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
MyWin =pygame.init()
print(MyWin)
screen = pygame.display.set_mode((width, height), flags=pygame.FULLSCREEN)
pygame.font.init()
###############################################################################################################
menu = pygame_menu.Menu('Rian Drop', 800, 400,
theme=pygame_menu.themes.THEME_DARK)
menu.add.text_input('姓名:', default='mathfrog',font_name='方正粗黑宋简体.ttf')
menu.add.selector('游戏难度 :', [('骨灰级', 1), ('高手级', 2),('入门级', 3)], onchange=set_difficulty(screen,width, height),font_name='方正粗黑宋简体.ttf')
menu.add.button('开始游戏', start_the_game,screen,width,height,background_color=(0,124,11),border_color=(255,0,0),
font_name='方正粗黑宋简体.ttf',font_color=(0,0,255),font_size=40)
# menu.add.button('开始', start_the_game,font_name='方正粗黑宋简体.ttf')
menu.add.button('Quit',pygame_menu.events.EXIT, font_name='方正粗黑宋简体.ttf')
menu.mainloop(screen)
###############################################################################################################
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()