1

This is my second algorithm and I will try to make it as simple for you to understand how it works.

Visual picture of the valid points where the direction of collision is calculated at

It works by splitting a square into 4 sides and then by determining if an edge is within a side (which is a triangle). Then collision can respond by using collision direction as a tool to reduce velocity in the y axis or x.

class Collisions():


def Detect(me, ent):
        me_Pos = Vector.Add(me.GetPos(), [me.GetVelocity()[0], -me.GetVelocity()[1]])
        ent_pos     = Vector.Add(ent.GetPos(), [ent.GetVelocity()[0], -ent.GetVelocity()[1]])

        y_max, y_min, x_max, x_min = me_Pos[1] + (me.Entity.h * 0.5), me_Pos[1] - (me.Entity.h * 0.5),  me_Pos[0] + (me.Entity.w * 0.5), me_Pos[0] - (me.Entity.w * 0.5)
        y_max2, y_min2, x_min2, x_max2 = ent_pos[1] + (ent.Entity.h / 2), ent_pos[1] - (ent.Entity.h / 2), ent_pos[0] - (ent.Entity.w/2), ent_pos[0] + (ent.Entity.w/2)

        isColliding = ((x_max >= x_min2 and x_max <= x_max2) or (x_min <= x_max2 and x_min >= x_min2)) and ((y_min <= y_max2 and y_min >= y_min) or (y_max <= y_max2 and y_max >= y_min2))

        y_range   = Math.Clamp((abs(me_Pos[0] - ent_pos[0])) / (0.5 * ent.Entity.w) * ent.Entity.h, 0, ent.Entity.h) * 0.5
        y_range_2 = (y_range*0.5)

        left  =  (x_max >= x_min2 and x_max <= ent_pos[0]) and ((y_min <= ent_pos[1]+y_range and y_min >= ent_pos[1]-y_range) or (y_max <= ent_pos[1]+y_range and y_max >= ent_pos[1]-y_range))
        right = (x_min <= x_max2 and x_min >= ent_pos[0]) and ((y_min <= ent_pos[1]+y_range and y_min >= ent_pos[1]-y_range) or (y_max <= ent_pos[1]+y_range and y_max >= ent_pos[1]-y_range))

        top    = ((x_max >= x_min2 and x_max <= x_max2) or (x_min <= x_max2 and x_min >= x_min2)) and ((y_min <= y_max2 and y_min >= ent_pos[1] + y_range_2) or (y_max <= y_max2 and y_max >= ent_pos[1] + y_range_2))
        bottom    = ((x_max >= x_min2 and x_max <= x_max2) or (x_min <= x_max2 and x_min >= x_min2)) and ((y_max >= y_min2 and y_max <= ent_pos[1] - y_range_2) or (y_min >= y_min2 and y_min <= ent_pos[1] - y_range_2))

        Collisions.Response(me, ent, [isColliding, left, right, top, bottom])

        return isColliding, left, right, top, bottom

def Response(me, ent, physdata):
    isColliding, left, right, top, bottom = physdata[0], physdata[1], physdata[2], physdata[3], physdata[4]
    if left   == True:
        me.SetVelocity([me.GetVelocity()[0] * -0.2, me.GetVelocity()[1]])
    if right  == True:
        me.SetVelocity([me.GetVelocity()[0] * -0.2, me.GetVelocity()[1]])
    if top    ==  True:
        me.SetVelocity([me.GetVelocity()[0], me.GetVelocity()[1] * -0.2])
    if bottom == True:
        me.SetVelocity([me.GetVelocity()[0], me.GetVelocity()[1] * -0.2])
    me_Pos  = me.GetPos()
    ent_Pos = ent.GetPos()
    y_max, y_min, x_max, x_min = me_Pos[1] + (me.Entity.h * 0.5), me_Pos[1] - (me.Entity.h * 0.5),  me_Pos[0] + (me.Entity.w * 0.5), me_Pos[0] - (me.Entity.w * 0.5)

    for x in [x_max, x_min]:
        for y in [y_max, y_min]:
            colliding, byDistance = util.isInSphere([x,y], ent.GetPos(), ent.Entity.w * 0.5 )

            if colliding:

                me.Entity.move_ip(Vector.Multiply(Vector.Normalize(Vector.Sub(me.GetRealPos(),ent.GetRealPos())), 1+byDistance))
    Collisions.Stuck_Response(me, ent)
def Stuck_Response(me,ent):

    if Vector.Distance(me.GetRealPos(), ent.GetRealPos()) < me.Entity.w * 0.7:
        me.Entity.move_ip(random.randint(1,2), random.randint(1,2))
        me.Entity.move_ip(Vector.Sub(me.GetRealPos(), ent.GetRealPos()))


def Translate(table):
    for k, v in enumerate(table):
        for k2, v2 in enumerate(table):
            ent_one = table[k]
            ent_two = table[k2]
            if ent_one != ent_two:
                Collisions.Detect(ent_one, ent_two)
HDalton
  • 83
  • 5
  • Why don't you use pygame Sprites – Laschet Jain Oct 25 '15 at 20:11
  • Check this out http://programarcadegames.com/index.php?chapter=introduction_to_sprites – Laschet Jain Oct 25 '15 at 20:12
  • 2
    I want to write my own collision algorithm for purpose of doing it myself. – HDalton Oct 25 '15 at 20:12
  • please post it on http://codereview.stackexchange.com, you might get a better response there – Swastik Padhi Oct 25 '15 at 21:57
  • I suspect the largest performance gains you can get will come not from tweaking your entity-to-entity collision detection or response functions, but rather from adding a broad-phase to your collision detection system so that you have to test fewer pairs of entities. That's way too broad a topic for Stack Overflow though, so I suggest you do some reading about the options (like quad-trees and interval lists) and then ask a more specific question when you have tried one or more of them. – Blckknght Oct 25 '15 at 22:13

0 Answers0