9.6 C
New York
Thursday, November 13, 2025

How can I enhance the vector collision algorithm?


I am constructing a recreation (shock) in pygame and I used to be having hassle with tile-based collision detection. There are 5 several types of non-empty tiles (proven beneath) that may be rotated in 90 diploma increments and flipped on each the x-axis and y-axis.

Merely put, adjusting the delta time allowed the participant to move by gadgets they actually should not have. So, I developed an algorithm to transform the tile set right into a vector map, which may then be collided utilizing arithmetic, making a second vector from the place on the final body and the place within the present bodyYou are able to do a comparability to see if the 2 traces collide, proper?

Effectively, sure, however probably not. Floating level errors trigger the collision to easily not be recorded beneath sure circumstances. For context, I offered the next collision algorithm:

    def vectorcollide(self,vector,line):
    #calculate the slopes of each traces
    #get offset of perform. If it's a vertical line, offset behaves barely totally different: it's the x worth.
    strive:
        moveslope = (vector(0)(1)-vector(1)(1))/(vector(0)(0)-vector(1)(0))
        moveoffset = vector(0)(1)-moveslope*vector(0)(0)
    besides ZeroDivisionError:
        moveslope = "cringe"
        moveoffset = vector(0)(0)
    strive:
        lineslope = (line(0)(1)-line(1)(1))/(line(0)(0)-line(1)(0))
        lineoffset = line(0)(1)-lineslope*line(0)(0)
    besides ZeroDivisionError:
        lineslope = "cringe"
        lineoffset = line(0)(0)
    textual content = pygame.font.SysFont("Comedian Sans MS", 100)
    state.show.blit(textual content.render(f"{lineslope}", 0, (255,0,0)),(line(0)(0),line(0)(1)))
        
    #discover level that may lie on each traces in the event that they have been infinite
    if lineslope == "cringe":
        if moveslope == "cringe":
            #particular contingency if each traces are vertical
            if lineoffset == moveoffset:
                if line(0)(1)>=vector(0)(1) and line(0)(1)<=vector(1)(1):
                    return (lineoffset,line(0)(1))
                elif line(1)(1)>=vector(0)(1) and line(1)(1)<=vector(1)(1):
                    return (lineoffset,line(0)(1))
                else:
                    return None
            else:
                return None
        else:
            y = lineoffset*moveslope+moveoffset
            level = (lineoffset,y)
            #if level is definitely in each traces:
            if (level(1) <= line(0)(1) and level(1) >= line(1)(1)) or (level(1) >= line(0)(1) and level(1) <= line(1)(1)):
                if (level(1) <= vector(0)(1) and level(1) >= vector(1)(1)) or (level(1) >= vector(0)(1) and level(1) <= vector(1)(1)):
                    if (level(0) <= line(0)(0) and level(0) >= line(1)(0)) or (level(0) >= line(0)(0) and level(0) <= line(1)(0)):
                        if (level(0) <= vector(0)(0) and level(0) >= vector(1)(0)) or (level(0) >= vector(0)(0) and level(0) <= vector(1)(0)):
                            #return that time
                            return level
            return None

    else:
        if moveslope == "cringe":
            #particular contingency for vertical moveslope
            if moveoffset <= line(0)(0) and moveoffset >= line (1)(0) or moveoffset >= line(0)(0) and moveoffset <= line (1)(0):
                y = moveoffset*lineslope+lineoffset
                if (y <= vector(0)(1) and y >= vector(1)(1)) or (y >= vector(0)(1) and y <= vector(1)(1)):
                    return (moveoffset,y)
                else:
                    return None
            else:
                return None
        else:
            if moveslope == lineslope:
                #particular contingency for 2 traces with the identical slope
                if moveoffset == lineoffset:
                    xtru,ytru = False,False
                    if (line(0)(1)>=vector(0)(1) and line(0)(1)>=vector(1)(1))or(line(1)(1)>=vector(0)(1) and line(1)(1)>=vector(1)(1)):
                        ytru = True
                    if (line(0)(0)>=vector(0)(0) and line(0)(0)>=vector(1)(0))or(line(1)(0)>=vector(0)(0) and line(1)(0)>=vector(1)(0)):
                        xtru = True
                    if xtru and ytru:
                        return (vector(1))
                    else:
                        return None
                else:
                    return None
            else:
                x = (lineoffset-moveoffset)/(moveslope-lineslope)
                #contingency plan for horizontal traces
                if lineslope == 0:
                    y = line(0)(1)
                else:
                    y = moveslope*x+moveoffset
                level = (x,y)
                #pygame.draw.rect(state.show,(0,255,0), (level(0)-8,level(1)-8,16,16))
                #if level is definitely in each traces:
                if (level(1) <= line(0)(1) and level(1) >= line(1)(1)) or (level(1) >= line(0)(1) and level(1) <= line(1)(1)):
                    if (level(1) <= vector(0)(1) and level(1) >= vector(1)(1)) or (level(1) >= vector(0)(1) and level(1) <= vector(1)(1)):
                        if (level(0) <= line(0)(0) and level(0) >= line(1)(0)) or (level(0) >= line(0)(0) and level(0) <= line(1)(0)):
                            if (level(0) <= vector(0)(0) and level(0) >= vector(1)(0)) or (level(0) >= vector(0)(0) and level(0) <= vector(1)(0)):
                                #return that time
                                return level
                #by default, return nothing
                return None

At this level, I’ve limped the system by working the outdated tile-based system after the vector-based one, thus choosing up any slack (there are nonetheless some buggy collisions, nevertheless it’s higher than nothing ™).

Which brings me to my query: How do different individuals, particularly these within the business, clear up these issues? I’ve seen ideas about including a margin of error to collisions, however the quantity of multiplication and division concerned would in all probability imply that the margin must be fairly massive.

Others within the business should have methods to beat this – they’ve been utilizing vectors to collide for years. So what is the trick?

EDIT: As per @DMGregory’s request, I added some further context. Moreover, it has given me good floor to begin from. this challenge… however not all video games use a tiling system, particularly 3D ones! So I am nonetheless open to any recommendation individuals may give me on how such a factor is often performed, which I can use in later tasks.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles