《python编程从入门到实践》第十三章答案

13.1题
首先我们需要创立对象(xingxing.py),还有运行的主程序(13.1.py),然后有星星的设置要求settings.py,还有运行的一些功能的具体内容game_functions.

xingxing.py

import pygame

from pygame.sprite import Sprite

class Xingxing(Sprite):
    def __init__(self,screen,ai_settings):
        super().__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        #初始化星星的属性

        self.image = pygame.image.load('xingxing/xingxing.bmp')
        self.rect = self.image.get_rect()
        #加载星星的图像

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        #星星都在屏幕左上角

        self.y = float(self.rect.y)
        #存储小数

    def blitme(self):
        self.screen.blit(self.image,self.rect)
        #在指定位置刷新星星

settings.py

class Settings():
    def __init__(self):
        self.screen_width = 1600
        self.screen_height = 1200
        self.bg_color = (255,255,255)

game_functions.py

import pygame
import sys

from xingxing import Xingxing

def get_number_rows(ai_settings,xingxing_width):
    #计算屏幕可以容纳多少列外星人
    available_space_x = (ai_settings.screen_width - (3 * xingxing_width) )
    number_rows = int(available_space_x / (2 * xingxing_width))
    return number_rows

def get_xingxing_y(ai_settings,xingxing_height):
    available_space_y = ai_settings.screen_height - 2 *xingxing_height
    number_xingxing_y = int(available_space_y / (2 * xingxing_height))
    return number_xingxing_y
#每列可以存储多少个星星

def create_xingxing(ai_settings,xingxings,screen,xingxing_number,rows_number):
    xingxing = Xingxing(ai_settings,screen)
    xingxing_height = xingxing.rect.height
    xingxing.y = xingxing_height + 2 * xingxing_height * xingxing_number
    xingxing.rect.y = xingxing.y
    xingxing.rect.x = xingxing.rect.width + 2 * xingxing.rect.width * rows_number
    #记录下每个星星Y的坐标
    xingxings.add(xingxing)
    #创建一列的外星人坐标y

def create_fleet(ai_settings,screen,xingxings):
    xingxing = Xingxing(ai_settings,screen)
    number_xingxing_y = get_xingxing_y(ai_settings,xingxing.rect.height)
    number_rows = get_number_rows(ai_settings,xingxing.rect.width)
    #计算一列可以容下几个星星
    for rows_number in range (number_rows):
        for xingxing_number in range(number_xingxing_y):
            create_xingxing(ai_settings,xingxings,screen,xingxing_number,rows_number)
            #创建一系列星星

def check_keydown_events(event):
    if event.key == pygame.K_q:
        sys.exit()
    #按键相应事件

def check_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown_events(event)


def update_screen(ai_settings,screen,xingxings):
    screen.fill(ai_settings.bg_color)
    xingxings.draw(screen)
    pygame.display.flip()
    #刷新屏幕

最后运行主程序13.1.py就可以得到结果了

13.1.py

import pygame

from settings import Settings

from  xingxing import Xingxing

import game_functions as gf

from pygame.sprite import Group

def run_game():
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption('xingxing')
    #初始化游戏,并且建立一个屏幕对象

    xingxings = Group()
    gf.create_fleet(ai_settings,screen,xingxings)
    #创建一系列星星
    while True:
        gf.check_events()
        gf.update_screen(ai_settings, screen,xingxings)

run_game()

需要注意的是星星图片的高度不要太大,所有的文件都在一个文件夹里

13.2题
这题的setting和xingxing.py文件和13.1一致,需要改动下game_functions文件和13.2文件

game_functions0.py

import pygame
import sys
from random import randint

from xingxing import Xingxing

def get_number_rows(ai_settings,xingxing_width):
    #计算屏幕可以容纳多少列外星人
    available_space_x = (ai_settings.screen_width - (3 * xingxing_width) )
    number_rows = int(available_space_x / (2 * xingxing_width))
    return number_rows

def get_xingxing_y(ai_settings,xingxing_height):
    available_space_y = ai_settings.screen_height - 2 *xingxing_height
    number_xingxing_y = int(available_space_y / (2 * xingxing_height))
    return number_xingxing_y
#每列可以存储多少个星星

def create_xingxing(ai_settings,xingxings,screen,number_rows,number_xingxing_y):
    xingxing = Xingxing(ai_settings,screen)
    xingxing_height = xingxing.rect.height
    random_number_y = randint(0,number_xingxing_y)
    xingxing.y = xingxing_height + 2 * xingxing_height * random_number_y
    #使得星星的y坐标随机
    xingxing.rect.y = xingxing.y
    random_number_x = randint(0,number_rows)
    #使得星星的x坐标随机
    xingxing.rect.x = xingxing.rect.width + 2 * xingxing.rect.width * random_number_x
    #记录下每个星星Y的坐标
    xingxings.add(xingxing)
    #创建一列的外星人坐标y

