02py游戏开发基础

news2024/11/19 13:14:27

版本

pygame 2.4.0 (SDL 2.26.4, Python 3.8.2)
Hello from the pygame community. https://www.pygame.org/contribute.html

Python开发基础

Pygame常用模块

image-20230620092149535 image-20230620092158643
background_image_filename = "bg.jpg"#设置图像文件名称
mouse_image_filename = "ship.bmp"

# 将import pygame和from pygame.locals import *分两次写是为了区分导入pygame模块
# 和导入pygame.locals模块中的常量和枚举类型,以便代码的可读性和维护性
import pygame
from pygame.locals import *
# pygame.locals模块提供了一些常量和枚举类型,用于表示键盘、鼠标、事件等相关的常量和状态。
from sys import exit#从sys模块导入函数exit()用于退出程序

pygame.init()#初始化pygame,使用硬件做准备
screen = pygame.display.set_mode((640, 480), pygame.DOUBLEBUF | pygame.RESIZABLE, 32)#创建一个窗口
pygame.display.set_caption("Hello, World!")#设置窗口标题
#下面两行代码加载并转换图像
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()

#主循环 ● 处理事件。● 更新游戏状态。● 在屏幕上绘制游戏状态。
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
    screen.blit(background, (0,0))#将背景图画上去
    x, y = pygame.mouse.get_pos()#获得鼠标位置
    # 下面两行代码计算光标左上角位置
    # 使鼠标光标和光标图像中心对齐
    # pygame.mouse.set_visible(False)#隐藏鼠标
    print("旧")
    print(x, y)
    x -= mouse_cursor.get_width() / 2
    y -= mouse_cursor.get_height() / 2
    print("新")
    print(x, y)
    # print(mouse_cursor.get_width() / 2,mouse_cursor.get_height() / 2)
    screen.blit(mouse_cursor, (x, y))   #绘制光标
    #把光标画上去
    pygame.display.update()     #刷新画面

set_mode()

set_mode()方法用于创建一个窗口或全屏幕显示,它的函数签名为:

set_mode(resolution=(0,0), flags=0, depth=0)

其中,set_mode()方法有三个参数,分别为:

  1. resolution:表示窗口的分辨率,它是一个二元组,包含了窗口的宽度和高度。例如,(640, 480)表示窗口宽度为640像素,高度为480像素。如果将resolution设置为(0, 0),则表示创建一个全屏窗口。
  2. flags:表示窗口的特性,它是一个整数,可以通过按位或运算符(|)来组合多个特性。常用的特性包括:
    • pygame.FULLSCREEN:创建全屏窗口。
    • pygame.DOUBLEBUF:使用双缓冲技术,可以避免屏幕闪烁。
    • pygame.RESIZABLE:窗口可以调整大小。
    • pygame.HWSURFACE:使用硬件加速,可以提高绘制速度。
    • pygame.NOFRAME:创建一个没有边框的窗口。
  3. depth:表示颜色深度,它表示每个像素使用的位数。默认值为0,表示使用当前显示器的颜色深度。可以设置为16、24或32等值,表示使用16位、24位或32位颜色深度。

Surface对象

在Pygame中,Surface对象是表示图像和屏幕的基本类型,它是一个**二维的像素数组,**可以用来表示图像、屏幕、文本等。Surface对象可以通过加载图像文件、创建空白Surface对象、从屏幕截取图像等方式来创建。

Surface对象具有很多属性和方法,可以用来操作和绘制图像。一些常用的属性和方法包括:

  • get_width():返回Surface对象的宽度。
  • get_height():返回Surface对象的高度。
  • get_size():返回Surface对象的尺寸,是一个二元组。
  • blit():将一个Surface对象绘制到另一个Surface对象上。
  • fill():使用指定的颜色填充Surface对象。
  • convert():将Surface对象转换为指定的像素格式。
  • convert_alpha():将Surface对象转换为带有alpha通道的像素格式(保留了透明的部分,这样移动的光标才是不规则形状)。

主循环

游戏的主循环是一个无限循环,直到用户跳出。在这个主循环里做的事情就是不停地画背景和更新光标位置,虽然背景是不动的,但还是需要每次都画它,否则鼠标覆盖过的位置就不能恢复正常了

大都带有这样的一些while True循环,并且带有一条将该循环称为“main game loop”的注释。游戏循环(game loop,也叫作主循环main loop)中的代码做如下3件事情。

  • 处理事件。

  • 更新游戏状态。

  • 在屏幕上绘制游戏状态。

游戏状态

