Is there a way to allow the player to slide along the walls? I am making a 2D FPS game and the player needs to be able to move swiftly around the map. In order to do this I need the player to slide along the walls (to allow for faster and easier gameplay) but I have no clue on how to do that. I have attempted some solutions but all of them still "stuck" to the walls. Is there any way to do this? Assets: gunImg.png Code: ############################################################################## import pygame import math ####################################### pygame.init() X, Y = 800, 800 DISPLAY = pygame.display.set_mode((X, Y)) clock = pygame.time.Clock() FPS = 60 pygame.display.set_caption("2D First Person Shooter") white = (255, 255, 255) black = (0, 0, 0) grey = (128, 128, 128) red = (255, 0, 0) ############################################################################## def renderPlayer(playerXY, gunImg, mouseXY): playerRect = pygame.draw.circle(DISPLAY, white, playerXY, 10) dx, dy = mouseXY[0]-playerRect.centerx, mouseXY[1]-playerRect.centery angle = math.degrees(math.atan2(-dy, dx))-90 rotatedImg = pygame.transform.rotate(gunImg, angle) rotatedImgRect = rotatedImg.get_rect(center=playerRect.center) DISPLAY.blit(rotatedImg, rotatedImgRect.topleft) return playerRect ####################################### def renderObjects(map, mapDimensions): wallRects = [] for tile in range(len(map)): if map[tile] == 1: wallRects.append(pygame.Rect((tile%mapDimensions[0])*X/mapDimensions[0], (tile//mapDimensions[1])*Y/mapDimensions[1], X/mapDimensions[0], Y/mapDimensions[1])) return wallRects ####################################### def checkCollisions(playerRect, nextPlayerXY, wallRects): tempRect = playerRect.copy() tempRect.center = nextPlayerXY for rect in wallRects: if tempRect.colliderect(rect): return True return False ####################################### def DDA(targetX, targetY): targetX /= cellSize targetY /= cellSize rayStartX, rayStartY = (playerXY[0]/cellSize), (playerXY[1]/cellSize) rayDirX = (targetX-(playerXY[0]/cellSize)) rayDirY = (targetY-(playerXY[1]/cellSize)) rayDirLen = math.sqrt((rayDirX**2)+(rayDirY**2)) if rayDirLen != 0: rayDirX /= rayDirLen rayDirY /= rayDirLen rayUnitStepX = math.sqrt(1+(rayDirY/rayDirX)**2) if rayDirX != 0 else float('inf') rayUnitStepY = math.sqrt(1+(rayDirX/rayDirY)**2) if rayDirY != 0 else float('inf') mapCheckX, mapCheckY = int(rayStartX), int(rayStartY) rayLengthX, rayLengthY = 0, 0 stepX, stepY = 0, 0 if rayDirX < 0: stepX = -1 rayLengthX = (rayStartX-mapCheckX)*rayUnitStepX else: stepX = 1 rayLengthX = (mapCheckX+1-rayStartX)*rayUnitStepX if rayDirY < 0: stepY = -1 rayLengthY = (rayStartY-mapCheckY)*rayUnitStepY else: stepY = 1 rayLengthY = (mapCheckY+1-rayStartY)*rayUnitStepY tileFound = False maxDistance = 100 distance = 0 while not tileFound and distance < maxDistance: if rayLengthX < rayLengthY: mapCheckX += stepX distance = rayLengthX rayLengthX += rayUnitStepX else: mapCheckY += stepY distance = rayLengthY rayLengthY += rayUnitStepY if 0 <= mapCheckX < mapDimensions[0] and 0 <= mapCheckY < mapDimensions[1]: if map[(mapCheckY*mapDimensions[0])+mapCheckX] == 1: tileFound = True intersectionX, intersectionY = 0, 0 if tileFound: intersectionX = rayStartX+(rayDirX*distance) intersectionY = rayStartY+(rayDirY*distance) return intersectionX*cellSize, intersectionY*cellSize ####################################### #def fireBullet(playerXY, bullets): ############################################################################## playerXY = [375, 375] playerSpeed = 180/FPS map = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ] mapDimensions = (16, 16) cellSize = int(X/mapDimensions[0]) gunImg = pygame.image.load("Assets\gun.png") gunImg = pygame.transform.smoothscale(gunImg, (40, 40)) playerRect = renderPlayer(playerXY, gunImg, (0, 0)) ####################################### while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() heldKeys = pygame.key.get_pressed() mouseXY = pygame.mouse.get_pos() if heldKeys[pygame.K_w] or heldKeys[pygame.K_s]: directionX = mouseXY[0]-playerRect.centerx directionY = mouseXY[1]-playerRect.centery distance = math.hypot(directionX, directionY) if distance > 1: normalizedDX = directionX/distance normalizedDY = directionY/distance if heldKeys[pygame.K_w]: nextPlayerXY = [playerXY[0]+normalizedDX*playerSpeed, playerXY[1]+normalizedDY*playerSpeed] elif heldKeys[pygame.K_s]: nextPlayerXY = [playerXY[0]-normalizedDX*playerSpeed, playerXY[1]-normalizedDY*playerSpeed] if not checkCollisions(playerRect, nextPlayerXY, wallRects): playerXY = nextPlayerXY if heldKeys[pygame.K_a]: angleToMouse = math.atan2(mouseXY[1]-playerXY[1], mouseXY[0]-playerXY[0]) moveAngle = angleToMouse+math.pi/2 moveX = playerSpeed*math.cos(moveAngle) moveY = playerSpeed*math.sin(moveAngle) nextPlayerXY = [playerXY[0]+moveX, playerXY[1]+moveY] if not checkCollisions(playerRect, nextPlayerXY, wallRects): playerXY = nextPlayerXY if heldKeys[pygame.K_d]: angleToMouse = math.atan2(mouseXY[1]-playerXY[1], mouseXY[0]-playerXY[0]) moveAngle = angleToMouse-math.pi/2 moveX = playerSpeed*math.cos(moveAngle) moveY = playerSpeed*math.sin(moveAngle) nextPlayerXY = [playerXY[0]+moveX, playerXY[1]+moveY] if not checkCollisions(playerRect, nextPlayerXY, wallRects): playerXY = nextPlayerXY DISPLAY.fill(black) wallRects = renderObjects(map, mapDimensions) intersectionsPoints = [] for x in range(0, X): # Top intersectionsPoints.append(DDA(x, 0)) for y in range(0, Y): # Right intersectionsPoints.append(DDA(X, y)) for x in range(0, X): # Bottom intersectionsPoints.append(DDA(X-x, Y)) for y in range(0, Y): # Left intersectionsPoints.append(DDA(0, Y-y)) pygame.draw.polygon(DISPLAY, white, intersectionsPoints, 1) #rayDistances = [] #for rayEnd in intersectionsPoints: # rayDistances.append(math.dist(playerXY, rayEnd)) playerRect = renderPlayer(playerXY, gunImg, mouseXY) pygame.display.update() clock.tick(FPS) ############################################################################## Continue reading...