本章主要讲解:
使用py基础重难点的面向对象来学习pygame
不墨迹不废话 直接上全部类处理
- 一个可以关闭的空白窗体
- 使用精灵显示背景, 背景的循环展示
- 使用精灵玩家,玩家可以移动
- 使用精灵显示道具,玩家与道具碰撞检测
- UI的使用 (字体,鼠标点击检测)
一、一个可以关闭的空白窗体
import sys
import pygame
class GameManage:
def __init__(self):
# 初始化pygame
pygame.init()
# 构造一个屏幕 填充屏幕宽高
self.screen = pygame.display.set_mode((400, 600))
# 给窗体填充颜色
self.screen.fill('white')
# 设置窗口标题
pygame.display.set_caption('我什么都可以做')
def run(self):
# 循环监听事件 获取事件
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
# 卸载所有模块
pygame.quit()
# 确保退出程序
sys.exit()
# 更新屏幕显示
pygame.display.flip()
if __name__ == '__main__':
gm = GameManage()
gm.run()
二、使用精灵显示背景, 背景的循环展示
import sys
import pygame
class PlayerSprite(pygame.sprite.Sprite):
def __init__(self, img_url, center, speed):
super().__init__()
self.image = pygame.image.load(img_url)
self.rect = self.image.get_rect()
self.rect.center = center
self.speed = speed
def update(self):
get_pressed = pygame.key.get_pressed()
if get_pressed[pygame.K_LEFT]:
self.rect.left -= self.speed
if get_pressed[pygame.K_RIGHT]:
self.rect.left += self.speed
if get_pressed[pygame.K_UP]:
self.rect.top -= self.speed
if get_pressed[pygame.K_DOWN]:
self.rect.bottom += self.speed
class PlayerManage:
def __init__(self, gm):
self.gm = gm
# 玩家精灵组
self.player_group= pygame.sprite.Group()
self.birth()
def birth(self):
self.player = PlayerSprite('monkey1.png', (800, 500), 8)
self.player.add(self.player_group)
def update(self):
self.player_group.update()
self.player_group.draw(self.gm.screen)
class BGSprite(pygame.sprite.Sprite):
"""背景精灵类"""
def __init__(self, img_url, topleft, speed): # img_url 背景图片的地址
super().__init__()
self.image = pygame.image.load(img_url) # 加载背景图片
self.rect = self.image.get_rect() # 获取图片所在的矩形区域
self.rect.topleft = topleft # topleft 图片所在位置 (左上角)
self.speed = speed # 背景图片移动的速度
def update(self):
self.rect.bottom += self.speed
if self.rect.top >= 700:
self.rect.bottom = 0
class BGManage:
"""背景图片管理类"""
def __init__(self, gm):
# 初始化游戏管理类的实例
self.gm = gm
# 构建一个背景精灵组
self.bg_group = pygame.sprite.Group()
self.birth()
def birth(self):
"""背景生成"""
self.bg1 = BGSprite('bg_img.jpeg', (0, 0), 10)
self.bg2 = BGSprite('bg_img.jpeg', (0, -700), 10) # 第二张的头部位于第一张的尾部
# 将背景实例加入到背景精灵组
self.bg1.add(self.bg_group)
self.bg2.add(self.bg_group)
def update(self):
# 将背景精灵组更新并绘制到屏幕上
self.bg_group.update()
self.bg_group.draw(self.gm.screen)
class GameManage:
def __init__(self):
# 初始化pygame
pygame.init()
# 构造一个屏幕 填充屏幕宽高
self.screen = pygame.display.set_mode((1000, 700))
# 设置窗口标题
pygame.display.set_caption('我有精灵且屏幕可以滚动')
# 初始化时钟
self.clock = pygame.time.Clock()
# 实例化背景精灵管理
self.bg_manage = BGManage(self)
# 实例化玩家精灵管理
self.player_manage = PlayerManage(self)
def run(self):
# 循环监听事件 获取事件
while True:
self.clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
# 卸载所有模块
pygame.quit()
# 确保退出程序
sys.exit()
# 更新背景管理
self.bg_manage.update()
# 更新玩家精灵
self.player_manage.update()
# 更新屏幕显示
pygame.display.flip()
if __name__ == '__main__':
gm = GameManage()
gm.run()
后面的背景是滚动的 给人的感觉就像是猴子一直在前进一般
三、使用精灵玩家,玩家可以移动
import sys
import pygame
class PlayerSprite(pygame.sprite.Sprite):
def __init__(self, img_url, center, speed):
super().__init__()
self.image = pygame.image.load(img_url) # 加载图片 注:image不能随意更改名字
self.rect = self.image.get_rect() # 获取图片所在的矩形区域 rect不能随意更改名字
self.rect.center = center
self.speed = speed # 玩家移动速度
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_LEFT]:
self.rect.left -= self.speed
if key_pressed[pygame.K_RIGHT]:
self.rect.left += self.speed
if key_pressed[pygame.K_UP]:
self.rect.top -= self.speed
if key_pressed[pygame.K_DOWN]:
self.rect.top += self.speed
class PlayerManage:
def __init__(self, gm):
self.gm = gm
# 初始化新建一个玩家精灵组
self.player_group = pygame.sprite.Group()
self.birth()
def birth(self):
self.player = PlayerSprite('player_plane.png', (200, 300), 10)
self.player.add(self.player_group)
def update(self):
self.player_group.update()
self.player_group.draw(self.gm.screen)
class GameManage:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((400, 600))
# 给屏幕填充颜色
self.screen.fill('pink') # 粉色超好看
# 初始化帧率时钟
self.clock = pygame.time.Clock()
# 设置标题
pygame.display.set_caption('我有玩家且可以移动')
# 初始化玩家管理实例
self.player_manage = PlayerManage(self)
def run(self):
while True:
self.clock.tick(24)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 飞机移动一下 屏幕刷新一下
self.screen.fill('pink')
# 更新玩家
self.player_manage.update()
pygame.display.flip()
if __name__ == '__main__':
gm = GameManage()
gm.run()
图片可以通过上下左右移动方向
四、使用精灵显示道具,玩家与道具碰撞检测
import sys
import pygame
# 这里就不让被碰撞的物体动了
# 实现方法同玩家差不多 需要的同学评论1 我私发给你 不然显的太繁琐了
class EnemySprite(pygame.sprite.Sprite):
def __init__(self, img_url, center):
super().__init__()
self.image = pygame.image.load(img_url)
self.rect = self.image.get_rect()
self.rect.center = center
def update(self):
pass
class EnemyManage:
def __init__(self, gm):
self.gm = gm
# 初始化一个敌人组
self.enemy_group = pygame.sprite.Group()
self.birth()
def birth(self):
EnemySprite('monkey1.png', (100, 200)).add(self.enemy_group)
EnemySprite('monkey1.png', (200, 200)).add(self.enemy_group)
EnemySprite('monkey1.png', (300, 300)).add(self.enemy_group)
def update(self):
self.enemy_group.update()
self.enemy_group.draw(self.gm.screen)
class PlayerSprite(pygame.sprite.Sprite):
def __init__(self, img_url, center, speed):
super().__init__()
self.image = pygame.image.load(img_url) # 加载图片 注:image不能随意更改名字
self.rect = self.image.get_rect() # 获取图片所在的矩形区域 rect不能随意更改名字
self.rect.center = center
self.speed = speed # 玩家移动速度
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_LEFT]:
self.rect.left -= self.speed
if key_pressed[pygame.K_RIGHT]:
self.rect.left += self.speed
if key_pressed[pygame.K_UP]:
self.rect.top -= self.speed
if key_pressed[pygame.K_DOWN]:
self.rect.top += self.speed
class PlayerManage:
def __init__(self, gm):
self.gm = gm
# 初始化新建一个玩家精灵组
self.player_group = pygame.sprite.Group()
self.birth()
def birth(self):
self.player = PlayerSprite('player_plane.png', (300, 500), 10)
self.player.add(self.player_group)
def update(self):
self.player_group.update()
self.player_group.draw(self.gm.screen)
class GameManage:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((400, 600))
# 给屏幕填充颜色
self.screen.fill('pink') # 粉色超好看
# 初始化帧率时钟
self.clock = pygame.time.Clock()
# 设置标题
pygame.display.set_caption('我有玩家且可以移动')
# 初始化玩家管理实例
self.player_manage = PlayerManage(self)
# 初始化敌人管理实例
self.enemy_manage = EnemyManage(self)
def collide_event(self):
"""碰撞事件"""
pygame.sprite.groupcollide(self.player_manage.player_group, self.enemy_manage.enemy_group, False, True)
def run(self):
while True:
self.clock.tick(24)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
self.collide_event()
# 飞机移动一下 屏幕刷新一下
self.screen.fill('pink')
# 更新玩家
self.player_manage.update()
# 更新敌人
self.enemy_manage.update()
pygame.display.flip()
if __name__ == '__main__':
gm = GameManage()
gm.run()
效果图:
五、UI的使用 (字体,鼠标点击检测)
import sys
import pygame
class Toolkit:
@staticmethod
def mouse_event(rect):
"""传入一个矩形区域,鼠标左键点击在矩形区域内返回True,否则返回False"""
if pygame.mouse.get_pressed()[0]:
if rect.collidepoint(pygame.mouse.get_pos()):
return True
return False
class UISprite(pygame.sprite.Sprite):
def __init__(self, img_url, center):
super().__init__()
self.image = pygame.image.load(img_url)
self.rect = self.image.get_rect(center=center)
class UIManage:
def __init__(self, gm):
self.gm = gm
# 初始化并加载一个字体
self.font = pygame.font.Font('simkai.ttf', 24)
def update(self):
# 将字体绘制到屏幕上
font_surface = self.font.render('CALL ME!', True, (255, 0, 0))
self.gm.screen.blit(font_surface, (200, 200))
if Toolkit.mouse_event(font_surface.get_rect(topleft=(200, 200))):
font_surface = self.font.render('你好好好好好啊', True, (0, 0, 255))
self.gm.screen.blit(font_surface, (200, 300))
class Manage:
"""总的管理类"""
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((400, 600))
pygame.display.set_caption('我是UI检测')
# 填充背景色
self.screen.fill((255, 182, 193))
# 初始化一个精灵UI管理实例
self.ui_manage = UIManage(self)
def run(self):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
self.screen.fill((255, 182, 193))
self.ui_manage.update()
pygame.display.flip()
if __name__ == '__main__':
m = Manage()
m.run()
演示: