蟒蛇玩家与敌人和子弹相撞

  • 本文关键字:子弹 敌人 玩家 pygame
  • 更新时间 :
  • 英文 :


我正在处理一个"射击;游戏的角色类和5个不同的子弹类。玩家和敌人是角色类的对象。我将子弹的起始位置设置在字符rect的中心(所以子弹从字符中射出(。

碰撞由collectrect定义。示例:";敌人.直接.碰撞直接(bullet1(";当玩家向敌人射击时,效果很好。如果敌人因为子弹在自己的矩形内相撞而开始向玩家射击,问题就开始了。

我可以通过将"子弹头"类相乘来解决这个问题。然后玩家和敌人将从不同的职业射击。但每个字符都有5个不同的项目符号类,每个类都有不同的变量,而较短的类有很多代码。

我确信有一个聪明的解决方案,而不是我的代码行(大约500行(

有什么建议吗?谢谢:(

一个简单的解决方案是,您可以简单地为项目符号提供一个额外的参数:一个不应该检查的矩形。所以在检查时项目符号冲突您将此矩形排除在检查之外。

最小示例(代码注释中的解释(:

import pygame

pygame.init()
screen = pygame.display.set_mode((500, 400))
clock = pygame.time.Clock()

class Bullet:
# provide an argument for what to check and what to exclude
def __init__(self, start_pos, x_direction, check, exclude):
self.image = pygame.Surface((10, 10))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect(center=start_pos)
self.x_direction = x_direction
self.check, self.exclude = check, exclude
self.x_velocity = 5 * self.x_direction
self.damage = 5
self.destroy = False
def draw(self, surf):
surf.blit(self.image, self.rect)
def update(self):
# go over the list of entities to check
for entity in self.check:
# if the entity is not the one that is excluded and the entity has
# attributes that are needed here check for collision
# and if there is then set the destroy flag to True
# and stop updating. Also some check to see if the bullet has traveled
# too far or somethin like that could be added
if (entity is not self.exclude and hasattr(entity, 'health')
and hasattr(entity, 'rect')):
if self.rect.colliderect(entity.rect):
entity.health -= self.damage
self.destroy = True
return
self.rect.move_ip(self.x_velocity, 0)

# simple entity class to represent entities (in this case
# only the players and enemies since theoretically this could
# be base class both for bullets and players and enemies)
class Entity:
def __init__(self, x, y, color, name):
self.color, self.name = color, name
self.rect = pygame.Rect(x, y, 30, 60)
self.health = 100
self.prev_health = self.health
def draw(self, surf):
pygame.draw.rect(surf, self.color, self.rect)
def update(self):
# if health has been reduced print the current health
if self.health < self.prev_health:
print(f'{self.name} health: {self.health}')
self.prev_health = self.health

# create the entities
player = Entity(100, 200, (0, 255, 0), 'player')
enemy = Entity(370, 200, (255, 0, 0), 'enemy')
# create a list to store bullets in
bullets = []
while True:
screen.fill((0, 0, 0))

# create a list for bullets to remove
# so that they can be removed later
# without interfering with the checking for loop
remove_bullets = []
for bullet in bullets:
# if the bullet should be destroyed don't update it
# and add to the bullets to remove
if bullet.destroy:
remove_bullets.append(bullet)
else:
bullet.update()
bullet.draw(screen)
# remove destroyed bullets from the main list
for bullet in remove_bullets:
bullets.remove(bullet)

# update
enemy.update()
enemy.draw(screen)
player.update()
player.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
# usually you would just pass a list of entities that are not like
# this but rather referenced by name so you would use that
# instead of passing a list like this. In that case it would make more
# sense to have an excluded entity as in this case you could just not include
# in the list at all. Also going over a list to remove a single element
# would likely be more wasteful
if event.key == pygame.K_a:
# if a pressed create a bullet traveling from enemy to player
bullet = Bullet(enemy.rect.center, -1, [player, enemy], enemy)
bullets.append(bullet)
if event.key == pygame.K_d:
# if d pressed create a bullet traveling from player to enemy
bullet = Bullet(player.rect.center, 1, [player, enemy], player)
bullets.append(bullet)
pygame.display.update()
clock.tick(60)

此外,我觉得你不需要5个子弹类(敌人和玩家绝对不需要5(,如果子弹的行为相似,你应该能够简单地更改子弹的一些参数,而不是创建5个类。

bullets = []
to shoot, append this V to list
[[positionX, positionY], [directionX, directionY], Rect for the bullet]
collisions:
for bullet in bullets:
<update stuff here>
if bullet[2].colliderect(playerrect): # (rect)
bullets.remove(bullet)
pass

最新更新