想要用python做小游戏 快来了解以下pygame的N个小技巧吧!!!

目录

介绍:pygame

下载 :pygame

1  一个可以关闭的空白窗体

二  使用精灵显示背景, 背景的循环展示

三   使用精灵玩家,玩家可以移动

四   使用精灵显示道具,玩家与道具碰撞检测

五   UI的使用 (字体,鼠标点击检测)

五     Pygame Draw绘图函数详解

1) 绘制矩形

2)绘制圆形

六  精灵的检测碰撞

如果你掌握了这几个方法,那么你离做出来属于自己的游戏不远了,让我们一起实现游戏自由吧!!!有想更深入了解Pygame 让我们一起讨论一下吧 !!!下一篇更新飞机大战游戏~~~


介绍:pygame

首先我们先来讨论一下pygame!!!

Pygame是一个用于开发2D图形和游戏的Python库。它建立在SDL(Simple DirectMedia Layer)库之上,提供了一系列用于处理图形、声音、输入和事件等功能的工具和方法。

Pygame具有简单易用的接口,使得游戏开发者能够快速构建各种类型的游戏,包括平台游戏、动作游戏、迷宫游戏等。它提供了一个图形引擎,可以处理图像、文本和几何形状,并支持各种特效和动画。

Pygame还提供了音频功能,可播放音乐和音效。它支持各种音频格式,并具有音量控制、音效合成和混音等功能,让开发者能够为游戏添加丰富的声音效果。

此外,Pygame还支持用户输入和事件处理。开发者可以轻松地获取鼠标和键盘输入,以及处理游戏中发生的各种事件,如碰撞、按键和时间等。

Pygame是一个跨平台的库,可以在多个操作系统上运行,包括Windows、macOS和Linux。它是使用Python开发游戏的常用工具,因为它易于学习、灵活且强大。

总的来说,Pygame是一个功能丰富、易用的Python游戏开发库,适合初学者和有经验的开发者使用,使他们能够快速开发出自己的2D游戏作品。

下载 :pygame

打开pygame的终端  输入命令 : pip install pygame  (前提是没有下载pygame) 

当出现

 表示下载成功

接下来我们来实现一些基本的功能,之后会来写我们的一个小游戏。

一  一个可以关闭的空白窗体

首先我们要导包 

import pygame

之后再来实现其功能

初始化pygame 一般情况下pygame中只要初始化字体

pygame.init()

然后设置一个窗口  我这边是800x600的窗口  单位是像素

screen = pygame.display.set_mode((800,600))

给窗口设置一个题目  

pygame.display.set.caption("窗口")

最后一步也是最重要的

因为我们刚才设置的窗口运行过后 会闪一下就会关闭  所以现在我们来设置一个死循环不让窗体关闭

 while True:
     for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

whileTrue  死循环  for event in pygame.event.get()  来获取窗口里面发生的任何事情  其中get 在整个游戏中只能出现一次  死循环就是一直循环 所以目前窗体是关不了的 所以要用到pygame.quit() 和sys.exit()(要导入sys包) 关闭

最后更新一下窗体就可以实现了

pygame.display.flip()

代码:

# 游戏管理类
class GameManage:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((1500, 900))
        pygame.display.set_caption("飞机")
        self.bg_manage.update()

    def run(self):
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            pygame.display.flip()
gm = GameManage()
gm.run()

二  使用精灵显示背景, 背景的循环展示

步骤和上面的基本一样 要写一个窗口  背景循环就是让一张背景重复出现  当一张背景向下移动时 上面的背景跟着第一张背景移动 形成一个循环 

代码实现:

# 游戏管理类
class GameManage:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((1500, 900))
        pygame.display.set_caption("飞机")
        self.bg_manage.update()

    def run(self):
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            pygame.display.flip()
gm = GameManage()
gm.run()

# 要写一个精灵 必须要有基本精灵类 
#  BaseSprite 基本精灵类  继承pygame.sprite.Sprite
class BaseSprite(pygame.sprite.Sprite):
#    初始化name
    def __init__(self, name):
    #    继承父类
        super().__init__()
        # 加载一个背景图片name
        self.image = pygame.image.load(name)
        # 获取背景的大小 位置
        self.rect = self.image.get_rect()

