def update(self, time_step, players, level): cam_goal = sum(p.position for p in players.values()) / len(players) #cam_goal[0] = max(cam_goal[0], self.half_width[0] / self.zoom) #cam_goal[0] = min(cam_goal[0], level.width - self.half_width[0] / self.zoom) if level.height > 2 * self.half_height[1] / self.zoom: cam_goal[1] = max(cam_goal[1], self.half_height[1] / self.zoom) cam_goal[1] = min(cam_goal[1], level.height - self.half_height[1] / self.zoom) else: cam_goal[1] = level.position[1] self.position[:] += time_step * (cam_goal - self.position) if len(players) > 1: dist2 = max(norm2(p.position - cam_goal) for p in players.values()) zoom_goal = max(min(500 / (np.sqrt(dist2) + 1e-6), self.max_zoom), level.width) self.zoom += time_step * (zoom_goal - self.zoom) self.shake = sum(p.camera_shake for p in players.values()) self.shake += sum(o.camera_shake for o in level.objects.values() if type(o) is Grenade)
def set_spawn(self, level, players): i = 0 max_dist = 0.0 for j, s in enumerate(level.player_spawns): if len(players) == 1: break min_dist = np.inf for p in players.values(): if not p.destroyed: min_dist = min(min_dist, norm2(s.position - p.position)) if min_dist > max_dist: max_dist = min_dist i = j self.set_position(level.player_spawns[i].position)
def overlap(self, other): overlap = np.zeros(2) if type(other) is Circle: dist = norm2(self.position - other.position) if dist > (self.radius + other.radius)**2: return overlap if dist == 0.0: overlap = (self.radius + other.radius) * basis(1) else: dist = np.sqrt(dist) unit = (self.position - other.position) / dist overlap = (self.radius + other.radius - dist) * unit elif type(other) is Rectangle: overlap = -other.overlap(self) return overlap
def grab_object(self): if self.grab_timer > 0: return if self.object: return for c in self.hand.collider.collisions: if c.collider.group in { Group.PROPS, Group.GUNS, Group.SHIELDS, Group.SWORDS }: if norm2(self.shoulder - c.collider.position) > 1.5**2: continue self.object = c.collider.parent self.object.on_ground = False self.object.gravity_scale = 0.0 if self.object.parent: self.object.parent.throw_object() self.object.parent = self self.object.angular_velocity = 0.0 break
def point_inside(self, point): return norm2(self.position - point) <= self.radius**2
def update(self, gravity, time_step, colliders): for p in self.particle_clouds: p.update(gravity, time_step) if not p.active: self.particle_clouds.remove(p) if not self.active: return if self.velocity[1] != 0: self.on_ground = False self.speed = norm(self.velocity) if self.speed != 0: self.velocity *= min(self.speed, MAX_SPEED) / self.speed delta_pos = self.velocity * time_step + 0.5 * self.acceleration * time_step**2 self.set_position(self.position + delta_pos) acc_old = self.acceleration.copy() self.acceleration = self.get_acceleration(gravity) if self.rest_angle is None: self.angular_velocity = -self.gravity_scale * self.velocity[0] delta_angle = self.angular_velocity * time_step + 0.5 * self.angular_acceleration * time_step**2 if delta_angle: self.rotate(delta_angle) ang_acc_old = float(self.angular_acceleration) self.angular_acceleration = 0.0 if self.collider is None or not self.collision_enabled: return if any(np.abs(delta_pos) > 0.01) or abs(delta_angle) > 1e-3: self.collider.update_occupied_squares(colliders) self.collider.update_collisions(colliders) for collision in self.collider.collisions: collider = collision.collider if not collider.parent.collision_enabled: continue if collider.group is Group.PLATFORMS: if self.parent and self.collider.group in {Group.GUNS, Group.SWORDS, Group.SHIELDS}: self.collider.collisions.remove(collision) continue if collider.half_height[1] > 0: if self.collider.position[1] - delta_pos[1] - self.collider.axis_half_width(basis(1)) \ < collider.position[1] + collider.half_height[1]: self.collider.collisions.remove(collision) continue elif self.collider.position[1] - delta_pos[1] + self.collider.axis_half_width(basis(1)) \ > collider.position[1] + collider.half_height[1]: self.collider.collisions.remove(collision) continue if self.collider.group is Group.THROWN: if collider.parent is self.parent: self.collider.collisions.remove(collision) continue try: collider.parent.parent.throw_object() except AttributeError: pass if collision.overlap[1] > 0: self.on_ground = True if not self.parent: if self.rest_angle is not None: self.rotate(-self.angle + self.direction * self.rest_angle) self.angular_velocity = 0.0 elif collision.overlap[0] != 0: self.angular_velocity *= -1 n = min(int(self.speed * 5), 10) if n > 1: self.particle_clouds.append(Dust(self.position, self.speed * normalized(collision.overlap), n)) self.set_position(self.position + collision.overlap) n = collision.overlap self.velocity -= 2 * self.velocity.dot(n) * n / norm2(n) self.velocity *= self.bounce if not self.parent and isinstance(collider.parent, PhysicsObject): collider.parent.velocity[:] = -self.velocity if self.collider.group is Group.THROWN and self.collider.collisions: self.parent = None self.collider.group = self.group self.velocity += 0.5 * (acc_old + self.acceleration) * time_step self.angular_velocity += 0.5 * (ang_acc_old + self.angular_acceleration) * time_step if abs(self.velocity[0]) < 0.05: self.velocity[0] = 0.0 if self.parent is None and self.collider.collisions and self.speed > 0.1: self.sounds.add(self.bump_sound)