Im a coding beginner who just got into python turtle. I have recently been working on a project where you control 2 characters. They are trying to shoot each other over a river. But i ran into an error where whenever one side fires a bullet and then the other one does aswell, the first bullet just freezes in place until the first one is finished. This ruins the entire game. Ive seen other posts with this "if name = main" thing but i dont understand it.
I have worked out that this is due to a function being called while another is still running. Ive tried multithreading it but it did not work and im way too much of a beginner to understand this. If someone could give me an explanation on how to fix this i would be very happy. (Yes the code is in german but the names of the variables dont really matter).
import turtle
sieg_1 = 0
sieg_2 = 0
kugel1speed = 4
kugel2speed = 4
screen = turtle.Screen()
screen.title("Paintball River")
screen.bgcolor("darkgreen")
screen.setup(width=800, height=600)
#wasd / links
character1 = turtle.Turtle()
character1.shape("square")
character1.color("mediumblue")
character1.speed(0)
character1.penup()
character1.goto(-200,0)
#pfeiltasten / rechts
character2 = turtle.Turtle()
character2.shape("square")
character2.color("red")
character2.speed(0)
character2.penup()
character2.goto(200, 0)
####################################################################
randkröte = turtle.Turtle()
randkröte.shape("square")
randkröte.color("grey")
randkröte.speed(100)
randkröte.pencolor("grey")
randkröte.pensize(30)
randkröte.penup()
randkröte.goto(386,0)
randkröte.pendown()
randkröte.left(90)
randkröte.forward(285)
randkröte.left(90)
randkröte.forward(772)
randkröte.left(90)
randkröte.forward(571)
randkröte.left(90)
randkröte.forward(790)
randkröte.penup()
randkröte.goto(386,-300)
randkröte.left(90)
randkröte.pendown()
randkröte.forward(400)
randkröte.penup()
randkröte.goto(-400,300)
randkröte.pendown()
randkröte.forward(1)
flusskröte = turtle.Turtle()
flusskröte.shape("square")
flusskröte.color("royalblue")
flusskröte.speed(100)
flusskröte.pencolor("royalblue")
flusskröte.pensize(179)
flusskröte.penup()
flusskröte.goto(0,-400)
flusskröte.pendown()
flusskröte.left(90)
flusskröte.forward(800)
###################################################################################
def schießen1():
x1 = character1.xcor()
y1 = character1.ycor()
kugely1 = kugel1.ycor()
if kugely1 == 330:
kugel1.teleport(x1,y1)
kugel1.goto(365,y1)
def schießen2(x,y):
x2 = character2.xcor()
y2 = character2.ycor()
kugely2 = kugel2.ycor()
if kugely2 == 350:
kugel2.teleport(x2,y2)
kugel2.goto(-365,y2)
kugel1 = turtle.Turtle()
kugel1.speed(kugel1speed)
kugel1.color("darkblue")
kugel1.shape("circle")
kugel1.shapesize(0.5)
kugel1.penup()
kugel1.hideturtle()
kugel1.goto(0,330)
kugel1.showturtle()
kugel2 = turtle.Turtle()
kugel2.speed(kugel2speed)
kugel2.color("darkred")
kugel2.shape("circle")
kugel2.shapesize(0.5)
kugel2.penup()
kugel2.hideturtle()
kugel2.goto(0,350)
kugel2.showturtle()
######################################################################################
speed = 20
def hoch1():
y = character1.ycor()
if y < 260:
character1.sety(y + speed)
def runter1():
y = character1.ycor()
if y > -260:
character1.sety(y - speed)
def links1():
x = character1.xcor()
if x > -350:
character1.setx(x - speed)
def rechts1():
x = character1.xcor()
if x < -100:
character1.setx(x + speed)
def hoch2():
y = character2.ycor()
if y < 260:
character2.sety(y + speed)
def runter2():
y = character2.ycor()
if y > -260:
character2.sety(y - speed)
def links2():
x = character2.xcor()
if x > 100:
character2.setx(x - speed)
def rechts2():
x = character2.xcor()
if x < 350:
character2.setx(x + speed)
screen.listen()
screen.onkeypress(screen.bye, "Escape")
screen.onkeyrelease(hoch2, "Up")
screen.onkeyrelease(runter2, "Down")
screen.onkeyrelease(links2, "Left")
screen.onkeyrelease(rechts2, "Right")
screen.onkeyrelease(hoch1, "w")
screen.onkeyrelease(runter1, "s")
screen.onkeyrelease(links1, "a")
screen.onkeyrelease(rechts1, "d")
screen.onkeyrelease(schießen1,"e")
screen.onscreenclick(schießen2)
######################################################################################
while True:
screen.update()
kugelx1 = kugel1.xcor()
kugelx2 = kugel2.xcor()
if kugelx1 == 365:
kugel1.teleport(0,330)
if kugelx2 == -365:
kugel2.teleport(0,350)
One common approach is to use multiprocess, but since said you dont want mutlithread since beginner level i assume you don't like that approach.
Second approach coul be by making bullets to move bit by bit. Currently it looks like an instant translate for bullets.
Trying smaller steps in each iteration of main game while loop allows bullet movement appear like they move in parallel instead of freezing
So to achieve this we have two flags for flight of each bullet. if bullet is on flight it moves slightly.
import turtle
sieg_1 = 0
sieg_2 = 0
kugel1speed = 4
kugel2speed = 4
screen = turtle.Screen()
screen.title("Paintball River")
screen.bgcolor("darkgreen")
screen.setup(width=800, height=600)
# wasd / links
character1 = turtle.Turtle()
character1.shape("square")
character1.color("mediumblue")
character1.speed(0)
character1.penup()
character1.goto(-200, 0)
# pfeiltasten / rechts
character2 = turtle.Turtle()
character2.shape("square")
character2.color("red")
character2.speed(0)
character2.penup()
character2.goto(200, 0)
# Field boundaries
randkröte = turtle.Turtle()
randkröte.shape("square")
randkröte.color("grey")
randkröte.speed(100)
randkröte.pencolor("grey")
randkröte.pensize(30)
randkröte.penup()
randkröte.goto(386, 0)
randkröte.pendown()
randkröte.left(90)
randkröte.forward(285)
randkröte.left(90)
randkröte.forward(772)
randkröte.left(90)
randkröte.forward(571)
randkröte.left(90)
randkröte.forward(790)
randkröte.penup()
randkröte.goto(386, -300)
randkröte.left(90)
randkröte.pendown()
randkröte.forward(400)
randkröte.penup()
randkröte.goto(-400, 300)
randkröte.pendown()
randkröte.forward(1)
flusskröte = turtle.Turtle()
flusskröte.shape("square")
flusskröte.color("royalblue")
flusskröte.speed(100)
flusskröte.pencolor("royalblue")
flusskröte.pensize(179)
flusskröte.penup()
flusskröte.goto(0, -400)
flusskröte.pendown()
flusskröte.left(90)
flusskröte.forward(800)
# Bullet state flags
kugel1_on_flight = False
kugel2_on_flight = False
# Functions
def schießen1():
global kugel1_on_flight
if not kugel1_on_flight:
x1 = character1.xcor()
y1 = character1.ycor()
kugel1.goto(x1, y1)
kugel1_on_flight = True
def schießen2(x, y):
global kugel2_on_flight
if not kugel2_on_flight:
x2 = character2.xcor()
y2 = character2.ycor()
kugel2.goto(x2, y2)
kugel2_on_flight = True
kugel1 = turtle.Turtle()
kugel1.speed(kugel1speed)
kugel1.color("darkblue")
kugel1.shape("circle")
kugel1.shapesize(0.5)
kugel1.penup()
kugel1.hideturtle()
kugel1.goto(0, 330)
kugel1.showturtle()
kugel2 = turtle.Turtle()
kugel2.speed(kugel2speed)
kugel2.color("darkred")
kugel2.shape("circle")
kugel2.shapesize(0.5)
kugel2.penup()
kugel2.hideturtle()
kugel2.goto(0, 350)
kugel2.showturtle()
speed = 20
def hoch1():
y = character1.ycor()
if y < 260:
character1.sety(y + speed)
def runter1():
y = character1.ycor()
if y > -260:
character1.sety(y - speed)
def links1():
x = character1.xcor()
if x > -350:
character1.setx(x - speed)
def rechts1():
x = character1.xcor()
if x < -100:
character1.setx(x + speed)
def hoch2():
y = character2.ycor()
if y < 260:
character2.sety(y + speed)
def runter2():
y = character2.ycor()
if y > -260:
character2.sety(y - speed)
def links2():
x = character2.xcor()
if x > 100:
character2.setx(x - speed)
def rechts2():
x = character2.xcor()
if x < 350:
character2.setx(x + speed)
screen.listen()
screen.onkeypress(screen.bye, "Escape")
screen.onkeyrelease(hoch2, "Up")
screen.onkeyrelease(runter2, "Down")
screen.onkeyrelease(links2, "Left")
screen.onkeyrelease(rechts2, "Right")
screen.onkeyrelease(hoch1, "w")
screen.onkeyrelease(runter1, "s")
screen.onkeyrelease(links1, "a")
screen.onkeyrelease(rechts1, "d")
screen.onkeyrelease(schießen1, "e")
screen.onscreenclick(schießen2)
# Main game loop
while True:
screen.update()
# Update kugel1 position if on flight
if kugel1_on_flight:
kugel1.setx(kugel1.xcor() + 20) # Move right
if kugel1.xcor() >= 365: # Reset if out of bounds
kugel1.goto(0, 330)
kugel1_on_flight = False
# Update kugel2 position if on flight
if kugel2_on_flight:
kugel2.setx(kugel2.xcor() - 20) # Move left
if kugel2.xcor() <= -365: # Reset if out of bounds
kugel2.goto(0, 350)
kugel2_on_flight = False