13-1 星星:找一幅星星图像,并在屏幕上显示一系列整齐排列的星星。
import pygame
import sys
from pygame.sprite import Group
from pygame.sprite import Sprite
class Settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0, 0, 51)
class Star(Sprite):
def __init__(self, settings, screen):
super().__init__()
self.settings = settings
self.screen = screen
self.image = pygame.image.load('images/star.png')
self.rect = self.image.get_rect()
self.rect.x = self.rect.width
self.rect.y = self.rect.height
def blitme(self):
self.screen.blit(self.image, self.rect)
def get_number_star_x(settings, star_width):
available_space_x = settings.screen_width - 2 * star_width
number_stars_x = int(available_space_x / (star_width * 2))
return number_stars_x
def get_number_rows(settings, star_height):
"""计算屏幕可容纳多少行外星人"""
available_space_y = (settings.screen_height - 2 * star_height)
number_rows = int(available_space_y / (star_height * 2))
return number_rows
def create_star(settings, screen, stars, star_number, row_number):
star = Star(settings, screen)
star.rect.x = star.rect.width + 2 * star.rect.width * star_number
star.rect.y = star.rect.height + 2 * star.rect.height * row_number
stars.add(star)
def create_star_group(settgings, screen, stars):
star = Star(settgings, screen)
number_stars_x = get_number_star_x(settgings, star.rect.width)
number_rows = get_number_rows(settgings, star.rect.height)
for row_number in range(number_rows):
for star_number in range(number_stars_x):
create_star(settgings, screen, stars, star_number, row_number)
def run_star():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
pygame.display.set_caption('Stars')
stars = Group()
create_star_group(settings, screen, stars)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(settings.bg_color)
stars.draw(screen)
pygame.display.flip()
run_star()
运行结果:
13-2 更逼真的星星:为让星星的分布更逼真,可随机地放置星星。
import pygame
import sys
from pygame.sprite import Group
from pygame.sprite import Sprite
from random import randint
class Settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0, 0, 51)
class Star(Sprite):
def __init__(self, settings, screen):
super().__init__()
self.settings = settings
self.screen = screen
self.random_number = randint(-10, 10)
self.image = pygame.image.load('images/star.png')
self.rect = self.image.get_rect()
self.rect.x = self.rect.width + self.random_number
self.rect.y = self.rect.height + self.random_number
def blitme(self):
self.screen.blit(self.image, self.rect)
def get_number_star_x(settings, star_width):
available_space_x = settings.screen_width - 2 * star_width
number_stars_x = int(available_space_x / (star_width * 2))
return number_stars_x
def get_number_rows(settings, star_height):
"""计算屏幕可容纳多少行外星人"""
available_space_y = (settings.screen_height - 2 * star_height)
number_rows = int(available_space_y / (star_height * 2))
return number_rows
def create_star(settings, screen, stars, star_number, row_number):
star = Star(settings, screen)
star.rect.x = star.rect.x + 2 * star.rect.x * star_number
star.rect.y = star.rect.y + 2 * star.rect.y * row_number
stars.add(star)
def create_star_group(settgings, screen, stars):
star = Star(settgings, screen)
number_stars_x = get_number_star_x(settgings, star.rect.width)
number_rows = get_number_rows(settgings, star.rect.height)
for row_number in range(number_rows):
for star_number in range(number_stars_x):
create_star(settgings, screen, stars, star_number, row_number)
def run_star():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
pygame.display.set_caption('Stars')
stars = Group()
create_star_group(settings, screen, stars)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(settings.bg_color)
stars.draw(screen)
pygame.display.flip()
run_star()
运行结果:
13-3 雨滴:寻找一幅雨滴图像,并创建一系列整齐排列的雨滴。让这些雨滴往下落,直到到达屏幕底端后消失。
import sys
import pygame
from pygame.sprite import Group
from pygame.sprite import Sprite
class Settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (255, 255, 255)
class Rain(Sprite):
def __init__(self, settings, screen):
super().__init__()
self.settings = settings
self.screen = screen
self.image = pygame.image.load('images/rain.png')
self.rect = self.image.get_rect()
self.drop_speed = 1
def update(self):
self.rect.y += self.drop_speed
def blitme(self):
self.screen.blit(self.image, self.rect)
def get_number_rains_x(settings, rain_width):
available_space_x = settings.screen_width - rain_width * 2
number_rains_x = int(available_space_x / (rain_width * 2))
return number_rains_x
def create_rain(settings, screen, rains, number_rain):
rain = Rain(settings, screen)
rain.rect.x = rain.rect.width + 2 * rain.rect.width * number_rain
rains.add(rain)
def create_rain_group(settings, screen, rains):
rain = Rain(settings, screen)
number_rains_x = get_number_rains_x(settings, rain.rect.width)
for rain_number in range(number_rains_x):
create_rain(settings, screen, rains, rain_number)
def update_rains(settings, rains):
"""更新雨滴的位置,并删除已经消失的雨滴"""
# 更新雨滴的位置
rains.update()
# 删除已消失的雨滴
for rain in rains.copy():
if rain.rect.bottom >= settings.screen_height:
rains.remove(rain)
def run_rain():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
pygame.display.set_caption('Raining')
rains = Group()
create_rain_group(settings, screen, rains)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(settings.bg_color)
rains.draw(screen)
update_rains(settings, rains)
pygame.display.flip()
run_rain()
运行结果:
13-4 连绵细雨: 修改为完成练习13-3而编写的代码,使一行雨滴消失在屏幕底端后,屏幕顶端又出现一行新雨滴,并开始往下落。
import sys
import pygame
from pygame.sprite import Group
from pygame.sprite import Sprite
class Settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (255, 255, 255)
self.get_new_rain = True
class Rain(Sprite):
def __init__(self, settings, screen):
super().__init__()
self.settings = settings
self.screen = screen
self.image = pygame.image.load('images/rain.png')
self.rect = self.image.get_rect()
self.drop_speed = 1
def update(self):
self.rect.y += self.drop_speed
def blitme(self):
self.screen.blit(self.image, self.rect)
def get_number_rains_x(settings, rain_width):
available_space_x = settings.screen_width - rain_width * 2
number_rains_x = int(available_space_x / (rain_width * 2))
return number_rains_x
def create_rain(settings, screen, rains, number_rain):
rain = Rain(settings, screen)
rain.rect.x = rain.rect.width + 2 * rain.rect.width * number_rain
rains.add(rain)
def create_rain_group(settings, screen, rains):
rain = Rain(settings, screen)
number_rains_x = get_number_rains_x(settings, rain.rect.width)
for rain_number in range(number_rains_x):
create_rain(settings, screen, rains, rain_number)
def update_rains(settings, screen, rains):
"""更新雨滴的位置,并删除已经消失的雨滴"""
# 更新雨滴的位置
rains.update()
# 删除已消失的雨滴,并添加新雨滴
for rain in rains:
if rain.rect.bottom >= settings.screen_height:
rains.remove(rain)
if rain.rect.bottom >= settings.screen_height:
create_rain_group(settings, screen, rains)
def run_rain():
pygame.init()
settings = Settings()
screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
pygame.display.set_caption('Raining')
rains = Group()
create_rain_group(settings, screen, rains)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(settings.bg_color)
update_rains(settings, screen, rains)
rains.draw(screen)
pygame.display.flip()
run_rain()
运行结果:
截图见上一幅,雨滴到底之后会重新生成新雨滴下降。