Python游戏编程(Pygame)

Python游戏编程(Pygame)安装PygamepipinstallpygameC:\Users>pipinstallpygameCollectingpygameDownloadinghttps://files.pythonhosted.org/packages/3e/f5/feabd88a2856ec86166a897b62…

大家好,又见面了,我是你们的朋友全栈君。

安装Pygame

pip install pygame
C:\Users> pip install pygame                
Collecting pygame                   
  Downloading https://files.pythonhosted.org/packages/3e/f5/feabd88a2856ec86166a897b62bfad828bfe7a94a27cbd7ebf07fd
70399/pygame-1.9.4-cp37-cp37m-win_amd64.whl (4.2MB)
    100% |██████████████████████████| 4.2MB 6.6MB/s
Installing collected packages: pygam
Successfully installed pygame-1.9.4 

Pygame常用模块

模块名 功能
pygame.cdrom 访问光驱
pygame.cursors 加载光标
pygame.display 访问显示设备
pygame.draw 绘制形状、线和点
pygame.event 管理事件
pygame.font 使用字体
pygame.image 加载和存储图片
pygame.joystick 使用游戏手柄或者类似的东西
pygame.key 读取键盘按键
pygame.mixer 声音
pygame.mouse 鼠标
pygame.movie 播放视频
pygame.music 播放音频
pygame.overlay 访问高级视频叠加
pygame.rect 管理矩形区域
pygame.scrap 本地剪贴板访问
pygame.sndarray 操作声音数据
pygame.sprite 操作移动图像
pygame.surface 管理图像和屏幕
pygame.surfarray 管理点阵图像数据
pygame.time 管理时间和帧信息
pygame.transform 缩放和移动图像

简单示例:

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 320, 240  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口

while True:  # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()

pygame.quit()  # 退出pygame

执行结果:
Python游戏编程(Pygame)

制作一个跳跃的小球游戏

创建一个游戏窗口,然后在窗口内创建一个小球。以一定的速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续运动按照如下步骤实现该功能:

创建游戏窗口

1. 创建一个游戏窗口,宽和高设置为640*480。代码如下:

import sys
import pygame
pygame.init()                       # 初始化pygame
size = width, height = 640, 480     # 设置窗口大小
screen = pygame.display.set_mode()  # 显示窗口

上述代码中,首先导入pygame模块,然后调用init()方法初始化pygame模块,接下来,设置窗口的宽和高,最后使用display模块显示窗体。

display模块的常用方法

方法名 功能
pygame.display.init() 初始化display模块
pygame.display.quit() 结束display模块
pygame.display.get_init() 如果display模块已经被初始化,则返回True
pygame.display.set_mode() 初始化一个准备显示的界面
pygame.display.get_surface() 获取当前的Surface对象
pygame.display.flip() 更新整个待显示的Surface对象到屏幕上
pygame.display.update() 更新部分内容显示到屏幕上,如果没有参数,则与flip功能相同(上一条)

保持窗口显示

2. 运行第一步的代码后会出现一个一闪而过的黑色窗口,这是因为程序执行完成后,会自动关闭。如果想要让窗口一直显示,需要使用while True让程序一直执行,此外,还需要设置关闭按钮。具体代码如下:

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 320, 240  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口

while True:  # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()

pygame.quit()  # 退出pygame

上述代码中添加了轮询事件检测。pygame.event.get()能够获取事件队列,使用for...in遍历事件,然后根据type属性判断事件类型。这里的事件处理方式与GUI类似,如event.type等于pygame.QUIT表示检测到关闭pygame窗口事件,pygame.KEYDOWN表示键盘按下事件,pygame.MOUSEBUTTONDOWN表示鼠标按下事件等。

加载游戏图片

开发过程中使用的图片

3. 在窗口添加小球。我们先准备好一张ball.png
图片,然后加载该图片,最后将图片显示在窗口中,具体代码如下:

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 640, 480  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口
color = (0, 0, 0)  # 设置颜色
ball = pygame.image.load('ball.png')  # 加载图片
ballrect = ball.get_rect()  # 获取矩形区域

while True:  # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()
    screen.fill(color)  # 填充颜色(设置为0,执不执行这行代码都一样)
    screen.blit(ball, ballrect)  # 将图片画到窗口上
    pygame.display.flip()  # 更新全部显示

pygame.quit()  # 退出pygame

上述代码中使用iamge模块的load()方法加载图片,返回值ball是一个Surface对象。Surface是用来代表图片的pygame对象,可以对一个Surface对象进行涂画、变形、复制等各种操作。事实上,屏幕也只是一个Surfacepygame.display.set_mode()就返回了一个屏幕Surface对象。如果将ball这个Surface对象画到screen Surface 对象,需要使用blit()方法,最后使用display模块的flip()方法更新整个待显示的Surface对象到屏幕上。

