Python Forum
[PyGame] Keeping the player within a polygon
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Keeping the player within a polygon
#1
Hi, I'm trying to implement a polygonal boundary to stop the player from leaving the polygon. The player uses a circular collider. I've looked around online and haven't found anything that really helps. Below is a simple example of what I've got so far. If anyone can help explain an algorithm or at least provide a link to something that might help I would greatly appreciate it.

"""Circle with a polygonal boundary"""
import pygame as pg

pg.init()

display = pg.display.set_mode((1024, 768))

edge_poly = [(10, 10), (400, 10), (350, 300), (150, 400)]
player_pos = pg.Vector2(100, 50)
player_radius = 15
player_speed = .2

running = True
while running:
    # events
    for event in pg.event.get ():
        if event.type == pg.QUIT:
            running = False

    keys_down = pg.key.get_pressed()
    if keys_down[pg.K_w]:
        player_pos.y -= player_speed
    if keys_down[pg.K_s]:
        player_pos.y += player_speed
    if keys_down[pg.K_a]:
        player_pos.x -= player_speed
    if keys_down[pg.K_d]:
        player_pos.x += player_speed
    # updates

    # drawing
    display.fill((255, 255, 255))
    pg.draw.polygon(display, (0, 0, 0), edge_poly, 1)
    pg.draw.circle(display, (0, 0, 0), player_pos, player_radius)
    pg.display.update()

pg.quit()
quit()
Again thanks for taking the time to read, I appreciate any help you guys can offer.
Reply
#2
As is you do not have any collision detection whatsoever in your example. Your player is just drawn and not an object. Same as your boundary line, it is just drawn and not an object.

First i would make the player an object with a rect collsiion detection and work from there on. Then detail it further for circular. With the boundary, i would create it as an object with its specified coordinates and identify the lines between them to create collision detection upon those lines.
Recommended Tutorials:
Reply
#3
Thanks for your response. In the actual game I'm making I've got aabb collisions working, I understand that the code I posted is just drawing them and there's no collision detection in place yet. The example was just meant to be a visual that someone could add the collision code to if they wanted to. Sorry for being unclear but I think I can figure it out now, like you said it's just collisions between a circle and a series of lines and I've found some examples already on how to implement that. I appreciate the reply, hope you have a good day ^_^
Reply
#4
Sorry, i assumed you only had this code and nothing else. Sometimes people do not understand the concept that pygame.draw does not accommodate for collision detection by itself and assumes that things should just work out the way they expect without additional code.
Atekka likes this post
Recommended Tutorials:
Reply
#5
If you use this function, it will give you the list of points that makeup your boundary.

def cast_ray(start, end):
    start_x, start_y = start
    end_x, end_y = end
    # y = mx + b
    # or, using words since we're not barbarians...
    # y = (slope * x) + y_intercept

    # add a small nudge to x, to avoid dividing by zero
    x_diff = start_x - end_x + 0.01
    slope = (start_y - end_y) / x_diff
    #    print(start, end, slope)
    # y_intercept = y - (slope * x)
    y_intercept = start_y - (slope * start_x)

    points = set()
    min_x = min(start_x, end_x)
    max_x = max(start_x, end_x)
    #  print(min_x, max_x, y_intercept)
    for x in range(min_x, max_x):
        y = (slope * x) + y_intercept
        points.add((x, round(y)))

    min_y = min(start_y, end_y)
    max_y = max(start_y, end_y)
    for y in range(int(min_y),int(max_y)):
        x = (y - y_intercept) / slope
        points.add((round(x), y))
    return list(points)
Give your player a pygame.Rect(), and then loop over the list to see if those points are within the player rect.
for point in list_of_points:
    if player_rect.collidepoint(point):
        collision = True
Atekka and metulburr like this post
Reply
#6
Thank you michael, that helps out. I'm just unsure how to correct the position of the player upon collision but I'm sure I can find a way to do it. I appreciate the help.
Reply
#7
Try moving the player, check for collision, and it there is move the player back to where it was.
Atekka likes this post
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020