#12-1 蓝色天空 :创建一个背景为蓝色的Pygame窗口
import pygame
def show_sky():
pygame.init()
screen=pygame.display.set_mode((1200,800))
pygame.display.set_caption("Blue Sky")
while True:
screen.fill((135,206,250))
pygame.display.flip()
show_sky()
结果:
import pygame,sys
#12-2 游戏角色 :找一幅你喜欢的游戏角色位图图像或将一幅图像转换为位图。创建一个类,将该角色绘制到屏幕中央,
# 并将该图像的背景色设置为屏幕背景色,或将屏幕背景色设置为该图像的背景色。
class Draw_center():
"""绘制到屏幕中央"""
def __init__(self,screen):
self.screen=screen
self.image=pygame.image.load("image/dog.bmp")
self.rect=self.image.get_rect()
self.screen_rect=screen.get_rect()
self.rect.centerx=self.screen_rect.centerx
self.rect.centery = self.screen_rect.centery
def blitme(self):
self.screen.blit(self.image, self.rect)
#12-1 蓝色天空 :创建一个背景为蓝色的Pygame窗口
def show_sky():
pygame.init()
screen=pygame.display.set_mode((1200,800))
pygame.display.set_caption("Blue Sky")
draw_center=Draw_center(screen)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((135,206,250))
draw_center.blitme()
pygame.display.flip()
show_sky()
结果:
#12-3 火箭 :编写一个游戏,开始时屏幕中央有一个火箭,而玩家可使用四个方向键上下左右移动火箭。
# 请务必确保火箭不会移到屏幕外面。
import pygame,sys
class Settings():
"""存储《外星人入侵》的所有设置的类"""
def __init__(self):
"""初始化游戏的设置"""
# 屏幕设置
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (135,206,250)
self.ship_speed_factor = 10
#-----------------------------------------------------
class Ship():
def __init__(self, ai_settings,screen):
"""初始化飞船并设置其初始位置"""
self.screen = screen
self.ai_settings=ai_settings
# 加载飞船图像并获取其外接矩形
self.image = pygame.image.load('image/ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 将每艘新飞船放在屏幕底部中央
self.rect.centerx = self.screen_rect.centerx
self.rect.centery= self.screen_rect.centery
self.moving_right=False
self.moving_left=False
self.moving_top = False
self.moving_bottom = False
#在飞船的属性center中存储小数值
self.center = float(self.rect.centerx)
def update(self):
"""根据移动标志调整飞船的位置"""
# 更新飞船的center值,而不是rect
if self.moving_right and self.rect.right < self.screen_rect.right:
self.rect.centerx += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.rect.centerx -= self.ai_settings.ship_speed_factor
if self.moving_top and self.rect.top >0:
self.rect.centery -= self.ai_settings.ship_speed_factor
if self.moving_bottom and self.rect.bottom <self.screen_rect.bottom:
self.rect.centery += self.ai_settings.ship_speed_factor
def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image, self.rect)
#----------------------------------------------------------
def check_keydown_events(event, ship):
"""响应按键"""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_UP:
ship.moving_top = True
elif event.key == pygame.K_DOWN:
ship.moving_bottom = True
def check_keyup_events(event, ship):
"""响应松开"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
elif event.key == pygame.K_UP:
ship.moving_top = False
elif event.key == pygame.K_DOWN:
ship.moving_bottom = False
def check_events(ship):
"""监视键盘和鼠标事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def update_screen(ai_settings,screen,ship):
"""更新屏幕上的图像,并切换到新屏幕"""
# 每次循环时都重绘屏幕
screen.fill(ai_settings.bg_color)
ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()
def show_sky():
pygame.init()
screen=pygame.display.set_mode((1200,800))
ai_settings=Settings()
pygame.display.set_caption("ship moving")
ship=Ship(ai_settings,screen)
while True:
update_screen(ai_settings,screen,ship)
ship.update()
check_events(ship)
show_sky()
#结果
# 12-4 按键 :创建一个程序,显示一个空屏幕。在事件循环中,每当检测到pygame.KEYDOWN 事件时都打印属性event.key 。
# 运行这个程序,并按各种键,看看Pygame如何响应。
def show_void():
pygame.init()
screens=pygame.display.set_mode((800,300))
pygame.display.set_caption('Nothing hey')
bg=(230,230,230)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
bg=(0,255,0)
else:
bg=(255,0,0)
screens.fill(bg)
pygame.display.flip()
show_void()
结果:
按下UP键:
按下DOWN/LEFT/RIGHT键:
# 12-5 侧面射击 :编写一个游戏,将一艘飞船放在屏幕左边,并允许玩家上下移动飞船。
#在玩家按空格键时,让飞船发射一颗在屏幕中向右穿行的子弹,并在子弹离开屏幕而消失后将其删除。
#########bullet.py#################
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
def __init__(self,setting,screen,ship):
super().__init__()
self.screen=screen
#在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
self.rect = pygame.Rect(0,0,setting.bullet_width,setting.bullet_height)
self.rect.centery = ship.rect.centery
self.rect.right = ship.rect.right
# 存储用小数表示的子弹位置
self.x = float(self.rect.x)
self.color = setting.bullet_color
self.speed_factor = setting.bullet_speed_factor
def update(self):
"""向右移动子弹"""
# 更新表示子弹位置的小数值
self.x += self.speed_factor
#更新表示子弹的rect的位置
self.rect.x = self.x
def draw_bullets(self):
"""在屏幕上绘制子弹"""
pygame.draw.rect(self.screen,self.color,self.rect)
#########ship.py###################
import pygame
class Ship():
def __init__(self,setting,screen):
"""初始化飞船并设置其初始位置"""
self.screen = screen
self.setting = setting
# 加载飞船图像并获取其外接矩形
self.image = pygame.image.load('images/ships.bmp')
self.rect = self.image.get_rect()
self.screen_rect = self.screen.get_rect()
# 将每艘新飞船放在屏幕左边中央
self.rect.centery = self.screen_rect.centery
self.rect.left = self.screen_rect.left
self.moving_top = False
self.moving_bottom = False
# 在飞船的属性center中存储小数值(因为rect的centery等属性只能存储整数值)
self.center = float(self.rect.centery)
def update(self):
"""根据移动标志调整飞船的位置"""
# 更新飞船的center值,而不是rect
if self.moving_top and self.rect.top > 0:
self.center -= self.setting.ship_speed_factor
if self.moving_bottom and self.rect.bottom < self.screen_rect.bottom:
self.center += self.setting.ship_speed_factor
# 根据self.center更新rect对象
self.rect.centery=self.center
def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image,self.rect)
#########shot_function.py##########
import pygame,sys
from bullet import Bullet
def check_keydown_events(event,setting,screen,ship,bullets):
"""响应按键"""
if event.key==pygame.K_UP:
ship.moving_top=True
if event.key==pygame.K_DOWN:
ship.moving_bottom=True
if event.key==pygame.K_SPACE:
fire_bullets(setting, screen, ship, bullets)
def check_keyup_events(event,ship):
"""响应松开"""
if event.key == pygame.K_UP:
ship.moving_top = False
elif event.key == pygame.K_DOWN:
ship.moving_bottom = False
def check_events(setting,screen,ship,bullets):
"""监视键盘和鼠标事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,setting,screen,ship,bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def update_screen(setting,screen,ship,bullets):
"""更新屏幕上的图像,并切换到新屏幕"""
# 每次循环时都重绘屏幕
# 在飞船和外星人后面重绘所有子弹
screen.fill(setting.bg)
for bullet in bullets.sprites():
bullet.draw_bullets()
ship.blitme()
#让最近绘制的屏幕可见
pygame.display.flip()
def update_bullets(right,bullets):
"""更新子弹的位置,并删除已消失的子弹"""
#更新子弹的位置
bullets.update()
# 删除已消失的子弹
for bullet in bullets.copy():
if bullet.rect.left > right:
bullets.remove(bullet)
def fire_bullets(setting, screen, ship, bullets):
"""#创建新子弹并将其加入到编组bullets中"""
if len(bullets) < setting.bullet_allowed:
new_bullet = Bullet(setting, screen, ship)
bullets.add(new_bullet)
#########setting.py##############
class Setting():
def __init__(self):
#屏幕
self.screen_width = 1500
self.screen_height = 800
self.bg=(230,230,230)
self.ship_speed_factor=2.5
#子弹
self.bullet_speed_factor = 0.7
self.bullet_width = 15
self.bullet_height = 3
self.bullet_color = 0,0,0
self.bullet_allowed = 30
########主函数,shot.py###########
import pygame
import shot_functions as sf
from setting import Setting
from pygame.sprite import Group
from ship import Ship
def show_left():
pygame.init()
setting = Setting()
screen=pygame.display.set_mode((setting.screen_width,setting.screen_height ))
pygame.display.set_caption("侧面射击")
ship = Ship(setting,screen)
bullet = Group()
while True:
sf.check_events(setting, screen, ship, bullet)
ship.update()
sf.update_bullets(screen.get_rect().right,bullet)
sf.update_screen(setting, screen, ship, bullet)
show_left()
结果:
#13-1 星星 :找一幅星星图像,并在屏幕上显示一系列整齐排列的星星。
import pygame,sys
from pygame.sprite import Group
from pygame.sprite import Sprite
class Star(Sprite):
def __init__(self,screen):
super(Star,self).__init__()
self.screen=screen
self.image=pygame.image.load("image/starmans.bmp")
self.rect=self.image.get_rect()
self.rect.x=self.rect.width
self.rect.y=self.rect.height
self.x=float(self.rect.x)
def blitme(self):
self.screen.blit(self.image,self.rect)
def get_number_stars_x(screen_width,stars_width):
available_sapce_x = screen_width-2*stars_width
number_stars_x = int(available_sapce_x/(2*stars_width))
return number_stars_x
def get_number_rows(screen_height,stars_height):
available_sapce_x = screen_height - 2 * stars_height
number_rows = int(available_sapce_x / (2 * stars_height))
return number_rows
def create_stars(screen,stars,star_number,row_number):
star = Star(screen)
star.x = star.rect.width + 2*star.rect.width*star_number
star.rect.x = star.x
star.rect.y = star.rect.height+2*star.rect.height*row_number
stars.add(star)
def show_stars():
pygame.init()
screen=pygame.display.set_mode((800,600))
pygame.display.set_caption("starry starry night")
stars=Group()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
star=Star(screen)
number_stars_x = get_number_stars_x(800,star.rect.width)
number_rows = get_number_rows(600,star.rect.height)
for row_number in range(number_rows):
for star_number in range(number_stars_x):
create_stars(star.screen,stars,star_number,row_number)
screen.fill((230,230,230))
stars.draw(screen)
pygame.display.flip()
show_stars()
结果:
#13-2 更逼真的星星 :为让星星的分布更逼真,可随机地放置星星。本书前面说过,可像下面这样来生成随机数:
# from random import randint
# random_number = randint(-10,10)
import pygame,sys
from pygame.sprite import Group
from pygame.sprite import Sprite
from random import randint
class Star(Sprite):
def __init__(self,screen):
super().__init__()
self.screen=screen
self.image=pygame.image.load("image/starmans.bmp")
self.rect=self.image.get_rect()
self.number_random = randint(-10,10)
self.rect.x=self.rect.width+self.number_random
self.rect.y=self.rect.height+self.number_random
self.x=float(self.rect.x)
def blitme(self):
self.screen.blit(self.image,self.rect)
def get_number_stars_x(screen_width,stars_width):
available_space_x = screen_width-2*stars_width
number_stars_x = int(available_space_x/(2*stars_width))
return number_stars_x
def get_number_rows(screen_height,stars_height):
available_space_y = screen_height - 2 * stars_height
number_rows = int(available_space_y / (2 * stars_height))
return number_rows
def create_stars(screen,stars,star_number,row_number):
star = Star(screen)
star.x = star.rect.x + 2*star.rect.x*star_number
star.rect.x = star.x
star.rect.y = star.rect.y+2*star.rect.y*row_number
stars.add(star)
def show_stars():
pygame.init()
screen=pygame.display.set_mode((800,600))
pygame.display.set_caption("starry starry night")
stars=Group()
star = Star(screen)
number_stars_x = get_number_stars_x(800, star.rect.width)
number_rows = get_number_rows(600, star.rect.height)
for row_number in range(number_rows):
for star_number in range(number_stars_x):
create_stars(star.screen, stars, star_number, row_number)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((230,230,230))
stars.draw(screen)
pygame.display.flip()
show_stars()
结果:
#13-3 雨滴 :寻找一幅雨滴图像,并创建一系列整齐排列的雨滴。让这些雨滴往下落,直到到达屏幕底端后消失。
#13-4 连绵细雨 :修改为完成练习13-3而编写的代码,使得一行雨滴消失在屏幕底端后,屏幕顶端又出现一行新雨滴,
# 并开始往下落。
import pygame,sys
from pygame.sprite import Group
from pygame.sprite import Sprite
class Raindrop(Sprite):
def __init__(self,screen):
super().__init__()
self.screen=screen
self.image=pygame.image.load("image/raindrops.bmp")
self.rect=self.image.get_rect()
self.rect.x=self.rect.width
self.rect.y=self.rect.height
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_raindrops_x(screen_width,raindrops_width):
available_space_x = screen_width-2*raindrops_width
number_raindrops_x = int(available_space_x/(2*raindrops_width))
return number_raindrops_x
def create_raindrops(screen,raindrops,raindrop_number):
raindrop=Raindrop(screen)
raindrop.rect.x = raindrop.rect.x+2*raindrop.rect.x*raindrop_number
raindrops.add(raindrop)
def create_raindrops_group(screen, raindrops):
raindrop = Raindrop(screen)
raindrop_number = get_number_raindrops_x(800, raindrop.rect.width)
for raindrop_num in range(raindrop_number):
create_raindrops(raindrop.screen, raindrops, raindrop_num)
def update_raindrops(screen,raindrops):
"""更新雨滴的位置,删除已经消失的雨滴"""
raindrops.update()
for raindrop in raindrops:
if raindrop.rect.top >= 600:
raindrops.remove(raindrop)
if raindrop.rect.top >= 600:
create_raindrops_group(screen,raindrops)
def show_raindrops():
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("rainbow raindrops")
raindrops=Group()
create_raindrops_group(screen, raindrops)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((230,230,230))
update_raindrops(screen, raindrops)
raindrops.draw(screen)
pygame.display.flip()
show_raindrops()
结果:
#13-5 抓球 :创建一个游戏,在屏幕底端放置一个玩家可左右移动的角色。让一个球出现在屏幕顶端,
# 且水平位置是随机的,并让这个球以固定的速度往下落。如果角色与球发生碰撞(表示将球抓住了),
# 就让球消失。每当角色抓住球或球因抵达屏幕底端而消失后,都创建一个新球。
import pygame,sys
from random import randint
from pygame.sprite import Sprite
from pygame.sprite import Group
class Ball(Sprite):
def __init__(self,screen):
super().__init__()
self.screen = screen
self.image = pygame.image.load("image/ball.jpg")
self.rect = self.image.get_rect()
self.number_random = randint(10,600)
self.rect.x = self.rect.width+self.number_random
self.drop_speed = 1
def update(self):
self.rect.y += self.drop_speed
def blitme(self):
self.screen.blit(self.image,self.rect)
class Man(Sprite):
def __init__(self,screen):
super().__init__()
self.screen = screen
self.image = pygame.image.load("image/man.jpg")
self.rect = self.image.get_rect()
self.rect.centerx = self.screen.get_rect().centerx
self.rect.bottom = self.screen.get_rect().bottom
self.moving_right = False
self.moving_left = False
self.center = float(self.rect.centerx)
def update(self):
if self.moving_left and self.rect.left > 0:
self.center -= 50
if self.moving_right and self.rect.right < 800:
self.center += 50
self.rect.centerx = self.center
def blitme(self):
self.screen.blit(self.image,self.rect)
def check_keydown(event,man):
if event.key == pygame.K_RIGHT:
man.moving_right = True
elif event.key == pygame.K_LEFT:
man.moving_left = True
def check_keyup(event,man):
"""响应松开"""
if event.key == pygame.K_RIGHT:
man.moving_right = False
elif event.key == pygame.K_LEFT:
man.moving_left = False
def create_ball(balls,screen):
if len(balls) ==0:
b = Ball(screen)
balls.add(b)
else:
pass
def update_ball(balls,mans):
for ball in balls:
balls.update()
if ball.rect.y >= 600:
balls.remove(ball)
collisions = pygame.sprite.groupcollide(balls, mans, True, True)
def show_ball():
pygame.init()
screen = pygame.display.set_mode((800,600))
mans = Group()
balls = Group()
pygame.display.set_caption("Catch the ball!")
while True:
screen.fill((230, 230, 230))
if len(mans) == 0:
mans.add(Man(screen))
for man in mans:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown(event,man)
elif event.type == pygame.KEYUP:
check_keyup(event,man)
man.update()
mans.draw(screen)
create_ball(balls, screen)
update_ball(balls,mans)
balls.draw(screen)
pygame.display.flip()
show_ball()
13-5结果: