I am making a sport (shocker) in pygame and had points with tile-based collision detection. Merely put, adjusting for deltatime was permitting the participant to part via objects they actually should not have. So, I developed an algorithm to transform the set of tiles to a map of vectors, which might then be collided with utilizing math–by making a second vector from the place on the final body and the place on the present body, a comparability might be run to see if the 2 strains collide, proper?
Properly, sure however truly no. Floating level errors trigger collision below sure circumstances to easily not register. For context, I’ve supplied the collision algorithm beneath:
def vectorcollide(self,vector,line):
#calculate the slopes of each strains
#get offset of operate. If it's a vertical line, offset behaves barely completely 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 strains in the event that they have been infinite
if lineslope == "cringe":
if moveslope == "cringe":
#particular contingency if each strains are vertical
if lineoffset == moveoffset:
if line[0][1]>=vector[0][1] and line[0][1]=vector[0][1] and line[1][1]= line[1][1]) or (level[1] >= line[0][1] and level[1] = vector[1][1]) or (level[1] >= vector[0][1] and level[1] = line[1][0]) or (level[0] >= line[0][0] and level[0] = vector[1][0]) or (level[0] >= vector[0][0] and level[0] = line [1][0] or moveoffset >= line[0][0] and moveoffset = vector[1][1]) or (y >= vector[0][1] and y =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 strains
if lineslope == 0:
y = line[0][1]
else:
y = moveslope*x+moveoffset
level = (x,y)
#pygame.draw.rect(state.show,(0,255,0), [point[0]-8,level[1]-8,16,16])
#if level is definitely in each strains:
if (level[1] = line[1][1]) or (level[1] >= line[0][1] and level[1] = vector[1][1]) or (level[1] >= vector[0][1] and level[1] = line[1][0]) or (level[0] >= line[0][0] and level[0] = vector[1][0]) or (level[0] >= vector[0][0] and level[0]
Proper now, I’ve kind of made the system limp alongside by working the outdated tile-based system after the vector-based one, thus selecting up any slack (there are nonetheless some buggy collisions, however it’s higher than nothing(tm)).
Which brings me to my query: How do different folks, particularly these within the business, clear up these issues? I’ve seen solutions about including a margin of error to the collisions, however the variety of multiplications and divisions at play would possible imply 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?