#再写一个背景精灵 背景管理  一般情况下一个精灵类 要有它对应的管理类 去管理这个精灵类

class BGSprite(BaseSprite):
    def __init__(self, name, topleft):
        super().__init__(name)
        self.rect.topleft = topleft

    def update(self):
#        背景移动的方向 与速度
        self.rect.top += 2
#      这两句话实现了背景的循环  需要两张背景图 当一张背景图下来的时候 另一张背景图跟着下来 当背景都移动出窗口的时候  新的背景就会出现 
        if self.rect.top >= 900:
#   这句 实现了 新的背景就会出现 
            self.rect.top = -900


class BGManage:
    def __init__(self, gm):
#背景管理类与游戏管理类取得关联  从而更容易实现功能
        self.gm = gm
#        创建一个精灵组  用来装精灵
        self.bg_group = pygame.sprite.Group()
        #调用BGSprite 加载图片

        BGSprite("img/gaming_bg.jpg", (0, 0)).add(self.bg_group)
        BGSprite("img/gaming_bg.jpg", (0, -900)).add(self.bg_group)
            #更新精灵组 将精灵组绘制到 窗口上
    def update(self):
        self.bg_group.update()
        self.bg_group.draw(self.gm.screen)

三   使用精灵玩家,玩家可以移动

想要玩家移动 要有玩家  所以可以来一个  玩家精灵PlayerSprite  玩家类PlayerManage  玩家类去管理玩家精灵 

想要玩家移动 我们知道我们用电脑的键盘上下左右去控制

我们就要了解到pygame中的  pygame.key.get_pressed()

移动代码 实现:

key_presses = pygame.key.get_pressed()
        if key_presses[pygame.K_a] and self.rect.left > 0:
            self.rect.left -= self.speed
        if key_presses[pygame.K_d] and self.rect.right < 1500:
            self.rect.right += self.speed
        if key_presses[pygame.K_w] and self.rect.top > 0:
            self.rect.top -= self.speed
        if key_presses[pygame.K_s] and self.rect.bottom < 900:
            self.rect.bottom += self.speed

具体代码:后面会有全部代码
 

四   使用精灵显示道具,玩家与道具碰撞检测

使用精灵显示道具 要写一个道具精灵类 与一个道具管理类  道具管理类用于管理道具精灵类的

代码实现 :

#道具精灵类
class PropSprite(BaseSprite):
    def __init__(self, name, centerx, y, speed, type):
#继承父类  初始化
        super().__init__(name)
        self.rect.centerx = centerx
        self.rect.top = y
        self.speed = speed
        self.time_count3 = 2
        self.type = type
# update 用于更新道具精灵组的基本属性 
比如 移动 或者 自己的属性

    def update(self):
        self.time_count3 -= 2
        if self.time_count3 <= 0:
            self.time_count3 = 2
            self.rect.top += self.speed
            if self.rect.y > 900:
                self.kill()

# 道具精灵类 每一个time_count 都代表的是一个计时器 用于调节执行程序的快慢
class PropManage:
    def __init__(self, gm):
        self.gm = gm
        # 创建道具精灵组 精灵组一般都在管理类的初始化中去初始化
        self.prop_group = pygame.sprite.Group()
        self.time_count4 = 6
    # 这里面是生成道具的函数
    def generate(self):
        value = random.random()
        if value > 0.9:
            PropSprite("img/daojubaozha.png", random.randrange(50, 1450, 25), 0, 8, 1).add(self.prop_group)
        elif value > 0.5:
            PropSprite("img/jiaxie.png", random.randrange(75, 1450, 25), 0, 8, 2).add(self.prop_group)
        else:
            PropSprite("img/player1(1).png", random.randrange(50, 1450, 25), 0, 8, 3).add(self.prop_group)
    # 这里面的update 不同于前方的update 这里面的是用于更新道具精灵组的  然后将道具精灵组绘制到窗口上
    def update(self):
        self.time_count4 -= 0.2
        if self.time_count4 <= 0:
            self.time_count4 = 6
            self.generate()
        self.prop_group.update()
        self.prop_group.draw(self.gm.screen)

