前言:上次昼汗,參考了Ahab的文章俩莽,實現(xiàn)了一個簡單的降雪腳本。但是乔遮,身為一個強(qiáng)迫癥患者扮超,怎么能用圓代替大自然那完美的六邊形的雪花那。所以蹋肮,今天出刷,我就在上次的基礎(chǔ)上,改進(jìn)了一下,對比一下:
1.0版本
2.0版本
是不是和大自然的雪花更加像了坯辩。
好馁龟,接下來,看一下如何實現(xiàn)漆魔。
源碼:
'''
人工降雪v2.0
Data:2018-12-11
Author:Lingyin
reference:https://mp.weixin.qq.com/s/fki-eGBzrSsz2xDbk--vpw
'''
import pygame
import random
import os
from pygame.locals import *
from pygame.compat import geterror
if not pygame.mixer: print('Warning, sound disabled')
SIZE = (1300,700)
#設(shè)置一些基本的顏色
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
main_dir = os.path.split(os.path.abspath(__file__))[0]
data_dir = os.path.join(main_dir, 'data')
#初始化
pygame.init()
screen = pygame.display.set_mode(SIZE)
#設(shè)置標(biāo)題
pygame.display.set_caption('唯美雪景')
#設(shè)置鼠標(biāo)光標(biāo)不可見
pygame.mouse.set_visible(0)
#加載圖片坷檩,利用os模塊,實現(xiàn)跨平臺
def load_image(name):
fullname = os.path.join(data_dir,name)
try:
image = pygame.image.load(fullname)
except pygame.error as e:
raise e
image = image.convert()
return image
def load_sound(name):
class NoneSound:
def play(self): pass
if not pygame.mixer or not pygame.mixer.get_init():
return NoneSound()
fullname = os.path.join(data_dir, name)
print(fullname)
try:
pygame.mixer.music.load(fullname)
pygame.mixer.music.play()
except pygame.error:
print('Cannot load sound: %s' % fullname)
raise SystemExit(str(geterror()))
class Snow(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.width = random.randrange(5,15)
self.image = pygame.transform.scale(load_image('snowflake.png'),(self.width,self.width))
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0,1300)
self.rect.y = random.randrange(0,700)
self.speedx = random.randrange(-3,5)
self.speedy = random.randrange(3,5)
def update(self):
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.x > SIZE[0] or self.rect.x < 0 or self.rect.y > SIZE[1]:
self.rect.x = random.randrange(0,1300)
self.rect.y = 0
flow = pygame.sprite.Group()
for i in range(300):
s = Snow()
flow.add(s)
def main():
#加載背景
background = load_image('Lingyin0.jpg')
screen.blit(background,(0,0))
#顯示背景
pygame.display.flip()
clock = pygame.time.Clock()
snow = Snow()
load_sound('flower.mp3')
#主循環(huán)
going = True
while going:
clock.tick(20)
for event in pygame.event.get():
if event.type == QUIT:
going = False
elif event.type == KEYDOWN and event.key == K_ESCAPE:
going = False
flow.update()
flow.draw(screen)
pygame.display.flip()
screen.blit(background, (0, 0))
pygame.quit()
if __name__ == '__main__':
main()
其實和上次的代碼改抡,沒有太大的區(qū)別矢炼。最主要的就是,這次我增加了一個Snow類阿纤。下面句灌,我逐步講解。
class Snow(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.width = random.randrange(5,15)
self.image = pygame.transform.scale(load_image('snowflake.png'),(self.width,self.width))
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0,1300)
self.rect.y = random.randrange(0,700)
self.speedx = random.randrange(-3,5)
self.speedy = random.randrange(3,5)
def update(self):
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.x > SIZE[0] or self.rect.x < 0 or self.rect.y > SIZE[1]:
self.rect.x = random.randrange(0,1300)
self.rect.y = 0#random.randrange(0,700)
首先,定義了一個Snow類胰锌,它繼承自pygame.sprite.Sprite,這是pygame模塊內(nèi)部的一個類骗绕,不用管它是什么,只管用就行资昧。
load_image('snowflake.png')
這個函數(shù)和1.0版本的一樣酬土,不需要講解。
下面我們看看pygame.transform.scale()這個函數(shù)
self.image = pygame.transform.scale(load_image('snowflake.png'),(self.width,self.width))
這個函數(shù)的作用就是改變圖片的尺寸格带,所以它接受兩個參數(shù)撤缴,一個是我們加載的圖片,另一個是元組践惑,也就是要改變的大小腹泌。將改變后的圖片交給自定義的self.image.由于雪花的大小并不是一樣的,所以在實例初始化的時候尔觉,我們隨機(jī)生成了它的大小:
self.width = random.randrange(5,15)
用過貼圖做程序的同學(xué)一定知道凉袱,我們加載的圖片,是一個矩形侦铜,但是當(dāng)我們玩游戲的時候专甩,角色并不是矩形的啊钉稍?這就需要下面這條語句來處理了:
self.image.set_colorkey(BLACK)
用它處理后涤躲,我們的雪花,看起來才是一個六邊形的形狀贡未,那如果种樱,不加這條語句會是什么效果,看一下:
看見雪花周圍的黑色框框了嗎
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0,1300)
self.rect.y = random.randrange(0,700)
self.speedx = random.randrange(-3,5)
self.speedy = random.randrange(3,5)
然后俊卤,通過self.image的get_rect方法嫩挤,獲取了雪花圖片本身這個矩形
并且通過隨機(jī)函數(shù)對它的起始坐標(biāo)進(jìn)行了賦值。最后消恍,對它在x和y軸的速度進(jìn)行了隨機(jī)賦值岂昭。
接下來是update()函數(shù)
def update(self):
self.rect.x += self.speedx
self.rect.y += self.speedy
if self.rect.x > SIZE[0] or self.rect.x < 0 or self.rect.y > SIZE[1]:
self.rect.x = random.randrange(0,1300)
self.rect.y = 0
update()是用來移動雪花,也就是更新雪花的位置的狠怨。雪花的x和y分別加上各自的速度约啊。最后判斷,如果雪花移出了屏幕范圍佣赖,再將它的x隨機(jī)賦值恰矩,y賦值為0,即從屏幕最上方下落茵汰。
flow = pygame.sprite.Group()
pygame.sprite模塊有一個Group類枢里,大致應(yīng)用就是可以將我們定義的類的實例包含進(jìn)來,然后蹂午,同時進(jìn)行一個操作栏豺。具體的使用方法,可以去pygame的官網(wǎng)去查閱
for i in range(300):
s = Snow()
flow.add(s)
flow有一個add方法豆胸,將實例添加進(jìn)去奥洼。這里,我通過迭代晚胡,創(chuàng)建了300個雪花的實例灵奖,如果你想讓美女體驗一場暴雪的話,可以將它的值調(diào)到更大估盘,但是瓷患,啟動速度可就降下來了!G餐住擅编!
flow.update()
flow.draw(screen)
pygame.display.flip()
screen.blit(background, (0, 0))
最后,將所有的雪花實例update()箫踩,即更新位置爱态,然后畫到屏幕上->顯示->擦除->update()->畫->....一直循環(huán)。
源碼和圖片放到了我的GitHub上:
地址:https://github.com/dmzlingyin/pygame