Python飞机大战,Pygame入门,源码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python飞机大战,Pygame入门,源码相关的知识,希望对你有一定的参考价值。


1、pep8语法规范

  • 遵循语法规范,可以让我们的代码可读性更好,更容易融入新的开发环境。
  • 大多数语法规范可以使用alt + ctrl + L 进行格式化
  • 但是很多规范还是要靠自己调整

2、飞机大战学习的意义

  • 学习飞机大战不是为了让大家做游戏,而是巩固之前学习的知识,让大家了解框架或者三方模块的使用方式
  • 学习飞机大战要学会查询api文档,而不是将所有的函数或方法背下来
  • 使用第三方框架或者包,是为了调用其功能,不是为了解决技术难题,所以不必过度钻研底层代码

3、pygame包的安装

  • 第一种方式:File —> Setting—> Project:工程名—>Python interpret–> 到解释器模块列表下方的+点击—>查询要安装的模块—>点击底下的 Install Package
  • 第二种方式:点击pycharm底下的terminal 打开终端,使用pip list 查看解释器的模块列表,如果有pygame就证明已将安装成功了,如果没有,就输入pip install pygame 进行安装
  • 注意:如果警告pip不是最新版本,不用管他

4、添加python环境变量

​不是内部或外部命令,也不是可运行的程序 或批处理文件。 ​

  • 提示这个就是因为没有认真听讲或者不听话。(没有在安装解释器时勾选add to path)
  • 手动添加环境变量流程:
  • 在此电脑中右键点击属性
  • 在属性中选择高级系统设置
  • 点击环境变量按钮
  • 在系统环境变量中双击 Path
  • 找到你的解释器所在的文件夹:(可以使用全局搜索找到python.exe文件)
  • 点击新建,将路径添加到环境变量中
  • 然后找到python.exe所在路径下的Script目录,继续将路径添加到环境变量中
  • 测试 python 和pip 能否正常使用(如果是在终端中执行,需要将终端重启后环境变量才会生效)

5、飞机大战的实现流程

# 如果想要是实现飞机大战,需要分析飞机大战的实现流程恒
# 流程:
# 1.游戏需要有一个呈现数据的窗口,我们称之为窗体或者窗口,也就是显示飞机大战游戏的容器.
# 2.在窗口上添加图片,用于作为飞机大战的背景
# 3.在窗口中添加敌机,并且让敌机进行运动
# 4.在窗口中添加玩家飞机,并且让玩家飞机,根据鼠标的移动而移动位置
# 5.在窗口中添加子弹,并实现让子弹移动的功能
# 6.判断子弹和敌机的碰撞,如果碰撞,则敌机销毁
# 7.判断玩家飞机和敌机的碰撞,碰撞后退出游戏

6、创建飞机大战窗口

# 导入pygame模块
import pygame
import pygame.locals


# 创建窗口
# 怎么设计窗口的大小??? 窗体大小,要与背景图片大小一致
# 背景图片的大小是512*768所以窗口大小,就定义为512*768就可以了
window = pygame.display.set_mode((512, 768))

# 为了让窗口不会立即关闭,而是等待我们的操作,需要循环刷新窗口
# 直接使用while True 死循环刷新窗口
while True:
# 刷新窗口内容的命令
pygame.display.update()
# 再刷新窗口时,也要不断获取用户的操作信息,如果我们想要获取可以使用evnet
# 获取所有的窗口事件(事件就是用户做出的操作)
# 当前方法的返回值是一个列表,内部获取了所有的窗口事件(用户的点击,鼠标移动,关闭按钮的点击等)
# 我们可以根据不同的事件做出不同的反馈例如QUIT 可以退出程序
# print(pygame.event.get())
for event in pygame.event.get():
if event.type == pygame.locals.QUIT:
exit(退出游戏)

7、飞机大战背景图片的添加

# 导入pygame模块
import pygame
import pygame.locals

# 创建窗口
window = pygame.display.set_mode((512, 768))

