基本的に、以下を使用して、以下のスプライトに衝突検出を追加しようとしています。
self.rect = bounds_rect
collide = pygame.sprite.spritecollide(self, wall_list, False)
if collide:
# yes
print("collide")
ただし、衝突がトリガーされると、「衝突」が何度も繰り返し印刷されるようですが、代わりに、オブジェクトを通り抜けることができないようにしたい場合は、助けになりますか?
def update(self, time_passed):
""" Update the creep.
time_passed:
The time passed (in ms) since the previous update.
"""
if self.state == Creep.ALIVE:
# Maybe it's time to change the direction ?
#
self._change_direction(time_passed)
# Make the creep point in the correct direction.
# Since our direction vector is in screen coordinates
# (i.e. right bottom is 1, 1), and rotate() rotates
# counter-clockwise, the angle must be inverted to
# work correctly.
#
self.image = pygame.transform.rotate(
self.base_image, -self.direction.angle)
# Compute and apply the displacement to the position
# vector. The displacement is a vector, having the angle
# of self.direction (which is normalized to not affect
# the magnitude of the displacement)
#
displacement = vec2d(
self.direction.x * self.speed * time_passed,
self.direction.y * self.speed * time_passed)
self.pos += displacement
# When the image is rotated, its size is changed.
# We must take the size into account for detecting
# collisions with the walls.
#
self.image_w, self.image_h = self.image.get_size()
global bounds_rect
bounds_rect = self.field.inflate(
-self.image_w, -self.image_h)
if self.pos.x < bounds_rect.left:
self.pos.x = bounds_rect.left
self.direction.x *= -1
elif self.pos.x > bounds_rect.right:
self.pos.x = bounds_rect.right
self.direction.x *= -1
elif self.pos.y < bounds_rect.top:
self.pos.y = bounds_rect.top
self.direction.y *= -1
elif self.pos.y > bounds_rect.bottom:
self.pos.y = bounds_rect.bottom
self.direction.y *= -1
self.rect = bounds_rect
collide = pygame.sprite.spritecollide(self, wall_list, False)
if collide:
# yes
print("collide")
elif self.state == Creep.EXPLODING:
if self.explode_animation.active:
self.explode_animation.update(time_passed)
else:
self.state = Creep.DEAD
self.kill()
elif self.state == Creep.DEAD:
pass
#------------------ PRIVATE PARTS ------------------#
# States the creep can be in.
#
# ALIVE: The creep is roaming around the screen
# EXPLODING:
# The creep is now exploding, just a moment before dying.
# DEAD: The creep is dead and inactive
#
(ALIVE, EXPLODING, DEAD) = range(3)
_counter = 0
def _change_direction(self, time_passed):
""" Turn by 45 degrees in a random direction once per
0.4 to 0.5 seconds.
"""
self._counter += time_passed
if self._counter > randint(400, 500):
self.direction.rotate(45 * randint(-1, 1))
self._counter = 0
def _point_is_inside(self, point):
""" Is the point (given as a vec2d) inside our creep's
body?
"""
img_point = point - vec2d(
int(self.pos.x - self.image_w / 2),
int(self.pos.y - self.image_h / 2))
try:
pix = self.image.get_at(img_point)
return pix[3] > 0
except IndexError:
return False
def _decrease_health(self, n):
""" Decrease my health by n (or to 0, if it's currently
less than n)
"""
self.health = max(0, self.health - n)
if self.health == 0:
self._explode()
def _explode(self):
""" Starts the explosion animation that ends the Creep's
life.
"""
self.state = Creep.EXPLODING
pos = ( self.pos.x - self.explosion_images[0].get_width() / 2,
self.pos.y - self.explosion_images[0].get_height() / 2)
self.explode_animation = SimpleAnimation(
self.screen, pos, self.explosion_images,
100, 300)
global remainingCreeps
remainingCreeps-=1
if remainingCreeps == 0:
print("all dead")