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 sysimport 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: # 检测是否点击右上角窗口小xrunning = Falsepygame.quit()sys.exit()# 退出游戏辣!
运行结果:
二、案件输入
需要修改的代码:
if __name__ == "__main__":while running:for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = 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 sysimport 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: # 检测是否点击右上角窗口小xrunning = 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 // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.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 sysimport 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 // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.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: # 检测是否点击右上角窗口小xrunning = 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 // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue") # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef 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 sysimport 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 // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue") # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef 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: # 检测是否点击右上角窗口小xrunning = 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 = xself.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 Truereturn False
需要检测的时候直接调用CollisionController.RectCollide()
即可,参数中传入两个矩形碰撞箱。
下文将教你写一个敌人来运用这个函数。
5.2 敌人和碰撞
5.2.1 敌人or朋友?
定义一个敌人:
class Enemy(Player):pass
哈哈哈,直接继承玩家类就行了,多好!人生苦短我用Python, 懒得复写我用继承,游戏开发不能没有面向对象!!
别忘记生成对象,并且在主函数中加入更新的方法:
main.py
import sysimport 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 = xself.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 Truereturn Falseclass Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue") # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef 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: # 检测是否点击右上角窗口小xrunning = 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 sysimport 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 = xself.y = yclass Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue") # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef 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):passclass 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 Truereturn 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: # 检测是否点击右上角窗口小xrunning = 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()# 退出游戏辣!
可以看到,现在每次撞一下都会被聪明的计算机给发现。