前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python之pygame学习精灵碰撞做一个躲避球游戏(13)

Python之pygame学习精灵碰撞做一个躲避球游戏(13)

作者头像
萌海无涯
发布2019-08-20 11:44:53
3.1K0
发布2019-08-20 11:44:53
举报
文章被收录于专栏:萌海无涯
pygame学习精灵碰撞做一个躲避球

碰撞球,这次真的是碰撞球了。!!

这里设置的碰撞次数是2次。

我们来学习两种检测碰撞的的方法:

  1. 精灵组与精灵组:

这里有个坑,有个坑,有个坑!

  • pygame.sprite.groupcollide()
  • 找到在两组之间发生碰撞的所有精灵。 groupcollide(group1,group2,dokill1,dokill2,collided = None) - > Sprite_dict 这将在两组中找到所有精灵之间的碰撞。通过比较Sprite.rect每个Sprite 的属性或通过使用碰撞函数(如果它不是None)来确定碰撞。 group1中的每个Sprite都被添加到返回字典中。每个项目的值是group2中相交的Sprite列表。 如果dokill参数为True,则将从各自的组中删除碰撞的Sprite。 碰撞参数是一个回调函数,用于计算两个精灵是否发生碰撞。它应该将两个精灵作为值并返回一个bool值,指示它们是否发生碰撞。如果未传递碰撞, 则所有精灵必须具有“rect”值,该值是精灵区域的矩形,将用于计算碰撞。

这句话很重要!精灵一定要有rect这个属性,不然会报错,说这个对象没有rect。

精灵与精灵组:

  • pygame.sprite.spritecollideany()
  • 如果精灵与组中的任何内容相交,则进行简单测试。 spritecollideany(sprite,group,collided = None) - > Sprite与返回的精灵碰撞。 spritecollideany(sprite,group,collided = None) - >无无冲突 如果精灵与组中的任何一个精灵发生碰撞,则返回该组中的一个精灵。无冲突时返回无。 如果您不需要该功能的所有pygame.sprite.spritecollide()功能,此功能将更快一些。 碰撞参数是一个回调函数,用于计算两个精灵是否发生碰撞。它应该将两个精灵作为值并返回一个bool值,指示它们是否发生碰撞。如果未传递碰撞,则所有精灵必须具有“rect”值,该值是精灵区域的矩形,将用于计算碰撞。

同样注意需要有rect属性!!

看上面两种以为就没坑了???

想多了!还有个坑!

获取鼠标返回的坐标,用这个坐标来画圆的时候,设置好不能超出边框,结果圆居然能出去????

然后我画一个辅助矩形,看看圆的圆心是否与矩形的中心对齐。。结果不是的,圆的中心在矩形的左上角!

嗯,没问题,画圆就是指定的圆心坐标!

解决方法,用矩形区域的中心来设置圆的圆心,解决!

然后设置下游戏的碰撞次数,设置一定次数后出现游戏结束,按空格键重置次数。。

代码语言:javascript
复制
import random
import pygame


W = 600
H = 500


class Jl(pygame.sprite.Sprite):
    """ 精灵类"""
    def __init__(self):
        # 初始化继承类方法
        super().__init__()
        # 宽
        self.w = 30
        # 高
        self.h = 30
        # 速度
        self.xs = 1
        self.ys = 1

        # # 反弹到一定次数死亡
        # self.cont = random.randint(10,20)

        # 随机的位置
        x = random.randint(0,W-self.w)
        y = random.randint(0,H-self.h)
        self.rect = pygame.Rect(x,y,self.w *2, self.h *2)

    def update(self,screen, *args):
        """ 精灵更新"""
        # print("精灵更新")
        # print(self.cont)
        self.rect.x += self.xs
        self.rect.y += self.ys
        if self.rect.x > W  - self.w or self.rect.x < 0 :
            self.xs = -self.xs
        elif self.rect.y > H - self.h or self.rect.y < 0:
            self.ys = -self.ys

        # if self.cont == 0:
        #     self.kill()
        # 绘制精灵
        # pygame.draw.rect(screen, (255, 0, 0), [self.fk.x,self.fk.y,self.fk.w, self.fk.h])
        # screen.blit('',(self.fk.x, self.fk.y))
        # 矩形边框,用于查看球是不是在矩形内部
        pygame.draw.rect(screen,(0,255,0),[self.rect.x, self.rect.y, self.rect.w, self.rect.h],1)
        # 绘制球
        pygame.draw.circle(screen,(255,0,0),[self.rect.center[0],self.rect.center[1]],self.w)

    # def remove(self, *groups):


    def __del__(self):
        """ 删除"""
        print("删除精灵")

class ShuBiao(pygame.sprite.Sprite):
    def __init__(self):

        super().__init__()
        self.q = 30
        self.rect = pygame.Rect(0, 0, self.q * 2, self.q * 2)

    def update(self, screen, *args):
        # 检测程序界面是否获得鼠标焦点
        if pygame.mouse.get_focused():
            # 获取光标位置,2个值
            self.rect.center = pygame.mouse.get_pos()

        # 限制球不能半身跑到边框上
        if self.rect.x < 0 :
            self.rect.x = 0
        elif self.rect.x > W - self.rect.w:
            self.rect.x = W - self.rect.w
        elif self.rect.y < 0:
            self.rect.y = 0
        elif self.rect.y > H - self.rect.h:
            self.rect.y = H - self.rect.h
        # 矩形边框,用于查看球是不是在矩形内部
        pygame.draw.rect(screen,(0,255,0),[self.rect.x, self.rect.y, self.rect.w, self.rect.h],1)
        # 画个球
        pygame.draw.circle(screen, (255, 0, 0), [self.rect.center[0], self.rect.center[1]], self.q)





def main():
    # 初始化pygame模块
    pygame.init()
    # 创建事件常量
    # 如果创建第二个事件常量可以使用 pygame.USEREVENT + 1 来设置
    ADD_JL = pygame.USEREVENT
    # 添加定时器事件
    pygame.time.set_timer(ADD_JL, 1000)
    # 初始化字体
    pygame.font.init()
    zt = pygame.font.SysFont('幼圆',30)
    over = zt.render("游戏结束啦!,空格重新开始!",True,(255,0,0))
    # 设置窗口大小
    screen = pygame.display.set_mode((W,H))
    # 设置窗口标题
    pygame.display.set_caption('窗口标题')

    # # 精灵列表
    jlz = pygame.sprite.Group(Jl())

    # 鼠标精灵,及精灵组
    sb = ShuBiao()
    sbz = pygame.sprite.Group(sb)

    # 游戏时钟 这次就不用啦!
    clock = pygame.time.Clock()

    # 碰撞次数检测
    cont = 0
    while True:
        # 碰撞10次游戏结束
        # 重绘屏幕
        screen.fill((0))
        if cont >= 2:
            screen.blit(over,[10,300])

        pzcs = zt.render("已经碰撞次数:{}".format(cont), True, (255, 0, 0))
        screen.blit(pzcs,[10,10])
        # clock.tick(60)

        # 两个精灵组之间的碰撞检测
        # cs = pygame.sprite.groupcollide(jlz,sbz,True,False)
        # 一个精灵和指定精灵组的碰撞检测
        cs = pygame.sprite.spritecollide(sb,jlz,True)
        if len(cs) > 0:
            cont += 1

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit(0)
            elif event.type == pygame.KEYDOWN:
            # 按下空格重新计数
                if event.key == pygame.K_SPACE:
                    cont = 0
            elif event.type == ADD_JL:
                # 定时器添加精灵
                jlz.add(Jl())

        # 精灵更新操作
        jlz.update(screen)
        sbz.update(screen)

        if len(jlz) > 5:
            # 获取精灵组列表
            deljl = jlz.sprites()
            # 删除精灵组列表的第一个元素
            jlz.remove(deljl[0])

        # 刷新显示
        pygame.display.update()


if __name__ == '__main__':
    main()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萌海无涯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档