pygame 基础功能学习

两分钟让你上手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图标

 通过 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 安装包,如下所示:

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验证安装

三 、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 中还有很多方法去构造一个游戏,我这里只是列举了简单的几个部分,看我写的相信你比较容易上手,写的不足之处还望多多指教,赶快动手始时吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值