Pygame介绍与游戏开发

提供pygame功能介绍的文档:Pygame Front Page — pygame v2.6.0 documentation

基础语法和实现逻辑

与CLI不同,pygame提供了图形化使用界面GUI(graphical user interface)基于图像的界面可以创建一个有图像和颜色的窗口

要让pygame的众多函数可以被调用,首先要调用pygame.init()

然后我们要创建一个surface对象:pygame.display.set_mode((400, 300))

并用pygame.display.set_caption()设置窗口顶部的标题文本

game loop—游戏循环一直在做三件事:处理事件、更新游戏状态、在屏幕上绘制游戏状态

最常见的游戏循环状态就是事件处理(而循环由while True进行)

 while True:#main game loop
       for event in pygame.event.get():

quit函数是一种与init相反的函数,在调用sys.exit前总是先调用pygame.quit()

而进行这一语句的条件则是if event.type==QUIT:

在在for循环的事件和事件处理条件if结束,游戏状态开始更新,pygame.display.update()

它把pygame.display.set_ mode()所返回的Surface对象绘制到屏幕上。

由此,我们就可以创建一个最简单最无聊的屏幕游戏了

import pygame, sys
from pygame.locals import *

# 初始化Pygame
pygame.init()

# 设置窗口大小和标题
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')

# 主游戏循环
while True:
    # 事件处理
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # 更新显示
    pygame.display.update()

坐标系和图形建立

不管是2D游戏还是3D游戏,我们都需要有空间界定来判断事件发生与否,而这也是所有游戏当中最常见的引发事件方法,为此,我们要建立合适的像素坐标

 这里我们选择使用一个笛卡尔坐标系统来表示一个特定的点:值得注意的是,这里的Y轴坐标从最顶部的0开始,然后向下增加,而不是向上增加,这也是在大多数编程语言当中笛卡尔坐标是最有效的

在有了基本的空间界定以后,我们需要对其进行上色和透明度处理,其中颜色由RGB来表示,为了表示透明度,我们在RGB后面再加上一个大小在0~255的元素其中255表示完全不透明,RGB(0,0,0)为黑色RGB(255,255,255)为白色,想要使用透明颜色进行绘制,就必须使用convert_alpha()方法来创建一个Surface对象

anotherSurface=DISPLAYSURF.convert_alpha()

除了用四个整数构造的元组以外,也可以调用pygame.Color()填入参数

 Rect对象是一种表示矩形区域的方法

 例如,上述代码所表示的是所表示对象左上角位于(10,20)宽度为200像素,高度为300像素

如果想要访问对象最右边的x坐标,就必须要输入spamRect.right,当你对原坐标作出修改,其他坐标会自动算出,相应做出修改

pygame.Rect 提供了丰富的属性,用于描述矩形的位置和尺寸,以下是其主要属性:
基本位置和尺寸属性
•  x:矩形左上角的 x 坐标。
•  y:矩形左上角的 y 坐标。
•  width:矩形的宽度。
•  height:矩形的高度。
•  size:矩形的尺寸,返回一个元组 (width, height)。
边界属性
•  left:矩形左边缘的 x 坐标。
•  right:矩形右边缘的 x 坐标。
•  top:矩形上边缘的 y 坐标。
•  bottom:矩形下边缘的 y 坐标。
中心和角点属性
•  center:矩形的中心点坐标,返回一个元组 (centerx, centery)。
•  centerx:矩形水平中心的 x 坐标。
•  centery:矩形垂直中心的 y 坐标。
•  topleft:矩形左上角的坐标。
•  bottomleft:矩形左下角的坐标。
•  topright:矩形右上角的坐标。
•  bottomright:矩形右下角的坐标。
•  midtop:矩形上边中点的坐标。
•  midleft:矩形左边中点的坐标。
•  midbottom:矩形下边中点的坐标。
•  midright:矩形右边中点的坐标。
简化属性
•  w:与 width 相同,表示矩形的宽度。
•  h:与 height 相同,表示矩形的高度。
这些属性不仅可以用于获取矩形的相关信息,还可以通过赋值来修改矩形的位置或尺寸。

pygame的基本绘制函数

import pygame, sys
from pygame.locals import *

pygame.init()

# set up the window
DISPLAYSURF = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption('Drawing')

# set up the colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# draw on the surface object
DISPLAYSURF.fill(WHITE)
pygame.draw.polygon(DISPLAYSURF, GREEN, ((146, 0), (291, 106), (236, 277), (56, 277), (0, 106)))
pygame.draw.line(DISPLAYSURF, BLUE, (60, 60), (120, 60), 4)
pygame.draw.line(DISPLAYSURF, BLUE, (120, 60), (60, 120))
pygame.draw.line(DISPLAYSURF, BLUE, (60, 120), (120, 120), 4)
pygame.draw.circle(DISPLAYSURF, BLUE, (300, 50), 20, 0)
pygame.draw.ellipse(DISPLAYSURF, RED, (300, 250, 40, 80), 1)
pygame.draw.rect(DISPLAYSURF, RED, (200, 150, 100, 50))

pixObj = pygame.PixelArray(DISPLAYSURF)
pixObj[480][380] = BLACK
pixObj[482][382] = BLACK
pixObj[484][384] = BLACK
pixObj[486][386] = BLACK
pixObj[488][388] = BLACK
del pixObj

# run the game loop
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

 在编写代码时,我们往往会为每一种颜色设置常变量,这样会使代码更具有可读性,绘制函数则是根据他们的形状来命名,传递给这些函数的参数,则告诉他们它们在哪一个Surface对象上绘制,将形状绘制到何处

部分函数和方法介绍:

fill(color):会使传递给color参数到任何颜色来填充整个Surface对象

pygame.draw.polygon(surface,color,pointlist,width):多边形是由多个平坦的边组成的形状,surface和color参数告诉函数,将多边形绘制到哪一个surface上,以及用什么颜色绘制,其中:pointlist参数是一个元组或者点的列表(也就是说,用于XY 坐标的元组,或者两个整数的元组的列表)。多边形是通过这样的方式来绘制的,即在每个点以及元组中其后续的点之间绘制线条,然后,从最后的点到第一个点绘制一个线条。你也可以传递点的列表,而不是点的元组。
width参数是可选的。如果你漏掉了这个参数,多边形将会绘制为填充的,就像是屏幕上的绿色多边形那样,会用颜色来填充它。如果确实给width参数传递了一个整数值,则只是绘制出多边形的边框。这个整数表示多边形的边框会有多少个像素那么宽。给width参数传递1,将会绘制一个边框细瘦的多边形,而传递4、10或者20,将会绘制一个边框较粗一些的多边形。如果给width参数传入0,多边形将会是填充的(这和完全漏掉了width参数的效果一样)。

pygame.draw.line(surface, color, start_point, end_point, width) ——这个函数在start_point和end_point参数之间绘制一条直线。

pygame.draw.lines(surface, color, closed, pointlist, width) ——这个函数绘制了从一个点到下一个点的一系列的线条,这和pygame.draw.polygon()函数非常相似。唯一的区别在于如果你给closed参数传递了False,将不会有从pointlist中的最后一个点到第一个点的那条直线了。如果你传递了True,将会绘制从最后一个点到第一个点的直线。

pygame.draw.circle(surface, color, center_point, radius, width) ——该函数绘制一个圆。center_point参数指定了圆的圆心。传递给radius的参数为整数,表示的是圆的半径。

pygame.draw.ellipse(surface, color, bounding_rectangle, width) ——该函数绘制一个椭圆形。bounding_rectangle参数可以是一个pygame.Rect对象或者是4个整数的一个元组,就是表示出一个长方体的形状,由函数自动拟出椭圆。

pygame.draw.rect(surface, color, rectangle_tuple, width) ——该函数绘制一个矩形。

使用PixelArray()可以单个或批量设置像素的颜色,值得注意的是,PixelArray会将surface对象锁定,此时不能够使用blit()方法在其上绘制,诸如png,jpg这样的图像,如果想要查看一个对象是否被锁定了,可以使用get_locked()方法(锁定了会返回True),可以通过del语句删除PixelArray对象,以此outlocked

将图像连成动画需要通过多个图像来让人们的眼睛产生幻觉,通过提高帧率来让动画足够逼真

而pygame.time.Clock对象可以帮助我们确保程序以某一个最大的FPS运行。Clock对象将会在每一次迭代完成后都设置一个小小的暂停。调用一个Clock对象的tick方法,则能够确保无论计算机有多快,游戏都会按相同的速度运行。因此,这条代码应该放在循环的末尾。

 如果只是想要绘制简单的形状,绘制函数已经很好用了,但是实际上在制作游戏的过程中我们往往需要将PNG、JPG、GIF和BMP等文件格式的图像加载到我们的游戏当中——要加载图像,可以将图像名与后缀传递给pygame.image.load()函数,但是由此返回的surface对象和原来的surface对象并非用一个surface对象并非同一个surface对象,因此我们还需要用到位图复制(Blitting),可以将一个surface的内容复制到另一个surface上面,用的是blit()函数

import pygame, sys
from pygame.locals import *

# 初始化Pygame
pygame.init()

# 设置帧率
FPS = 30
fpsClock = pygame.time.Clock()

# 设置窗口
DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32)
pygame.display.set_caption('Animation')

# 定义颜色和图像
WHITE = (255, 255, 255)
catImg = pygame.image.load('cat.png')
catx = 10
caty = 10
direction = 'right'

# 主游戏循环
while True:
    # 填充背景色
    DISPLAYSURF.fill(WHITE)

    # 根据方向移动猫
    if direction == 'right':
        catx += 5
        if catx == 280:
            direction = 'down'
    elif direction == 'down':
        caty += 5
        if caty == 220:
            direction = 'left'
    elif direction == 'left':
        catx -= 5
        if catx == 10:
            direction = 'up'
    elif direction == 'up':
        caty -= 5
        if caty == 10:
            direction = 'right'

    # 绘制猫图像
    DISPLAYSURF.blit(catImg, (catx, caty))

    # 事件处理
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # 更新显示并控制帧率
    pygame.display.update()
    fpsClock.tick(FPS)

除此之外,我们还会在编写游戏的过程当中用到文本:

想要把文本绘制到屏幕,一共有六步:
1.创建一个pygame.font.Font对象
2.创建一个Surface对象,通过调用Font对象的render()方法,将文本绘制其上
3.通过调用Surface对象的get_rect()方法,从Surface对象创建一个Rect对象
4.通过修改Rect对象的属性之一,来设置其位置。
5.将带有文本的Surface对象复制到pygame.display.set_mode()所返回的Surface对象上
6.调用pygame.display.update(),使显示Surface出现在屏幕上

import pygame, sys
from pygame.locals import *

pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLUE = (0, 0, 128)

fontObj = pygame.font.Font('freesansbold.ttf', 32)
textSurfaceObj = fontObj.render('Hello world!', True, GREEN, BLUE)
textRectObj = textSurfaceObj.get_rect()
textRectObj.center = (200, 150)

while True:  # main game loop
    DISPLAYSURF.fill(WHITE)
    DISPLAYSURF.blit(textSurfaceObj, textRectObj)
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

render方法中提供了抗锯齿的图形技术,通过给文本和图形的边缘进行模糊化处理,使其看上不不那么块状化,(给render的第二个参数传入True)

用户体验升级:声音和交互按钮

播放声音可以使用pygame.mixer.Sound()构造函数,以此创建pygame.mixer.Sound对象,要播放音乐时可以调用sound对象的play()方式,停止则使用stop()方式,值得注意的是,sound一次只能加载一个音乐文件,因此我们要加载一个背景声音文件,调用pygame.mixer.music.load()函数并且将要加载的声音文件作为一个字符串参数传递。该函数一共有两个参数第一个表示指定循环的次数,第二个参数表示从音频的多少秒处开始播放。

此外作为能实现交互的游戏我们需要对按钮进行制作Pygame本身并没有直接提供一个现成的Button类或按钮交互功能,但可以通过自定义实现按钮交互。以下是实现按钮交互的基本方法:
创建按钮
1.  定义按钮类:通常需要定义一个Button类,包含按钮的矩形区域(pygame.Rect)、颜色、文本等属性。
2.  绘制按钮:使用pygame.draw.rect()绘制按钮的矩形背景,并通过pygame.font渲染文本。
实现按钮交互
1.  监听鼠标事件:在主循环中,通过pygame.event.get()获取事件,检测鼠标点击事件(pygame.MOUSEBUTTONDOWN)。
2.  判断点击位置:使用pygame.Rect.collidepoint()方法判断鼠标点击位置是否在按钮矩形内。
3.  执行操作:如果点击位置在按钮内,则执行相应的操作,例如打印消息或调用函数。
示例代码
以下是一个简单的按钮实现示例:

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("Pygame Button Example")

class Button:
    def __init__(self, rect, color, text, font):
        self.rect = rect
        self.color = color
        self.text = text
        self.font = font

    def draw(self, surface):
        pygame.draw.rect(surface, self.color, self.rect)
        text_surface = self.font.render(self.text, True, (0, 0, 0))
        text_rect = text_surface.get_rect(center=self.rect.center)
        surface.blit(text_surface, text_rect)

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and self.rect.collidepoint(event.pos):
            print("Button clicked!")

button = Button(pygame.Rect(150, 125, 100, 50), (255, 0, 0), "Click Me", pygame.font.Font(None, 36))

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        button.handle_event(event)

    screen.fill((255, 255, 255))
    button.draw(screen)
    pygame.display.flip()

pygame.quit()

此外,也有一些第三方库或项目封装了按钮功能,例如pygame-button-interface-switch,可以方便地集成到Pygame项目中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966209.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity VideoPlayer播放视屏不清晰的一种情况

VideoPlayer的Rnder Texture可以设置Size,如果你的视屏是1920*1080那么就设置成1920*1080。 如果设置成其他分辨率比如800*600会导致视屏不清晰。

使用PyCharm创建项目以及如何注释代码

创建好项目后会出现如下图所示的画面,我们可以通过在项目文件夹上点击鼠标右键,选择“New”菜单下的“Python File”来创建一个 Python 文件,在给文件命名时建议使用英文字母和下划线的组合,创建好的 Python 文件会自动打开&#…

02.06 网络编程_套接字

思维导图: 网络编程基础:套接字的使用 网络编程是现代软件开发中不可或缺的一部分,而套接字(Socket)是网络编程中用于实现不同主机间通信的基本工具。本文将详细介绍套接字的概念、创建方法、如何通过套接字发送和接…

< OS 有关 > Ubuntu 版本升级 实践 24.04 -> 24.10, 安装 .NET

原因: 想安装 .NET 9 去编译 GitHut 项目,这回用不熟悉的 Ubuntu来做,不知道怎么拐去给 Ubuntu 升级,看到现在版本是 24.10 但不是 LTS 版本,记录下升级过程。 一、实践过程: 1. 查看当前版本 命令1: l…

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件:vsCode和Node(本人电脑Win11安装) 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装,点击下一步即可 …

音频进阶学习十二——Z变换一(Z变换、收敛域、性质与定理)

文章目录 前言一、Z变换1.Z变换的作用2.Z变换公式3.Z的状态表示1&#xff09; r 1 r1 r12&#xff09; 0 < r < 1 0<r<1 0<r<13&#xff09; r > 1 r>1 r>1 4.关于Z的解释 二、收敛域1.收敛域的定义2.收敛域的表示方式3.ROC的分析1&#xff09;当 …

分布式微服务系统架构第91集:系统性能指标总结

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ 系统性能指标总结 系统性能指标包括哪些&#xff1f; 业务指标、资源指标、中间件指标、数据库指标、前端指标、稳定性指标、批量处理指标、可扩展性指标、可靠性指标。 …

【C语言标准库函数】指数与对数函数:exp(), log(), log10()

目录 一、头文件 二、函数简介 2.1. exp(double x) 2.2. log(double x) 2.3. log10(double x) 三、函数实现&#xff08;概念性&#xff09; 3.1. exp(double x) 的模拟实现 3.2. log(double x) 和 log10(double x) 的模拟实现 四、注意事项 4.1. exp(double x) 的注…

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中&#xff0c;处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性&#xff0c;帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性&#xff1f; overflow 属性用于控制当元素的内容…