Surface对象的常用方法

方法名 功能
pygame.Surface.blit() 将一个图像画到另一个图像上
pygame.Surface.convert() 转换图像的像素格式
pygame.Surface.convert_alpha() 转化图像的像素格式,包含alpha通道的转换
pygame.Surface.fill() 使用颜色填充Surface
pygame.Surface.get_rect() 获取Surface的矩形区域

移动图片

4. 下面让小球动起来,ball.get_rect()方法返回值ballrect是一个Rect对象,该对象有一个move()方法可以用于移动矩形。move(x, y)函数有两个参数,第一个参数是 X 轴移动的距离,第二个参数是 Y 轴移动的距离。窗口的左上角是(0, 0),如果是move(100, 50)就是左移100下移50。

为实现小球不停移动,将move()函数添加到while循环内,具体代码如下:

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 640, 480  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口
color = (0, 0, 0)  # 设置颜色
ball = pygame.image.load('ball.png')  # 加载图片
ballrect = ball.get_rect()  # 获取矩形区域

speed = [5, 5]  # 设置移动的X轴、Y轴
while True:  # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()
    ballrect = ballrect.move(speed)  # 移动小球
    screen.fill(color)  # 填充颜色(设置为0,执不执行这行代码都一样)
    screen.blit(ball, ballrect)  # 将图片画到窗口上
    pygame.display.flip()  # 更新全部显示

pygame.quit()  # 退出pygame

碰撞检测

5. 运行上述代码,发现小球在屏幕中一闪而过,此时,小球并没有真正消失,而是移动到窗体之外,此时需要添加碰撞检测的功能。当小球与窗体任一边缘发生碰撞,则更改小球的移动方向,具体代码如下:

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 640, 480  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口
color = (0, 0, 0)  # 设置颜色
ball = pygame.image.load('ball.png')  # 加载图片
ballrect = ball.get_rect()  # 获取矩形区域
speed = [5, 5]  # 设置移动的X轴、Y轴

while True:  # 死循环确保窗口一直显示
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()
            
    ballrect = ballrect.move(speed)  # 移动小球
    # 碰到左右边缘
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # 碰到上下边缘
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    screen.fill(color)  # 填充颜色(设置为0,执不执行这行代码都一样)
    screen.blit(ball, ballrect)  # 将图片画到窗口上
    pygame.display.flip()  # 更新全部显示

pygame.quit()  # 退出pygame

上述代码中,添加了碰撞检测功能。如果碰到左右边缘,更改X轴数据为负数,如果碰到上下边缘,更改Y轴数据为负数。

限制移动速度

6. 运行上述代码看似有很多球,这是因为运行上述代码的时间非常短,运行快的错觉,使用pygame的time模块,使用pygame时钟之前,必须先创建Clock对象的一个实例,然后在while循环中设置多长时间运行一次。

import pygame
import sys

pygame.init()  # 初始化pygame
size = width, height = 640, 480  # 设置窗口大小
screen = pygame.display.set_mode(size)  # 显示窗口
color = (0, 0, 0)  # 设置颜色
ball = pygame.image.load('ball.png')  # 加载图片
ballrect = ball.get_rect()  # 获取矩形区域
speed = [5, 5]  # 设置移动的X轴、Y轴
clock = pygame.time.Clock()  # 设置时钟

while True:  # 死循环确保窗口一直显示
    clock.tick(60)  # 每秒执行60次
    for event in pygame.event.get():  # 遍历所有事件
        if event.type == pygame.QUIT:  # 如果单击关闭窗口,则退出
            sys.exit()

    ballrect = ballrect.move(speed)  # 移动小球
    # 碰到左右边缘
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # 碰到上下边缘
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    screen.fill(color)  # 填充颜色(设置为0,执不执行这行代码都一样)
    screen.blit(ball, ballrect)  # 将图片画到窗口上
    pygame.display.flip()  # 更新全部显示

pygame.quit()  # 退出pygame

开发Flappy Bird游戏

Flappy Bird是一款鸟类飞行游戏,一根手指操控按下小鸟上飞。

分析
在Flappy Bird游戏中,主要有两个对象:小鸟、管道。可以创建Brid类和Pineline类来分别表示这两个对象。小鸟可以通过上下移动来躲避管道,所以在Brid类中创建一个bridUpdate()方法,实现小鸟的上下移动,为了体现小鸟向前飞行的特征,可以让管道一直向左侧移动,这样在窗口中就好像小鸟在向前飞行。所以在Pineline类中也创建一个updatePipeline()方法,实现管道的向左侧移动。此外还创建了3个函数:createMap()函数用于绘制地图;checkDead()函数用于判断小鸟的生命状态;getResult()函数用于获取最终分数。最后在主逻辑中实例化并调用相关方法,实现相应的功能。

搭建主框架

# -*- coding:utf-8 -*-
import sys  # 导入sys模块
import pygame  # 导入pygame模块
import random


class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        pass

    def birdUpdate(self):
        pass


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""

    def updatePipeline(self):
        """水平移动"""


def createMap():
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))  # 填充颜色(screen还没定义不要着急)
    screen.blit(background, (0, 0))  # 填入到背景
    pygame.display.update()  # 更新显示


if __name__ == '__main__':
    pygame.init()                           # 初始化pygame
    size = width, height = 400, 650         # 设置窗口大小
    screen = pygame.display.set_mode(size)  # 显示窗口
    clock = pygame.time.Clock()             # 设置时钟
    Pipeline = Pipeline()                   # 实例化管道类
    while True:
        clock.tick(60)                      # 每秒执行60次
        # 轮询事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:   # 如果检测到事件是关闭窗口
                sys.exit()

        background = pygame.image.load("assets/background.png")  # 加载背景图片
        createMap()
    pygame.quit()  # 退出

执行结果:
Python游戏编程(Pygame)

开发过程中使用的图片

创建小鸟类、创建管道类、计算得分、碰撞检测

import pygame
import sys
import random


class Bird(object):
    """定义一个鸟类"""

    def __init__(self):
        """定义初始化方法"""
        self.birdRect = pygame.Rect(65, 50, 50, 50)  # 鸟的矩形
        # 定义鸟的3种状态列表
        self.birdStatus = [pygame.image.load("assets/1.png"),
                           pygame.image.load("assets/2.png"),
                           pygame.image.load("assets/dead.png")]
        self.status = 0      # 默认飞行状态
        self.birdX = 120     # 鸟所在X轴坐标,即是向右飞行的速度
        self.birdY = 350     # 鸟所在Y轴坐标,即上下飞行高度
        self.jump = False    # 默认情况小鸟自动降落
        self.jumpSpeed = 10  # 跳跃高度
        self.gravity = 5     # 重力
        self.dead = False    # 默认小鸟生命状态为活着

    def birdUpdate(self):
        if self.jump:
            # 小鸟跳跃
            self.jumpSpeed -= 1           # 速度递减,上升越来越慢
            self.birdY -= self.jumpSpeed  # 鸟Y轴坐标减小,小鸟上升
        else:
            # 小鸟坠落
            self.gravity += 0.2           # 重力递增,下降越来越快
            self.birdY += self.gravity    # 鸟Y轴坐标增加,小鸟下降
        self.birdRect[1] = self.birdY     # 更改Y轴位置


class Pipeline(object):
    """定义一个管道类"""

    def __init__(self):
        """定义初始化方法"""
        self.wallx = 400  # 管道所在X轴坐标
        self.pineUp = pygame.image.load("assets/top.png")
        self.pineDown = pygame.image.load("assets/bottom.png")

    def updatePipeline(self):
        """"管道移动方法"""
        self.wallx -= 5  # 管道X轴坐标递减,即管道向左移动
        # 当管道运行到一定位置,即小鸟飞越管道,分数加1,并且重置管道
        if self.wallx < -80:
            global score
            score += 1
            self.wallx = 400


def createMap():
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))  # 填入到背景

    # 显示管道
    screen.blit(Pipeline.pineUp, (Pipeline.wallx, -300))   # 上管道坐标位置
    screen.blit(Pipeline.pineDown, (Pipeline.wallx, 500))  # 下管道坐标位置
    Pipeline.updatePipeline()  # 管道移动

    # 显示小鸟
    if Bird.dead:              # 撞管道状态
        Bird.status = 2
    elif Bird.jump:            # 起飞状态
        Bird.status = 1
    screen.blit(Bird.birdStatus[Bird.status], (Bird.birdX, Bird.birdY))              # 设置小鸟的坐标
    Bird.birdUpdate()          # 鸟移动

    # 显示分数
    screen.blit(font.render('Score:' + str(score), -1, (255, 255, 255)), (100, 50))  # 设置颜色及坐标位置
    pygame.display.update()    # 更新显示


def checkDead():
    # 上方管子的矩形位置
    upRect = pygame.Rect(Pipeline.wallx, -300,
                         Pipeline.pineUp.get_width() - 10,
                         Pipeline.pineUp.get_height())

    # 下方管子的矩形位置
    downRect = pygame.Rect(Pipeline.wallx, 500,
                           Pipeline.pineDown.get_width() - 10,
                           Pipeline.pineDown.get_height())
    # 检测小鸟与上下方管子是否碰撞
    if upRect.colliderect(Bird.birdRect) or downRect.colliderect(Bird.birdRect):
        Bird.dead = True
    # 检测小鸟是否飞出上下边界
    if not 0 < Bird.birdRect[1] < height:
        Bird.dead = True
        return True
    else:
        return False


