pythondebuggingcollision-detectionpython-turtlepacman

I am trying to make the Pac-Man game using only turtle random and math module


I am having trouble when Pac-Man collides with the wall. I have inputted a maze and using a for loop, I have drawn the maze. The Pac-Man movement is all working fine as well, but when it hits a wall, I want it to stop.

How can I make it stop and then wait for the user's input to switch directions using keys?

I tried using a variable to say it stopped and it would stop, but it wouldn’t respond to any of the keys I would input for it to move again.

import turtle

maze = [
"XXXXXXXXXXXXXXXXXXXXXXXXX",
"XP  XXXXXXXE           XX",
"X  XXXXXXX  XXXXXX  XXXXX",
"X       XX  XXXXXX  XXXXX",
"X       XX  XXX       EXX",
"XXXXXX  XX  XXX        XX",
"XXXXXX  XX  XXXXXX  XXXXX",
"XXXXXX  XX    XXXX  XXXXX",
"X  XXX        XXXX  XXXXX",
"X  XXX  XXXXXXXXXXXXXXXXX",
"X         XXXXXXXXXXXXXXX",
"X                XXXXXXXX",
"XXXXXXXXXXXX     XXXXX  X",
"XXXXXXXXXXXXXXX  XXXXX  X",
"XXX  XXXXXXXXXX         X",
"XXXE                    X",
"XXX         XXXXXXXXXXXXX",
"XXXXXXXXXX  XXXXXXXXXXXXX",
"XXXXXXXXXX              X",
"XX   XXXXX              X",
"XX   XXXXXXXXXXXXX  XXXXX",
"XX    YXXXXXXXXXXX  XXXXX",
"XX          XXXX        X",
"XXXXE                   X",
"XXXXXXXXXXXXXXXXXXXXXXXXX"
]

def move():
    if player.direction == "right":
        player.setx(player.xcor() + 7)
    if player.direction == "left":
        player.setx(player.xcor() - 7)
    if player.direction == "up":
        player.sety(player.ycor() + 7)
    if player.direction == "down":
        player.sety(player.ycor() - 7)

def right():
    player.direction = "right"

def left():
    player.direction = "left"

def up():
    player.direction = "up"

def down():
    player.direction = "down"

def exit():
    turtle.bye()

screen = turtle.Screen()
screen.bgcolor("black")
screen.setup(900, 900)
screen.tracer(n=0)
walllist = []
x = -365
y = 360

for r in maze:
    for h in r:
        if h == "X":
            wall = turtle.Turtle()
            wall.color("blue")
            wall.shapesize(1.43, 1.43, 1)
            wall.shape("square")
            wall.penup()
            wall.goto(x, y)
            walllist.append(wall)
        if h == "P":
            player = turtle.Turtle()
            player.speed(0)
            player.color("yellow")
            player.shape("circle")
            player.penup()
            player.direction = "stop"
            player.goto(x, y)
        x += 30
    x = -365
    y -= 30


screen.listen()
screen.onkey(right, "Right")
screen.onkey(up, "Up")
screen.onkey(down, "Down")
screen.onkey(left, "Left")
screen.onkey(exit, "Escape")

while True:
    move()
    screen.update()
    for wall in walllist:
        if player.distance(wall) < 29:
            player.direction = "stop"

Solution

  • If you move the screen update below the for loop the pacman will keep responding to moves after hitting a wall:

    while True:
      move()
      for wall in walllist:
        if player.distance(wall)<29:
          player.direction="stop"
      screen.update()
    

    Note however that the pacman won't move freely if it's grasping a wall but it will "drag", resulting in you having to hit the direction keys repeatedly for it to move. Worse, the pacman will be able to enter the walls. All this, of course, is directly related to how you wrote the algorithm to detect and, more importantly, approve the next move. Specifically, the criterion layer.distance(wall)<29 makes reference to the distance to the wall irrespective of the direction along which the pacman moves. This requires another way to think about it.