14天学习训练营之 入门Pygame

Posted YF云飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了14天学习训练营之 入门Pygame相关的知识,希望对你有一定的参考价值。

目录

学习知识点

pygame 的 “hello world”

          pygame 模块概览

事件

理解事件

事件检索

处理鼠标事件

处理键盘事件

事件过滤

产生事件

模板代码

写一个把所有发生的事件输出的程序

使用方向键来移动图片

产生一个完全自定义的全新事件

这个程序让 “hello world” 程序中的鱼动起来

这个程序使得物体斜线运动并且触边反弹

相关总结

绘制各种图形

一些说明

鼠标控制


14天学习训练营导师课程:
李宁《Python Pygame游戏开发入门与实战》
李宁《计算机视觉OpenCV Python项目实战》1
李宁《计算机视觉OpenCV Python项目实战》2
李宁《计算机视觉OpenCV Python项目实战》3


学习知识点

pygame 的 “hello world”

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pygame
from pygame.locals import * from sys import exit background_image = 'image/sushiplate.jpg' mouse_image = 'image/fugu.png' # 初始化pygame,为使用硬件做准备
pygame.init() # 创建了一个窗口
screen = pygame.display.set_mode((640, 480), 0, 32) # 设置窗口标题 pygame.display.set_caption("hello world") # 加载并转换图像
background = pygame.image.load(background_image).convert()
mouse_cursor = pygame.image.load(mouse_image).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() # 获得鼠标位置 
-= mouse_cursor.get_width()/2 y -= mouse_cursor.get_height()/2 # 计算光标左上角位置x 
screen.blit(mouse_cursor, (x, y)) # 画上光标
pygame.display.update() # 刷新画面 


pygame 模块概览

set_mode: 返回一个 Surface 对象,代表了桌面上出现的窗口。第一个参数代表分辨率;第二个参数是标志位,如果不需要使用热河特性,则指定为 0;第三个为色深。

标志位功能
FULLSCREEN创建一个全屏窗口 (create a fullscreen display)
DOUBLEBUF创建一个 “双缓冲” 窗口,建议在 HWSURFACE 或者 OPENGL 时使用( recommended for HWSURFACE or OPENGL)
HWSURFACE创建一个硬件加速的窗口,必须和 FULLSCREEN 同时使用( hardware accelerated, only in FULLSCREEN)
OPENGL创建一个 OPENGL 渲染的窗口 (create an OpenGL-renderable display)
RESIZABLE创建一个可以改变大小的窗口 (display window should be sizeable)
NOFRAME创建一个没有边框的窗口 (display window will have no border or controls)

convert_alpha: 相比 convert,保留了 Alpha 通道信息(可以简单理解为透明的部分),这样我们的光标才可以是不规则的形状。可以试试不用 convert_alpha () 生成的效果。

blit: 第一个参数为一个 Surface 对象,第二个为左上角位置。画完以后得用 update 更新,否则画面一片漆黑。


事件

理解事件


我们上一个程序,一直运行直到关闭窗口而产生了一个 QUIT 事件,Pygame 会接受用户的各种操作(比如按键盘,移动鼠标等)产生事件。事件随时可能发生,而且量也可能会很大,Pygame 的做法是把一系列的事件存放一个队列里,逐个的处理。


事件检索


上个程序中,使用了 pygame.event.get() 来处理所有的事件;也可以使用 pygame.event.wait(),pygame 会等到发生一个时间才继续下去;另外一个方法 pygame.event.poll(),一旦调用,它会根据现在的情形返回一个真实的事件,或者一个 “什么都没有”。下表是一个常用事件集:

事件产生途径参数
QUIT用户按下关闭按钮none
ATIVEEVENTPygame 被激活或者隐藏gain, state
KEYDOWN键盘被按下unicode, key, mod
KEYUP键盘被放开key, mod
MOUSEMOTION鼠标移动pos, rel, buttons
MOUSEBUTTONDOWN鼠标按下pos, button
MOUSEBUTTONUP鼠标放开pos, button
JOYAXISMOTION游戏手柄 (Joystick or pad) 移动joy, axis, value
JOYBALLMOTION游戏球 (Joy ball)? 移动joy, axis, value
JOYHATMOTION游戏手柄 (Joystick)? 移动joy, axis, value
JOYBUTTONDOWN游戏手柄按下joy, button
JOYBUTTONUP游戏手柄放开joy, button
VIDEORESIZEPygame 窗口缩放size, w, h
VIDEOEXPOSEPygame 窗口部分公开 (expose)?none
USEREVENT触发了一个用户事件code

处理鼠标事件

MOUSEMOTION 事件会在鼠标动作的时候发生,它有三个参数:

  • buttons – 一个含有三个数字的元组,三个值分别代表左键、中键和右键,1 就是按下了。
  • pos – 位置
  • rel – 代表了现在距离上次产生鼠标事件时的距离

和 MOUSEMOTION 类似的,我们还有 MOUSEBUTTONDOWN 和 MOUSEBUTTONUP 两个事件。它们的参数为:

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

  • pos – 位置


处理键盘事件

键盘的事件为 KEYDOWNKEYUP

KEYDOWNKEYUP 的参数描述如下:http://www.pygame.org/docs/ref/key.html

  • key – 按下或者放开的键值,是一个数字,Pygame 中可以使用 K_xxx 来表示,比如字母 a 就是 K_a,还有 K_SPACE 和 K_RETURN 等。
  • mod – 包含了组合键信息,如果 mod & KMOD_CTRL 是真的话,表示用户同时按下了 Ctrl 键。类似的还有 KMOD_SHIFTKMOD_ALT
  • unicode – 代表了按下键的 Unicode 值

事件过滤

并不是所有的事件都需要处理。我们使用 pygame.event.set_blocked(type) 来完成。如果有好多事件需要过滤,可以传递一个列表,比如 pygame.event.set_blocked ([KEYDOWN, KEYUP]),如果你设置参数 None,那么所有的事件有被打开了。与之相对的,我们使用 pygame.event.set_allowed() 来设定允许的事件。


产生事件

通常玩家做什么,Pygame 就产生对应的事件就可以了,不过有的时候我们需要模拟出一些事件来,比如录像回放的时候,我们就要把用户的操作再现一遍。

为了产生事件,必须先造一个出来,然后再传递它:

my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=' ')
# 你也可以像下面这样写
my_event = pygame.event.Event(KEYDOWN, "key":K_SPACE, "mod":0, "unicode":' ') pygame.event.post(my_event)

Event():Event (type, dict) 或者 Event (type, **attributes),

post(): 把新的事件放在事件队列的最后。


模板代码

写一个把所有发生的事件输出的程序

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pygame
from pygame.locals import * from sys import exit pygame.init() SCREEN_SIZE = (640, 480) screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
font = pygame.font.SysFont("MicrosoftYaHei", 16)
font_height = font.get_linesize()
event_text = []
while True: event = pygame.event.wait()
event_text.append(str(event)) # 保证event_text里面只保留一个屏幕的文字
event_text = event_text[-SCREEN_SIZE[1]//font_height:]
if event.type == QUIT: exit() screen.fill((255, 255, 255)) # 寻找一个合适的起笔位置,最下面开始,留一行的空
y = SCREEN_SIZE[1] - font_height for text in reversed(event_text): screen.blit(font.render(text, True, (0, 0, 0)), (0, y)) y -= font_height pygame.display.update()

使用方向键来移动图片

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pygame from pygame.locals
import * from sys
import exit
background_image = '../image/sushiplate.jpg'
screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(background_image).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_x = 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()

产生一个完全自定义的全新事件

import pygame from pygame.locals
import * from sys

pygame.init()
my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=' ')
# my_event = pygame.event.Event(KEYDOWN,"key":K_SPACE, "mod":0, "unicode":' ') pygame.event.post(my_event) # 产生一个自定义的全新事件
CATONKEYBOARD = USEREVENT + 1
my_event = pygame.event.Event(CATONKEYBOARD, message="bad act!") pygame.event.post(my_event) # 获得这个事件
for event in pygame.event.get():
if event.type == CATONKEYBOARD: print( event.message)