游戏状态(game state)只不过是针对游戏程序中用到的所有变量的一组值的一种叫法

事件基础

事件

在Pygame中,事件是指用户与程序交互时产生的动作,例如按键、鼠标移动、窗口关闭等。Pygame通过pygame.event模块来处理事件,可以使用pygame.event.get()函数获取当前所有的事件,并通过遍历事件队列来处理不同类型的事件。

image-20230620103755060 image-20230620105602919

pygame.quit()

在Event对象中有一个名为type的成员变量,其功能是告诉对象表示哪一种事件。针对pygame.locals模块中每一种可能的类型,Pygame都有一个常量变量。

pygame.quit()是pygame.init()的相反函数

pygame.event.Event对象

在任何时候,当用户按下一个按键或者把鼠标移动到程序的窗口上面等动作时,Pygame库就会创建一个pygame.event.Event对象来记录这个动作,这就是事件。我们可以调用函数pygame.event.get()来获取发生的事件,此函数会返回pygame.event.Event对象(简称为Event对象)的一个列表。这个Event对象的列表包含了自上次调用pygame.event.get()函数之后所发生的所有事件(如果从来没有调用过pygame.event.get(),会包括自程序启动以来所发生的所有事件)。

处理鼠标事件

在Pygame框架中,MOUSEMOTION事件会在鼠标动作的时候发生,它有如下所示的3个参数。

  • buttons:一个含有3个数字的元组,3个值分别代表左键、中键和右键,1就说明按下了。

  • pos:位置。

  • rel:代表现在距离上次产生鼠标事件时的距离。和MOUSEMOTION类似,常用的鼠标事件还有MOUSEBUTTONDOWN和MOUSEBUTTONUP两个。这两个事件的参数如下所示。

  • button:这个值代表了哪个按键被操作。

  • pos:位置。

import pygame
#判断一个点是否在指定范围内
def is_rect(pos,rect):
    x, y = pos
    rx, ry, rw, rh = rect
    if(rx <= x <= rx+rw) and (ry <= y <= ry+rh):
        return True
    return False

if __name__ == "__main__":
    pygame.init()
    screen = pygame.display.set_mode((600,600))
    screen.fill((255,255,255))
    pygame.display.set_caption("图片拖拽")
    #显示一张图片
    image = pygame.image.load("bg.jpg")
    image_x = 100
    image_y = 100

    screen.blit(image, (image_x, image_y))
    pygame.display.flip()
    #用来存储图片是否可以移动
    is_move = False
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            #鼠标按下,让状态可以移动
            if event.type == pygame.MOUSEBUTTONDOWN:
                w, h = image.get_size()
                if is_rect(event.pos, (image_x,image_y,w,h)):
                    is_move = True
            if event.type == pygame.MOUSEMOTION:
                if is_move:
                    screen.fill((255,255,255,255))
                    x, y = event.pos
                    image_w, image_h=image.get_size()
                    #保证鼠标在图片的中心
                    image_x=x-image_h/2
                    image_y=y-image_w/2
                    screen.blit(image,(image_x,image_y))
                    pygame.display.update()

处理键盘事件

在Pygame框架中,键盘和游戏手柄的事件比较类似,处理键盘的事件为KEYDOWN和KEYUP。KEYDOWN和KEYUP事件的参数描述如下所示。

  • key:按下或者放开的键值,是一个数字,因为很少有人可以记住,所以在Pygame中可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACE和K_RETURN等。
  • mod:包含了组合键信息,如果mod &KMOD_CTRL是真的话,表示用户同时按下了〈Ctrl〉键。类似的还有KMOD_SHIFT和KMOD_ALT。
  • unicode:代表按下键对应的Unicode值。例如在下面的实例文件shi.py中,演示了在Pygame框架中处理键盘事件的过程。
background_image_filename = "bg.jpg"
import pygame
from pygame.locals import *
from sys import exit

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
#下面一行代码加载并转换图像
background = pygame.image.load(background_image_filename).convert()
x, y = 0, 0#设置初始位置
move_x, move_y = 0, 0#水平纵向两个方向的移动距离
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == KEYDOWN:#如果键盘有按键按下
           if event.key == K_LEFT:
               move_x = -1
           elif event.key == K_RIGHT:
               move_y = 1
           elif event.key == K_UP:
               move_y = -1
           elif event.key == K_DOWN:
               move_y = 1
        elif event.type == KEYUP:#如果按键放开,不移动
            move_x = 0
            move_y = 0
        #下面两行计算出新的坐标
        x += move_x
        y += move_y
        screen.fill((0,0,0))#屏幕填充黑色
        screen.blit(background, (x, y))
        #在新的位置画图
        pygame.display.update()#更新绘制操作后屏幕的显示

事件过滤

在现实应用中,并不是所有的事件都是需要处理的。应该有一个方法来过滤掉一些不感兴趣的事件。

  • 这时需要使用pygame.event.set_blocked(事件名)来完成。如果有好多事件需要过滤,可以传递一个专用列表来实现比如pygame.event.set_blocked([KEYDOWN,KEYUP]),如果设置参数None,那么所有的事件又被打开了。与之相对应的是,使用**pygame.event.set_allowed()**函数来设定允许的事件。

  • pygame.event.set_blocked():控制哪些事件禁止进入队列。

    • set_blocked(type)-> Noneset_blocked(typelist)-> None
    • set_blocked(None)-> None参数指定类型的事件均不允许出现在事件队列中。默认是允许所有事件进入队列的。多次禁止同一类型的事件并不会引发什么问题。如果传入None,则表示允许所有的事件进入队列。
  • pygame.event.set_allowed():控制哪些事件允许进入队列。

    • set_allowed(type)-> None
    • set_allowed(typelist)-> None
    • set_allowed(None)-> None参数指定类型的事件均允许出现在事件队列中。默认是允许所有事件进入队列。多次允许同一类型的事件并不会引发什么问题。如果传入None,则表示禁止所有的事件进入队列。
  • pygame.event.get_blocked():检测某一类型的事件是否被禁止进入队列

    • get_blocked(type)-> bool如果参数指定类型的事件被禁止进入队列,则返回

产生事件

有时候需要模拟出一些对应的事件,可以自定义一个全新事件

案例

move_ball.py

from sys import exit
import  pygame
from pygame.locals import *
#事件类型:"键盘输入",就根据方向键计算出这个速度(默认从左向右为1,从上向下为1)
def control_ball(event):
    speed = [0, 0]#设置相对位移
    speed_offset = 1

    if event.type == KEYDOWN:
        if event.key == pygame.K_LEFT:
            speed[0] -= speed_offset

        if event.key == pygame.K_RIGHT:
            speed[0] =  speed_offset
            print(event.key)

        if event.key == pygame.K_UP:#Y轴朝下是正
            speed[1] -= speed_offset

        if event.key == pygame.K_DOWN:
            speed[1] =  speed_offset
    #如果没有按键输入速度为0小球不动
    if event.type == KEYUP:
        speed = [0, 0]
    return speed


def play_ball():
    pygame.init()

    window_size = Rect(0, 0, 806, 480)
    screen = pygame.display.set_mode(window_size.size)
    pygame.display.set_caption("坤坤找不到他的篮球了")
    ball_image = pygame.image.load("ball01.png").convert_alpha()
    back_image = pygame.image.load("bg1.jpg")
    ball_rect = ball_image.get_rect()#获取小球图片所在区域

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()

        control_speed = control_ball(event)#获取小球移动方向
        ball_rect = ball_rect.move(control_speed).clamp(window_size)#限制小球图片在window_size这个区域里

        screen.blit(back_image, (0, 0))#绘制游戏窗口
        screen.blit(ball_image, ball_rect)#把小球绘制到背景Surface上

        # pygame.display.flip()
        pygame.display.update()

if __name__ == "__main__":
    play_ball()

pygame.Rect()

Rect()是Pygame中的一个类,用于创建矩形对象。它接受四个参数,分别是矩形的左上角x坐标、左上角y坐标、矩形的宽度和高度。

Rect().size()返回一个元组,包含矩形的宽度和高度

pygame.Surface.get_rect()

get_rect():是Surface对象的一个方法,用于获取表示该表面的矩形区域的Rect对象。

get_rect()方法返回一个Rect对象,该对象表示了Surface的矩形区域。这个矩形区域的左上角坐标为(0, 0),宽度和高度与Surface的尺寸相匹配。

get_rect()方法还接受一个可选的关键字参数kwargs,可以用于设置Rect对象的属性。例如,可以使用kwargs参数来设置矩形区域的位置或大小。

pygame.Rect.clamp()

clamp()

moves the rectangle inside another

clamp(Rect) -> Rect

更新窗口内容