def create_fleet(ai_settings,screen,xingxings):
    xingxing = Xingxing(ai_settings,screen)
    number_xingxing_y = get_xingxing_y(ai_settings,xingxing.rect.height)
    number_rows = get_number_rows(ai_settings,xingxing.rect.width)
    #计算一列可以容下几个星星
    for rows_number in range (number_rows):
        for xingxing_number in range(number_xingxing_y):
            create_xingxing(ai_settings,xingxings,screen,number_rows,number_xingxing_y)
            #创建一系列星星

def check_keydown_events(event):
    if event.key == pygame.K_q:
        sys.exit()
    #按键相应事件

def check_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown_events(event)


def update_screen(ai_settings,screen,xingxings):
    screen.fill(ai_settings.bg_color)
    xingxings.draw(screen)
    pygame.display.flip()
    #刷新屏幕

其实这样做的结果就是让一些星星的位置重叠了,然后出现了空缺,然后就是随机了

13.2.py

import pygame

from settings import Settings

from  xingxing import Xingxing

import game_functions0 as gf

from pygame.sprite import Group

def run_game():
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption('xingxing')
    #初始化游戏,并且建立一个屏幕对象

    xingxings = Group()
    gf.create_fleet(ai_settings,screen,xingxings)
    #创建一列星星
    while True:
        gf.check_events()
        gf.update_screen(ai_settings, screen,xingxings)

run_game()

运行13.2.py就可以得到随机生成的星星图了

13.3题

和之前的题目一样,我们需要创立雨滴,设置和功能,还有主运行程序文件
yudi.py

import pygame
from pygame.sprite import Sprite

class Yudi(Sprite):
    def __init__(self,ai_settings,screen):
        super(Yudi,self).__init__()
        self.ai_settings = ai_settings
        self.screen = screen
        #初始化雨滴的属性与位置

        self.image = pygame.image.load('yudi/yudi.bmp')
        self.rect = self.image.get_rect()
        #加载雨滴的图像,设置rect值

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.y = float(self.rect.y)
        #存储雨滴位置小数

    def blitme(self):
        #在指定位置绘制雨滴图像和外形
        self.screen.blit(self.image,self.rect)


    def check_edges(self):
        screen_rect = self.screen.get_rect()
        if self.rect.bottom >= screen_rect.bottom:
            return True
        #判断雨滴是否到了最底下
        
    def update(self):
        self.y += self.ai_settings.fleet_drop_speed
        self.rect.y = self.y
        #雨滴自由下落

game_functions.py

import pygame
import sys

from yudi import Yudi



def get_number_rows(ai_settings,yudi_height):
    #计算屏幕可以容纳多少行雨滴
    available_space_y = (ai_settings.screen_height - (3 * yudi_height))
    number_rows = int(available_space_y / (2 * yudi_height))
    return number_rows

def get_munber_yudis_x(ai_settings,yudi_width):
    #计算每行可以容纳多少雨滴,并返回这个值
    available_space_x = ai_settings.screen_width - 2 * yudi_width
    number_yudis_x = int(available_space_x / (2 * yudi_width))
    return number_yudis_x

def create_yudi(ai_settings,screen,yudis,yudi_number,row_number):
    yudi = Yudi(ai_settings, screen)
    #创立雨滴放在当前行
    yudi_width = yudi.rect.width
    yudi.x = yudi_width + 2 * yudi_width * yudi_number
    yudi.rect.x = yudi.x
    yudi.rect.y = yudi.rect.height + 2 * yudi.rect.height * row_number
    yudis.add(yudi)
    #创立每个雨滴的坐标

def create_fleet(ai_settings,screen,yudis):
    #创立一个雨滴,并计算一行可以容纳多少个雨滴(这个雨滴的创立是用来计算的)
    yudi= Yudi(ai_settings,screen)
    number_yudis_x = get_munber_yudis_x(ai_settings,yudi.rect.width)
    number_rows = get_number_rows(ai_settings,yudi.rect.height)

    #创立整行雨滴,其实我这里也没理解为什么做出来的是一行,而不是整个屏幕都是雨滴的效果
    for row_number in range(number_rows):
        for yudi_number in range(number_yudis_x):
            create_yudi(ai_settings,screen,yudis,yudi_number,row_number)

def check_keydown_events(event):
    if event.key == pygame.K_q:
        sys.exit()
    #按键相应事件

def check_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown_events(event)


def update_screen(ai_settings,screen,yudis):
    screen.fill(ai_settings.bg_color)
    yudis.draw(screen)
    pygame.display.flip()
    #刷新屏幕

