def wallBounce(sprite, partner, game, friction=0): """ Bounce off orthogonally to the wall. """ if not oncePerStep(sprite, game, 'lastbounce'): return sprite.speed *= (1. - friction) stepBack(sprite, partner, game) if abs(sprite.rect.centerx - partner.rect.centerx) > abs(sprite.rect.centery - partner.rect.centery): sprite.orientation = (-sprite.orientation[0], sprite.orientation[1]) else: sprite.orientation = (sprite.orientation[0], -sprite.orientation[1])
def pullWithIt(sprite, partner, game): """ The partner sprite adds its movement to the sprite's. """ if not oncePerStep(sprite, game, 'lastpull'): return tmp = sprite.lastrect v = unitVector(partner.lastdirection) sprite._updatePos(v, partner.speed * sprite.physics.gridsize[0]) if isinstance(sprite.physics, ContinuousPhysics): sprite.speed = partner.speed sprite.orientation = partner.lastdirection sprite.lastrect = tmp
def wallStop(sprite, partner, game, friction=0): """ Stop just in front of the wall, removing that velocity component, but possibly sliding along it. """ if not oncePerStep(sprite, game, 'laststop'): return stepBack(sprite, partner, game) if abs(sprite.rect.centerx - partner.rect.centerx) > abs(sprite.rect.centery - partner.rect.centery): sprite.orientation = (0, sprite.orientation[1] * (1. - friction)) else: sprite.orientation = (sprite.orientation[0] * (1. - friction), 0) sprite.speed = vectNorm(sprite.orientation) * sprite.speed sprite.orientation = unitVector(sprite.orientation)
def wallStop(sprite, partner, game, friction=0): """ It is important both horizontal and vertical collisions are resolved. Vertical collisions keep gravity from building up. """ # if not oncePerStep(sprite, game, 'laststop'): # return # We will revise the velocity used for the last movement old_delta = Vector2(sprite.rect.topleft) - Vector2(sprite.lastrect.topleft) collision_vec = Vector2(partner.rect.center) - Vector2(sprite.rect.center) lastcollision_vec = Vector2(partner.rect.center) - Vector2(sprite.lastrect.center) # Probably a duplicate, because delta is never 0 with a collision if old_delta == Vector2(0,0): return same_vertical = partner.rect.left < sprite.rect.right < partner.rect.right or \ partner.rect.left < sprite.rect.left < partner.rect.right # Horizontal collision # Assume you need horizontal velocity to effect a horizontal collision if abs(lastcollision_vec.x) > abs(lastcollision_vec.y): if not oncePerStep(sprite, game, 'last_horizontal_stop'): return # velocity = (0, sprite.velocity[1] * (1. - friction)) if sprite.velocity[0] > 0: x_clip = partner.rect.left - sprite.rect.right else: x_clip = partner.rect.right - sprite.rect.left if old_delta.x == 0: import ipdb; ipdb.set_trace() # TODO clean up unused factors rescale = (old_delta.x + x_clip) / old_delta.x # new_delta = old_delta * rescale new_delta = old_delta + (x_clip, 0) sprite.passive_force = (0, sprite.passive_force[1]) velocity = (0, sprite.velocity[1]) y_clip = None else: if not oncePerStep(sprite, game, 'last_vertical_stop'): return # Downward motion, so downward collision if sprite.velocity[1] > 0: y_clip = partner.rect.top - sprite.rect.bottom else: y_clip = partner.rect.bottom - sprite.rect.top if old_delta.y == 0: import ipdb; ipdb.set_trace() rescale = (old_delta.y + y_clip) / old_delta.y # new_delta = old_delta.elementwise() * (1, rescale) # new_delta = old_delta * rescale new_delta = old_delta + (0, y_clip) # Counter-act passive movement that has been applied earlier sprite.passive_force = (sprite.passive_force[0], 0) velocity = (sprite.velocity[0], 0) # TODO x_clip = None sprite.rect = sprite.lastrect.move(new_delta) sprite.update_velocity(velocity)