Python学习笔记(1)—B站黑马程序员
【python|Python学习笔记(3)---B站黑马程序员】Python学习笔记(2)—B站黑马程序员
Python学习笔记(3)—B站黑马程序员
文章目录
- 五、项目实战——飞机大战
-
- 001-Pycharm中安装pygame
- 002-快速入门
-
- (1)项目准备
- (2)使用 pygame 创建图形窗口
- (3)理解图像并实现图像绘制
- (4)理解游戏循环和游戏时钟
- (5)理解精灵和精灵组
- 003-游戏框架搭建
-
- (1)明确主程序职责
- (2)实现主程序类
- (3)准备游戏精灵组
- 004-游戏背景
-
- (1)背景交替滚动
- (2)显示游戏背景
- (3)简化代码
- 005-敌机
-
- (1)使用定时器添加敌机
- (2)设计Enemy类
- 006-英雄和子弹
-
- (1)设计英雄和子弹类
- (2)创建和移动英雄
- (3)创建和发射子弹
- 007-碰撞检测
- 六、Vi
五、项目实战——飞机大战 001-Pycharm中安装pygame (1)点击pycharm下方的Terminal:
文章图片
(2)输入命令:pip install pygame
文章图片
(3)输入命令验证pygame是否安装:python -m pygame.examples.aliens
文章图片
002-快速入门
文章图片
(1)项目准备
文章图片
游戏素材评论区有,这里给出链接:
飞机大战游戏素材
移动静止的图像产生动画效果
(2)使用 pygame 创建图形窗口
文章图片
文章图片
文章图片
文章图片
文章图片
游戏中的所有元素(物体)都是以 矩形区域 来描述位置的
通过四个要素(x, y)物体在游戏窗口中的位置(物体所在矩形区域的左上角),
(width, height)物体所在矩形区域的宽度和高度,来描述这个矩形区域。python提供pygame.Rect类来描述矩形区域,这个类中很多属性,如上图。
pygame.Rect(x, y, width, height) ---> 创建对象
size属性返回一个元组(width, height)不执行 pygame.init()方法,同样可以使用 pygame.Rect
文章图片
文章图片
文章图片
文章图片
(3)理解图像并实现图像绘制
文章图片
文章图片
文章图片
文章图片
文章图片
上面图像的小格子是透明区域
文章图片
(4)理解游戏循环和游戏时钟
文章图片
每次调用update方法会将之前所有绘制的结果,一次性更新到游戏屏幕上。
每次调用update方法得到的结果是帧,一般要达到每秒调用60次update方法。
游戏中的动画效果,大部分是通过静态图像移动显示的。
文章图片
文章图片
文章图片
文章图片
英雄(飞机)每移动一次,背景图片就要被重新绘制一次,否则英雄会有残影。
文章图片
当飞机“完全”从上方飞出屏幕之后,再将飞机移动到屏幕底部:
两种方法:
if hero_rect.y + hero_rect.height <= 0:
hero_rect.y = 700
或者
hero_rect.bottom = hero_rect.y + hero_rect.height
if hero_rect.bottom <= 0:
hero_rect.y = 700
文章图片
文章图片
pygame.event.get()可以获得用户所有的操作:
鼠标移动,按键盘,关闭窗口等等上面的代码,点击叉号 是无法关闭游戏窗口的,下面演示如何关闭游戏窗口:
文章图片
文章图片
(5)理解精灵和精灵组
文章图片
文章图片
在一个游戏中,有很多游戏对象。
对于每一个游戏对象,都要设置它的图像image,位置rect等属性和更新位置update等方法,
如果一个一个创建游戏对象很麻烦,所以pygame提供里两个类:sprite是精灵的意思。
pygame.sprite.Sprite ---> 专门设置游戏对象的图像,位置等属性和更新位置等方法
pygame.sprite.Group ---> 游戏对象组,放置多个游戏对象,可以同时设置多个游戏对象注意:pygame.sprite.Sprite类中本身是没有image和rect两个属性的,要在它的派生子类中设置
并且默认的update方法中也没有写任何代码,要在子类中重写。
文章图片
如果一个类的父类不是object,在重写初始化方法__init__时,要先super()调用一个父类的__init__方法,因为父类的__init__也写有代码,需要执行,而子类重写__init__方法会覆盖父类的init方法,导致父类的init方法无法执行。
文章图片
文章图片
文章图片
文章图片
文章图片
import pygame
from plane_sprites import *pygame.init()# 创建游戏窗口 宽480像素 高700像素,返回游戏屏幕
screen = pygame.display.set_mode((480, 700))# 绘制背景图像
# 1>加载图像数据
background = pygame.image.load("./images/background.png")# 2> blit 设置图像位置:(0, 0) 图像的左上角放在游戏窗口左上角
screen.blit(background, (0, 0))# 3> update 更新屏幕显示
# pygame.display.update()# 绘制英雄的飞机图像
hero = pygame.image.load("./images/me1.png")
screen.blit(hero, (200, 500))# 最后调用一次update方法即可
pygame.display.update()# 创建游戏时钟对象
clock = pygame.time.Clock()# 1.定义英雄的初始位置
hero_rect = pygame.Rect(150, 500, 102, 126)# 创建敌机精灵
enemy1 = GameSprite("./images/enemy1.png")
enemy2 = GameSprite("./images/enemy1.png", 2)
enemy2.rect.x = 200
# 创建敌机精灵组
enemy_group = pygame.sprite.Group(enemy1, enemy2)# 游戏循环,让游戏窗口一直保持(游戏循环,意味着游戏开始)
while True:
# 设置游戏刷新帧率
clock.tick(60)# 监听事件(同一时刻可能会发生多个事件,所以用for)
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("游戏结束。。。")# 卸载所有游戏模块
pygame.quit()# 终止程序执行(因为有for和while,所以不能使用break)
exit()# 2.更新英雄位置
hero_rect.y -= 1# 3.如果移出屏幕,则将英雄从顶部移动到屏幕底部if hero_rect.y + hero_rect.height <= 0:
hero_rect.y = 700# 4.绘制背景图片(英雄每移动一次,背景图片就要被重新绘制一次,否则会出现英雄的残影)
screen.blit(background, (0, 0))# 5.绘制英雄图像
screen.blit(hero, hero_rect)# 让精灵组调用两个方法
# update--->调用精灵组的update方法可以让每一个精灵分别调用自己的update方法(让组中的所有精灵更新位置)
enemy_group.update()
# draw(self,surface屏幕对象)--->将所有的精灵图像显示到屏幕上(在screen上绘制所有的精灵)
enemy_group.draw(screen)# 6.更新显示
pygame.display.update()pygame.quit()
003-游戏框架搭建
文章图片
(1)明确主程序职责
文章图片
一个游戏主程序的职责有两个:
游戏初始化:init
设置游戏窗口
创建游戏时钟
创建精灵/精灵组 --->创建一个私有方法__create_sprites专门处理 游戏循环(即游戏开始):start_game
设置刷新帧率
事件监听--->__event_handler
碰撞检测--->__check_collide
更新/绘制精灵组--->__update_sprites
更新屏幕显示游戏结束--->__game_over 在事件监听到鼠标点击×时调用
一个循环里写了太多东西,所以创建相应的私有方法解决部分操作。
文章图片
(2)实现主程序类
文章图片
文章图片
文章图片
文章图片
文章图片
文章图片
文章图片
文章图片
import pygame
from plane_sprites import *class PlaneGame(object):
"""飞机大战游戏主程序"""def __init__(self):
print("游戏初始化")
# 1.创建游戏的窗口(set_mode(元组) SCREEN_RECT.size--->元组(屏幕宽度,屏幕高度))
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 2.创建游戏的时钟
self.clock = pygame.time.Clock()
# 3.调用私有方法,创建精灵和精灵组
self.__create_sprites()def __create_sprites(self):
passdef start_game(self):
print("开始游戏。。。")while True:
pass# 测试当前程序:创建游戏对象,开始游戏
# __name__代表当前模块名,如果__name__=__main__则导入当前模块
if __name__ == "__main__":
# 创建游戏对象
game = PlaneGame()# 开始游戏
game.start_game()
文章图片
文章图片
import pygame
from plane_sprites import *class PlaneGame(object):
"""飞机大战游戏主程序"""def __init__(self):
print("游戏初始化")
# 1.创建游戏的窗口(set_mode(元组) SCREEN_RECT.size--->元组(屏幕宽度,屏幕高度))
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 2.创建游戏的时钟
self.clock = pygame.time.Clock()
# 3.调用私有方法,创建精灵和精灵组
self.__create_sprites()def __create_sprites(self):
passdef start_game(self):
print("开始游戏。。。")# 游戏循环(代表游戏开始)
while True:
# 1.设置刷新帧率(将刷新帧率设置为常量,在为主程序提供工具的plane_sprites文件中设置)
self.clock.tick(FRAME_PER_SCREEN)
# 2.事件监听
self.__event_handler()
# 3.碰撞检测
self.__check_collide()
# 4.更新精灵组
self.__update_sprites()
# 5.更新屏幕显示
pygame.display.update()def __event_handler(self):
"""事件监听"""for event in pygame.event.get():
# 游戏结束
if event.type == pygame.QUIT:
PlaneGame.__game_over()def __check_collide(self):
"""碰撞检测"""
passdef __update_sprites(self):
"""更新精灵组"""
pass@staticmethod
# 没有调用任何属性,应设置位静态方法
def __game_over():
"""游戏结束"""print("游戏结束")
pygame.quit()
exit()# 测试当前程序:创建游戏对象,开始游戏
# __name__代表当前模块名,如果__name__=__main__则导入当前模块
if __name__ == "__main__":
# 创建游戏对象
game = PlaneGame()# 开始游戏
game.start_game()
(3)准备游戏精灵组
以下操作先不写,看懂就好,跳过这一步。
文章图片
文章图片
004-游戏背景
文章图片
(1)背景交替滚动
文章图片
文章图片
文章图片
父类GameSprite的update方法无法实现背景图片滚动,所以再写一个子类Background重写父类的update方法。
文章图片
(2)显示游戏背景
文章图片
(3)简化代码
文章图片
文章图片
文章图片
文章图片
文章图片
005-敌机
文章图片
(1)使用定时器添加敌机
文章图片
文章图片
文章图片
(2)设计Enemy类
文章图片
文章图片
文章图片
在plane_main.py的__create_sprites,添加敌机精灵组:
敌机是定时被创建的,因此在这里不需要创建敌机精灵。
文章图片
在plane_main.py的__event_handler,定时创建敌机,并添加到敌机精灵组:
文章图片
在plane_main.py的__update_sprites,更新精灵组并绘制到屏幕上:
文章图片
文章图片
import random 写在 import pygame 上方
文章图片
文章图片
不做任何修改,敌机的初始位置如下的红方格:
文章图片
敌机y方向的初始位置:bottom=0或者y=bottom-height
文章图片
文章图片
文章图片
使用自带的kill()方法可以将精灵从精灵组中移出(即删除这个精灵)
因为__del__内置方法会在对象被销毁前调用,所以可以用来判断对象是否被销毁。
在 plane_sprites.py 中写如下代码:
文章图片
006-英雄和子弹
文章图片
(1)设计英雄和子弹类
文章图片
文章图片
(2)创建和移动英雄
首先将plane_sprites中的print()注释掉,太多了。然后给__del__中添加pass。
文章图片
文章图片
文章图片
文章图片
使用第二种方式
文章图片
文章图片
文章图片
文章图片
(3)创建和发射子弹
文章图片
文章图片
文章图片
文章图片
文章图片
007-碰撞检测
文章图片
groupcollide()方法--->两个精灵组中所有的精灵的碰撞检测:
group1--->精灵组1
group2--->精灵组2
dokill1--->布尔类型,若设为True,则发生碰撞时销毁group1中发生碰撞的精灵
dokill2--->布尔类型,若设为True,则发生碰撞时销毁group2中发生碰撞的精灵
文章图片
spritecollide()方法--->判断某个精灵和指定精灵组中的精灵是否发生碰撞:
sprite--->某个精灵
group--->指定精灵组
dokill--->布尔类型,如为True,则指定精灵组中发生碰撞的精灵会被自动移除
该方法返回 指定精灵组中被移除的精灵列表
文章图片
六、Vi
在评论区找到的讲义:
B站的Python课程讲义
推荐阅读
- 线性回归|多元统计分析
- Python|Anaconda安装教程及使用教程(图文)
- pytorch|pytorch_lesson2 张量的索引+torch.index_select+torch.view+张量的分片函数+张量的合并操作+张量的维度变换
- 深度学习|【深度学习】Yolov5标签归一化处理——json转换为txt
- sklearn|t-SNE非线性降维
- python|python编写冒泡算法
- Python|Pandas合并数据集
- VUE|Flask+VUE 实现页面增删改查显示开发+测试(图文教程附源码)
- #|Python学习笔记 - Python编程规范