def check_fleet_edges(yudis):
    yudi_update(yudis)
    #当有雨滴到达边缘时删除雨滴
    for yudi in yudis.sprites():
        if yudi.check_edges():
            yudis.remove(yudi)


def yudi_update(yudis):
    for yudi in yudis.sprites():
        yudi.update()
        #雨滴的运动轨迹

settings.py

class Settings():
    def __init__(self):
        #屏幕设置
        self.screen_width = 1600
        self.screen_height = 1200
        self.bg_color = (230,230,230)

        self.fleet_drop_speed = 5

13.3.py

import pygame
import pygame

from settings import Settings

from yudi import Yudi
import game_functions as gf

from pygame.sprite import Group

def run_game():
    #初始化游戏并创立一个屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("xialuode yudi")

    yudis = Group()
    #创立雨滴编组

    gf.create_fleet(ai_settings, screen, yudis)
    #创立雨滴群
    while True:
        gf.check_events()
        gf.check_fleet_edges(yudis)
        gf.update_screen(ai_settings, screen,yudis)

run_game()

最后的结果就是一行雨滴落下来到最下方消失,如果有人可以帮我解答下为什么不是一整个屏幕的雨滴落下来就万分感谢了,自己也测试删除代码试了下,就是因为13.3.py的 gf.check_fleet_edges(yudis)这一句代码导致的

13.4题

此题只需要在13.3代码上做一些小小改动就好了,改变雨滴落到屏幕底部时的内容
settings.py

class Settings():
    def __init__(self):
        #屏幕设置
        self.screen_width = 1600
        self.screen_height = 1200
        self.bg_color = (230,230,230)

        self.fleet_drop_speed = 1

game_functions.py

import pygame
import sys

from yudi import Yudi



def get_munber_yudis_x(ai_settings,yudi_width):
    #计算每行可以容纳多少雨滴,并返回这个值
    available_space_x = ai_settings.screen_width - 2 * yudi_width
    number_yudis_x = int(available_space_x / (2 * yudi_width))
    return number_yudis_x

def create_yudi(ai_settings,screen,yudis,yudi_number):
    yudi = Yudi(ai_settings, screen)
    #创立雨滴放在当前行
    yudi_width = yudi.rect.width
    yudi.x = yudi_width + 2 * yudi_width * yudi_number
    yudi.rect.x = yudi.x
    yudis.add(yudi)
    #创立每个雨滴的坐标

def create_fleet(ai_settings,screen,yudis):
    #创立一个雨滴,并计算一行可以容纳多少个雨滴(这个雨滴的创立是用来计算的)
    yudi= Yudi(ai_settings,screen)
    number_yudis_x = get_munber_yudis_x(ai_settings,yudi.rect.width)
    #创立整行雨滴,其实我这里也没理解为什么做出来的是一行,而不是整个屏幕都是雨滴的效果

    for yudi_number in range(number_yudis_x):
        create_yudi(ai_settings,screen,yudis,yudi_number)

def check_keydown_events(event):
    if event.key == pygame.K_q:
        sys.exit()
    #按键相应事件

def check_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            check_keydown_events(event)


def update_screen(ai_settings,screen,yudis):
    screen.fill(ai_settings.bg_color)
    yudis.draw(screen)
    pygame.display.flip()
    #刷新屏幕

def check_fleet_edges(ai_settings,screen,yudis):
    yudi_update(yudis)
    #当有雨滴到达边缘时删除雨滴
    for yudi in yudis.sprites():
        if yudi.check_edges():
            yudis.remove(yudi)
    if yudi.check_edges():
        create_fleet(ai_settings, screen, yudis)
    #当有雨滴到达底部边缘时再此重新创建一行雨滴




def yudi_update(yudis):
    for yudi in yudis.sprites():
        yudi.update()
        #雨滴的运动轨迹

yudi.py

import pygame
from pygame.sprite import Sprite


class Yudi(Sprite):
    def __init__(self, ai_settings, screen):
        super(Yudi, self).__init__()
        self.ai_settings = ai_settings
        self.screen = screen
        # 初始化雨滴的属性与位置

        self.image = pygame.image.load('yudi/yudi.bmp')
        self.rect = self.image.get_rect()
        # 加载雨滴的图像,设置rect值

        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        self.y = float(self.rect.y)
        # 存储雨滴位置小数

    def blitme(self):
        # 在指定位置绘制雨滴图像和外形
        self.screen.blit(self.image, self.rect)

    def check_edges(self):
        screen_rect = self.screen.get_rect()
        if self.rect.bottom >= screen_rect.bottom:
            return True
        # 判断雨滴是否到了最底下

    def update(self):
        screen_rect = self.screen.get_rect()
        if self.rect.bottom <= screen_rect.bottom:
            self.y += self.ai_settings.fleet_drop_speed
            self.rect.y = self.y
        # 雨滴自由下落

