Home > other >  How to calculate distance from a player to a dynamic collision point
How to calculate distance from a player to a dynamic collision point

Time:12-03

I'm trying to create sensors for a car to keep track of the distances from the car to the borders of the track. My goal is to have 5 sensors (see image below) and use them to train a machine learning algorithm.

But I can't figure out a way to calculate these distances. For now, I just need a sample of code and a logical explanation of how to implement this with PyGame. But a mathematical and geometrical explanation would be really nice as well for further reading. I'm using enter image description here

I've tried different approaches to this problem, but for now, my biggest problem is how to get the position of the blue dots:

sensors position

--- Edit from the feedback ------

I added a new paragraph to better explain the problem. This way I hope it is clearer why this problem is different from those said to be related to it. The other problem we have the desired final position (mouse or enemy) in this one we have to figure out which point is the one we are going to use to create the line, and this is my issue.

My GitHub repo of the project enter image description here

As we can see when the bullet hits the wall we can create a line that connects the point to the car. This is not the best solution, as it takes time for the bullet to hit the wall and in the meantime, the car is "blind".

As Rabbid76 commented, using raycasting may be the solution I was looking for.

Code for reference:

Sensor Bullet class

class SensorBullet:
    def __init__(self, car, base_angle, vel, color):
        self.x = car.x   CAR_WIDTH/2
        self.y = car.y   CAR_HEIGHT/2
        self.angle = car.angle
        self.base_angle = base_angle
        self.vel = vel
        self.color = color
        self.img = pygame.Surface((4, 4))
        self.fired = False
        self.hit = False
        self.last_poi = None

    def draw(self, win):
        pygame.draw.circle(win, self.color, (self.x, self.y), 2)

    def fire(self, car):
        self.angle = car.angle   self.base_angle
        self.x = car.x   CAR_WIDTH/2
        self.y = car.y   CAR_HEIGHT/2
        self.fired = True
        self.hit = False

    def move(self):
        if(self.fired):
            radians = math.radians(self.angle)
            vertical = math.cos(radians) * self.vel
            horizontal = math.sin(radians) * self.vel

            self.y -= vertical
            self.x -= horizontal

    def collide(self, x=0, y=0):
        bullet_mask = pygame.mask.from_surface(self.img)
        offset = (int(self.x - x), int(self.y - y))
        poi = TRACK_BORDER_MASK.overlap(bullet_mask, offset)
        if poi:
            self.fired = False
            self.hit = True
            self.last_poi = poi
        return poi

    def draw_line(self, win, car):
        if self.hit:
            pygame.draw.line(win, self.color, (car.x   CAR_WIDTH/2, car.y   CAR_HEIGHT/2), (self.x, self.y), 1)
            pygame.display.update()

    def get_distance_from_poi(self, car):
        if self.last_poi is None:
            return -1
        return math.sqrt((car.x - self.last_poi[0])**2   (car.y - self.last_poi[1])**2)

Methods the car must perform to use the sensor

# Inside car's __init__ method
self.sensors = [SensorBullet(self, 25, 12, (100, 0, 255)), SensorBullet(self, 10, 12, (200, 0, 255)), SensorBullet(self, 0, 12, (0, 255, 0)), SensorBullet(self, -10, 12, (0, 0, 255)), SensorBullet(self, -25, 12, (0, 0, 255))]
# ------

# Cars methods
def fireSensors(self): 
    for bullet in self.sensors:
        bullet.fire(self)

def sensorControl(self):
    #print(contains(self.sensors, lambda x: x.hit))

    for bullet in self.sensors:
        if not bullet.fired:
            bullet.fire(self)

    for bullet in self.sensors:
        bullet.move()

def get_distance_array(self):
    return [bullet.get_distance_from_poi(self) for bullet in self.sensors]

  • Related