两分钟让你上手pygame
文章目录
目录
前言
Python Pygame 是一款专门为开发和设计 2D 电子游戏而生的软件包,它支 Windows、Linux、Mac OS 等操作系统,具有良好的跨平台性。Pygame 由 Pete Shinners 于 2000 年开发而成,是一款免费、开源的的软件包,因此您可以放心地使用它来开发游戏,不用担心有任何费用产生。
Pygame 在 SDL(Simple DirectMedia Layer,使用 C语言编写的多媒体开发库) 的基础上开发而成,它提供了诸多操作模块,比如图像模块(image)、声音模块(mixer)、输入/输出(鼠标、键盘、显示屏)模块等。相比于开发 3D 游戏而言,Pygame 更擅长开发 2D 游戏,比如于飞机大战、贪吃蛇、扫雷等游戏。
一、pygame是什么?
顾名思义,Pygame 是一个专门用来开发游戏的 Python 模块,主要为开发、设计 2D 电子游戏而生,它是一个免费、开源的第三方软件包,支持多种操作系统,具有良好的跨平台性(比如 Windows、Linux、Mac 等)。Pygame 是 Pete Shinners 在 SDL(Simple DirectMedia Layer,一套开源的跨平台多媒体开发库)基础上开发而来,其目的是取代 PySDL。
通过 Pygame 我们能够创建各种各样的游戏和多媒体程序,但相比于开发大型 3D 游戏来说,它更擅长与开发 2D 游戏,比如扫雷、纸牌游戏、贪吃蛇、超级马里奥、飞机大战等,如果是 3D 游戏,可以选择一些功能更为全面的 Python 游戏开发库,比如 Panda3D(迪士尼开发的3D游戏引擎),PyOgre(Ogre 3D渲染引擎)等。
Python 作为一门解释型语言并不适合开发大型的 3D 游戏,但 Python 通过对其他语言的接口封装,使自身具备了开发大型 3D 游戏的能力,例如 Panda3D 的底层是用 C++ 语言编写的。一些较为知名的 3D 游戏,比如魔兽世界、文明帝国4、战地风云2,这些游戏都是使用 Python 语言开发的,而国内较为知名的“阴阳师”手游,也是由 Python 语言开发而成。
“俗话说,术业有专攻”,每一种语言都有自己擅长的一方面,不能因为某种语言不适合某一领域,就认为它是劣质语言。
Pygame 官方网站(https://www.pygame.org/tags/all)提供许多丰富的游戏案例,它们全部使用 Pygame 开发,如下所示
二、pygame 下载安装
Pygame 的下载非常简单,可分为两种方式:一是通过 Python 的包管理器 pip 来安装;二是下载二进制安装包进行安装。其中使用 pip 包管理器安装是最简单、最轻量级的方法,下面以 Windows 系统为例对上述两种方式进行讲解。
1. pip包管理器安装
这是最为轻便的一种安装方式,推荐大家使用。首先确定的您的电脑已经安装了 Python(推荐使用 3.7 以上版本),然后打开 cmd 命令行工具,或者打开pycharm控制台,输入以下命令即可成功安装:
pip install pygame
上述安装方法同样适用于 Linux 和 Mac 操作系统。
2.二进制安装
Python 第三方库官网 PyPI(点击前往下载)提供了不同操作平台的 Pygame 安装包,如下所示:
这里我们选择 Windows 版本进行下载。下载完成后,打开一个 cmd 命令窗口,切换到该安装程序所在的文件夹,并执行以下命令进行安装:
Python - m pip install --user pygame-2.0.2-cp27m-win_amd64.whl
无论采用上述哪种方式都可以安装 Pygame,不过我们强烈建议您使用第一种方式来安装。
最后使用以下命令检查 Pygame 版本,从而验证是否安装成功。
python -m pygame --version
或者您也可以在 Python 解释器的交互界面导入 Pygame 包,如果显示如下,则证明已经安装成功
三 、pygame小功能
1.显示主窗口
代码如下:
# 创建一个 400*600 的黑色窗口
# 导入模块 pygame sys
import pygame,sys
# 初始化函数
pygame.init()
# 绘制到屏幕 使用set_mode(),用元组形式填写长和宽
screen = pygame.display.set_mode((400,600))
# 填充颜色
screen.fill((225,125,125))
# 设置窗口的标题,即游戏的名称
pygame.display.set_caption("pygame小游戏")
# 假设死循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.flip()
2. 精灵显示背景 动态背景
首先先创建背景精灵类,写入图片的name,位置,更新图片每次+1,如果大于600(600是屏幕的高度),执行-600,意思是再次循环,然后在背景管理类中将两张图片加入背景组中,更新,绘制到主屏幕中
import pygame, sys
pygame.init()
# 设置背景精灵
class BgSprite(pygame.sprite.Sprite, ):
def __init__(self, name, topleft):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = topleft
def update(self):
self.rect.top += 1
if self.rect.top > 600:
self.rect.top = -600
class BgManage:
def __init__(self, gm):
self.gm = gm
self.bg_group = pygame.sprite.Group()
self.bg1 = BgSprite("img11/bg.png", (200, 300))
self.bg1.add(self.bg_group)
BgSprite("img11/bg.png", (200, -300)).add(self.bg_group)
def update(self):
self.bg_group.update()
self.bg_group.draw(self.gm.screen)
class GameManage:
def __init__(self):
self.screen = pygame.display.set_mode((400, 600))
self.screen.fill((225, 125, 125))
pygame.display.set_caption("pygame小游戏")
self.bg_manage = BgManage(self)
def check_evevt(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
def run(self):
while True:
self.check_evevt()
self.bg_manage.update()
pygame.display.flip()
pygame.display.flip()
gm = GameManage()
gm.run()
# 将背景精灵组 绘制到屏幕上
3.使用精灵玩家,玩家可以移动
在第二个背景的基础上添加玩家精灵和玩家管理类,在玩家精灵中设置上下移动的范围,在玩家管理里更新玩家,绘制到屏幕上,最后在游戏管理类中调用玩家管理类,并且将玩家管理一直更新在死循环中,这样玩家就可以一直出现在屏幕中
# 用精灵玩家,玩家可以移动
import pygame, sys
pygame.init()
class BaseSprite(pygame.sprite.Sprite):
def __init__(self, name):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
class BgSptite(BaseSprite):
def __init__(self, name):
super().__init__(name)
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
def update(self):
pass
# self.rect.top += 2
# if self.rect.top >= 600:
# self.rect.top = -600
class BgManage:
def __init__(self, gm):
self.gm = gm
self.bg_group = pygame.sprite.Group()
self.bg = BgSptite("img11/bg.png")
self.bg.add(self.bg_group)
# BgSptite("img11/bg.png", (200, -300)).add(self.bg_group)
def update(self):
self.bg_group.update()
self.bg_group.draw(self.gm.screen)
class PlaySprite(BaseSprite):
def __init__(self, name, center):
super().__init__(name)
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = center
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_LEFT] and self.rect.left > 0:
self.rect.left -= 5
if key_pressed[pygame.K_RIGHT] and self.rect.right < 400:
self.rect.right += 5
if key_pressed[pygame.K_UP] and 0 < self.rect.top < 600:
self.rect.top -= 5
if key_pressed[pygame.K_DOWN] and 0 < self.rect.bottom < 600:
self.rect.bottom += 5
class PlayManage:
def __init__(self, gm):
self.gm = gm
self.play_group = pygame.sprite.Group()
self.player = PlaySprite("img11/1.jpeg", (300, 500))
self.player.add(self.play_group)
def update(self):
self.play_group.update()
self.play_group.draw(self.gm.screen)
class GamaManage:
def __init__(self, name):
self.screen = pygame.display.set_mode((400, 600))
pygame.display.set_caption(name)
self.bg_manage = BgManage(self)
self.player_manage = PlayManage(self)
# def check_event(self):
def run(self):
while True:
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()
gm = GamaManage("奔跑吧")
gm.run()
4.使用精灵显示道具,玩家与道具碰撞检测
设定 道具精灵,道具组,道具和玩家碰撞
# 4. 使用精灵显示道具,玩家与道具碰撞检测
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((400, 600))
pygame.display.set_caption("道具碰撞")
class BgSprite(pygame.sprite.Sprite):
def __init__(self, name):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
Bg_group = pygame.sprite.Group()
bg = BgSprite("img11/bg.png")
bg.add(Bg_group)
class PlaySprite(pygame.sprite.Sprite):
def __init__(self, name, center):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = center
def update(self):
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_LEFT] and self.rect.left > 0:
self.rect.left -= 5
if key_pressed[pygame.K_RIGHT] and self.rect.right < 300:
self.rect.right += 5
if key_pressed[pygame.K_UP] and 0 < self.rect.top < 600:
self.rect.top -= 5
if key_pressed[pygame.K_DOWN] and 600 > self.rect.bottom > 0:
self.rect.bottom += 5
play_group = pygame.sprite.Group()
player = PlaySprite("img11/1.jpeg", (300, 500))
player.add(play_group)
class PropSprite(pygame.sprite.Sprite):
def __init__(self, name, center):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.center = center
prop_group = pygame.sprite.Group()
prop1 = PropSprite("img11/2.jpg", (50, 50))
prop1.add(prop_group)
prop2 = PropSprite("img11/3.jpg", (150, 100))
prop2.add(prop_group)
prop3 = PropSprite("img11/4.jpg", (50, 150))
prop3.add(prop_group)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
Bg_group.draw(screen)
prop_group.draw(screen)
play_group.draw(screen)
pygame.display.flip()
play_group.update()
result = pygame.sprite.groupcollide(play_group, prop_group, False, True)
if result:
for vs in result.values():
for v in vs:
print(f"杀敌{v}")
5. ui使用 (字体鼠标点击测试)
鼠标点击 设置功能函数util,点击事件,设置ui精灵和ui管理类,游戏开始前,游戏中,游戏结束从来
# 5.UI的使用 (字体,鼠标点击检测)
import pygame,sys
pygame.init()
class Util:
@staticmethod
def click_check(sprite):
if pygame.mouse.get_pressed()[0]:
if sprite.rect.collidepoint(pygame.mouse.get_pos()):
return True
return False
class BaseSprite(pygame.sprite.Sprite):
def __init__(self,name):
super().__init__()
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
class UiSprite(BaseSprite):
def __init__(self,name,center):
super().__init__(name)
self.image = pygame.image.load(name)
self.rect = self.image.get_rect()
self.rect.center = center
class UiManger:
def __init__(self,gm):
self.gm =gm
# 字体
self.font = pygame.font.Font("Deng.ttf",32)
# 开始前UI元素
self.ready_group = pygame.sprite.Group()
self.begin_btn = UiSprite("img/begin_btn.png",(200,300))
self.begin_btn.add(self.ready_group)
# 游戏中
self.score_surface = self.font.render(f"Score{0}",True,(125,0,0))
# 游戏结束
self.end_group = pygame.sprite.Group()
self.reply_btn = UiSprite("img/replay_btn.png",(200,300))
self.reply_btn.add(self.end_group)
def update(self):
if self.gm.state == "ready":
self.ready_group.draw(self.gm.screen)
if Util.click_check(self.begin_btn):
self.gm.state ='gaming'
elif self.gm.state == "gaming":
self.score_surface = self.font.render(f"Score{0}", True, (125, 0, 0))
self.gm.screen.blit(self.score_surface, (30, 20))
elif self.gm.state == "end":
self.end_group.draw(self.gm.screen)
if Util.click_check(self.reply_btn):
self.gm.state = "gaming"
class GameMange:
def __init__(self,name):
self.state = "ready"
self.screen = pygame.display.set_mode((400,600))
pygame.display.set_caption(name)
self.ui_manage = UiManger(self)
def check_event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 测试功能 一剑杀死
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
self.state = "end"
def run(self):
while True:
self.check_event()
self.screen.fill((225,225,225))
self.ui_manage.update()
pygame.display.flip()
gm =GameMange("点击测试")
gm.run()
点击画面(开始前)----------------------游戏中--------------------------------游戏结束(从新开始)
总结
pygame 中还有很多方法去构造一个游戏,我这里只是列举了简单的几个部分,看我写的相信你比较容易上手,写的不足之处还望多多指教,赶快动手始时吧!