一、基础知识

pygame安装

pygame就是一个Python模块,专为店子游戏设计

安装pygame(Windows):

pip install pygame

验证安装

python -m pygame.examples.aliens

会出现一个游戏界面,则表示安装成功。

pygame快速入门

1、使用pygame创建图形窗口

1.1游戏的初始化和退出

要使用pygame提供的所有功能之前,需要调用init方法
在游戏结束前需要调用quit方法

方法 说明
pygame.init() 导入并初始化所有pygame模块,使用其他模块之前,必须先调用init方法
pygame.quit() 卸载所有pygame模块,在游戏结束之前调用!

1.2理解游戏中的坐标

坐标系:
 原点在左上角(0,0)
 x轴水平方向向右,逐渐增加
 y轴垂直方向向下,逐渐增加

 在游戏中,所有可见的元素都是以矩形区域来描述位置的:
  要描述一个矩形区域有四个要素:(x,y)(width,height)

pygame专门提供了一个类pygame.Rect用于描述矩形区域

Rect(x, y , width , height )  --->Rect


提示:
pygame.Rect 是一个比较特殊的类,内部只是封装了一些数字计算
 不执行pygame.init()方法同样能够直接使用

例子:

import pygame
first_rect = pygame.Rect(100,500,120,125)
print(' 第一个矩形区域的原点为: %d %d' %(first_rect.x , first_rect.y))
print(' 第一个矩形区域的尺寸为:%d %d' %(first_rect.width , first_rect.height))
print('尺寸:',first_rect.size)

1.3创建游戏主窗口

  • pygame专门提供了一个模块pygame.display用于创建、管理游戏窗口
方法 说明
pygame.display.set_mode() 初始化游戏显示窗口
pygame.display.update() 刷新屏幕内容显示

set_mode 方法:

set_mode(resolution=(0,0),flags=0) -->Surface
  • 作用 —创建游戏显示窗口
  • 参数:
    resolution 指定屏幕的宽和高,默认创建的窗口大小和屏幕大小一致
    flags 参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递
    depth 参数表示颜色的位数,默认自动匹配
  • 注意:必须使用变量记录set_mode方法的返回结果。因为:后续所有的图像绘制都基于这个返回结果
#创建游戏主窗口
screen = pygame.display.set_mode((480,700))

1.4简单的游戏循环

  • 为了做到游戏程序启动后,不会立即退出,通常会在游戏程序中添加一个游戏循环
  • 游戏循环就是一个无限循环
  • 在创建游戏串口代码下方,增加一个无限循环(使用 while true)
  •   注意:游戏窗口不需要重复创建

2、理解图像并实现图像绘制

  • 在游戏中,能够看到的游戏元素大多都是图像
  •   图像文件初始是保存在磁盘上的,如果需要使用,第一步就需要被加载到内存中。
  • 要在屏幕上看到某一个图像的内容,需要按照三个步骤:
  • 1、使用pygame.image.load()加载图像的数据
  • 2、使用游戏屏幕对象,调用blit方法,将图像绘制到指定位置
  • 3、调用pygame.display.update()方法更新整个屏幕的显示

    提示:要想在屏幕上看到绘制的结果,就一定要调用pygame.display.update()方法
    例子:
# 绘制背景图像
# 加载图像数据
bg=pygame.image.load("./images/background.png")
hero=pygame.image.load("./images/me1.png")
# blit绘制图像
screen.blit(bg,(0,0))
screen.blit(hero,(200,500))
# update更新屏幕显示
pygame.display.update()

理解update()方法的作用

  • 使用display.set_mode()创建的screen对象是一个内存中的屏幕数据对象
  • screen.blit方法可以在画布上绘制很多图像
  • display.update()会将画布的最终结果绘制在屏幕上,这样可以提高屏幕绘制效率,增加游戏的流畅度。

3、理解游戏循环和游戏时钟