# TODO:加载背景图片
# 加载图片完成后,将图片保存到变量中
background_img = pygame.image.load(res/img_bg_level_2.jpg)
# TODO:将图片添加到窗口中
# window.blit(图片, (图片的x坐标, 图片的y坐标))
window.blit(background_img, (0, 0))

while True:
# 刷新窗口内容的命令
pygame.display.update()
# 获取关闭窗口事件
for event in pygame.event.get():
if event.type == pygame.locals.QUIT:
exit(退出游戏)

8、背景图片的移动

# 导入pygame模块
import pygame
import pygame.locals

# TODO: 可以创建全局变量,在循环中每次加载完图片后,将y值进行自增,则图片会不断向下移动
background_y = 0

# 创建窗口
window = pygame.display.set_mode((512, 768))

# 加载背景图片
# 加载图片完成后,将图片保存到变量中
background_img = pygame.image.load(res/img_bg_level_2.jpg)
# background_img1 = pygame.image.load(res/img_bg_level_1.jpg)
# 将图片添加到窗口中
# window.blit(图片, (图片的x坐标, 图片的y坐标))
window.blit(background_img, (0, 0))

while True:
# TODO: 让背景图片进行移动
# 如果我们想让背景图片移动,在每次刷新窗口之前,需要改变图片的位置
# 改变图片的位置非常简单只需要修改图片的x,y坐标位置即可
window.blit(background_img, (0, background_y))
# TODO: 添加辅助背景
# 如果想让图片进行无缝的滚动,需要再次添加一张图片,与现有图片首尾相接,当图片滚动到超出屏幕范围时,回到原始位置
window.blit(background_img, (0, background_y - 768))
# 怎样可以让图片随着循环不断向下移动??? 每次循环对于y左边进行自增
# background_y += 1
# 思考??这样移动出了屏幕是不是就看不见了???也就没有存在的价值了
# 所以我们需要让背景图片反复移动,当图片完全移出窗体范围,则恢复到原始位置(0,0)
if background_y >= 768:
background_y = 0
else:
background_y += 1

# 刷新窗口内容的命令
pygame.display.update()
# 获取关闭窗口事件
for event in pygame.event.get():
if event.type == pygame.locals.QUIT:
exit(退出游戏)

9、将变量及函数抽取出来

# 导入pygame模块
import pygame
import pygame.locals

# TODO: 抽取常量和变量
# 思考: 变量是统一管理更为方便还是分散管理方便?? 统一管理
# 在代码中出现的数字有没有单位,比如 apples = 5 此时显示的是重量还是个数??? 不清楚
# 为了增加代码的可读性,尽量减少程序中出现的魔法数字,可以将魔法数字提取出来作为常量出现.
# 在编程中,一般不可以被修改的变量叫做常量,Python中本身是没有常量的,所以我们使用标识符大写来备注常量
# 但是这个常量可以被修改,只是提醒协同人员或调用模块的人这个是一个常量而已
# 抽取常量
WINDOW_WIDTH = 512 # 窗口宽度
WINDOW_HEIGHT = 768 # 窗口高度

# 创建全局变量
background_x = 0
background_y = 0

# 创建窗口
# window = pygame.display.set_mode((512, 768))
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

# # 加载背景图片
# background_img = pygame.image.load(res/img_bg_level_2.jpg)
# # 将图片添加到窗口中
# window.blit(background_img, (0, 0))

# TODO: 抽取函数
# 函数一般就是一个特定的功能,完整的功能保存到函数中进行调用即可

# 移动背景图片
def move_background():
"""可以滚动显示背景图片"""
# 如果想要在函数体内部修改全局变量的值,需要声明全局变量才可以
global background_y
global background_x

# 加载背景图片
background_img = pygame.image.load(res/img_bg_level_2.jpg)

# 让背景图片进行移动
window.blit(background_img, (background_x, background_y))
# 添加辅助背景
window.blit(background_img, (background_x, background_y - WINDOW_HEIGHT))
# 循环移动
if background_y >= WINDOW_HEIGHT:
background_y = 0
else:
background_y += 1

# 获取窗口事件
def get_window_event():
"""获取所有的窗口事件,并且进行处理"""
# 获取关闭窗口事件
for event in pygame.event.get():
if event.type == pygame.locals.QUIT:
exit(退出游戏)


while True:
# # 让背景图片进行移动
# window.blit(background_img, (background_x, background_y))
# # 添加辅助背景
# window.blit(background_img, (background_x, background_y - WINDOW_HEIGHT))
# # 循环移动
# if background_y >= WINDOW_HEIGHT:
# background_y = 0
# else:
# background_y += 1
# TODO: 调用移动背景的方法
move_background()

# 刷新窗口内容的命令
pygame.display.update()
# 获取关闭窗口事件
# for event in pygame.event.get():
# if event.type == pygame.locals.QUIT:
# exit(退出游戏)
# TODO: 调用获取事件的方法
get_window_event()

10、添加敌机

# 导入pygame模块
import random

import pygame
import pygame.locals

# 抽取常量
WINDOW_WIDTH = 512 # 窗口宽度
WINDOW_HEIGHT = 768 # 窗口高度

# TODO: 添加敌机的尺寸
ENEMY_WIDTH = 100 # 敌机宽度
ENEMY_HEIGHT = 68 # 敌机高度

# 创建全局变量
background_x = 0
background_y = 0

# TODO: 添加敌机坐标
enemy_x = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH) # 敌机的x坐标
enemy_y = -ENEMY_HEIGHT # 敌机的y坐标

# TODO: 添加敌机速度
enemy_speed = random.randint(2, 4) # 敌机的速度

# 创建窗口
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))


# 移动背景图片
def move_background():
"""可以滚动显示背景图片"""
# 如果想要在函数体内部修改全局变量的值,需要声明全局变量才可以
global background_y
global background_x

# 加载背景图片
background_img = pygame.image.load(res/img_bg_level_2.jpg)
# 让背景图片进行移动
window.blit(background_img, (background_x, background_y))
# 添加辅助背景
window.blit(background_img, (background_x, background_y - WINDOW_HEIGHT))
# 循环移动
if background_y >= WINDOW_HEIGHT:
background_y = 0
else:
background_y += 1


# TODO: 添加并移动敌机
def move_enemy():
"""添加敌机并且移动敌机的函数"""
# 声明全局变量
global enemy_x
global enemy_y
global enemy_speed
# 加载敌机图片
enemy_img = pygame.image.load(res/img-plane_1.png)
# 在窗口上显示敌机
window.blit(enemy_img, (enemy_x, enemy_y))
# 移动敌机
# 为了让敌机有一个俯冲的效果,所以让敌机移动速度大于背景图片的移动速度
# enemy_y += 2
# 当敌机移动到屏幕之外我们就不需要再去显示他了,为了让敌机变量复用
# 当敌机超出屏幕范围时,将敌机恢复原位(如果我们想让敌机有一个进入到屏幕的效果,
# 我们需要将敌机的初始位置设置到屏幕外边,此时初始位置左边y值应该为负的敌机的高度)
if enemy_y >= WINDOW_HEIGHT:
enemy_y = -ENEMY_HEIGHT
# 每次进入屏幕时都会重置x的值
enemy_x = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH)
# 每次重新进入屏幕时,重置速度值
enemy_speed = random.randint(2, 4)
else:
enemy_y += enemy_speed
# 思考如果每次敌机都从一个位置出现未免太过死板游戏过于简单,所以要将敌机出现的位置x坐标设置为随机值


# 获取窗口事件
def get_window_event():
"""获取所有的窗口事件,并且进行处理"""
for event in pygame.event.get():
# 获取关闭窗口事件
if event.type == pygame.locals.QUIT:
exit(退出游戏)


if __name__ == __main__:
while True:
# 调用移动背景的方法
move_background()
# TODO: 调用移动敌机的方法
move_enemy()
# 刷新窗口内容的命令
pygame.display.update()
# 调用获取事件的方法
get_window_event()

11、添加多架敌机

