python - 如何使用组碰撞?
问题描述
所以我一直想知道如何使用pygame groupcollide。我现在完全被难住了。因为我正在使用collide_rect,所以很好。但是对于 groupcollide 我似乎无法弄清楚如何调用该组内项目的属性。而且我不能做碰撞矩形,因为会有很多子弹。
def check_blast_collisions(player,bullet):
hits = pg.sprite.groupcollide(player,bullet,False,True)
for hit in hits:
print (hits)
if hit.vx == 20:
player.vx += 40
elif hit.vx == -20:
player.vx += -40
这是我尝试使用 groupcollide 的片段。在我做了这个功能之后,子弹甚至都没有出现。(子弹应该被称为爆炸,但我在这个函数中忘记了它。)
import pygame as pg
#settings
CAPTION = "Knockback Arena"
resolution = 1600,900
WIDTH = resolution[0]
HEIGHT = resolution[1]
FPS = 60
player_jump_height = 30
player_max_fall_speed = 30
player_fall_speed_increase = 2
player_lives = 5
shoot_cooldown = 500
#initialize pygame
pg.init()
pg.mixer.init()
pg.font.init
screen = pg.display.set_mode(resolution)
pg.display.set_caption(CAPTION)
clock = pg.time.Clock()
#sprites
class Platform(pg.sprite.Sprite):
def __init__(self,x,y,width,height,r,g,b):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((width,height))
self.image.fill((r,g,b))
self.rect = self.image.get_rect()
self.rect.center = (x,y)
class Player(pg.sprite.Sprite):
def __init__(self,r,g,b,x,y):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((40, 100))
self.image.fill((r,g,b))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.startx = x
self.starty = y
self.vx = 0
self.vy = 5
self.vy_max = player_max_fall_speed
self.vy_increase = player_fall_speed_increase
self.lives = player_lives
self.last_shot = 0
self.facing_right = False
self.facing_left = False
def update(self):
self.rect.x += self.vx
self.rect.y += self.vy
if self.vy >= self.vy_max:
self.vy = self.vy_max
self.vy_increase = 0
if self.vy < self.vy_max:
self.vy_increase = player_fall_speed_increase
if self.rect.bottom < HEIGHT:
self.vy += self.vy_increase
if self.rect.top >= HEIGHT:
self.rect.x = self.startx
self.rect.y = self.starty
self.lives -= 1
if self.lives <= 0:
self.kill()
if self.rect.right >= WIDTH:
self.rect.right = WIDTH
self.vx = 0
if self.rect.left <= 0:
self.rect.left = 0
self.vx = 0
def jump(self):
if self.rect.bottom >= main_platform.rect.top:
self.vy -= player_jump_height
if self.rect.bottom >= HEIGHT:
self.vy -= player_jump_height
def shoot(self):
if pg.time.get_ticks() - self.last_shot >= shoot_cooldown:
if self.facing_left == True:
return "shoot_left"
elif self.facing_right == True:
return "shoot_right"
else:
return "cd_not_done"
class Blast(pg.sprite.Sprite):
def __init__(self,player,direction):
pg.sprite.Sprite.__init__(self)
self.image = pg.Surface((20,10))
self.image.fill((0,255,255))
self.rect = self.image.get_rect()
self.rect.center = (player.rect.center)
self.direction = direction
if self.direction == 0:
self.vx = -20
elif self.direction == 1:
self.vx = 20
def update(self):
self.rect.x += self.vx
if self.rect.right < 0:
self.kill()
if self.rect.left > WIDTH:
self.kill()
#functions
def check_for_collisions(player,platform):
hits = pg.sprite.collide_rect(player,platform)
if hits:
if hits and player.vy > 0:
player.rect.bottom = platform.rect.top
player.vy = 0
def check_blast_collisions(player,bullet):
hits = pg.sprite.groupcollide(player,bullet,False,True)
for hit in hits:
print (hits)
if hit.vx == 20:
player.vx += 40
elif hit.vx == -20:
player.vx += -40
font = pg.font.Font('font/Roboto-Light.ttf', 30)
all_sprites = pg.sprite.Group()
players = pg.sprite.Group()
platforms = pg.sprite.Group()
blasts = pg.sprite.Group()
main_platform = Platform(WIDTH/2,650,1000,100,0,200,0)
player_1 = Player(0,0,255,WIDTH/2 + -100,200)
player_2 = Player(255,0,0,WIDTH/2 + 100,200)
platforms.add(main_platform)
players.add(player_1)
players.add(player_2)
all_sprites.add(player_1)
all_sprites.add(player_2)
all_sprites.add(main_platform)
menu = True
run = True
while run:
#check for closing window
for event in pg.event.get():
if event.type == pg.KEYDOWN:
if event.key == pg.K_w:
player_1.jump()
if event.key == pg.K_a:
player_1.vx = -10
player_1.facing_left = True
player_1.facing_right = False
elif event.key == pg.K_d:
player_1.vx = 10
player_1.facing_right = True
player_1.facing_left = False
if event.key == pg.K_UP:
player_2.jump()
if event.key == pg.K_LEFT:
player_2.vx = -10
player_2.facing_left = True
player_2.facing_right = False
elif event.key == pg.K_RIGHT:
player_2.vx = 10
player_2.facing_right = True
player_2.facing_left = False
if event.key == pg.K_j:
if player_1.shoot() == "shoot_left":
b = Blast(player_1,0)
all_sprites.add(b)
blasts.add(b)
elif player_1.shoot() == "shoot_right":
b = Blast(player_1,1)
all_sprites.add(b)
blasts.add(b)
if event.key == pg.K_KP1:
if player_2.shoot() == "shoot_left":
b = Blast(player_2,0)
all_sprites.add(b)
blasts.add(b)
elif player_2.shoot() == "shoot_right":
b = Blast(player_2,1)
all_sprites.add(b)
blasts.add(b)
elif event.type == pg.KEYUP:
if event.key == pg.K_a:
player_1.vx = 0
if event.key == pg.K_d:
player_1.vx = 0
if event.key == pg.K_LEFT:
player_2.vx = 0
if event.key == pg.K_RIGHT:
player_2.vx = 0
if event.type == pg.QUIT:
pg.quit()
exit()
#update all sprites
all_sprites.update()
check_for_collisions(player_1,main_platform)
check_for_collisions(player_2,main_platform)
check_blast_collisions(players,blasts)
#draw sprites
screen.fill((255,255,255))
all_sprites.draw(screen)
#draw other stuff
p1lives = font.render(str(player_1.lives), False, (0,0,255))
screen.blit(p1lives,(20,50))
p2lives = font.render(str(player_2.lives), False, (255,0,0))
screen.blit(p2lives,(1580,50))
clock.tick(FPS)
pg.display.flip()
这是整个代码。任何帮助深表感谢。谢谢。
解决方案
你不能pygame.sprite.groupcollide()
在这里使用,因为子弹会与发射子弹的玩家发生碰撞。
您必须使用pygame.sprite.spritecollide()
, 与一名玩家和对手的子弹一起使用。为每个玩家调用一次。
推荐阅读
- ios - 我怎样才能得到这种耀眼的颜色?
- ios - React 本机 iOS 字体无法以任何方式工作
- python - 按日期选择文件并包含文本,Python
- javascript - ElectronJS Vue Axios Basic Authentication Access-Control-Allow-Origin 错误
- c# - excelworkbook.saveas() 在 C# 中抛出错误
- com - 来自 COM exe 的 STDOUT 和 STDERR
- css - 为什么不定位:粘性;工作
- java - ElasticSearch Java API 从查询构建器中获取不同的值
- javascript - Material UI 表格分页问题 React
- r - R并行后端:当一个进程面临异常时会发生什么?