02py游戏开发基础

news/2024/11/19 19:33:43/

版本

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() / 2y -= mouse_cursor.get_height() / 2print("新")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 = posrx, ry, rw, rh = rectif(rx <= x <= rx+rw) and (ry <= y <= ry+rh):return Truereturn Falseif __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 = 100image_y = 100screen.blit(image, (image_x, image_y))pygame.display.flip()#用来存储图片是否可以移动is_move = Falsewhile 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 = Trueif event.type == pygame.MOUSEMOTION:if is_move:screen.fill((255,255,255,255))x, y = event.posimage_w, image_h=image.get_size()#保证鼠标在图片的中心image_x=x-image_h/2image_y=y-image_w/2screen.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 exitpygame.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 = -1elif event.key == K_RIGHT:move_y = 1elif event.key == K_UP:move_y = -1elif event.key == K_DOWN:move_y = 1elif event.type == KEYUP:#如果按键放开,不移动move_x = 0move_y = 0#下面两行计算出新的坐标x += move_xy += move_yscreen.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 = 1if event.type == KEYDOWN:if event.key == pygame.K_LEFT:speed[0] -= speed_offsetif event.key == pygame.K_RIGHT:speed[0] =  speed_offsetprint(event.key)if event.key == pygame.K_UP:#Y轴朝下是正speed[1] -= speed_offsetif event.key == pygame.K_DOWN:speed[1] =  speed_offset#如果没有按键输入速度为0小球不动if event.type == KEYUP:speed = [0, 0]return speeddef 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.ppmy.cn/news/497388.html

相关文章

去中心化金融(DeFi)的发展历史

随着Web3.0的兴起&#xff0c;去中心化金融&#xff08;Decentralized Finance&#xff0c;DeFi&#xff09;正逐渐成为金融领域的热门话题。DeFi旨在通过区块链技术和智能合约&#xff0c;实现无需信任的金融交易和服务&#xff0c;摆脱传统金融中心化的限制。然而&#xff0c…

vue elementUI封装的无限多级导航菜单(递归循环)

需要封装成两个文件&#xff1a; menu/index.vue <template><el-menuclass"box-card"unique-opened:collapse"$store.state.isCollapse":default-active"$store.state.nowPage"background-color"#2f3332"text-color"…

大疆智图的常见问题

大疆智图部分功能不能正常使用&#xff0c;需收费&#xff1a;在网页激活之后&#xff0c;在智图个人中心查看许可证是否绑定&#xff0c;软件激活之后无网使用需要隔两天进行一次登录 连接不上服务器&#xff0c;无法进行权限验证&#xff1a;1、注销后重新登录/更换网络环境&…

大疆无人机参数解释YAW/Roll/Pitch

大疆无人机安卓Mobile Sdk开发&#xff08;一&#xff09;简单介绍 很多人对yaw&#xff0c;roll&#xff0c;和picth的含义不是很懂&#xff0c;下面用大疆官方的一张图给大家解释一下&#xff0c;一目了然 pitch是俯仰&#xff0c;roll是横滚&#xff0c;yaw是航向&#xf…

大疆红外相机测温

一、API&#xff08;以Android SDK为例&#xff09; 1、isThermalCamera // 判断是否是热成像相机 判断是否是热成像相机&#xff0c;只有热成像相机&#xff0c;调用以下的API才有意义2、setDisplayMode // 设置热成像相机显示模式&#xff1a;&#xff08;1&#xff09;可…

大疆激光雷达livox avia 在ubuntu18.04+ROS中基本使用方法

Readme 大疆livox avia 固态激光雷达操作步骤&#xff1a; 1.参考本人CSDN博客lsg_dawn中收藏中的一篇关于ubuntu18.04中使用livox avia 雷达的文章 Livox Avia 雷达测试使用 ----- 测试使用&#xff08;Ubuntu18.04 ROS Melodic&#xff09;_杰尼君的博客-CSDN博客 2.连接好…

大疆无人机飞行器航空器坐标知识整理

一、大地坐标系。GIS开发&#xff0c;移动开发&#xff0c;web开发&#xff0c;GPS&#xff08;非专业GIS人士&#xff0c;若有错误求轻锤&#xff09;。全文以大疆无人机开发为背景举例说明。 我们常用的民用坐标系常用的有&#xff1a; 1、WGS84坐标系&#xff1a;即地球坐…

大疆热红外图片温度读取

适用于 大疆禅思 Zenmuse H20 系列拍摄的红外图片&#xff0c;依赖于大疆发布的TSDK&#xff08;DJI Thermal SDK&#xff09;&#xff0c;可用于视频的动态测温。 其实对TSDK并未深入研究&#xff0c;只是某一个小项目要使用TSDK处理H20拍摄的红外照片&#xff0c;利用TSDK中…