3.1游戏中动画实现原理

  • 通过在电脑上每秒绘制60次,就能够到大非常连续高品质的动画效果。每次绘制的结果被成为帧Frame

3.2游戏循环

游戏的两个组成部分:

游戏循环的开始就意味着游戏的正式开始


游戏循环的作用:
1、保证游戏不会直接退出
2、变化图像位置—动画效果
 每个1/60 秒移动一下所有图像的位置
 调用pygame.display.update()更新屏幕显示
3、检测用户交互 —按键、鼠标等

3.3游戏时钟

  • pygame专门提供了一个类pygame.time.Clock可以非常方便的设置屏幕绘制速度—刷新帧率。
  • 要使用时钟对象需要两步:
  • 1)在游戏初始化创建一个时钟对象
  • 2)在游戏循环中让时钟对象调用tick(帧率)方法
  • tick方法会根据上次被调用的时间,自动设置游戏循环中的延时
# 创建时钟对象
clock = pygame.time.Clock()
# tick参数可以指定循环体内部循环的频率
clock.tick(60)  #在循环体内部使用

3.4简单动画实现

需求:
 1、在游戏初始化定义一个pygame.Rect的变量记录英雄的初始位置
 2、在游戏循环中每次让英雄的y-1 ----向上移动
 3、当y<=0时,将英雄丕东到屏幕的底部

提示:
每一次调用update()方法之前,需要把所有的游戏图像都重新绘制一边
而且应该最先重新绘制背景图像

3.5在游戏循环中监听事件

事件event

  • 就是启动游戏后,用户针对游戏所做的操作

  • 例如:点击关闭按钮,点击鼠标,按下键盘…
    监听

  • 在游戏循环中,判断用户具体操作

  • 只有捕获到用户具体的操作,才能针对性的做出响应

pygame中通过pygame.event.get()可以获得用户当前所做动作的事件列表
 用户可以同一时间做很多事情
提示:这段代码非常固定,几乎所有的pygame游戏都大同小异。

例子:

for event in pygame.event.get():#判断用户是否点击了关闭按钮if event.type == pygame.QUIT:print("退出游戏...")pygame.quit()#直接退出系统exit()

理解精灵和精灵组

在之前写的案列中,图像加载、位置变化、绘制图像都需要程序员编写代码分别处理。

为了简化开发步骤,pygame提供了两个类

  • pygame.sprite.Sprite —存储图像数据image和位置rect对象
  • pygame.sprite.Group