玩家与道具碰撞检测 这个很简单  实质就是玩家组 与 道具组 碰撞  用到groupcollider方法

 # 玩家与道具
        player_prop_collider = pygame.sprite.groupcollide(self.player_manage.player_group, self.prop_manage.prop_group,
                                                          False, True)
        if player_prop_collider:
            for props in player_prop_collider.values():
                for prop in props:
                    if prop.type == 1:
                        self.enemy_manage.enemy_group.empty()
                    if prop.type == 2:
                        self.player_manage.player.hp += 1
                        if self.player_manage.player.hp > self.player_manage.player.max_hp:
                            self.player_manage.player.hp = self.player_manage.player.max_hp
                    if prop.type == 3:
                        value = random.random()
                        if value > 0.5:
                            self.player_manage.player.super_bullet_num1 = 20
                        else:
                            self.player_manage.player.super_bullet_num2 = 20

看  我这边是三种道具  分别为道具类型1  道具类型2  道具类型3  玩家与道具碰撞会让道具消失 所以 第二个为True  玩家组与道具组碰撞 道具组中每一个道具都对应不同的功能 所以才会分三种情况考虑

五   UI的使用 (字体,鼠标点击检测)

我们首先要创建一个UI精灵类  然后有对应的精灵管理类去管理

自己写的代码 纯手工  

在Pygame中,可以使用字体和鼠标点击检测来创建用户界面(UI)。下面是一些关于如何使用字体和鼠标点击检测的基本示例:

1. 字体的使用:

   首先,需要导入pygame和pygame.font模块:


   import pygame
   from pygame import font
 

   然后,选择并加载你喜欢的字体:


   pygame.init()
   font_name = pygame.font.match_font('arial')
   my_font = font.Font(font_name, font_size)

   在此示例中,我们选择使用arial字体,可以根据需要更改字体名称和大小。

   接下来,可以使用所选的字体来渲染文本:


   text_surface = my_font.render('Hello, Pygame!', True, (255, 255, 255))

   这将创建一个包含指定文本的Surface对象,第一个参数是文本内容,第二个参数表示是否开启反锯齿效果,第三个参数是文本颜色。

   最后,将渲染好的文本Surface绘制到屏幕上:


   screen.blit(text_surface, (x, y))
   pygame.display.update()
  

   其中,(x, y)是文本绘制的坐标位置。需要确保在调用显示更新函数前绘制文本。

2. 鼠标点击检测:

   要检测鼠标点击事件,可以使用pygame.mouse.get_pressed()函数。该函数返回一个包含三个元素的元组,对应左键、中键和右键是否按下,元素值为1表示按下,为0表示未按下。

   在游戏循环中的事件处理部分,可以使用如下代码检测鼠标点击事件:

 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  
               

   在这个示例中,我们检测到鼠标的按下事件后,获取当前鼠标的位置pygame.mouse.get_pos(),然后使用collidepoint()方法检测其是否在按钮的矩形范围内。如果是,则可以执行相应的逻辑。

   注意,sprite_rect是按钮的矩形对象,可以使用pygame.rect()函数创建矩形并设置其位置和尺寸。

   这只是一种简单的鼠标点击检测方式,你可以根据自己的需求进行修改和扩展。

六   Pygame Draw绘图函数详解

Pygame 中提供了一个draw模块用来绘制一些简单的图形状,比如矩形、多边形、圆形、直线、弧线等。

Pygame.draw 模块的常用方法如下表所示:

方法说明
pygame.draw.rect() 绘制矩形
pygame.draw.polygon() 绘制多边形
pygame.draw.circle() 根据圆心和半径绘制圆形
pygame.draw.ellipse() 绘制一个椭圆形
pygame.draw.arc() 绘制弧线(挥着椭圆的一部分)
pygame.draw.line() 绘制线段(直线)
pygame.draw.lines() 绘制多条连续的线段
pygame.draw.aaline() 绘制一条平滑的线段(抗锯齿)
pygame.draw.aalines() 绘制多条连续的线段

表格中的函数使用方法大同小异,它们都可以在 Surface 对象上绘制一些简单的形状,返回值是一个 Rect 对象,表示实际绘制图形的矩形区域。上述绘图函数都提供了一个 color 参数,我们可以通过以下三种方式来传递 color 参数值:

  • 使用 pygame.color 对象
  • RGB 三元组
  • RGBA 四元组

下面通对上述一些方法的参数进行详细说明:

1)绘制矩形

绘制矩形的语法格式如下

pygame.draw.rect(surface, color, rect, width)

参数说明如下:

  • surface:指主游戏窗口,无特殊情况,一般都会绘制在主屏幕上;
  • color:该参数用于该图形着色;
  • rect:绘制图形的位置和尺寸大小;
  • width:可选参数,指定边框的宽度,默认为 0,表示填充该矩形区域

注意,当 width > 0 时,表示线框的宽度;而 width < 0 时,此时不会绘制任何图形。

2)绘制圆形
pygame.circle(surface, color, pos, radius, width=0)

上述参数的含义如下:

  • pos:该参数用来指定的圆心位置;

  • radius:用来指定圆的半径;

目前就说明两个 其他的都不怎么用!!!!!

七  精灵的检测碰撞

在开始学习相关知识点之前,我们有必要先学习精灵和碰撞检测的含义。

精灵(英文译为 Sprite),其实在一个游戏程序中,精灵本质指的是一张张小尺寸的图片,比如游戏中的各种道具、人物、场景装饰等,它们都可以看做成一张张小的“精灵”图。除此之外,人物的移动也可以看做是一系列小精灵图构成的序列(按帧组成的序列),如下图所示:

 动作逐帧分解图

如果将逐帧分解后的动作,按照一定的频率播放,那么就形成了动画精灵,您将会看到雄鹰展翅高飞、人在策马奔腾、运动员奋力跳远。

精灵有个特点就是允许精灵之间进行交互,也称之为碰撞,而碰撞检测,指的就是检测两个精灵之间是否发生了碰撞。比如在贪吃蛇游戏中蛇的头部是否与食物发生了碰撞,或者飞机大战游戏中子弹是否击中了外星人等等。当检测到碰撞发生后,接下来会触发某些事件,比如子弹击中外星人,外星人就会消失,玩家的得分也会随之增加,并且在游戏屏幕上又会出现一个外星人。

Pygame 专门提供了一个处理精灵的模块,也就是 sprite(pygame.sprite)模块。通常情况下,我们使用该模块的基类 Sprite 来创建一个子类,从而达到处理精灵的目的,该子类提供了操作精灵的常用属性和方法,如下所示:

属性&方法说明
self.image加载要显示的精灵图片,控制图片大小和填充色
self.rect精灵图片显示在哪个位置
Sprite.update()刷新精灵图,使其相应效果生效
Sprite.add()添加精灵图到精灵组中(groups)
Sprite.remove()从精灵组中删除选中的精灵图
Sprite.kill()删除精灵组中全部的精灵
Sprite.alive()判断某个精灵是否属于精灵组

注意,当游戏中有大量的精灵时,操作它们将变得复杂,此时通过构建精灵容器(group 类)也就是精灵组来统一管理这些精灵。构建方法如下:
 

# 创建精灵组
group = pygame.sprite.Group()
# 向组内添加一个精灵
group.add(sprite_one)

于此同时pygame.sprite模块也提供了多种检测精灵是否碰撞的方法,如下所示:

方法说明
pygame.sprite.collide_rect() 两个精灵之间的矩形检测,即矩形区域是否有交汇,返回一个布尔值。
pygame.sprite.collide_circle()两个精灵之间的圆形检测,即圆形区域是否有交汇,返回一个布尔值。
pygame.sprite.collide_mask() 两个精灵之间的像素蒙版检测,更为精准的一种检测方式。
pygame.sprite.spritecollide() 精灵和精灵组之间的矩形碰撞检测,一个组内的所有精灵会逐一地对另外一个单个精灵进行碰撞检测,返回值是一个列表,包含了发生碰撞的所有精灵。
pygame.sprite.spritecollideany()精灵和精灵组之间的矩形碰撞检测,上述函数的变体,当发生碰撞时,返回组内的一个精灵,无碰撞发生时,返回 None。
pygame.sprite.groupcollide()检测在两个组之间发生碰撞的所有精灵,它返回值是一个字典,将第一组中发生碰撞的精灵作为键,第二个组中发生碰撞的精灵作为值。