# 导入pygame模块
import random

import pygame
import pygame.locals

# 抽取常量
WINDOW_WIDTH = 512 # 窗口宽度
WINDOW_HEIGHT = 768 # 窗口高度

ENEMY_WIDTH = 100 # 敌机宽度
ENEMY_HEIGHT = 68 # 敌机高度

# 创建全局变量
background_x = 0
background_y = 0

# TODO: 创建一个储存敌机数据的容器
# 如果添加添加多架敌机,每一架敌机都要保存几个数据??? 每一架敌机大小相同,所以需要保存三个数据x, y ,speed
# 多架敌机用什么数据类型进行保存更为合适???? 列表嵌套字典
# 示例[x:200, y:300, speed:3, x:300, y:500, speed: 4]
enemy_list = []
# enemy_x = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH) # 敌机的x坐标
# enemy_y = -ENEMY_HEIGHT # 敌机的y坐标
#
# enemy_speed = random.randint(2, 4) # 敌机的速度

# 创建窗口
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))


# TODO: 初始化敌机的函数
def init_enemy_list():
global enemy_list
# 循环多少次就有多少架敌机
for i in range(5):
enemy_list.append(
x: random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH),
y: -ENEMY_HEIGHT,
speed: random.randint(2, 4)

)


# 移动背景图片
def move_background():
"""可以滚动显示背景图片"""
# 如果想要在函数体内部修改全局变量的值,需要声明全局变量才可以
global background_y
global background_x

# 加载背景图片
background_img = pygame.image.load(res/img_bg_level_2.jpg)
# 让背景图片进行移动
window.blit(background_img, (background_x, background_y))
# 添加辅助背景
window.blit(background_img, (background_x, background_y - WINDOW_HEIGHT))
# 循环移动
if background_y >= WINDOW_HEIGHT:
background_y = 0
else:
background_y += 1


# 添加并移动敌机
# TODO: 将每一架敌机数据组成的字典传递进来
# TODO: 将所有的敌机的x,y,speed 用字典中的数据进行替换
def move_enemy(enemy_dict):
"""添加敌机并且移动敌机的函数"""
# 声明全局变量
# global enemy_x
# global enemy_y
# global enemy_speed
# 加载敌机图片
# TODO: 随机加载飞机图片
# 如果想要随机加载敌机图片,就对敌机的路径进行随机从plane1- plane7
# 课下感兴趣的同学自己完成
enemy_img = pygame.image.load(res/img-plane_1.png)
# 在窗口上显示敌机
window.blit(enemy_img, (enemy_dict[x], enemy_dict[y]))
# 移动敌机
# 为了让敌机有一个俯冲的效果,所以让敌机移动速度大于背景图片的移动速度
# enemy_y += 2
# 当敌机移动到屏幕之外我们就不需要再去显示他了,为了让敌机变量复用
# 当敌机超出屏幕范围时,将敌机恢复原位(如果我们想让敌机有一个进入到屏幕的效果,
# 我们需要将敌机的初始位置设置到屏幕外边,此时初始位置左边y值应该为负的敌机的高度)
if enemy_dict[y] >= WINDOW_HEIGHT:
enemy_dict[y] = -ENEMY_HEIGHT
# 每次进入屏幕时都会重置x的值
enemy_dict[x] = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH)
# 每次重新进入屏幕时,重置速度值
enemy_dict[speed] = random.randint(2, 4)
else:
enemy_dict[y] += enemy_dict[speed]
# 思考如果每次敌机都从一个位置出现未免太过死板游戏过于简单,所以要将敌机出现的位置x坐标设置为随机值


# 获取窗口事件
def get_window_event():
"""获取所有的窗口事件,并且进行处理"""
for event in pygame.event.get():
# 获取关闭窗口事件
if event.type == pygame.locals.QUIT:
exit(退出游戏)


