我的碰撞检测看起来相当昂贵,我希望你的意见

时间:2015-10-25 20:10:22

标签: python pygame

这是我的第二个算法,我会尽量让你理解它是如何工作的。

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

它的工作原理是将一个正方形分成4个边,然后确定边是否在一边(这是一个三角形)。然后碰撞可以通过使用碰撞方向作为降低y轴或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)

0 个答案:

没有答案