这个程序让 “hello world” 程序中的鱼动起来

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pygame from pygame.locals
import * from sys
import exit
background_image = '../image/sushiplate.jpg' sprite_image = '../image/fugu.png' pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(background_image).convert()
sprite = pygame.image.load(sprite_image) # sprite的起始坐标
x = 0
while True:
for event in pygame.event.get():
if event.type == QUIT: exit()
screen.blit(background, (0, 0))
screen.blit(sprite, (x, 100))
x += 1
if x>640:
x = 0
pygame.display.update()

这个程序使得物体斜线运动并且触边反弹

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pygame from pygame.locals
import * from sys
import exit
background_image = '../image/sushiplate.jpg'
sprite_image = '../image/fugu.png'
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
background = pygame.image.load(background_image).convert()
sprite = pygame.image.load(sprite_image)
clock = pygame.time.Clock()
x, y = 100, 100
speed_x, speed_y = 133, 170
while True:
for event in pygame.event.get(): if event.type == QUIT: exit()
screen.blit(background, (0, 0))
screen.blit(sprite, (x, y))
time_passed = clock.tick(30)
time_passed_seconds = time_passed/1000
x += speed_x * time_passed_seconds
y += speed_y * time_passed_seconds
# 到达边界后速度反向:
if x > 640 - sprite.get_width(): speed_x = -speed_x
x = 640 - sprite.get_width()
elif
x < 0: speed_x = -speed_x
x = 0
if y > 480 - sprite.get_height(): speed_y = -speed_y
y = 480 - sprite.get_height()
elif
y < 0: speed_y = -speed_y y = 0 pygame.display.update()

相关总结

绘制各种图形

pygame 使用 pygame.draw 来绘制图形。其包含以下几种函数:

函数作用用法
rect绘制矩形rect(Surface, color, Rect, width=0)
polygon绘制多边形polygon(Surface, color, pointlist, width=0)
circle绘制圆circle(Surface, color, pos, radius, width=0)
ellipse绘制椭圆ellipse(Surface, color, Rect, width=0)
arc绘制圆弧arc(Surface, color, Rect, start_angle, stop_angle, width=1)
line绘制线line(Surface, color, start_pos, end_pos, width=1)
lines绘制一系列的线lines(Surface, color, closed, pointlist, width=1)
aaline绘制一根平滑的线aaline(Surface, color, startpos, endpos, blend=1)
aalines绘制一系列平滑的线aalines(Surface, color, closed, pointlist, blend=1)

一些说明

  • width 参数:width 参数为 0 或省略,则填充。

  • 画填充的矩形,有另一个方法 Surface.fill (),事实上,这种方法速度更快。

  • lines 函数的 closed 为一个布尔变量,如果 closed 为真,则会画一条连接第一个和最后一个点的线,是整个图形闭合。

鼠标控制

pygame.mouse 的函数:

  • pygame.mouse.get_pressed —— 返回按键按下情况,返回的是一元组,分别为 (左键,中键,右键),如按下则为 True

  • pygame.mouse.get_rel —— 返回相对偏移量,(x 方向,y 方向) 的一元组

  • pygame.mouse.get_pos —— 返回当前鼠标位置 (x, y)

  • pygame.mouse.set_pos —— 设置鼠标位置

  • pygame.mouse.set_visible —— 设置鼠标光标是否可见

  • pygame.mouse.get_focused —— 检查窗口是否接受鼠标事件,即鼠标是否 focus 到窗口

  • pygame.mouse.set_cursor —— 设置鼠标光标式样

  • pyGame.mouse.get_cursor —— 得到鼠标图片

以上是关于14天学习训练营之 入门Pygame的主要内容,如果未能解决你的问题,请参考以下文章

pygame入门之环境配置

pygame入门之环境配置

如何在 PyGame 中初始化所有导入的模块

如何在 PyGame 中初始化所有导入的模块

练手项目:利用pygame库编写射击游戏

练手小项目:利用pygame库编写飞机大战游戏