Пример #1
0
void instance_activate_circle(int x, int y, int r, int inside)
{
    std::map<int,enigma::inst_iter*>::iterator iter = enigma::instance_deactivated_list.begin();
    while (iter != enigma::instance_deactivated_list.end()) {
        enigma::object_collisions* const inst = ((enigma::object_collisions*)(iter->second->inst));

        if (inst->sprite_index == -1 && (inst->mask_index == -1)) { //no sprite/mask then no collision
            ++iter;
            continue;
        }

        const bbox_rect_t &box = inst->$bbox_relative();
        const double x1 = inst->x, y1 = inst->y,
        xscale = inst->image_xscale, yscale = inst->image_yscale,
        ia = inst->image_angle;

        int left, top, right, bottom;
        get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x1, y1, xscale, yscale, ia);

        const bool intersects = line_ellipse_intersects(r, r, left-x, top-y, bottom-y) ||
                                 line_ellipse_intersects(r, r, right-x, top-y, bottom-y) ||
                                 line_ellipse_intersects(r, r, top-y, left-x, right-x) ||
                                 line_ellipse_intersects(r, r, bottom-y, left-x, right-x) ||
                                 (x >= left && x <= right && y >= top && y <= bottom); // Circle inside bbox.

        bool removed = false;
        if (intersects)
        {
            if (inside)
            {
                inst->activate();
                enigma::instance_deactivated_list.erase(iter++);
                removed = true;
            }
        }
        else
        {
            if (!inside)
            {
                inst->activate();
                enigma::instance_deactivated_list.erase(iter++);
                removed = true;
            }
        }
        if (!removed) {
            ++iter;
        }
    }
}
Пример #2
0
void instance_deactivate_circle(int x, int y, int r, int inside, bool notme)
{
    for (enigma::iterator it = enigma::instance_list_first(); it; ++it)
    {
        if (notme && (*it)->id == enigma::instance_event_iterator->inst->id)
            continue;
        enigma::object_collisions* const inst = ((enigma::object_collisions*)*it);

        if (inst->sprite_index == -1 && (inst->mask_index == -1)) //no sprite/mask then no collision
            continue;

        const bbox_rect_t &box = inst->$bbox_relative();
        const double x1 = inst->x, y1 = inst->y,
        xscale = inst->image_xscale, yscale = inst->image_yscale,
        ia = inst->image_angle;

        int left, top, right, bottom;
        get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x1, y1, xscale, yscale, ia);

        const bool intersects = line_ellipse_intersects(r, r, left-x, top-y, bottom-y) ||
                                 line_ellipse_intersects(r, r, right-x, top-y, bottom-y) ||
                                 line_ellipse_intersects(r, r, top-y, left-x, right-x) ||
                                 line_ellipse_intersects(r, r, bottom-y, left-x, right-x) ||
                                 (x >= left && x <= right && y >= top && y <= bottom); // Circle inside bbox.

        if (intersects)
        {
            if (inside)
            {
                inst->deactivate();
                enigma::instance_deactivated_list.insert(inode_pair((*it)->id,it.it));
            }
        }
        else
        {
            if (!inside)
            {
                inst->deactivate();
                enigma::instance_deactivated_list.insert(inode_pair((*it)->id,it.it));
            }
        }
    }
}
Пример #3
0
enigma::object_collisions* const collide_inst_ellipse(int object, bool solid_only, bool prec, bool notme, int x1, int y1, double rx, double ry)
{
    if (rx == 0 || ry == 0)
        return 0;

    for (enigma::iterator it = enigma::fetch_inst_iter_by_int(object); it; ++it)
    {
        enigma::object_collisions* const inst = (enigma::object_collisions*)*it;
        if (notme && inst->id == enigma::instance_event_iterator->inst->id)
            continue;
        if (solid_only && !inst->solid)
            continue;
        if (inst->sprite_index == -1 && inst->mask_index == -1) // No sprite/mask then no collision.
            continue;

        const bbox_rect_t &box = inst->$bbox_relative();
        const double x = inst->x, y = inst->y,
                     xscale = inst->image_xscale, yscale = inst->image_yscale,
                     ia = inst->image_angle;
        int left, top, right, bottom;
        get_border(&left, &right, &top, &bottom, box.left, box.top, box.right, box.bottom, x, y, xscale, yscale, ia);

        const bool intersects = line_ellipse_intersects(rx, ry, left-x1, top-y1, bottom-y1) ||
                                 line_ellipse_intersects(rx, ry, right-x1, top-y1, bottom-y1) ||
                                 line_ellipse_intersects(ry, rx, top-y1, left-x1, right-x1) ||
                                 line_ellipse_intersects(ry, rx, bottom-y1, left-x1, right-x1) ||
                                 (x1 >= left && x1 <= right && y1 >= top && y1 <= bottom); // Ellipse inside bbox.

        if (intersects) {

            if (!prec) {
                return inst;
            }

            const int collsprite_index = inst->mask_index != -1 ? inst->mask_index : inst->sprite_index;

            enigma::sprite* sprite = enigma::spritestructarray[collsprite_index];

            const int usi = ((int) inst->image_index) % sprite->subcount;

            unsigned char* pixels = (unsigned char*) (sprite->colldata[usi]);

            if (pixels == 0) { // Bounding Box.
                return inst;
            }
            else { // Precise.
                // Intersection.
                const int ins_left = max(left, (int)(x1-rx));
                const int ins_right = min(right, (int)(x1+rx));
                const int ins_top = max(top, (int)(y1-ry));
                const int ins_bottom = min(bottom, (int)(y1+ry));

                // Check per pixel.

                const int w = sprite->width;
                const int h = sprite->height;

                const double xoffset = sprite->xoffset;
                const double yoffset = sprite->yoffset;

                const bool coll_result = precise_collision_ellipse(
                    ins_left, ins_right, ins_top, ins_bottom,
                    x, y,
                    xscale, yscale,
                    ia,
                    pixels,
                    w, h,
                    xoffset, yoffset,
                    x1, y1, rx, ry
                );

                if (coll_result) {
                    return inst;
                }
            }
        }
    }
    return NULL;
}