def getResutl():
    final_text1 = "Game Over"
    final_text2 = "Your final score is: " + str(score)
    ft1_font = pygame.font.SysFont("Arial", 70)                                      # 设置第一行文字字体
    ft1_surf = font.render(final_text1, 1, (242, 3, 36))                             # 设置第一行文字颜色
    ft2_font = pygame.font.SysFont("Arial", 50)                                      # 设置第二行文字字体
    ft2_surf = font.render(final_text2, 1, (253, 177, 6))                            # 设置第二行文字颜色
    screen.blit(ft1_surf, [screen.get_width() / 2 - ft1_surf.get_width() / 2, 100])  # 设置第一行文字显示位置
    screen.blit(ft2_surf, [screen.get_width() / 2 - ft2_surf.get_width() / 2, 200])  # 设置第二行文字显示位置
    pygame.display.flip()                                                            # 更新整个待显示的Surface对象到屏幕上


if __name__ == '__main__':
    """主程序"""
    pygame.init()                            # 初始化pygame
    pygame.font.init()                       # 初始化字体
    font = pygame.font.SysFont("Arial", 50)  # 设置字体和大小
    size = width, height = 400, 650          # 设置窗口
    screen = pygame.display.set_mode(size)   # 显示窗口
    clock = pygame.time.Clock()              # 设置时钟
    Pipeline = Pipeline()                    # 实例化管道类
    Bird = Bird()                            # 实例化鸟类
    score = 0
    while True:
        clock.tick(60)                       # 每秒执行60次
        # 轮询事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead:
                Bird.jump = True             # 跳跃
                Bird.gravity = 5             # 重力
                Bird.jumpSpeed = 10          # 跳跃速度

        background = pygame.image.load("assets/background.png")  # 加载背景图片
        if checkDead():                      # 检测小鸟生命状态
            getResutl()                      # 如果小鸟死亡,显示游戏总分数
        else:
            createMap()                      # 创建地图
    pygame.quit()

执行结果:

Python游戏编程(Pygame)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151683.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea 2022 激活码永久 mac【2022.01最新】2022.02.27

    (idea 2022 激活码永久 mac)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html2K…

  • vue跨域解决方案 简书_springboot允许跨域

    vue跨域解决方案 简书_springboot允许跨域一:为什么会出现跨域问题?出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。二:什么是跨域?当一个请求url的协议、域

  • Stata做空间杜宾模型、莫兰指数等操作

    Stata做空间杜宾模型、莫兰指数等操作以下内容完全由本人在实际操作中搜集整理总结得到,很细致的介绍:从如何在stata中导入数据,怎么定义面板数据,再到如何做局部和全局空间相关性检验(莫兰指数)和空间杜宾模型等。1、导入面板数据在excel中输入如下格式的数据:打开STATA,data-dataeditor-dataeditor(edit),将excel中数据复制上去接着在STATA主界面的comm…

  • python向量叉乘_矢量的点乘和叉乘公式

    python向量叉乘_矢量的点乘和叉乘公式向量的内积(点乘)定义概括地说,向量的内积(点乘/数量积)。对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,如下所示,对于向量a和向量b:a和b的点积公式为:这里要求一维向量a和向量b的行列数相同。注意:点乘的结果是一个标量(数量而不是向量)定义:两个向量a与b的内积为a·b=|a||b|cos∠(a,b),特别地,0·a=a·0=0;若a,b是非零向量,则a…

  • apk加壳加密工具(apk protect) v1.0下载「建议收藏」

    apk加壳加密工具(apk protect) v1.0下载「建议收藏」apk加壳加密工具(apk_protect)是用于加密apk文件中dex文件的加密工具,加密的东西主要有字符串加密、流程加密、类名加密和api加密(未完成,后续支持)等,有于较好的保护apk文件,使之不易激活成功教程分析。__我对apk_protect在线加密的有效性进行了测试和分析,发现确实给android_apk提供了无法激活成功教程的加密壳。虽然在线加密已经是非常省时省力的了,但是仍然有不少程序员懒于折腾(尽管这已经不叫折腾了,就是上传一下再下载,比起写代码来说,这简直就是享受)。于是,意外的发现他们已经推出了懒人版

  • Aspose.PSD for Java 21.6 Crack

    Aspose.PSD for Java 21.6 CrackAspose.PSDforJava21.6Aspose.PSDforJava是一个易于使用的AdobePhotoshop文件格式操作API。????578867473知道它可以轻松加载和读取PSD、PSB和AI文件,使Java开发人员可以执行更新图层属性、添加水印、压缩、旋转、缩放或将一种文件格式渲染为另一种文件格式等操作,而无需安装Adob​​ePhotoshop。JPEG、TIFF、GIF、PNG、BMP、JPEG2000等图像格式,只需几行代码即可轻松打开和添加为

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号