Search code examples
pythonpython-turtle

Python Game Using Turtle Not PyGame: Error Message


I'm in the beginning stages of making a sort of bumper cars game for Python using turtle. I have created the following code this far, and this code is JUST for the creation of the "bumper" turtles. I'm trying to make these turtles spawn randomly on the screen within the range listed (they all appear in the middle and I can't figure out why), and I'm trying to make it so that they move about randomly and stay within the boundary I listed (if not, return to 0,0). However, they don't move and they spawn in the middle. This is the only code I've created this far, and I'm also not sure how to create an obstacle type code so that when they run into the main turtle the user will be able to control (not yet implemented or attempted), they disappear off the screen. Any help with my current issue or tips for my goal would be greatly appreciated! However, when I run this code, I get the error message:

TypeError: check_boundary() takes 0 positional arguments but 1 was given

Anyways, here is my code this far:

import turtle
import random
from random import randint

class BumperTurtles():
    def __init__(bumper, name, color):
        bumper.color = color
        bumper.turtle = turtle.Turtle()
        bumper.turtle.shape("classic")
        bumper.turtle.color(bumper.color)
        bumper.turtle.speed(100)
        bumper.turtle.pd()
#Having them spawn within the desired range:
        x = random.randint (-150, 150)
        y = random.randint (-150, 150)

#Making sure they don't move out of bounds
    def check_boundary():
        if (-300 <= prey.xcor() <= 300 and -300 <= prey.ycor() <=300):
            return
        prey.goto(0, 0)

    def move(bumper):
        bumper.turtle.penup()
        turn = randint(0,2)
        if turn == 1:
            bumper.turtle.lt(45)
        elif turn == 2:
            bumper.turtle.rt(45)
        bumper.turtle.forward(5)

#Creating my bumper turtles
turtles = []
turtles.append(BumperTurtles('bump1', 'blue'))
turtles.append(BumperTurtles('bump2', 'blue'))
turtles.append(BumperTurtles('bump3', 'blue'))
turtles.append(BumperTurtles('bump4', 'blue'))
turtles.append(BumperTurtles('bump5', 'blue'))
turtles.append(BumperTurtles('bump6', 'blue'))
turtles.append(BumperTurtles('bump7', 'blue'))
turtles.append(BumperTurtles('bump8', 'blue'))

#Calling for them to move
ok = True
while ok:
    for t in turtles:
        t.move()
        if t.check_boundary():
            t.goto(0,0)
            ok = False

Solution

  • Your code is never going to work the way you're going about this. You test the result of check_boundary() which doesn't return anything; you refer to a prey variable that doesn't exist (even if you make it the argument, it will fail on the xcor() call); you pass a random value to the speed() method; you compute the bumper turtle's x and y position but fail to use them; etc.

    Let's take your program apart and put it back together as something you can actually run and watch the random progression of your bumper turtles:

    from turtle import Screen, Turtle
    from random import choice, randint
    
    class BumperTurtle(Turtle):
        def __init__(self, name, color):
            super().__init__(shape='classic', visible=False)
    
            self.color(color)
            self.speed('fastest')
            self.penup()
    
            x = randint(-150, 150)
            y = randint(-150, 150)
    
            self.goto(x, y)
            self.showturtle()
    
        def inside_boundary(self):
            return -300 <= self.xcor() <= 300 and -300 <= self.ycor() <= 300
    
        def move(self):
            angle = choice([-45, 0, 45])
            self.right(angle)
            self.forward(5)
    
    def bump():
        for bumper in bumpers:
            bumper.move()
            if not bumper.inside_boundary():
                bumper.goto(0, 0)
    
        screen.update()
        screen.ontimer(bump, 100)
    
    bumpers = []
    bumpers.append(BumperTurtle('bump1', 'blue'))
    bumpers.append(BumperTurtle('bump2', 'blue'))
    bumpers.append(BumperTurtle('bump3', 'blue'))
    bumpers.append(BumperTurtle('bump4', 'blue'))
    bumpers.append(BumperTurtle('bump5', 'blue'))
    bumpers.append(BumperTurtle('bump6', 'blue'))
    bumpers.append(BumperTurtle('bump7', 'blue'))
    bumpers.append(BumperTurtle('bump8', 'blue'))
    
    screen = Screen()
    screen.tracer(False)
    
    bump()
    
    screen.mainloop()
    

    Note that I've changed BumperTurtle from containing a turtle to instead being a turtle subclass. I replaced your while True: loop with a proper timer event. I switched to the conventional self argument for your methods. I turned off tracing and added update() to get increase the graphics performance so that it has a real bumper car feel -- you can adjust the speed by adjusting the second argument to ontimer() which is the time between calls in milliseconds.