pygame.display.flipUpdate the full display Surface to the screen
pygame.display.updateUpdate portions of the screen for software displays
  1. pygame.display.flip():
    • flip()函数用于交换屏幕缓冲区的内容。在绘制完成后,调用flip()函数可以将绘制的内容立即显示在屏幕上。
    • flip()函数没有参数,它会更新整个屏幕的显示。
    • flip()函数比较简单,适用于简单的图形绘制场景。
  2. pygame.display.update():
    • update()函数用于更新屏幕的部分区域。它可以接受一个可选的参数,表示要更新的矩形区域。如果不指定参数,update()函数将更新整个屏幕。
    • update()函数可以更加灵活地控制屏幕的更新。您可以选择只更新需要更新的部分,以提高性能。
    • update()函数可以接受一个矩形列表作为参数,表示要更新的多个矩形区域。

主程序运行

if __name__ == "__main__": 是一个常见的Python代码约定,用于判断当前模块是否作为主程序直接运行。

当一个Python脚本作为主程序直接运行时,__name__变量的值会被设置为__main__。而当一个脚本被作为模块导入时,__name__变量的值会是模块的名称。

因此,使用if __name__ == "__main__": 来判断__name__的值,可以使得一部分代码只在脚本作为主程序运行时执行,而在被导入时不执行。

在您的代码中,play_ball()函数会在if __name__ == "__main__": 条件满足时被调用。这意味着当您的脚本作为主程序直接运行时,play_ball()函数会被执行。但如果您的脚本被作为模块导入,play_ball()函数不会被执行。

这种约定可以用于将一些测试代码或调试代码放在if __name__ == "__main__": 条件下,以便在开发和调试阶段执行,而在实际使用时不执行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM优化00

JVM优化 0.目标 了解下我们为什么要学习JVM优化掌握jvm的运行参数以及参数的设置掌握jvm的内存模型&#xff08;堆内存&#xff09;掌握jmap命令的使用以及通过MAT工具进行分析掌握定位分析内存溢出的方法掌握jstack命令的使用掌握VisualJVM工具的使用 1.为什么学习JVM优化 …

LeetCode - #82 删除排序链表中的重复元素 II

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

异常的介绍与处理

目录 第七章 异常 1.异常 2.处理方法 2.1.try-catch 2.2.多重catch块 2.3.finally 2.4.throw 与 throws 2.5.程序分析 3.自定义异常 内容仅供学习交流&#xff0c;如有问题请留言或私信&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 有空您就点点赞…

【计算机视觉】计算机视觉的简单入门代码介绍(含源代码)

文章目录 一、介绍二、项目代码2.1 导入三方包2.2 读取和展示图片2.3 在图像上绘画2.4 混合图像2.5 图像变换2.6 图像处理2.7 特征检测 一、介绍 计算机视觉是一门研究计算机如何理解和解释图像和视频的学科。 它的目标是让计算机能够模拟人类视觉系统&#xff0c;让它们能够识…

Vivado 下 LED 灯闪烁实验

目录 Vivado 下 LED 灯闪烁实验 1、简介 2、实验环境 3、实验任务 4、硬件设计 5、程序设计 5.1、LED 闪烁模块代码 5.2、Vivado 仿真验证 5.2.1、编写 TB 仿真代码 6、下载验证 6.1、添加约束文件 .xdc 6.2、下载验证 注意&#xff1a;一定要先把下载器的一端连接…

FDM3D打印系列——2、一些基础概念

大家好&#xff0c;我是阿赵。 在买3D打印机之前&#xff0c;一般都会很迷茫&#xff0c;不知道3D打印机是怎样工作的&#xff0c;也不知道有哪些地方需要注意。上一篇文章通过打印一个模型&#xff0c;完整的体验了一次FDM打印3D模型的过程。这里解释一些在3D打印里面的比较基…

PMP考试自学可以吗?

PMP考试不建议自学&#xff0c;听劝&#xff0c;不该省的别省。 PMP现在没有自学了&#xff0c;今年3月的考试报了培训班的同学都说难&#xff0c;培训班的资源老师的专业&#xff0c;怎么也比自己单打独斗强吧&#xff0c;真的报培训班省事很多。 PS&#xff1a;网上说包过的…

X86架构与Arm架构区别

X86架构和ARM架构是主流的两种CPU架构&#xff0c;X86架构的CPU是PC服务器行业的老大&#xff0c;ARM架构的CPU则是移动端的老大。X86架构和arm架构实际上就是CISC与RISC之间的区别&#xff0c;很多用户不理解它们两个之间到底有哪些区别&#xff0c;实际就是它们的领域不太相同…

Liunx安装window中文字体解决中文变方框问题