if __name__ == __main__:
# TODO: 调用函数初始化敌机数据
init_enemy_list()
while True:
# 调用移动背景的方法
move_background()
# TODO: 如果想要添加多架敌机,要么在函数中进行循环,要么执行多次添加一架敌机的方法,我们选择后者
for enemy in enemy_list:
move_enemy(enemy)
# 刷新窗口内容的命令
pygame.display.update()
# 调用获取事件的方法
get_window_event()

12、随机设置敌机的颜色

# 导入pygame模块
import random

import pygame
import pygame.locals

# 抽取常量
WINDOW_WIDTH = 512 # 窗口宽度
WINDOW_HEIGHT = 768 # 窗口高度

ENEMY_WIDTH = 100 # 敌机宽度
ENEMY_HEIGHT = 68 # 敌机高度

# 创建全局变量
background_x = 0
background_y = 0

# 创建一个储存敌机数据的容器
enemy_list = []

# 创建窗口
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))


# 初始化敌机的函数
def init_enemy_list():
# 循环多少次就有多少架敌机
for i in range(5):
enemy_list.append(
x: random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH),
y: -ENEMY_HEIGHT,
speed: random.randint(2, 4),
# TODO: 让敌机保存自己的飞机颜色图片
img_path:fres/img-plane_random.randint(1,7).png

)


# 移动背景图片
def move_background():
"""可以滚动显示背景图片"""
# 如果想要在函数体内部修改全局变量的值,需要声明全局变量才可以
global background_y
global background_x

# 加载背景图片
background_img = pygame.image.load(res/img_bg_level_2.jpg)
# 让背景图片进行移动
window.blit(background_img, (background_x, background_y))
# 添加辅助背景
window.blit(background_img, (background_x, background_y - WINDOW_HEIGHT))
# 循环移动
if background_y >= WINDOW_HEIGHT:
background_y = 0
else:
background_y += 1


# 添加并移动敌机
def move_enemy(enemy_dict):
"""添加敌机并且移动敌机的函数"""
# 加载敌机图片
# 动态随机添加敌机图片
# 如果在此处我们进行图片随机,每一架飞机的图片都是一直在变化的,我们需要的结果
# 是在敌机进入到窗口中,颜色就不再变化了,只有重新回到起点后,才会重置敌机颜色
# TODO: 加载图片时,获取敌机字典中的图片路径进行加载
enemy_img = pygame.image.load(enemy_dict[img_path])
# 在窗口上显示敌机
window.blit(enemy_img, (enemy_dict[x], enemy_dict[y]))
# 移动敌机
if enemy_dict[y] >= WINDOW_HEIGHT:
enemy_dict[y] = -ENEMY_HEIGHT
# 每次进入屏幕时都会重置x的值
enemy_dict[x] = random.randint(0, WINDOW_WIDTH - ENEMY_WIDTH)
# 每次重新进入屏幕时,重置速度值
enemy_dict[speed] = random.randint(2, 4)
# TODO: 每次回到起始位置时重置自己的图片路径
enemy_dict[img_path] = fres/img-plane_random.randint(1,7).png
else:
enemy_dict[y] += enemy_dict[speed]
# 思考如果每次敌机都从一个位置出现未免太过死板游戏过于简单,所以要将敌机出现的位置x坐标设置为随机值


# 获取窗口事件
def get_window_event():
"""获取所有的窗口事件,并且进行处理"""
for event in pygame.event.get():
# 获取关闭窗口事件
if event.type == pygame.locals.QUIT:
exit(退出游戏)


if __name__ == __main__:
# 调用函数初始化敌机数据
init_enemy_list()
while True:
# 调用移动背景的方法
move_background()
# 如果想要添加多架敌机,要么在函数中进行循环,要么执行多次添加一架敌机的方法,我们选择后者
for enemy in enemy_list:
move_enemy(enemy)
# 刷新窗口内容的命令
pygame.display.update()
# 调用获取事件的方法
get_window_event()


以上是关于Python飞机大战,Pygame入门,源码的主要内容,如果未能解决你的问题,请参考以下文章

飞机大战

怎么用python学飞机大战?

如何用用python写飞机大战?

飞机大战

飞机大战代码-plane_sprites

PyGame快速入门