精灵(需要派生子类
image 记录图像数据
rect 记录在屏幕上的位置
update(*args):更新精灵位置
kill():从所有组中删除
精灵组
init(self , *精灵):
add(*sprites):向组中添加精灵
update(*args):让组中所有精灵调用update方法
sprites():返回所有精灵列表
draw(Surface):将组中所有精灵的image,绘制到Surface的rect位置

4.1创建游戏精灵:

新建一个plane_sprites.py文件
定义GameSprite类继承自pygame.sprite.Sprite

注意:

  • 如果一个类的父类不是object
  • 在重写初始化方法时,一定要先super()一下父类的__init__方法
  • 保证父类中实现的__init__代码能够被正常执行

    属性:
  • image精灵图像,使用image_name加载
  • rect精灵大小,默认使用图像大小
  • speed精灵移动速度,默认为1
    方法:
    update每次更新屏幕时在游戏循环内调用
    让精灵的self.rect.x+=self.speed
    提示:
    image的get_rect()方法,可以返回pygame.Rect(0,0,图像宽,图像高)的对象

实现代码:

class GameSprite(pygame.sprite.Sprite):"""飞机大战游戏的精灵"""def __init__(self,image_name,speed=1):#调用父类的初始化方法super().__init__()#定义对象属性:#这里的image_name是图片的存放路径self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speed = speed#定义更新def update(self):#在屏幕的垂直方向上移动self.rect.y += self.speed

4.2使用游戏精灵和精灵组创建敌机

步骤
1、使用from导入plane_sprites模块

  • from导入的模块可以直接使用
  • import 导入的模块需要通过模块名来使用
    2、在游戏初始化创建精灵对象和精灵组对象
    3、在游戏循环中让精灵组分别调用update()和draw(screen)方法
    职责
  • 精灵
  • 封装图像image、位置rect和速度speed
  • 提供update()方法,根据游戏需求,更新位置rect
  • 精灵组
  • 包含多个精灵对象
  • update方法,让精灵组中的所有精灵调用update方法更新位置
  • draw(screen)方法,在screen上绘制精灵组中的所有精灵
    代码
#创建敌机的精灵
enemy = GameSprite("./images/enmey1.png")
#创建敌机的精灵组
enemy_group = pygame.sprite.Group(enemy)#游戏循环
while True:#tick参数可以指定循环体内部循环的频率,记得import time模块clock.tick(60)# 捕获事件for event in pygame.event.get():# 判断事件类型是否是退出事件if event.type == pygame.QUIT:print('游戏退出...')# quit卸载所有模块pygame.quit()# exit() 直接终止当前正在执行的程序exit()#让精灵组调用两个方法#update --让组中的所有精灵更新位置enemy_group.update()#draw --在screen上绘制所有的精灵enemy_group.draw(screen)#screen是最开始创建的游戏窗口#screen = pygame.display.set_mode((480,700))

游戏框架搭建

目标—使用面向对象设计飞机大战游戏类

目标:

  • 明确主程序职责
  • 实现主程序类
  • 准备游戏精灵组

01.明确主程序职责

一个游戏程序的职责可以分为两个部分:

  • 游戏初始化
  • 游戏循环
    根据明确的职责,设计PlaneGame类如下:
    |PlaneGame|
    |:–|
    |screen |
PlaneGame
screen
clock
精灵或精灵组…
__init__(self):
__create_sprites(self):

start_game(self):
__event_handler(self):
__update_sprites(self):
__game_over():

提示:根据职责封装私有方法,可以避免某一个方法的代码写得太过冗长,如果某一个方法编写的太长,及不好阅读,也不好维护

方法 职责
__event_handler(self) 事件监听
__check_collide(self) 碰撞检测—子弹销毁敌机、敌机撞毁英雄
__update_sprites(self) 精灵组更新和绘制
__game_over() 游戏结束

02.明确文件职责

  • plane_main:
    1、封装主游戏类
    2、创建游戏对象
    3、启动游戏
  • plane_sprites
    1、封装游戏中所有需要使用的精灵子类
    2、提供游戏的相关工具
    代码实现
  • 新建plane_main.py文件,并设置为可执行
  • 编写基础代码
import pygame
from plane_sprites import *class PlaneGame(object):"""飞机大战主游戏"""def __init__(self)print("游戏初始化")def start_game(self):print("游戏开始")#游戏循环体while True:passif __name__=='__main__':#创建游戏对象game = PlaneGame()#启动游戏game.start_game()

在游戏初始化中需要设置游戏窗口、创建游戏时钟、创建精灵、精灵组。
在PlaneGame类中的__init__函数中进行这些操作:

def __init__(self):print("游戏初始化")#1.设置游戏窗口self.screen = pygame.display.set_mode(SCREEN_RECT.size)#SCREEN_RECT是定义在plane_sprites.py中的屏幕大小的常量。#通过设置次常量,当我们需要修改屏幕大小时,直接在plane_spriyes.py文件定义常量的位置修改即可,不需要在主函数中一个一个的去找和去修改值。#提示:python中并没有真正意义的常量,只是通过命名的约定---所有字母都是大写的就是常量,开发时不要轻易修改。#2.创建游戏时钟self.clock = pygame.time.Clock()#3.调用私有方法,创建精灵和精灵组self.__create_sprites()#私有方法,创建精灵和精灵组
def __create_sprites(self):pass

在游戏循环中需要:设置刷新帧率、事件监听、碰撞检测、更新/绘制精灵组,更新屏幕显示。
代码如下:

def start_game(self):print("游戏开始")#游戏循环while True:#1.设置刷新帧率self.clock.tick(FRAME_PRE_SEC) #这里的FRAME_PRE_SEC同上屏幕大小#2.事件监听:self.__event_handle()#3.碰撞检测:self.__check_collide()#4.更新/绘制精灵self.__update_sprites()#5.更新显示pygame.display.update()#以下是游戏循环中函数的定义
#暂时只定义,不实现,稍后一个一个实现
def __event_handle(self):#使用pygame.event.get()获得操作事件#使用for循环遍历获得的操作事件for event in pygame.event.get():#判断是否退出游戏if event.type == pygame.QUIT:#定义的静态私有方法,不需要创建对象,直接就可以使用PlaneGame.__game_over()elif:passdef __check_collide(self):passdef __update_sprites(self):pass#定义退出游戏的静态私有方法
@staticmethod
def __game_over():print("游戏结束")pygame.quit()exit()

03.设计背景类

背景交替滚动的思路

游戏启动后,背景图像会连续不断地向下方移动
在视觉上产生飞机不断向上飞行的错觉:
 游戏背景不断变化
 游戏的主角位置保持不变

解决方法:
1.创建两张背景图像精灵
  第1张完全和屏幕重合
  第2张在屏幕的正上方
2.两张图像一起向下方运动
  self.rect.y +=self.speed
3.当任意背景精灵的 rect.y >= 屏幕的高度,说明移动到屏幕下方
4.将移动到屏幕下方的这张图像设置到屏幕的正上方
  rect.y = -rect.height

设计一个背景类Background,继承于GameSprite类,并且有自己的方法。

  • 初始化方法

  • 直接指定背景图片

  • is_alt判断是否是另一张图像

  •   False表示第一张图像,需要与屏幕重合

  •   True表示另一张图像,在屏幕的正上方。

  • update()方法

  •   判断是否移动出屏幕,如果是,将图像设置到屏幕的正上方,从而实现交替滚动。

提示:
继承如果父类提供的方法,不能满足子类的需求:
派生一个子类
在子类中针对特有的需求,重写父类方法,并且进行扩展

实现代码
plane_sprites.py

import pygame#定义屏幕大小的常量
SCREEN_RECT = pygame.Rect(0,0,480,700)
#定义屏幕刷新率
FRAME_PRE_SEC = 60class GameSprite(pygame.sprite.Sprite):"""飞机大战游戏精灵"""def __init__(self,image_name,speed=1):#调用父类的初始化方法super().__init__()#定义对象属性:#这里的image_name是图片的存放路径self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speed = speed#定义更新def update(self):#在屏幕的垂直方向上移动self.rect.y += self.speed#背景图片类
class Background(GameSprite):"""游戏背景精灵"""def __init__(self,is_alt=Flase):#1.调用父类方法实现精灵的创建super().__init__("./images/background.png")#2.判断是否是交替图像,如果是,需要设置初始位置if is_alt:self.rect.y = self.rect.heightdef update(self):#调用父类的方法实现super().update()#判断背景是否溢出屏幕,如果移出屏幕,将图像设置到屏幕的上方if self.rect.y>=SCREEN_RECT.height:self.rect.y = -self.rect.height

在plane_main.py中显示背景精灵

1、在__create_sprites方法中创建精灵和精灵组
2、在__update_sprites方法中,让精灵组调用update()draw()方法

#plane_main.py模块
class PlaneGame(object):"""飞机大战主游戏"""def __create_sprites(self):bg1 = Background()bf2 = Background(True)self.back_group = pygame.sprite.Group(bg1,bg2)def __update_sprites(self):self.back_group.update()self.back_group.draw(self.screen)

04敌机出场

01使用定时器添加敌机

1、游戏启动后,每隔1s会出现一架敌机
2、每架敌机向屏幕下方飞行,飞行速度各不相同
3、每架敌机出现的水平位置也不尽相同
4、当敌机从屏幕下方飞出,不会再飞回到屏幕中

1.1定时器

  • 在pygame中可以使用pygame.time.set_time()来添加定时器
  • 所谓定时器,就是每隔一段事件,去指定一些动作
set_timer(eventid,milliseconds) --->None
  • set_timer可以创建一个事件
  • 可以在游戏循环的事件监听方法中捕获到该事件
  • 第1个参数事件代号需要基于常量pygame.USEREVENT来指定
    USEREVENT是一个整数,再增加的事件可以使用USEREVENT+1指定,一次类推…
  • 第二个参数是事件触发间隔的毫秒值

定时器事件的监听

  • 通过pygame.event.get()可以获取当前时刻所有的事件列表
  • 遍历列表并且判断event.type是否等于eventid,如果相等,表示定时器事件发生。

1.2定义并监听创建敌机事件

pygame的定时器使用套路非常固定:
1、定义定时器常量—eventid
2、在初始化方法中,调用set_timer方法设置定时器事件
3、在游戏循环中,监听定时器事件

1)定义事件
在plane_sprites.py的顶部定义事件常量

