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

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属性!!

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

想多了!还有个坑!

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

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

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

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

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

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()

原文发布于微信公众号 - 萌海无涯(mhwyhtwa)

原文发表时间:2019-08-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券