Ejemplo n.º 1
0
    def box2box_collision(collider_a, collider_b):

        # offset the collision boxes relative to their transform positions
        get_relative_rect_pos(collider_a.entity.transform.position, collider_a)
        get_relative_rect_pos(collider_b.entity.transform.position, collider_b)

        # check for collision
        if collider_a.box.colliderect(collider_b.box):
            return True
        return False
Ejemplo n.º 2
0
    def box2box_collision(collider_a, collider_b):

        # offset the collision boxes relative to their transform positions
        get_relative_rect_pos(collider_a.entity.transform.position, collider_a)
        get_relative_rect_pos(collider_b.entity.transform.position, collider_b)

        # check for collision
        if collider_a.box.colliderect(collider_b.box):
            return True
        return False
Ejemplo n.º 3
0
    def debug(self, e):

        transform = e.transform

        # if we have nothing to draw on then return
        if transform is None:
            return

        display = self.world.engine.display

        # ------- Debug info -------- #

        x_origin = self.world.origin.x
        y_origin = self.world.origin.y

        x = transform.position.x
        y = transform.position.y

        # adjust for the camera
        if self.camera is not None:
            x -= self.camera.transform.position.x
            y -= self.camera.transform.position.y

        collider = e.collider
        rigid_body = e.rigid_body

        # transform origin crosshair
        pygame.draw.line(display, (255, 0, 0), (x-50, y), (x+50, y))
        pygame.draw.line(display, (255, 0, 0), (x, y-50), (x, y+50))

        # draw position vector relative to the world origin
        pygame.draw.line(display, (50, 50, 50), (x_origin, y_origin), (x, y))

        if rigid_body is not None:

            # obtain a fraction of the velocity vector
            length = Vector2.get_scaled_by(rigid_body.velocity, 0.2)
            xend = x + length.x
            yend = y + length.y

            # draw the velocity vector of the rigid
            pygame.draw.line(display, (0, 255, 0), (x, y), (xend, yend))

            # represent mass
            # larger circle means more mass
            mass = rigid_body.mass

            # scale down the mass
            mass /= 4

            # mask surface to match the size of the mass circle
            transparency_mask = pygame.Surface((mass*2, mass*2))

            # fill surface with a color mask and set the color key
            color_mask = (123, 54, 33)
            transparency_mask.fill(color_mask)
            transparency_mask.set_colorkey(color_mask)

            # draw circle to the transparency mask
            mass = int(mass)
            pygame.draw.circle(transparency_mask, (0, 100, 255), (mass, mass), mass)

            # change alpha
            transparency_mask.set_alpha(100)

            # draw transparency mask to the display
            display.blit(transparency_mask, (int(x)-mass, int(y)-mass))

        # box collider
        if collider is not None:

            if collider.tag == BoxCollider.tag:

                # get relative position to transform
                get_relative_rect_pos(transform.position, collider)

                # center the box image
                x -= collider.box.width/2
                y -= collider.box.height/2

                # render based on the offset of the collider as well
                x_offset = collider.offset.x
                y_offset = collider.offset.y
                box = Rect(x+x_offset, y+y_offset, collider.box.width, collider.box.height)

                tol = Rect(x+x_offset, y+y_offset, collider.tolerance_hitbox.width, collider.tolerance_hitbox.height)
                tol.center = box.center

                # display collider rect properties
                color = (255, 255, 255)
                if collider.is_trigger:
                    color = (0, 255, 255)

                pygame.draw.rect(display, color, box, 1)
                pygame.draw.rect(display, (255, 0, 0), tol, 1)
                pygame.draw.circle(display, (0, 255, 0), box.center, 3)
                pygame.draw.circle(display, (0, 255, 255), box.topleft, 5)

            elif collider.tag == CircleCollider.tag:
                radius = collider.radius
                pygame.draw.circle(display, (255, 255, 255), (int(x), int(y)), radius, 1)