#敌机出现
CREATE_ENEMY_EVENT = pygame.USEREVENT

2)在初始化方法中,调用set_timer方法设置定时器事件

#plane_main.py文件
class PlaneGame(object):def __ini__(self):#前面不再赘述#4.设置定时器事件 --创建敌机,每1s出现pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)

3)在游戏循环中,监听定时器事件

def __event_handler(self):for event in pygame.event.get():if event.type == pygame.QUIT():PlaneGame.__game_over()elif event.type == CREATE_ENEMY_EVENT:#创建敌机精灵enemy = Enemy()#将敌机精灵添加到敌机精灵组self.enemy_group.add(enemy)

02设计Enemy类

  • 初始化方法
    指定敌机图片
    随机敌机的初始位置和初始速度
  • 重写update()方法
    判断是否飞出屏幕,如果是,从精灵组删除
    代码
class Enemy(GameSprite):"""敌机精灵"""def __init__(self):#1.调用父类方法实现精灵的创建,同时指定敌机图片super().__init__("./images/enemy1.png")#2.指定敌机的初始随机速度1~3self.spedd = random.randint(1,3)#3.指定敌机的初始随机位置#self.rect.y = -self.rect.heightself.rect.bottom = 0self.rect.x = random.randint(0,SCREEN_RECT.width-self.rect.width)def update(self):#1.调用父类方法,保持垂直方向的飞行super().update()#2.判断是否飞出屏幕,如果是,需要从精灵组删除敌机if self.rect.y >= SCREEN_RECT.height:self.kill()def __del__(self):print("敌机挂了 %s"%self.rect)

