python|Python学习笔记(3)---B站黑马程序员

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:
python|Python学习笔记(3)---B站黑马程序员
文章图片

(2)输入命令:pip install pygame
python|Python学习笔记(3)---B站黑马程序员
文章图片

(3)输入命令验证pygame是否安装:python -m pygame.examples.aliens
python|Python学习笔记(3)---B站黑马程序员
文章图片

002-快速入门 python|Python学习笔记(3)---B站黑马程序员
文章图片

(1)项目准备
python|Python学习笔记(3)---B站黑马程序员
文章图片

游戏素材评论区有,这里给出链接:

飞机大战游戏素材
移动静止的图像产生动画效果

(2)使用 pygame 创建图形窗口
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

游戏中的所有元素(物体)都是以 矩形区域 来描述位置的 通过四个要素(x, y)物体在游戏窗口中的位置(物体所在矩形区域的左上角), (width, height)物体所在矩形区域的宽度和高度,来描述这个矩形区域。python提供pygame.Rect类来描述矩形区域,这个类中很多属性,如上图。 pygame.Rect(x, y, width, height) ---> 创建对象 size属性返回一个元组(width, height)不执行 pygame.init()方法,同样可以使用 pygame.Rect

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

(3)理解图像并实现图像绘制
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

上面图像的小格子是透明区域

python|Python学习笔记(3)---B站黑马程序员
文章图片

(4)理解游戏循环和游戏时钟
python|Python学习笔记(3)---B站黑马程序员
文章图片

每次调用update方法会将之前所有绘制的结果,一次性更新到游戏屏幕上。 每次调用update方法得到的结果是帧,一般要达到每秒调用60次update方法。 游戏中的动画效果,大部分是通过静态图像移动显示的。

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

英雄(飞机)每移动一次,背景图片就要被重新绘制一次,否则英雄会有残影。
python|Python学习笔记(3)---B站黑马程序员
文章图片

当飞机“完全”从上方飞出屏幕之后,再将飞机移动到屏幕底部: 两种方法: 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

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

pygame.event.get()可以获得用户所有的操作: 鼠标移动,按键盘,关闭窗口等等上面的代码,点击叉号 是无法关闭游戏窗口的,下面演示如何关闭游戏窗口:

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

(5)理解精灵和精灵组
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

在一个游戏中,有很多游戏对象。 对于每一个游戏对象,都要设置它的图像image,位置rect等属性和更新位置update等方法, 如果一个一个创建游戏对象很麻烦,所以pygame提供里两个类:sprite是精灵的意思。 pygame.sprite.Sprite ---> 专门设置游戏对象的图像,位置等属性和更新位置等方法 pygame.sprite.Group ---> 游戏对象组,放置多个游戏对象,可以同时设置多个游戏对象注意:pygame.sprite.Sprite类中本身是没有image和rect两个属性的,要在它的派生子类中设置 并且默认的update方法中也没有写任何代码,要在子类中重写。

python|Python学习笔记(3)---B站黑马程序员
文章图片

如果一个类的父类不是object,在重写初始化方法__init__时,要先super()调用一个父类的__init__方法,因为父类的__init__也写有代码,需要执行,而子类重写__init__方法会覆盖父类的init方法,导致父类的init方法无法执行。
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

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-游戏框架搭建 python|Python学习笔记(3)---B站黑马程序员
文章图片

(1)明确主程序职责
python|Python学习笔记(3)---B站黑马程序员
文章图片

一个游戏主程序的职责有两个: 游戏初始化:init 设置游戏窗口 创建游戏时钟 创建精灵/精灵组 --->创建一个私有方法__create_sprites专门处理 游戏循环(即游戏开始):start_game 设置刷新帧率 事件监听--->__event_handler 碰撞检测--->__check_collide 更新/绘制精灵组--->__update_sprites 更新屏幕显示游戏结束--->__game_over 在事件监听到鼠标点击×时调用 一个循环里写了太多东西,所以创建相应的私有方法解决部分操作。

python|Python学习笔记(3)---B站黑马程序员
文章图片

(2)实现主程序类
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

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()

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

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)准备游戏精灵组
以下操作先不写,看懂就好,跳过这一步。
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

004-游戏背景 python|Python学习笔记(3)---B站黑马程序员
文章图片

(1)背景交替滚动
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

父类GameSprite的update方法无法实现背景图片滚动,所以再写一个子类Background重写父类的update方法。

python|Python学习笔记(3)---B站黑马程序员
文章图片

(2)显示游戏背景
python|Python学习笔记(3)---B站黑马程序员
文章图片

(3)简化代码
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

005-敌机 python|Python学习笔记(3)---B站黑马程序员
文章图片

(1)使用定时器添加敌机
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

(2)设计Enemy类
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

在plane_main.py的__create_sprites,添加敌机精灵组: 敌机是定时被创建的,因此在这里不需要创建敌机精灵。

python|Python学习笔记(3)---B站黑马程序员
文章图片

在plane_main.py的__event_handler,定时创建敌机,并添加到敌机精灵组:

python|Python学习笔记(3)---B站黑马程序员
文章图片

在plane_main.py的__update_sprites,更新精灵组并绘制到屏幕上:

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

import random 写在 import pygame 上方
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

不做任何修改,敌机的初始位置如下的红方格:
python|Python学习笔记(3)---B站黑马程序员
文章图片

敌机y方向的初始位置:bottom=0或者y=bottom-height
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

使用自带的kill()方法可以将精灵从精灵组中移出(即删除这个精灵) 因为__del__内置方法会在对象被销毁前调用,所以可以用来判断对象是否被销毁。 在 plane_sprites.py 中写如下代码:

python|Python学习笔记(3)---B站黑马程序员
文章图片

006-英雄和子弹 python|Python学习笔记(3)---B站黑马程序员
文章图片

(1)设计英雄和子弹类
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

(2)创建和移动英雄
首先将plane_sprites中的print()注释掉,太多了。然后给__del__中添加pass。
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

使用第二种方式
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

(3)创建和发射子弹
python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

python|Python学习笔记(3)---B站黑马程序员
文章图片

007-碰撞检测 python|Python学习笔记(3)---B站黑马程序员
文章图片

groupcollide()方法--->两个精灵组中所有的精灵的碰撞检测: group1--->精灵组1 group2--->精灵组2 dokill1--->布尔类型,若设为True,则发生碰撞时销毁group1中发生碰撞的精灵 dokill2--->布尔类型,若设为True,则发生碰撞时销毁group2中发生碰撞的精灵

python|Python学习笔记(3)---B站黑马程序员
文章图片

spritecollide()方法--->判断某个精灵和指定精灵组中的精灵是否发生碰撞: sprite--->某个精灵 group--->指定精灵组 dokill--->布尔类型,如为True,则指定精灵组中发生碰撞的精灵会被自动移除 该方法返回 指定精灵组中被移除的精灵列表

python|Python学习笔记(3)---B站黑马程序员
文章图片

六、Vi
在评论区找到的讲义:

B站的Python课程讲义

    推荐阅读