Ejemplo n.º 4
0
    def process(self, entities):
        # save the collisions of the past frame
        #PhysicsSystem.past_collisions = PhysicsSystem.collision_queue[:]

        # empty the collision queue
        del PhysicsSystem.collision_queue[:]

        for eA in entities:

            # ignore disabled entities
            if eA.disabled:
                continue

            transform_a = eA.transform
            collider_a = eA.collider
            rigid_body_a = eA.rigid_body

            valid_collider = collider_a is not None

            # if there is a collider attached to the entity, then make sure that the
            # entity also has a rigid body to modify or if the collider should trigger a collision event.
            consider_entity = False
            if valid_collider:
                consider_entity = rigid_body_a is not None or collider_a.treat_as_dynamic

            if valid_collider and consider_entity:

                # Move the rigid body
                if rigid_body_a is not None:
                    self._integrate_motion(transform_a, rigid_body_a)

                # Find another entity that it may collide with
                for eB in entities:

                    if eB.disabled:
                        continue

                    transform_b = eB.transform
                    collider_b = eB.collider

                    # Check that coll_comp_b is valid and that coll_comp_a is not colliding with itself
                    if collider_b is not None and eA is not eB:

                        collision_occurred = False

                        # A flag to tell the physics systems not to apply physics or collision
                        # resolution on the entity if this collider collides with another collider.
                        b_isnt_trigger = not collider_b.is_trigger

                        # box to box collision
                        if collider_a.tag == BoxCollider.tag and collider_b.tag == BoxCollider.tag:

                            # check for collision
                            if PhysicsSystem.box2box_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger:
                                    PhysicsSystem.box2box_response(collider_a, collider_b)

                        # circle to circle collision
                        elif collider_a.tag == CircleCollider.tag and collider_b.tag == CircleCollider.tag:

                            # check if circles collided
                            if PhysicsSystem._circle2circle_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger:
                                    PhysicsSystem.circle2circle_response(collider_a, collider_b)

                        # circle to box
                        elif collider_a.tag == CircleCollider.tag and collider_b.tag == BoxCollider.tag:

                            # create a temporary box collider associated to A
                            box_collider_a = BoxCollider(collider_a.radius*2, collider_a.radius*2)
                            box_collider_a.entity = collider_a.entity
                            box_collider_a.restitution = collider_a.restitution
                            box_collider_a.surface_friction = collider_a.surface_friction

                            # Get the relative collision box positions to their transforms.
                            get_relative_rect_pos(transform_a.position, box_collider_a)
                            get_relative_rect_pos(transform_b.position, collider_b)

                            # check for collision
                            if PhysicsSystem._circle2box_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger:
                                    PhysicsSystem.box2box_response(box_collider_a, collider_b)

                        if collision_occurred:
                            # add collision event into the queue
                            PhysicsSystem.collision_queue.append((eA, eB))

                            # call the collision inside the scripts
                            for s in eA.scripts:
                                s.collision_event(collider_b)

                            for s in eB.scripts:
                                s.collision_event(collider_a)
Ejemplo n.º 5
0
    def debug(self, e):

        transform = e.transform

        # if we have nothing to draw on then return
        if transform is None:
            return

        display = self.world.engine.display

        # ------- Debug info -------- #

        x_origin = self.world.origin.x
        y_origin = self.world.origin.y

        x = transform.position.x
        y = transform.position.y

        # adjust for the camera
        if self.camera is not None:
            x -= self.camera.transform.position.x
            y -= self.camera.transform.position.y

        collider = e.collider
        rigid_body = e.rigid_body

        # transform origin crosshair
        pygame.draw.line(display, (255, 0, 0), (x-50, y), (x+50, y))
        pygame.draw.line(display, (255, 0, 0), (x, y-50), (x, y+50))

        # draw position vector relative to the world origin
        pygame.draw.line(display, (50, 50, 50), (x_origin, y_origin), (x, y))

        if rigid_body is not None:

            # obtain a fraction of the velocity vector
            length = Vector2.get_scaled_by(rigid_body.velocity, 0.2)
            xend = x + length.x
            yend = y + length.y

            # draw the velocity vector of the rigid
            pygame.draw.line(display, (0, 255, 0), (x, y), (xend, yend))

            # represent mass
            # larger circle means more mass
            mass = rigid_body.mass

            # scale down the mass
            mass /= 4

            # mask surface to match the size of the mass circle
            transparency_mask = pygame.Surface((mass*2, mass*2))

            # fill surface with a color mask and set the color key
            color_mask = (123, 54, 33)
            transparency_mask.fill(color_mask)
            transparency_mask.set_colorkey(color_mask)

            # draw circle to the transparency mask
            mass = int(mass)
            pygame.draw.circle(transparency_mask, (0, 100, 255), (mass, mass), mass)

            # change alpha
            transparency_mask.set_alpha(100)

            # draw transparency mask to the display
            display.blit(transparency_mask, (int(x)-mass, int(y)-mass))

        # box collider
        if collider is not None:

            if collider.tag == BoxCollider.tag:

                # get relative position to transform
                get_relative_rect_pos(transform.position, collider)

                # center the box image
                x -= collider.box.width/2
                y -= collider.box.height/2

                # render based on the offset of the collider as well
                x_offset = collider.offset.x
                y_offset = collider.offset.y
                box = Rect(x+x_offset, y+y_offset, collider.box.width, collider.box.height)

                tol = Rect(x+x_offset, y+y_offset, collider.tolerance_hitbox.width, collider.tolerance_hitbox.height)
                tol.center = box.center

                # display collider rect properties
                color = (255, 255, 255)
                if collider.is_trigger:
                    color = (0, 255, 255)

                pygame.draw.rect(display, color, box, 1)
                pygame.draw.rect(display, (255, 0, 0), tol, 1)
                pygame.draw.circle(display, (0, 255, 0), box.center, 3)
                pygame.draw.circle(display, (0, 255, 255), box.topleft, 5)

            elif collider.tag == CircleCollider.tag:
                radius = collider.radius
                pygame.draw.circle(display, (255, 255, 255), (int(x), int(y)), radius, 1)
