Pygame简明教程
引言:本教程中的源码已上传个人
Github
: GItHub链接
视频教程推荐:YouTube教程–有点过于简单了
官方文档推荐:虽然写的一般,但还是推荐!
Navigator~
- Pygame简明教程
- 安装pygame
- 一、代码框架
- 二、案件输入
- 三、绘制方块
- 3.1 绘制
- 3.2 移动
- 四、碰撞
- 4.1 检测方法
- 5.2 敌人和碰撞
- 5.2.1 敌人or朋友?
- 5.2.2 测试碰撞
安装pygame
cmd中安装即可
pip3 install pygame
一、代码框架
main.py
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
if __name__ == "__main__":
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
pygame.quit()
sys.exit()
# 退出游戏辣!
运行结果:
二、案件输入
需要修改的代码:
if __name__ == "__main__":
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
print("你按下了 \/ 哦!")
if keys[pygame.K_UP]:
print("你按下了 /\ 哦!")
if keys[pygame.K_LEFT]:
print("你按下了 < 哦!")
if keys[pygame.K_RIGHT]:
print("你按下了 > 哦!")
######################################
pygame.quit()
sys.exit()
# 退出游戏辣!
修改结束,完整代码如下:
main.py
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
if __name__ == "__main__":
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
print("你按下了 \/ 哦!")
if keys[pygame.K_UP]:
print("你按下了 /\ 哦!")
if keys[pygame.K_LEFT]:
print("你按下了 < 哦!")
if keys[pygame.K_RIGHT]:
print("你按下了 > 哦!")
######################################
pygame.quit()
sys.exit()
# 退出游戏辣!
三、绘制方块
3.1 绘制
我们使用该方法来进行绘制方块对象:
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
下文会出现碰撞箱,是为了便于使用后文中定义的碰撞检测方法。
定义Player类:
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
################### 创建一个方块对象
player = Player()
###################
main.py
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
################### 创建一个方块对象
player = Player()
###################
if __name__ == "__main__":
while running:
screen.fill(pygame.Color("White"))
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
print("你按下了 \/ 哦!")
if keys[pygame.K_UP]:
print("你按下了 /\ 哦!")
if keys[pygame.K_LEFT]:
print("你按下了 < 哦!")
if keys[pygame.K_RIGHT]:
print("你按下了 > 哦!")
######################################
player.update()
pygame.display.update()
pygame.quit()
sys.exit()
# 退出游戏辣!
3.2 移动
我们可以再加点猛料,让player
可以动起来:
Player类中作如下修改:
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
self.velocity = 10
def left(self):
self.x -= self.velocity
def right(self):
self.x += self.velocity
def up(self):
self.y -= self.velocity
def down(self):
self.y += self.velocity
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
按键部分也进行修改:
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player.down()
if keys[pygame.K_UP]:
player.up()
if keys[pygame.K_LEFT]:
player.left()
if keys[pygame.K_RIGHT]:
player.right()
######################################
完整代码如下:
main.py
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
self.velocity = 10
def left(self):
self.x -= self.velocity
def right(self):
self.x += self.velocity
def up(self):
self.y -= self.velocity
def down(self):
self.y += self.velocity
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
################### 创建一个方块对象
player = Player()
###################
if __name__ == "__main__":
while running:
screen.fill(pygame.Color("White"))
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player.down()
if keys[pygame.K_UP]:
player.up()
if keys[pygame.K_LEFT]:
player.left()
if keys[pygame.K_RIGHT]:
player.right()
######################################
player.update()
pygame.display.update()
pygame.quit()
sys.exit()
# 退出游戏辣!
由于动态不便于演示,这里省略。
四、碰撞
4.1 检测方法
pygame中对于碰撞检测的实现手段还是挺多的,可以使用
Sprite
精灵来统一管理,也可以自己手搓。
这里写后者~
检测两个矩形是否重叠即可判断是否碰撞,只要检测其中一个矩形的四个顶点是否在另一个矩形内部即可。
为了表示四个点,抽象出一个顶点类:
Point
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
这里定一个一个
CollisionController
类来统一检测所有碰撞
CollisionController
class CollisionController():
def RectCollide(hitbox1, hitbox2):
'''
检测四个点是否在另一个矩形体内即可
box1 = (x, y, width, height)
0 1 2 3
:param hitbox1:
:param hitbox2:
:return:
'''
p1 = Point(hitbox1[0], hitbox1[1])
p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])
p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])
p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])
points = [p1, p2, p3, p4]
for p in points:
if (p.x >= hitbox2[0]
and p.x <= hitbox2[0] + hitbox2[2]
and p.y >= hitbox2[1]
and p.y <= hitbox2[1] + hitbox2[3]):
return True
return False
需要检测的时候直接调用CollisionController.RectCollide()
即可,参数中传入两个矩形碰撞箱。
下文将教你写一个敌人来运用这个函数。
5.2 敌人和碰撞
5.2.1 敌人or朋友?
定义一个敌人:
class Enemy(Player):
pass
哈哈哈,直接继承玩家类就行了,多好!人生苦短我用Python, 懒得复写我用继承,游戏开发不能没有面向对象!!
别忘记生成对象,并且在主函数中加入更新的方法:
main.py
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
class CollisionController():
def RectCollide(hitbox1, hitbox2):
'''
检测四个点是否在另一个矩形体内即可
box1 = (x, y, width, height)
0 1 2 3
:param hitbox1:
:param hitbox2:
:return:
'''
p1 = Point(hitbox1[0], hitbox1[1])
p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])
p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])
p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])
points = [p1, p2, p3, p4]
for p in points:
if (p.x >= hitbox2[0]
and p.x <= hitbox2[0] + hitbox2[2]
and p.y >= hitbox2[1]
and p.y <= hitbox2[1] + hitbox2[3]):
return True
return False
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
self.velocity = 10
def left(self):
self.x -= self.velocity
def right(self):
self.x += self.velocity
def up(self):
self.y -= self.velocity
def down(self):
self.y += self.velocity
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
class Enemy(Player):
pass
################### 创建一个方块对象
player = Player()
enemy = Enemy()
###################
if __name__ == "__main__":
while running:
screen.fill(pygame.Color("White")) # 填充一个背景色
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player.down()
if keys[pygame.K_UP]:
player.up()
if keys[pygame.K_LEFT]:
player.left()
if keys[pygame.K_RIGHT]:
player.right()
######################################
# ****************** 更新对象 *******************
enemy.update()
player.update()
# ****************** ------ *******************
pygame.display.update() # 更新画面
pygame.quit()
sys.exit()
# 退出游戏辣!
运行发现多了一个小伙伴~
5.2.2 测试碰撞
import sys
import pygame
pygame.init() # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200 # 窗口宽度,高度
FPS = 60 # 帧率
running = True # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
class Player(object):
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
self.width = 100
self.height = 200
self.hit_box = (self.x, self.y, self.width, self.height)
self.color = pygame.Color("Blue") # 颜色
self.velocity = 10
def left(self):
self.x -= self.velocity
def right(self):
self.x += self.velocity
def up(self):
self.y -= self.velocity
def down(self):
self.y += self.velocity
def update(self):
self.hit_box = (self.x, self.y, self.width, self.height) # 更新碰撞箱位置
pygame.draw.rect(screen, self.color, self.hit_box) # 更新绘制
class Enemy(Player):
pass
class CollisionController():
def RectCollide(hitbox1, hitbox2):
'''
检测四个点是否在另一个矩形体内即可
box1 = (x, y, width, height)
0 1 2 3
:param hitbox1:
:param hitbox2:
:return:
'''
p1 = Point(hitbox1[0], hitbox1[1])
p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])
p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])
p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])
points = [p1, p2, p3, p4]
for p in points:
if (p.x >= hitbox2[0]
and p.x <= hitbox2[0] + hitbox2[2]
and p.y >= hitbox2[1]
and p.y <= hitbox2[1] + hitbox2[3]):
return True
return False
# def obj_collided(self, object1, object2):
# if self.RectCollide(object1.hit_box, object2.hit_box):
# return True
# else:
# return False
################### 创建一个方块对象
player = Player()
enemy = Enemy()
###################
if __name__ == "__main__":
while running:
screen.fill(pygame.Color("White")) # 填充一个背景色
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测是否点击右上角窗口小x
running = False
############ 获取输入 ##################
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player.down()
if keys[pygame.K_UP]:
player.up()
if keys[pygame.K_LEFT]:
player.left()
if keys[pygame.K_RIGHT]:
player.right()
######################################
# $$$$$$$$$$$$$$$ 碰撞检测 $$$$$$$$$$$$$$$$$$$
if CollisionController.RectCollide(player.hit_box, enemy.hit_box):
print("哎呀,创了一下咧!")
# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# ****************** 更新对象 *******************
enemy.update()
player.update()
# ****************** ------ *******************
pygame.display.update() # 更新画面
pygame.quit()
sys.exit()
# 退出游戏辣!
可以看到,现在每次撞一下都会被聪明的计算机给发现。