问题现象描述 没安装中文字体&#xff0c;有可能导致你的程序在windows上运行的好好的&#xff0c;部署到linux上运行就可能出现汉字变成小方块的问题&#xff0c;场景举例&#xff1a;svg文件转png图片&#xff0c;原svg中的中文会变成方框 按如下方法安装中文字体后&#xf…

南卡OE骨传导开放式蓝牙耳机评测!舒适与音质并存!

平时买耳机的时候&#xff0c;你最先会关注什么方向呢&#xff1f;是舒适、美观&#xff0c;还是音质、防水&#xff1f; 对于我来说&#xff0c;首先是功能。作为一个经常健身、跑步的人&#xff0c;最讨厌的就是平时运动流汗进入耳朵之后那种粘腻感觉。时间长了还容易让耳道…

凹下去的白色按钮

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>凹下去的按钮</title><style>import url("https://fonts.googleapis.com/css2?famil…

【SIGMOD 2023】深度学习弹性数据流水线系统GoldMiner,大幅提升任务和集群效率

第一板块&#xff1a;开篇 近日&#xff0c;阿里云机器学习平台PAI和北京大学杨智老师团队合作的论文《GoldMiner: Elastic Scaling of Training Data Pre-Processing Pipelines for Deep Learning》被数据库领域顶会SIGMOD 2023接收。 GoldMiner观察到深度学习任务中的数据预…

redis登录常见报错

第一次接触redis登录的时候遇见几个报错 一、使用以下两个命令报错&#xff1a; ./redis-cli -h 127.0.0.1 -p 6380 ./redis-cli -p 6380 报错&#xff1a;Could not connect to Redis at 127.0.0.1:6380: Connection refused 应该和redis.conf中配置的bind字段的IP有关…

一文全揽C/C++中所有指针相关知识点(从原理到示例,学不完根本学不完!!!!)

本篇会对C/C中【常见指针相关知识】一直进行总结迭代&#xff0c;记得收藏吃灰不迷路&#xff0c;一起学习分享喔 请大家批评指正&#xff0c;一起学习呀~ 一、指针基本知识1.1 指针的定义1.2 &#xff08;*&#xff09; 和&#xff08; &&#xff09; 运算符1.3 如何声明…

SM国密算法(四) -- SM3算法

一、简介 SM3密码杂凑算法是中国国家密码管理局2010年公布的中国商用密码杂凑算法标准。适用于商用密码应用中的数字签名和验证。 SM3是在[SHA-256]基础上改进实现的一种算法&#xff0c;其安全性和SHA-256相当。SM3和MD5的迭代过程类似&#xff0c;也采用Merkle-Damgard结构。…

OpenCV(图像处理)-基于python-滤波器(低通、高通滤波器的使用方法)

1.概念介绍2. 图像卷积filter2D() 3. 低通滤波器3.1 方盒滤波和均值滤波boxFilter()blur() 3.2 高斯滤波&#xff08;高斯噪音&#xff09;3.3 中值滤波&#xff08;胡椒噪音&#xff09;3.4 双边滤波 4. 高通滤波器4.1Sobel&#xff08;索贝尔&#xff09;&#xff08;高斯&am…

STL之set和map

目录 一. 原型二. 模板参数适配三. 迭代器四. 插入函数的修改四. 代码 一. 原型 简单实现的红黑树 template<class K, class V> struct RBTreeNode {RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;pair<K, V> …

FPGA_学习_11_IP核_RAM_乒乓操作

本篇博客学习另一个IP核&#xff0c;RAM。 用RAM实现什么功能呢&#xff1f; 实现乒乓操作。 乒乓操作是什么呢&#xff1f; 参考&#xff1a; FPGA中的乒乓操作思想_fpga中乒乓操作的原因_小林家的龙小年的博客-CSDN博客 何为乒乓操作_fanyuandrj的博客-CSDN博客 以下是本人理…

Clion开发STM32之日志模块(参考RT-Thread)

前言 日志对于开发和排错方面有着很重要的影响。通过查看RT-Thread的源码&#xff0c;将日志的打印输出划分到具体的文件和通过宏定义对具体的日志等级进行划分&#xff0c;这样就比较方便。结合此源码的形式将其分离出来&#xff0c;作为自己项目的日志框架进行使用分为日志驱…

crossover软件下载2023最新版虚拟机

在Mac系统中一直存在一个比较令用户们头疼的问题&#xff0c;那就是安装不了想要的Windows软件。如果使用的第一台电脑就是MacBook那接触到的Windows软件想必并不是很多。但我们中的大多数人都是从小先学习了Windows的操作系统&#xff0c;再过渡到Mac系统上的。 那有小伙伴会…