Ejemplo n.º 6
0
    def process(self, entities):
        # save the collisions of the past frame
        #PhysicsSystem.past_collisions = PhysicsSystem.collision_queue[:]

        # empty the collision queue
        del PhysicsSystem.collision_queue[:]

        for eA in entities:

            # ignore disabled entities
            if eA.disabled:
                continue

            transform_a = eA.transform
            collider_a = eA.collider
            rigid_body_a = eA.rigid_body

            valid_collider = collider_a is not None

            # if there is a collider attached to the entity, then make sure that the
            # entity also has a rigid body to modify or if the collider should trigger a collision event.
            consider_entity = False
            if valid_collider:
                consider_entity = rigid_body_a is not None or collider_a.treat_as_dynamic

            if valid_collider and consider_entity:

                # Move the rigid body
                if rigid_body_a is not None:
                    self._integrate_motion(transform_a, rigid_body_a)

                # Find another entity that it may collide with
                for eB in entities:

                    if eB.disabled:
                        continue

                    transform_b = eB.transform
                    collider_b = eB.collider

                    # Check that coll_comp_b is valid and that coll_comp_a is not colliding with itself
                    if collider_b is not None and eA is not eB:

                        collision_occurred = False

                        # A flag to tell the physics systems not to apply physics or collision
                        # resolution on the entity if this collider collides with another collider.
                        b_isnt_trigger = not collider_b.is_trigger
                        a_isnt_trigger = not collider_a.is_trigger

                        # box to box collision
                        if collider_a.tag == BoxCollider.tag and collider_b.tag == BoxCollider.tag:

                            # check for collision
                            if PhysicsSystem.box2box_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger and a_isnt_trigger:
                                    PhysicsSystem.box2box_response(collider_a, collider_b)

                        # circle to circle collision
                        elif collider_a.tag == CircleCollider.tag and collider_b.tag == CircleCollider.tag:

                            # check if circles collided
                            if PhysicsSystem._circle2circle_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger and a_isnt_trigger:
                                    PhysicsSystem.circle2circle_response(collider_a, collider_b)

                        # circle to box
                        elif collider_a.tag == CircleCollider.tag and collider_b.tag == BoxCollider.tag:

                            # create a temporary box collider associated to A
                            box_collider_a = BoxCollider(collider_a.radius*2, collider_a.radius*2)
                            box_collider_a.entity = collider_a.entity
                            box_collider_a.restitution = collider_a.restitution
                            box_collider_a.surface_friction = collider_a.surface_friction

                            # Get the relative collision box positions to their transforms.
                            get_relative_rect_pos(transform_a.position, box_collider_a)
                            get_relative_rect_pos(transform_b.position, collider_b)

                            # check for collision
                            if PhysicsSystem._circle2box_collision(collider_a, collider_b):
                                collision_occurred = True

                                if rigid_body_a is not None and b_isnt_trigger and a_isnt_trigger:
                                    PhysicsSystem.box2box_response(box_collider_a, collider_b)

                        if collision_occurred:
                            # add collision event into the queue
                            PhysicsSystem.collision_queue.append((eA, eB))

                            # call the collision inside the scripts
                            for s in eA.scripts:
                                s.collision_event(collider_b)

                            for s in eB.scripts:
                                s.collision_event(collider_a)