go语言中的接口

接口简介 现实生活中的接口 现实生活中手机、相机、U 盘都可以和电脑的 USB 接口建立连接。我们不需要关注 usb 卡槽大小是否一样&#xff0c;因为所有的 USB 接口都是按照统一的标准来设计的。 Golang 中的接口&#xff08;interface&#xff09; Golang 中的接口是一种抽象…

网络安全威胁框架与入侵分析模型概述

引言 “网络安全攻防的本质是人与人之间的对抗&#xff0c;每一次入侵背后都有一个实体&#xff08;个人或组织&#xff09;”。这一经典观点概括了网络攻防的深层本质。无论是APT&#xff08;高级持续性威胁&#xff09;攻击、零日漏洞利用&#xff0c;还是简单的钓鱼攻击&am…

Redis企业开发实战(三)——点评项目之优惠券秒杀

目录 一、全局唯一ID (一)概述 (二)全局ID生成器 (三)全局唯一ID生成策略 1. UUID (Universally Unique Identifier) 2. 雪花算法&#xff08;Snowflake&#xff09; 3. 数据库自增 4. Redis INCR/INCRBY 5.总结 (四)Redis实现全局唯一ID 1.工具类 2.测试类 3…

Verilog代码实例

Verilog语言学习&#xff01; 文章目录 目录 文章目录 前言 一、基本逻辑门代码设计和仿真 1.1 反相器 1.2 与非门 1.3 四位与非门 二、组合逻辑代码设计和仿真 2.1 二选一逻辑 2.2 case语句实现多路选择逻辑 2.3 补码转换 2.4 7段数码管译码器 三、时序逻辑代码设计和仿真 3.1…

排序算法--基数排序

核心思想是按位排序&#xff08;低位到高位&#xff09;。适用于定长的整数或字符串&#xff0c;如例如&#xff1a;手机号、身份证号排序。按数据的每一位从低位到高位&#xff08;或相反&#xff09;依次排序&#xff0c;每次排序使用稳定的算法&#xff08;如计数排序&#…

图形化界面MySQL(MySQL)(超级详细)

目录 1.官网地址 1.1在Linux直接点击NO thanks…? 1.2任何远端登录&#xff0c;再把jj数据库给授权 1.3建立新用户 优点和好处 示例代码&#xff08;MySQL Workbench&#xff09; 示例代码&#xff08;phpMyAdmin&#xff09; 总结 图形化界面 MySQL 工具大全及其功能…

C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输

CURL开源库介绍 CURL 是一个功能强大的开源库&#xff0c;用于在各种平台上进行网络数据传输。它支持众多的网络协议&#xff0c;像 HTTP、HTTPS、FTP、SMTP 等&#xff0c;能让开发者方便地在程序里实现与远程服务器的通信。 CURL 可以在 Windows、Linux、macOS 等多种操作系…

mapbox进阶,添加绘图扩展插件,绘制圆形

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…

网络工程师 (24)数据封装与解封装

一、数据封装 数据封装是指将协议数据单元&#xff08;PDU&#xff09;封装在一组协议头和尾中的过程。在OSI 7层参考模型中&#xff0c;数据从应用层开始&#xff0c;逐层向下封装&#xff0c;直到物理层。每一层都会为其PDU添加相应的协议头和尾&#xff0c;以包含必要的通信…

OSPF基础(3):区域划分

OSPF的区域划分 1、区域产生背景 路由器在同一个区域中泛洪LSA。为了确保每台路由器都拥有对网络拓扑的一致认知&#xff0c;LSDB需要在区域内进行同步。OSPF域如果仅有一个区域&#xff0c;随着网络规模越来越大&#xff0c;OSPF路由器的数量越来越多&#xff0c;这将导致诸…

C++----继承

一、继承的基本概念 本质&#xff1a;代码复用类关系建模&#xff08;是多态的基础&#xff09; class Person { /*...*/ }; class Student : public Person { /*...*/ }; // public继承 派生类继承基类成员&#xff08;数据方法&#xff09;&#xff0c;可以通过监视窗口检…