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 += 5if catx == 280:direction = 'down'elif direction == 'down':caty += 5if caty == 220:direction = 'left'elif direction == 'left':catx -= 5if catx == 10:direction = 'up'elif direction == 'up':caty -= 5if 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 loopDISPLAYSURF.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 pygamepygame.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 = rectself.color = colorself.text = textself.font = fontdef 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 = Falsebutton.handle_event(event)screen.fill((255, 255, 255))button.draw(screen)pygame.display.flip()pygame.quit()

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

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

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

FPGA|生成jic文件固化程序到flash

1、单击file-》convert programming files 2、flie type中选中jic文件,configuration decive里根据自己的硬件选择,单击flash loader选择右边的add device选项 3、选择自己的硬件,单击ok 4、选中sof选项,单机右侧的add file 5、选…

P3654 First Step (ファーストステップ)(贪心算法)

#include<bits/stdc.h> using namespace std;int main() {int r,c,k;cin>>r>>c>>k;char a[105][105];int ans0;for(int i0;i<r;i){for(int j0;j<c;j){cin>>a[i][j];}}for(int i0;i<r;i){int cnt0; // 用来记录连续空地的数量for(int j…

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …

ASP.NET Core中Filter与Middleware的区别

中间件是ASP.NET Core这个基础提供的功能&#xff0c;而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架&#xff0c;而Filter属于MVC中间件提供的功能。 区别 中间件可以处理所有的请求&#xff0c;而Filter只能处理对控制器的请求&#x…

ASP.NET Core对JWT的封装

目录 JWT封装 [Authorize]的注意事项 JWT封装 NuGet 库 |Microsoft.AspNetCore.Authentication.JwtBearer 9.0.1https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearerhttps://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBea…

【Uniapp-Vue3】从uniCloud中获取数据

需要先获取数据库对象&#xff1a; let db uniCloud.database(); 获取数据库中数据的方法&#xff1a; db.collection("数据表名称").get(); 所以就可以得到下面的这个模板&#xff1a; let 函数名 async () > { let res await db.collection("数据表名称…

腾讯云TI平台×DeepSeek:开启AI超强体验,解锁部署秘籍

引言 在人工智能飞速发展的今天&#xff0c;AI技术的应用场景已经渗透到我们生活的方方面面。从智能客服到自动驾驶&#xff0c;从精准医疗到金融科技&#xff0c;AI的应用正在不断推动各行业的变革与创新。作为AI领域的领军企业&#xff0c;腾讯云一直以来都在致力于为开发者…

利用 IMU 估计人体关节轴向和位置 —— 论文推导

Title: 利用 IMU 估计人体关节轴向和位置 —— “Joint axis and position estimation from inertial measurement data by exploiting kinematic constraints” —— 论文推导 文章目录 I. 论文回顾II. 铰接关节的约束1. 铰接关节约束的原理2. 铰接关节约束的梯度3. 铰接关节约…

pushgateway指标聚合问题

一 问题现象 一个job有多个实例推送指标&#xff0c;但是从pushgateway上看这个job的instance字段&#xff0c;只显示一个实例的ip&#xff0c;而不是多个实例。导致在grafana上无法正常根据ip查看监控。 应用的prometheus的配置 management:metrics:tags:application: ${spr…

无界构建微前端?NO!NO!NO!多系统融合思路!

文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…

Vim 多窗口编辑及文件对比

水平分割 :split 默认使用水平分割的方式。 :split :sp 垂直分割 :vsplit :vs 带文件的分割 :split 文件名 :sp 文件名 在光标所在的窗口&#xff0c;输入分割窗口命令就会对那个窗口进行分割。 切换窗口 Ctrlw 切换正在编辑的窗口 快速分割窗口 Ctrlwn 快速分割当前…

yolov11模型在Android设备上运行【踩坑记录】

0) 参考资料: https://github.com/Tencent/ncnn?tabreadme-ov-file https://github.com/pnnx/pnnx https://github.com/nihui/ncnn-android-yolov5 https://github.com/Tencent/ncnn?tabreadme-ov-file 1) &#xff1a;将xxx.pt模型转化成 xxx.onnx ONNX&#xff08;Ope…

电商平台的设计与实现(代码+数据库+LW)

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统商品交易信息管理难度大&#xff0c;容错率低&#xff0…

学习笔记:机器学习中的数学原理(一)

1. 集合 集合分为有限集和无限集&#xff1b; 对于有限集&#xff0c;两集合元素数相等即为等势&#xff1b; 对于无限集&#xff0c;两集合元素存在一一映射关系即为等势&#xff1b; 无限集根据是否与正整数集等势分为可数集和不可数集。 2. sigmoid函数&#xff08;也叫…

【翻译+论文阅读】DeepSeek-R1评测:粉碎GPT-4和Claude 3.5的开源AI革命

目录 一、DeepSeek-R1 势不可挡二、DeepSeek-R1 卓越之处三、DeepSeek-R1 创新设计四、DeepSeek-R1 进化之路1. 强化学习RL代替监督微调学习SFL2. Aha Moment “啊哈”时刻3. 蒸馏版本仅采用SFT4. 未来研究计划 部分内容有拓展&#xff0c;部分内容有删除&#xff0c;与原文会有…

互联网分布式ID解决方案

业界实现方案 1. 基于UUID 2. 基于DB数据库多种模式(自增主键、segment) 3. 基于Redis 4. 基于ZK、ETCD 5. 基于SnowFlake 6. 美团Leaf(DB-Segment、zkSnowFlake) 7. 百度uid-generator() 基于UUID生成唯一ID UUID生成策略 推荐阅读 DDD领域驱动与微服务架构设计设计模…

使用Python实现PDF与SVG相互转换

目录 使用工具 使用Python将SVG转换为PDF 使用Python将SVG添加到现有PDF中 使用Python将PDF转换为SVG 使用Python将PDF的特定页面转换为SVG SVG&#xff08;可缩放矢量图形&#xff09;和PDF&#xff08;便携式文档格式&#xff09;是两种常见且广泛使用的文件格式。SVG是…

CV(11)-图像分割

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 图像分割 语义分割不需要区分具体的个体&#xff0c;实例分割需要 反卷积/转置卷积&#xff1a; 它并不是正向卷积的完全逆过程。反卷积是一种特殊的正向卷积&#xff0c;先按照一定的比例通过补0 来扩大输入图像的尺寸&…

封装descriptions组件,描述,灵活

效果 1、组件1&#xff0c;dade-descriptions.vue <template><table><tbody><slot></slot></tbody> </table> </template><script> </script><style scoped>table {width: 100%;border-collapse: coll…