创建好敌机类后,在plane_main.py文件中创建精灵并加入到精灵组。创建精灵在监听定时器事件中已完成
加入精灵组

def __create_sprites(self):self.enemy_group = pygame.sprite.Gruop()

飞机大战游戏---Pygame相关推荐

  1. python飞机大战功能模块图_基于Python的飞机大战游戏设计

    第 2 3 卷 第 1 期 2019年 3 月 扬 州 职 业 大 学 学 报 Journal of Yangzhou Polytechnic College Vol .23 No . 1 Mar . ...

  2. 基于pygame实现的飞机大战游戏

    目录 1.引言 1.1 背景 1.2 意义 1.3 功能 2.系统结构 2.1 整体框架 2.2 精灵与精灵组 2.3 功能介绍 2.3.1 玩家飞机 2.3.2 敌机类型和关卡设定 2.3.3 敌机 ...

  3. Python实验,用pygame做飞机大战游戏设计

    飞机大战游戏设计 摘 要:根据课程要求,以及面向对象程序设计的编程思想,在Windows操作系统环境下,运用PyCharm编译程序,以Python语言为开发语言,最终实现飞机大战游戏相应的游戏操作功能 ...

  4. python飞机大战功能模块图_python pygame实现飞机大战游戏

    1.引言 1.1 项目背景 python是一种跨平台的计算机程序设计语言.是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.最初被设计用于编写自动化脚本(Shell),随着版本的不断更新 ...

  5. Python+pygame飞机大战游戏

    转载自IIronMan 的博客 Python:飞机大战游戏1:前期准备 Python:飞机大战游戏2:pygame 快速入门 Python:飞机大战游戏3:框架搭建 Python:飞机大战游戏4:背景 ...

  6. pygame实现飞机大战游戏

    标题:pygame实现飞机大战游戏 源码链接:我的github地址 一.具体演示 1.怪兽分为小怪,和大怪:大怪可以发射子弹 2.英雄飞机共有10个生命值 3.英雄飞机可以上下左右移动 4.显示了英雄 ...

  7. 基于Pygame开发的最完美的飞机大战游戏

    基于Pygame开发的最完美的飞机大战游戏 后期会给大家上源码,以及完整的实现思路.

  8. 体感游戏 | 手势识别玩飞机大战游戏(一) 用pygame实现飞机大战小游戏

    Color Space OpenCV与AI深度学习 后面将分四篇文章来介绍实现手势识别控制飞机大战游戏的功能,它们分别是: 使用Pygame实现简易飞机大战小游戏 使用Python+OpenCV实现简 ...

  9. python写飞机大战游戏_python实现飞机大战游戏

    飞机大战(Python)代码分为两个python文件,工具类和主类,需要安装pygame模块,能完美运行(网上好多不完整的,调试得心累.实现出来,成就感还是满满的),如图所示: 完整代码如下: 1.工 ...

