✕
碰撞球,这次真的是碰撞球了。!!
这里设置的碰撞次数是2次。
我们来学习两种检测碰撞的的方法:
这里有个坑,有个坑,有个坑!
pygame.sprite.groupcollide
()Sprite.rect
每个Sprite 的属性或通过使用碰撞函数(如果它不是None)来确定碰撞。
group1中的每个Sprite都被添加到返回字典中。每个项目的值是group2中相交的Sprite列表。
如果dokill参数为True,则将从各自的组中删除碰撞的Sprite。
碰撞参数是一个回调函数,用于计算两个精灵是否发生碰撞。它应该将两个精灵作为值并返回一个bool值,指示它们是否发生碰撞。如果未传递碰撞,
则所有精灵必须具有“rect”值,该值是精灵区域的矩形,将用于计算碰撞。这句话很重要!精灵一定要有rect这个属性,不然会报错,说这个对象没有rect。
精灵与精灵组:
pygame.sprite.spritecollideany
()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()