现在给大家实现具体的代码(以飞机大战为例):

    def check_collider(self):
        # 玩家与道具
        player_prop_collider = pygame.sprite.groupcollide(self.player_manage.player_group, self.prop_manage.prop_group,
                                                          False, True)
        if player_prop_collider:
            for props in player_prop_collider.values():
                for prop in props:
                    if prop.type == 1:
                        self.enemy_manage.enemy_group.empty()
                    if prop.type == 2:
                        self.player_manage.player.hp += 1
                        if self.player_manage.player.hp > self.player_manage.player.max_hp:
                            self.player_manage.player.hp = self.player_manage.player.max_hp
                    if prop.type == 3:
                        value = random.random()
                        if value > 0.5:
                            self.player_manage.player.super_bullet_num1 = 20
                        else:
                            self.player_manage.player.super_bullet_num2 = 20
        # 玩家子弹与敌人
        player_bullet_enemy_collider = pygame.sprite.groupcollide(self.player_manage.player.bullet_group,
                                                                  self.enemy_manage.enemy_group, True, False)
        if player_bullet_enemy_collider:
            for enemys in player_bullet_enemy_collider.values():
                for enemy in enemys:
                    enemy.hp -= 2
                    if enemy.hp <= 0:
                        self.player_manage.score += 1
                        enemy.kill()
        #  玩家子弹与boss
        player_bullet_boss_collider = pygame.sprite.groupcollide(self.player_manage.player.bullet_group,
                                                                 self.boss_manage.boss_group, True, False)
        if player_bullet_boss_collider:
            self.boss_manage.boss.hp -= 2
            if self.boss_manage.boss.hp <= 0:
                self.die()
                self.ui_manage.is_victory = True
                self.state = "end"

        #  玩家与敌人子弹
        for enemy in self.enemy_manage.enemy_group.sprites():
            player_enemy_bullet_collider = pygame.sprite.groupcollide(self.player_manage.player_group,
                                                                      enemy.bullet_group, False, True)
            if player_enemy_bullet_collider:
                self.player_manage.player.hp -= 1
                if self.player_manage.player.hp <= 0:
                    self.ui_manage.is_victory = False
                    self.die()
                    self.state = "end"

        # 玩家子弹与敌人子弹
        for enemy in self.enemy_manage.enemy_group.sprites():
            player_bullet_enemy_bullet_collider = pygame.sprite.groupcollide(self.player_manage.player.bullet_group,
                                                                             enemy.bullet_group, True, True)

        # 玩家与敌人
        player_enemy_group_collider = pygame.sprite.groupcollide(self.player_manage.player_group,
                                                                 self.enemy_manage.enemy_group,
                                                                 False, True)
        if player_enemy_group_collider:
            self.player_manage.player.hp -= 2
            if self.player_manage.player.hp <= 0:
                self.ui_manage.is_victory = False
                self.die()
                self.state = "end"

        #  玩家子弹与boss子弹
        player_bullet_boss_bullet_collider = pygame.sprite.groupcollide(self.player_manage.player.bullet_group,
                                                                        self.boss_manage.boss.bullet_group, True, True)

        # 玩家与boos子弹
        player_boos_bullet_collider = pygame.sprite.groupcollide(self.player_manage.player_group,
                                                                 self.boss_manage.boss.bullet_group, False, True)
        if player_boos_bullet_collider:
            self.player_manage.player.hp -= 1
            if self.player_manage.player.hp <= 0:
                self.ui_manage.is_victory = False
                self.die()
                self.state = "end"

        #     玩家与boss
        player_boss_body_collider = pygame.sprite.groupcollide(self.player_manage.player_group,
                                                               self.boss_manage.boss_group, False, False)
        if player_boss_body_collider:
            self.player_manage.player.hp -= 1
            if self.player_manage.player.hp <= 0:
                self.ui_manage.is_victory = False
                self.die()
                self.state = "end"

套路都是一样的 要用到pygame.sprite.groupcollide(group,group,True,True) 这个是精灵组与精灵组 碰撞  所以里面都是精灵组  后面的True 代表着第一个消失 False代表不消失  根据自己的情况设定   后面也可以进行扩展自己的思路。

如果你掌握了这几个方法,那么你离做出来属于自己的游戏不远了,让我们一起实现游戏自由吧!!!有想更深入了解Pygame 让我们一起讨论一下吧 !!!下一篇更新飞机大战游戏~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值