赞
踩
学习《python编程:从入门到实践》的第一个项目案例后,本来想把自己的注释笔记分享出来,但考虑到这样不得不把书上的代码暴露出来,为了保护版权所以还是算了。
这篇博客是用书本项目的前半段知识,自己写出来的小游戏,一些计分之类的功能还没有加上去。主要内容是控制一个挡板,躲避从上空掉落下来的球。
我把下面的挡板和上面的球都设置为黑色长方体了,可以自己把上面的黑色方块想象成小球
这是项目结构截图
下面是代码和我写上去的注释
game_main.py
运行游戏时的主体部分,在这里运行函数run()即可开始游戏
import pygame from configure import Configure import functions as func from baffle import Baffle from pygame.sprite import Group def run(): # 初始化游戏并创建一个屏幕对象 # 初始化背景设置,让pygame正常工作 pygame.init() # 创建一个Configure实例,并将其存储在变量 conf 中 conf = Configure() # 创建一个名为screen 的显示窗口,用来绘制这个游戏的所有图形元素 screen = pygame.display.set_mode((conf.screen_width, conf.screen_height)) # caption的意思是给漫画添加说明文字,这里是修改窗口名称 pygame.display.set_caption("Catch the ball") # 创建一个挡板实例 baffle = Baffle(conf,screen) # 创建一个balls列表 balls = Group() # 调用create_fleet函数往balls列表里面添加ball func.create_fleet(conf,screen,balls) # 当运行游戏也就是执行run()之后,这个while循环将一直执行,里面的函数也一直在被调用 while True: # 导入functions.py文件中的check_events函数,检测鼠标与键盘事件 # 前面说过,这个循环一直在执行,所以一旦出现鼠标键盘事件就会被立刻捕捉 func.check_events(baffle) # 更新挡板baffle的最新位置 baffle.update() # 更新balls也就是掉落的球组的最新位置 func.update_balls(conf,screen,baffle,balls) # 刷新背景屏幕 func.update_screen(conf,screen,baffle,balls) run()
ball.py,这个是从屏幕上方要掉落的小球
import pygame from pygame.sprite import Sprite class Ball(Sprite): def __init__(self,conf,screen): super().__init__() # 初始化conf与screen self.conf = conf self.screen = screen # 获取球ball的图像,并获取其尺寸大小 self.image = pygame.image.load('image/baffle.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) # 更新球的y轴位置,也就是模拟球向下掉落的过程 def update(self): self.y += self.conf.balls_drop_speed self.rect.y = self.y
baffle.py ,这个是屏幕下方的挡板,由玩家控制,要躲避从上方掉落的小球
import pygame class Baffle(): def __init__(self,conf,screen): # 初始化conf与screen self.screen = screen self.conf = conf # 获取挡板baffle的图像,并获取其尺寸大小 self.image = pygame.image.load('image/baffle.bmp') self.rect = self.image.get_rect() # 获取背景屏幕的尺寸 self.screen_rect = screen.get_rect() # 初始化挡板的位置,也就是屏幕底部中间的位置 # 当游戏开始后,挡板就会出现在这个设置好的位置上 self.rect.centerx = self.screen_rect.centerx self.rect.bottom = self.screen_rect.bottom self.center = float(self.rect.centerx) # 初始化挡板的左右移动标志,标志为False时挡板不在移动 self.moving_right = False self.moving_left = False def update(self): # 当向右移动标志为True而且挡板没有超过背景屏幕右侧时 if self.moving_right and self.rect.right < self.screen_rect.right: self.center += self.conf.baffle_speed # 当向左移动标志为True而且挡板没有超过背景屏幕左侧时 if self.moving_left and self.rect.left > 0: self.center -= self.conf.baffle_speed # 根据self.center更新rect对象 self.rect.centerx = self.center def blitme(self): # 在指定的地方绘制飞船 self.screen.blit(self.image,self.rect)
functions.py,这个用来存放游戏中会被调用的各种函数
import sys import pygame import random from ball import Ball from pygame.sprite import spritecollideany from baffle import Baffle # 键盘按下事件:keydown() 是在键盘按下就会触发 def check_keydown_events(event,baffle): # 检测到右键被按下 if event.key == pygame.K_RIGHT: # 更改向右移动状态为True,表明此时的挡板正在向右移动 baffle.moving_right = True # 检测到左键被按下 elif event.key == pygame.K_LEFT: # 更改向左移动状态为True,表明此时的挡板正在向左移动 baffle.moving_left = True # 键盘弹起事件:keyup() 是在键盘松手就会触发 def check_keyup_events(event,baffle): # 检测到右键被松开 if event.key == pygame.K_RIGHT: # 恢复向右移动状态为False baffle.moving_right = False # 检测到左键被送开 elif event.key == pygame.K_LEFT: # 恢复向左移动状态为False baffle.moving_left = False def check_events(baffle): for event in pygame.event.get(): # 如果鼠标点击窗口右上角的x,则退出游戏 if event.type == pygame.QUIT: sys.exit() # 如果事件类型为按下键盘 elif event.type == pygame.KEYDOWN: check_keydown_events(event, baffle) # 如果事件类型为松开键盘 elif event.type == pygame.KEYUP: check_keyup_events(event,baffle) def update_screen(conf,screen,baffle,balls): # 每次循环时都重绘屏幕 screen.fill(conf.color) # 绘制挡板 baffle.blitme() # 在屏幕上面绘制球 balls.draw(screen) pygame.display.flip() def update_balls(conf,screen,baffle,balls): # 获取背景屏幕尺寸 screen_rect = screen.get_rect() # 遍历balls中的每一个球ball,如果球落到了屏幕的下方,则删除这个球 for ball in balls.copy(): if ball.rect.bottom >= screen_rect.bottom: balls.remove(ball) # 检查屏幕上所剩的球的个数 check_num_balls(conf,screen,balls) balls.update() # 如果球和挡板发生了碰撞,则在终端打印“collision” if pygame.sprite.spritecollideany(baffle,balls): print("collision") def check_num_balls(conf,screen,balls): # 检查balls里面剩下的ball的数量,如果数量为0,则刷新出来新的balls if len(balls) == 0: create_fleet(conf,screen,balls) def get_num_x(conf,ball_width): # 计算一行里面可以有多少个球 available_space_x = conf.screen_width #球之间要有一定的空格,所以一个球所占的实际空间按两个球来算 number_ball_x = int(available_space_x / (ball_width * 2)) return number_ball_x def create_fleet(conf,screen,balls): ball = Ball(conf,screen) # 查看一行可以有多少个球 number_ball_x = get_num_x(conf,ball.rect.width) # 建立一个随机数列表,这样传入create_ball中的number_ball_x参数数值是随机的 ran = [] for n in range(number_ball_x): nums = random.randint(0,number_ball_x) ran.append(nums) # 遍历每一个球,调用create_ball,计算被遍历到的球的所在位置,然后加入balls列表中 for num in ran: create_ball(conf,screen,balls,num) def create_ball(conf,screen,balls,number_ball_x): ball = Ball(conf,screen) ball_width = ball.rect.width # 计算当前被遍历到的球所在的x轴位置 # 坐标在屏幕的左上角为(0,0),往右下角则x,y值增大 ball.rect.x = ball_width * 2 * number_ball_x # 球的y轴位置 ball.rect.y = ball.rect.height # 根据上面的x轴与y轴位置,将ball放入列表balls中 balls.add(ball)
configure.py,用来存放各种游戏元素的设置
class Configure():
def __init__(self):
# 设置屏幕的尺寸大小
self.screen_width = 1000
self.screen_height = 600
# 设置屏幕的背景颜色
self.color = (230, 230, 230)
# 设置挡板的移动速度
self.baffle_speed = 1
# 设置球的下落速度
self.balls_drop_speed = 0.5
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。