13.4.py

import pygame

from settings import Settings

from yudi import Yudi
import game_functions as gf

from pygame.sprite import Group

def run_game():
    #初始化游戏并创立一个屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("xialuode yudi")

    yudis = Group()
    #创立雨滴编组

    gf.create_fleet(ai_settings, screen, yudis)
    #创立雨滴群
    while True:
        gf.check_events()
        gf.check_fleet_edges(ai_settings, screen,yudis)
        gf.update_screen(ai_settings, screen,yudis)

run_game()

运行13.4.py就可以看到绵绵不断的雨啦

13.5题

ball.py

import pygame
from random import randint
from pygame.sprite import Sprite

class Ball(Sprite):
    def __init__(self,ai_settings,screen):
        super(Ball,self).__init__()
        self.ai_settings = ai_settings
        self.screen = screen
        #初始化设置

        self.image = pygame.image.load('ball/ball.bmp')
        self.rect = self.image.get_rect()
        #加载球的图像和外形

        self.rect.y = self.rect.height
        self.x = float(self.rect.x)
        self.rect.x = randint(self.rect.width, ai_settings.screen_width-self.rect.width)
        #初始化球的位置,使其出现在左上角

        self.y = float(self.rect.y)
        #y坐标存储小数

    def update(self,ai_settings):
        self.y += ai_settings.ball_fall_speed
        self.rect.y = self.y
        #球一直下落

role.py

import pygame
from pygame.sprite import Sprite

class Role(Sprite):
    def __init__(self,screen,ai_settings):
        super(Role,self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        # 初始化角色

        self.image = pygame.image.load('role/role.bmp')
        self.rect = self.image.get_rect()
        #加载人物的外形和图像
        self.moving_right = False
        self.moving_left = False
        #初始化按键标志

    def moving(self):
        if self.moving_right and self.rect.x <= self.ai_settings.screen_width:
            self.rect.x += self.ai_settings.role_move_speed
        elif self.moving_left and self.rect.x >= 0:
            self.rect.x -= self.ai_settings.role_move_speed
    def blitme(self):
        self.screen.blit(self.image,self.rect)
        #在指定位置绘制角色

settings.py

class Settings():
    def __init__(self):
        self.screen_width = 1600
        self.screen_height = 1200
        self.bg_color = (230,230,230)
        #屏幕设置

        self.ball_fall_speed = 5
        #球下坠速度设置

        self.role_move_speed = 1.5
        #人物移动速度设置

game_functions.py

import pygame
import sys
from ball import Ball

def create_ball(screen,ai_settings):
    #使得ball的水平位置随机
    ball = Ball(screen,ai_settings)


def check_keydown_events(event,role):
    if event.key == pygame.K_RIGHT:
        role.moving_right = True
    elif event.key == pygame.K_LEFT:
        role.moving_left =True
    elif event.key == pygame.K_q:
        sys.exit()
    #按键和相应的事件发生

def check_keyup_events(event,role):
    if event.key == pygame.K_RIGHT:
        role.moving_right = False
    elif event.key == pygame.K_LEFT:
            role.moving_left = False
    #按键松开和相应的事件发生

def check_events(role):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,role)

        elif event.type == pygame.KEYUP:
            check_keyup_events(event,role)

def check_ball_role_cllisions(ball,role,screen,ai_settings):`在这里插入代码片`
    callision = pygame.sprite.groupcollide(ball, role, True, True)
    #删除发生碰撞的球
    if ball.rect.y >= ball.ai_settings.screen_height:
        ball.remove()
    #当有球超出界限的时候删除
    if len(ball) == 0:
        create_ball(screen,ai_settings)
    #当没有球的时候,新建一个球

def update_screen(ai_settings, screen, ball,role):
    screen.fill(ai_settings.bg_color)
    #充满背景色
    role.blitme()
    ball.draw(screen)
    pygame.display.flip()
    #让最近绘制的屏幕可见

13.5.py

import pygame
from settings import Settings

from ball import Ball

import game_functions as gf

from role import Role

def run_game():
#初始化游戏并且创立一个屏幕对象
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
pygame.display.set_caption(‘jieqiu’)

role = Role(ai_settings,screen)
ball = Ball(ai_settings,screen)
while True:
    #开始循环
    ball.update(ai_settings)
    gf.check_events(role)
    gf.check_ball_role_cllisions(ball,role,screen,ai_settings)
    gf.update_screen(ai_settings, screen, ball,role)

run_game()

运行13.5.py即可

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值