最新文章

  1. pku 3411 Paid Roads DFS+灵活技巧卡节点访问次数
  2. 数据库选项--ALTER DATABASE WITH 选项
  3. 脑电信号特征提取算法c语言_应用深度学习EEGNet来处理脑电信号
  4. 转:两种转换mysql数据编码的方法-latin1转utf8
  5. scipy.optimize.curve_fit-曲线拟合
  6. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗
  7. javascript学习系列(21):数组中的reduceRight法
  8. 常系数线性微分方程的直接解法-利用特征方程
  9. PTA c语言 选择法排序过程
  10. SQL服务器名称更改
  11. java getpathinfo_request.getServletPath()和request.getPathInfo()用法
  12. 单位启用人脸识别考勤
  13. 第一家店开始要做品牌吗?
  14. 玩转接口测试,那些必备的技能
  15. javax.servlet.http.HttpServletResponse.setContentLengthLong(J)V,maven项目报错!!无法访问webapp下的文件,完美解决方案
  16. 黑苹果登录apple id_充分利用Apple登录功能
  17. 【Python】个人所得税
  18. win下连编socket时[Linker error] undefined reference to XXX
  19. 天空为什么刚才灰得就像哭过呢??
  20. python 无限循环小数_有关无限循环小数的一处漏洞

热门文章

  1. 用PYTHON画斐波那契数列银杏树(代码可复制)
  2. 如何对scrollbar位置进行控制?
  3. 【成长经历】【钉钉前端】 高中毕业-如何用 15 年从小白到技术专家
  4. 加入公司以来的工作总结反思
  5. PHP-身份证号码验证
  6. flash-W25Q32BV的读写
  7. 迈思德物联网网关极简宣传页
  8. 关于Android 版本更新
  9. 本周AI热点回顾:机器人写稿同样拥有著作权、大脑中竟存在“分布强化学习”
  10. match_phrase短语匹配和近似匹配