我的碰撞检测似乎相当昂贵,我想你对我的意见

2024-06-23 00:31:00 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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)

Tags: orandposifrangeminmaxme