pygame笔记
直接去看英文官方文档了:Pygame Front Page — pygame v2.6.0 documentation
以及pygame4000:
这是学习版连接,等以后有钱了,一定会补票的!!!
顺便(主要)锻炼一下英语能力。
这个笔记要记录什么呢?
大概就例子加代码吧,把官方文档从英文转为中文再加上一些我的自己的理解和遇到的坑.
不过这种东西我找到的就有很多,多我一个不多,少我一个不少,就随心记一记吧。
总而言是就是我怎么学的就怎么记,看到哪里有价值的往上写。
1.第一个程序
这个是根据pygame 4000 book 写的,感觉比较由浅入深。
1.导入库:
import pygame, sys,os
from pygame.locals import *
2.初始化:
pygame.init()
此函数的作用是将导入的pygame模块全部初始化,比较方便
3.设置游戏窗口:
window = pygame.display.set_mode((720,480))
这个是你游戏的窗口大小,前面是宽,后面是高
!!!里面的是个元组,而不是一个数
4.设置标题:
pygame.display.set_caption("漫宿骄盛的例子")
括号里面的就是游戏上面的标题了
5.获取画布:
screen = pygame.display.get_surface()
pygame.display.get_surface()函数用于获取当前显示的Surface对象。Surface是Pygame中的一个基本概念,可以理解为一个可以在其上绘制图像、形状或文本的画布。
6.获取资源地址:
main_dir = os.path.split(os.path.abspath(__file__))[0]
pic_dir = os.path.join(main_dir,'pic')
这两步的作用可以我的写的另一篇笔记:python库的常用函数1--4
7.加载图片资源:
monkey_pic = os.path.join(pic_dir,'chimp.bmp')
monkey_surface = pygame.image.load(monkey_pic)
screen.blit(monkey_surface,(0,0))
pygame.display.flip()
第一步的作用是获取名为"chimp.bmp"的图片地址
第二步 pygame.image.load()的作用是创建一个对象,用来加载这张图片
第三步screen.blit()的作用是设置monkey_surface的初始位置为0,0
第四步pygame.display.flip()的作用是刷新,告诉pygame 你已经将你要展示的图片弄好了,可以展出了
这个应该可以自定义一个函数完成上面的所有的东西,不过这就是第一个程序,就不弄那么多东西了。
8.设置退出事件:
def input(events):
for event in events:
if event.type == QUIT:
sys.exit(0)
这个的作用是让你点右上角的X号能直接退出程序
9.运行程序:
while True:
input(pygame.event.get())
pygame.event.get()的作用是时刻获取你的操作,从而能实现各种功能
10.完整代码:
import pygame,os,sys
from pygame.locals import *
pygame.init()
window = pygame.display.set_mode((720,480))
pygame.display.set_caption("漫宿骄盛的例子")
screen = pygame.display.get_surface()
main_dir = os.path.split(os.path.abspath(__file__))[0]
pic_dir = os.path.join(main_dir,'pic')
monkey_pic = os.path.join(pic_dir,'chimp.bmp')
monkey_surface = pygame.image.load(monkey_pic)
screen.blit(monkey_surface,(0,0))
pygame.display.flip()
def input(events):
for event in events:
if event.type == QUIT:
sys.exit(0)
while True:
input(pygame.event.get())
结果:

给的图片的实在有点小,后面应该会有设置图片尺寸的东西,点右上角的X号也能直接退出
第一个程序的使命达成了
作业练习:
没想到还有作业,这些也没有放到主要的内容上来,我还以为是一步一步的教所有的东西……
不会啊,先继续往下面看,回过头来再完成。

1.让图片移动:
我自己写了一个代码,然后让AI帮我看看,给我重构了一下,真是赏心悦目,比我写的屎好看多了
import pygame,os,sys
from pygame.locals import *
CONFIG={
'screen_size':(720,720),
'background_color':(250,250,250),
'fps':60,
'chimp_speed':8,
'chimp_image':'chimp.bmp',
'colorkey':-1,
}
def load_pic(name,colorkey=None):
fullname = os.path.join(CONFIG['pic_dir'],name)
try:
image = pygame.image.load(fullname)
except pygame.error:
print('Cannot load image:',fullname)
raise SystemExit
image = image.convert()
if colorkey is not None:
if colorkey == -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey,RLEACCEL)
return image,image.get_rect()
class Chimp(pygame.sprite.Sprite):
def __init__(self,image_path,colorkey=None,speed =8):
pygame.sprite.Sprite.__init__(self)
self.image,self.rect = load_pic(image_path,colorkey)
self.speed = speed
def game_init():
pygame.init()
window = pygame.display.set_mode(CONFIG['screen_size'])
pygame.display.set_caption("漫宿骄盛的例子")
background = pygame.Surface(window.get_size())
background = background.convert()
background.fill(CONFIG['background_color'])
return window,background
def handle_events(run):
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
run = False
return run
def updata_chimp(chimp):
keys = pygame.key.get_pressed()
chimp.rect.x += (keys[K_d] - keys[K_a])* chimp.speed
chimp.rect.y += (keys[K_s] - keys[K_w])* chimp.speed
chimp.rect.clamp_ip(window.get_rect())
def main():
global window,background,CONFIG
main_dir = os.path.split(os.path.abspath(__file__))[0]
CONFIG['pic_dir'] = os.path.join(main_dir,'pic')
CONFIG['font_dir'] = os.path.join(main_dir,'font')
window,background = game_init()
chimp = Chimp(CONFIG['chimp_image'],CONFIG['colorkey'],CONFIG['chimp_speed'])
all_sprites = pygame.sprite.RenderPlain((chimp,))
clock = pygame.time.Clock()
run = True
while run:
clock.tick(CONFIG['fps'])
run = handle_events(run)
updata_chimp(chimp)
window.blit(background,(0,0))
all_sprites.draw(window)
pygame.display.flip()
pygame.quit()
sys.exit()
if __name__ == '__main__':
main()
其实应该不用那么长的代码,但我就是想练习一下面向对象编程,还有规范的写代码,就这样弄了。
练习2,按任意退出:
def handle_events(run):
for event in pygame.event.get():
if event.type == QUIT or event.type == KEYDOWN:
run = False
return run
练习3,获取图片大小:
image_width,image_height = image.get_size()
print("size{}*{}".format(image_width,image_height))
练习4,按按键是图片移动到指定位置:
class Chimp(pygame.sprite.Sprite):
def __init__(self,image_path,colorkey=None,speed =8):
pygame.sprite.Sprite.__init__(self)
self.image,self.rect = load_pic(image_path,colorkey)
self.speed = speed
self.initial_position = self.rect.topleft
def reset(self,new_position):##添加此处
self.rect.topleft = new_position
def handle_events(run,chimp):
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
run = False##添加之下代码
elif event.type== KEYDOWN and event.key == K_KP5:
chimp.reset((110,100))
elif event.type== KEYDOWN and event.key == K_KP4:
chimp.reset((0,0))
return run
2.第二个程序.Chimp Tutorial, Line by Line(卷毛狒狒也能学会的教程)
Pygame Tutorials - Line By Line Chimp Example — pygame v2.6.0 documentation
这个在pygame 4000 上比较详细,我就用pygame 4000那个版本的了.
这个例子会一步一步教去做一个打猴子得金币的游戏?
0.导入库:
这一步的作用是获取文件地址,方便后续对文件的操作
import os
import pygame as pg
#检查pygame的字体文件
if not pg.font:
print("Warning, fonts disabled")
#检查pygame的音频文件
if not pg.mixer:
print("Warning, sound disabled")
main_dir = os.path.split(os.path.abspath(__file__))[0]
pic_dir = os.path.join(main_dir, "pic")
sound_dir = os.path.join(main_dir,'sound')
font_dir = os.path.join(main_dir,'font')
1.创建加载图片的函数:
#加载图片
def load_pic(name,colorkey=None):
fullname = os.path.join(pic_dir,name)
try:
image = pygame.image.load(fullname)
except pygame.error:
print('Cannot load image:',fullname)
raise SystemExit
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey,RLEACCEL)
return image,image.get_rect()
image.convert()是一个优化性能的函数
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey,RLEACCEL)
这个的作用是根据colorkey的数组来设置图片的透明度
2.创建加载声音的函数:
#加载音效
def load_sound(name):
class NoneSound:
def play(self): pass
if not pygame.mixer:
return NoneSound()
fullname = os.path.join(sound_dir,name)
try:
sound = pygame.mixer.Sound(fullname)
except pygame.error:
print("Cannot load sound:",fullname)
raise SystemExit
return sound
对照一下加载图片的函数:
pygame.mixer.Sound()这个应该是加载声音的函数
这个函数先检查pygame.mixer是否被正确加载(不过好像最开始就已经检测过了,这里应该作者的疏忽)
然后再尝试加载声音
3.游戏逻辑:
直接就到这里来了,但关于pygame的函数好多我都一无所知,我应该先去完成作业再来的,算了,等我理解这些逻辑再去完成上面的练习作业吧。
不过看的人应该能看到我完成的作业,应该能很好的理解下面的内容。
拳头的逻辑
lass Fist(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image,self.rect = load_pic('fist.bmp',-1)
self.punching =0
def update(self):
pos = pygame.mouse.get_pos()
self.rect.midtop = pos
if self.punching:
self.rect.move_ip(5,10)
def punch(self,target):
if not self.punching:
self.punching =1
hitbox = self.rect.inflate(-5,-5)
return hitbox.colliderect(target.rect)
def unpunch(self):
self.punching =0
self.rect中的rect是一种属性,用于控制位置,检测碰撞等等
pygame.mouse.get_pos()是获取鼠标位置
self.rect.midtop是设置self的矩形中心的位置
self.rect.move_ip(5,10)用了move_ip方法,向X轴移动5个像素,向Y轴移动10个像素.
self.rect.inflate(-5,-5)使用了inflate方法,这个的作用是将图片横向纵向加上这个数值,-5,就是缩小
hitbox.colliderect(target.rect)这个调用了colliderect()方法,检查hitbox与target.rect是否有体积碰撞。
__init__函数初始化了图片
update函数让拳头中心一直在鼠标上
punch函数检查是否处于打击状态,如果否,就调小碰撞体积,然后检测是否碰撞,
unpunch函数用来结束打击,使拳头回到正常
卷毛狒狒的逻辑
class Chimp(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image,self.rect = load_pic('chimp.bmp',-1)
screen = pygame.display.get_surface()
self.area = screen.get_rect()
self.rect.topleft = (10,10)
self.move = 9
self.dizzy =0
def update(self):
if self.dizzy:
self._spin()
else:
self._walk()
def _walk(self):
newpos = self.move((self.move),0)
if self.rect.left <self.area.left or self.rect.right >self.area.right:
self.move = -self.move
newpos = self.rect.move((self.move,0))
self.image = pygame.transform.flip(self.image,1,0)
self.rect = newpos
def _spin(self):
center = self.rect.center
self.dizzy = self.dizzy +12
if self.dizzy >=360:
self.dizzy =0
self.image = self.original
else:
rotate =pygame.transform.rotate
self.image = rotate(self.original,self.dizzy)
self.rect = self.image.get_rect()
self.rect.center = center
def punched(self):
if not self.dizzy:
self.dizzy =1
self.original =self.image
__init__函数中,初始化了资源,通过
screen = pygame.display.get_surface()#获取屏幕状态
self.area = screen.get_rect()#获取屏幕大小
这两个获取了窗口的大小,为后续移动做准备
self.rect.topleft = (10,10)将图片的左上角设置在10,10位置
self.move = 9,设置图片的移动速度为9像素/步,应该默认向右
self.dizzy =0初始化状态为没有旋转
updata 函数中根据猩猩是否旋转而判断采取哪种方法
_walk方法中检查是否超出屏幕,如果超出,则创建一个新对象,让其移动方向相反
pygame.transform.flip(self.image,1,0)这个是让图片反转,第一个参数是图片,第二个参数是判断是否垂直翻转,第二个是是否水平翻转。1是,0否
_spin方法,self.rect.center记录图片中心点,然后判断图片是否翻转,如果是,这恢复原来状态,否则就根据角度旋转图片
rotate =pygame.transform.rotate这一步其实是没用的……作者说这一步的作用其实是让代码看起来更美观……
注意,每次旋转后,图片的画质会下降,也会导致图片的大小发生改变
4.初始化其他
pygame.init()
screen = pygame.display.set_mode((468,60))
pygame.display.set_caption("攻击狒狒")
pygame.mouse.set_visible(0)
这个就不解释了
5.设置屏幕
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250,250,250))
pygame.Surface(screen.get_size())设置一个和窗口大小相同的背景
background.fill((250,250,250))颜色设为灰色
6.准备让屏幕上显示字
if pygame.font:
text = os.path.join(font_dir,'msyh.ttc')
font = pygame.font.Font(text,50)
text = font.render("击狒得¥¥",1,(10,10,10))
textpos =text.get_rect()
textpos.centerx = background.get_rect().centerx
background.blit(text,textpos)
text = os.path.join(font_dir,'msyh.ttc')这一行是获取字体路径,我想打中文,所以要有,用到是微软雅黑,如果是默认字体那么打出的汉字会是一个方块,无法正常显示。
pygame.font.Font(text,50)第一个text是设置字体,None就是默认,50是字的大小
font.render("击狒得¥¥",1,(10,10,10)) 1是判断是否开启拒斥,后面那个元组是颜色
textpos =text.get_rect()这是获取文字的大小,位置,颜色等信息
background.blit(text,textpos)这个是在textpos位置打出来文字
7.将上述准备展现:
screen.blit(background,(0,0))
pygame.display.flip()
screen.blit(background,(0,0))这个是将之前准备好的background放到0,0位置,也就是将整个屏幕设置为之前给其的颜色
pygame.display.flip() 刷新屏幕,展现之前所有的准备,在pygame中,所有的改变不会立刻可见,需要通过这个函数刷新才行。
结果:

8.准备游戏操作:
whiff_sound = load_sound('whiff.wav')
punch_sound = load_sound('punch.wav')
chimp =Chimp()
fist =Fist()
allsprites = pygame.sprite.RenderPlain((fist,chimp))
clock = pygame.time.Clock()
whiff_sound = load_sound('whiff.wav')加载声音文件
allsprites = pygame.sprite.RenderPlain((fist,chimp))创建一个精灵组,并将fist与chimp加入其中,RenderPlain 是精灵组的容器,用来批量管理精灵
clock = pygame.time.Clock()设置对帧率的对象
9.处理事件:
def main():
events = pygame.event.get()
for event in events:
if event.type ==QUIT:
sys.exit()
elif event.type == KEYDOWN and event.key == K_ESCAPE:
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if fist.punch(chimp):
punch_sound.play()
chimp.punched()
else:
whiff_sound.play()
elif event.type == MOUSEBUTTONUP:
fist.unpunch()
allsprites.update()
screen.blit(background, (0, 0))
allsprites.draw(screen)
pygame.display.flip()
while True:
clock.tick(60)
main()
剩下的我一股脑的全部列出来了
突然发现AI的注释很好用,我就直接用AI的了
def main():
# 获取当前帧的所有事件(鼠标、键盘等输入)
events = pygame.event.get()
# 遍历本帧发生的所有事件
for event in events:
# 处理窗口关闭事件(点击X按钮)
if event.type == QUIT:
sys.exit() # 退出游戏
# 处理键盘按下事件(实际代码有误,正确写法见下方说明)
elif event.type == KEYDOWN and event.type == K_ESCAPE:
sys.exit() # 按ESC键退出游戏
# 处理鼠标按下事件(任何鼠标按键)
elif event.type == MOUSEBUTTONDOWN:
# 检测拳头是否击中黑猩猩
if fist.punch(chimp):
punch_sound.play() # 播放击中音效
chimp.punched() # 触发黑猩猩被击中的动画/状态
else:
whiff_sound.play() # 播放挥空音效
# 处理鼠标松开事件
elif event.type == MOUSEBUTTONUP:
fist.unpunch() # 重置拳头状态为未出拳
# 更新所有精灵状态(位置、动画帧等)
allsprites.update()
# 绘制背景(将背景图像覆盖整个屏幕)
screen.blit(background, (0, 0))
# 绘制所有精灵到屏幕(自动调用每个精灵的draw方法)
allsprites.draw(screen)
# 更新屏幕显示(将内存中的画面推送到实际显示器)
pygame.display.flip()
# 主游戏循环
while True:
clock.tick(60) # 控制游戏帧率,确保每秒不超过60帧
main() # 每帧执行一次main函数
10.完整代码:
import pygame,os,sys
from pygame.locals import *
#获取资源地址
main_dir = os.path.split(os.path.abspath(__file__))[0]
pic_dir = os.path.join(main_dir,'pic')
sound_dir = os.path.join(main_dir,'sound')
font_dir = os.path.join(main_dir,'font')
#加载图片
def load_pic(name,colorkey=None):
fullname = os.path.join(pic_dir,name)
try:
image = pygame.image.load(fullname)
except pygame.error:
print('Cannot load image:',fullname)
raise SystemExit
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey,RLEACCEL)
return image,image.get_rect()
#加载音效
def load_sound(name):
class NoneSound:
def play(self): pass
if not pygame.mixer:
return NoneSound()
fullname = os.path.join(sound_dir,name)
try:
sound = pygame.mixer.Sound(fullname)
except pygame.error:
print("Cannot load sound:",fullname)
raise SystemExit
return sound
class Fist(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)#初始化sprite.Sprite
self.image,self.rect = load_pic('fist.bmp',-1)#加载图片
self.punching =0
def update(self):
pos = pygame.mouse.get_pos()#获取鼠标位置
self.rect.midtop = pos#让图片中心始终在鼠标位置
if self.punching:#如果打中
self.rect.move_ip(5,10)#图片向右移动,模拟动画
def punch(self,target):
#返回真,如果打中
if not self.punching:
self.punching =1
hitbox = self.rect.inflate(-5,-5)
return hitbox.colliderect(target.rect)
def unpunch(self):
#结束动作
self.punching =0
class Chimp(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image,self.rect = load_pic('chimp.bmp',-1)
screen = pygame.display.get_surface()
self.area = screen.get_rect()
self.rect.topleft = (10,10)
self.move = 9
self.dizzy =0
def update(self):
if self.dizzy:
self._spin()
else:
self._walk()
def _walk(self):
newpos = self.rect.move((self.move,0))
if self.rect.left <self.area.left or self.rect.right >self.area.right:
self.move = -self.move
newpos = self.rect.move((self.move,0))
self.image = pygame.transform.flip(self.image,1,0)
self.rect = newpos
def _spin(self):
center = self.rect.center
self.dizzy = self.dizzy +12
if self.dizzy >=360:
self.dizzy =0
self.image = self.original
else:
rotate =pygame.transform.rotate
self.image = rotate(self.original,self.dizzy)
self.rect = self.image.get_rect()
self.rect.center = center
def punched(self):
if not self.dizzy:
self.dizzy =1
self.original =self.image
pygame.init()
screen = pygame.display.set_mode((468,60))
pygame.display.set_caption("攻击狒狒")
pygame.mouse.set_visible(0)
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250,250,250))
if pygame.font:
text = os.path.join(font_dir,'msyh.ttc')
font = pygame.font.Font(text,50)
text = font.render("击狒得¥¥",1,(10,10,10))
textpos =text.get_rect()
textpos.centerx = background.get_rect().centerx
background.blit(text,textpos)
screen.blit(background,(0,0))
pygame.display.flip()
whiff_sound = load_sound('whiff.wav')
punch_sound = load_sound('punch.wav')
chimp =Chimp()
fist =Fist()
allsprites = pygame.sprite.RenderPlain((fist,chimp))
clock = pygame.time.Clock()
def main():
events = pygame.event.get()
for event in events:
if event.type ==QUIT:
sys.exit()
elif event.type == KEYDOWN and event.key == K_ESCAPE:
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
if fist.punch(chimp):
punch_sound.play()
chimp.punched()
else:
whiff_sound.play()
elif event.type == MOUSEBUTTONUP:
fist.unpunch()
allsprites.update()
screen.blit(background, (0, 0))
allsprites.draw(screen)
pygame.display.flip()
if __name__ == '__main__':
while True:
clock.tick(60)
main()
感觉这个代码有点太难看了,这就是屎吗,下次注意一下吧,
运行结果:

11.打包成exe
看我另一篇博客Pylnstaller打包 - 漫宿骄盛 - 博客园
12.后记
终于完成了一个基本能玩的游戏,虽然代码全是看书照抄的,但一回生二回熟,后面再抄几个就要独立去完成一个游戏了
本文来自博客园,作者:漫宿骄盛,转载请注明原文链接:https://www.cnblogs.com/msjs/p/18801872
都是顺手发的,写的时候可能有错误,如果发现了,望各位指出。

浙公网安备 33010602011771号