Esempio n. 1
0
/**
 * \brief Checks whether an entity collides with this detector.
 *
 * This function is called by the map when an entity has just moved.
 * It checks whether the entity collides with this detector.
 * Depending on the detector collision mode(s), the appropriate
 * test_collision_* functions are called.
 * If there is a collision, the notify_collision() method is called.
 *
 * \param entity the entity to check
 */
void Detector::check_collision(Entity& entity) {

  if (&entity != this
      && (has_layer_independent_collisions() || get_layer() == entity.get_layer())) { // the entity is in the same layer as the detector

    // detect the collision depending on the collision mode

    if (has_collision_mode(COLLISION_OVERLAPPING) && test_collision_rectangle(entity)) {
      notify_collision(entity, COLLISION_OVERLAPPING);
    }

    if (has_collision_mode(COLLISION_CONTAINING) && test_collision_inside(entity)) {
      notify_collision(entity, COLLISION_CONTAINING);
    }

    if (has_collision_mode(COLLISION_ORIGIN) && test_collision_origin_point(entity)) {
      notify_collision(entity, COLLISION_ORIGIN);
    }

    if (has_collision_mode(COLLISION_FACING) && test_collision_facing_point(entity)) {

      if (entity.get_facing_entity() == nullptr) { // make sure only one entity can think "I am the facing entity"
        entity.set_facing_entity(this);
      }
      notify_collision(entity, COLLISION_FACING);
    }

    if (has_collision_mode(COLLISION_TOUCHING) && test_collision_touching(entity)) {
      notify_collision(entity, COLLISION_TOUCHING);
    }

    if (has_collision_mode(COLLISION_CENTER) && test_collision_center(entity)) {
      notify_collision(entity, COLLISION_CENTER);
    }

    if (has_collision_mode(COLLISION_CUSTOM) && test_collision_custom(entity)) {
      notify_collision(entity, COLLISION_CUSTOM);
    }
  }
}
Esempio n. 2
0
/**
 * \copydoc Detector::test_collision_custom
 */
bool CustomEntity::test_collision_custom(MapEntity& entity) {

    if (!successful_collision_tests.empty()) {
        // Avoid reentrant collision tests.
        return false;
    }

    bool collision = false;

    const std::vector<CollisionInfo> collision_tests = this->collision_tests;
    for (const CollisionInfo& info: collision_tests) {

        switch (info.get_built_in_test()) {

        case COLLISION_OVERLAPPING:
            if (test_collision_rectangle(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_CONTAINING:
            if (test_collision_inside(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_ORIGIN:
            if (test_collision_origin_point(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_FACING:
            if (test_collision_facing_point(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_TOUCHING:
            if (test_collision_touching(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_CENTER:
            if (test_collision_center(entity)) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_CUSTOM:
            if (get_lua_context().do_custom_entity_collision_test_function(
                        info.get_custom_test_ref(), *this, entity)
               ) {
                collision = true;
                successful_collision_tests.push_back(info);
            }
            break;

        case COLLISION_SPRITE:
            // Not handled here.
            break;

        case COLLISION_NONE:
            Debug::die("Invalid collision mode");
            break;
        }
    }

    return collision;
}