Python Turtle code seems to be in an infinite loop - python

I want to make a code for turtles to conquer asteroids. But if you run the code, it falls into an infinite loop and doesn't work. Maybe the while part is the problem, but I don't know how to solve it. Please help me.
I'm so sorry for the long post because it's my first time posting.
I really want to fix the error. Thank you.
import turtle
import random
import math
player_speed = 2
score_num = 0
player = turtle.Turtle()
player.color('blue')
player.shape('turtle')
player.up()
player.speed(0)
screen = player.getscreen()
ai1_hide = False
ai1 = turtle.Turtle()
ai1.color('blue')
ai1.shape('circle')
ai1.up()
ai1.speed(0)
ai1.goto(random.randint(-300, 300), random.randint(-300, 300))
score = turtle.Turtle()
score.speed(0)
score.up()
score.hideturtle()
score.goto(-300,300)
score.write('score : ')
def Right():
player.setheading(0)
player.forward(10)
def Left():
player.setheading(180)
player.forward(10)
def Up():
player.setheading(90)
player.forward(10)
def Down():
player.setheading(270)
player.forward(10)
screen.onkeypress(Left, "Left")
screen.onkeypress(Right, "Right")
screen.onkeypress(Up, "Up")
screen.onkeypress(Down, "Down")
screen.listen()
Code thought to be an error :
while True:
distance = math.sqrt(math.pow(player.xcor() - ai1.xcor(), 2) + math.pow(player.ycor() - ai1.ycor(), 2))
if distance <= 20:
ai1.hideturtle()
score.clear()
if ai1_hide == False:
score_num += 1
ai1_hide = True
ai1.goto(0, 0)
score.write('score : ' + str(scoreNum))
if ai1.isvisible() != True:
break

You forgot to add update() method for screen
while True:
distance = math.sqrt(math.pow(player.xcor() - ai1.xcor(), 2) + math.pow(player.ycor() - ai1.ycor(), 2))
if distance <= 20:
ai1.hideturtle()
score.clear()
if ai1_hide == False:
score_num += 1
ai1_hide = True
ai1.goto(0, 0)
score.write('score : ' + str(scoreNum))
if not ai1.isvisible(): # boolean condition can also be simplified.
break
screen.update() # ADD this to your code

Add a variable
running = True
Then your loop can be
while running:
Over time you can change the variable so your loop can stop or the opposite.
Also, the break function won't work since your loop is a while true.

Related

Python Turtle becomes unresponsive and hangs after using a while loop

I'm trying to make a program that is essentially an etchasketck, with some minor tweaks for my school project(the required use of a main function, wasd as movement controls, and q to quit the program and p to pick up or drop down the turtle pen). I was testing this code in trinket.io and it was working fine. You can see it working there with this link: https://trinket.io/python/99fd3ec305. However, when I go to run it from pycharm, cmd, or the python IDLE, it always leaves the turtle hanging and unresponsive. I get no errors, just the turtle to pop up for a few seconds, then it hangs, and I'm unable to do anything.
Here's my code:
import sys
import turtle
arg_len = len(sys.argv)
# store length of arguments
if arg_len < 3:
print("Too less arguments, using default values..")
WIDTH = 200
HEIGHT = 200
else:
WIDTH = int(sys.argv[1])
HEIGHT = int(sys.argv[2])
screen = turtle.Screen()
screen.setup(WIDTH, HEIGHT)
# create a turtle instance
t = turtle.Turtle()
t.speed(0)
# slow down the turtle
# declare flags
move = False
exit_flag = False
def up():
global move
move = True
t.setheading(90)
def down():
global move
move = True
t.setheading(270)
def left():
global move
move = True
t.setheading(180)
def right():
global move
move = True
t.setheading(0)
# toggle pen up and down
def toggle_pen():
if t.isdown():
t.penup()
else:
t.pendown()
# set exit flag
def quit_program():
global exit_flag
exit_flag = True
def check_border():
if t.xcor() == WIDTH / 2:
t.penup()
t.setx(-WIDTH / 2)
elif t.xcor() == -WIDTH / 2:
t.penup()
t.setx(WIDTH / 2)
if t.ycor() == HEIGHT / 2:
t.penup()
t.sety(-HEIGHT / 2)
elif t.ycor() == -HEIGHT / 2:
t.penup()
t.sety(HEIGHT / 2)
def listen_keys():
screen.listen()
screen.onkey(up, "w")
screen.onkey(down, "s")
screen.onkey(left, "a")
screen.onkey(right, "d")
screen.onkey(toggle_pen, "p")
screen.onkey(quit_program, "q")
# main loop
def main():
listen_keys()
while not exit_flag:
global move
if move:
t.forward(0.5)
screen.update()
check_border()
else:
t.done()
main()
I'm using python 3.10, and I mainly use pycharm for the running.
I was trying to get the turtle to move indefinitly without user input after the first user input, I was going to achieve this with the while loop, but it just leaves my program unresponsive. Can anyone tell me what's wrong that I'm not seeing?
You've effectively put a while True: loop in an event-driven program where one should never be used. If I were writing this for the command line, with the constraints listed, I might go about it this way (dropping command line processing for example simplicity):
from turtle import Screen, Turtle
WIDTH, HEIGHT = 200, 200
def up():
turtle.setheading(90)
start_motion()
def down():
turtle.setheading(270)
start_motion()
def left():
turtle.setheading(180)
start_motion()
def right():
turtle.setheading(0)
start_motion()
def toggle_pen():
if turtle.isdown():
turtle.penup()
else:
turtle.pendown()
def quit_program():
screen.bye()
def check_border():
x, y = turtle.position()
if x >= WIDTH / 2:
turtle.penup()
turtle.setx(-WIDTH / 2)
elif x <= -WIDTH / 2:
turtle.penup()
turtle.setx(WIDTH / 2)
if y >= HEIGHT / 2:
turtle.penup()
turtle.sety(-HEIGHT / 2)
elif y <= -HEIGHT / 2:
turtle.penup()
turtle.sety(HEIGHT / 2)
def main():
screen.onkey(up, 'w')
screen.onkey(down, 's')
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.onkey(toggle_pen, 'p')
screen.onkey(quit_program, 'q')
screen.listen()
screen.mainloop()
def move():
turtle.forward(1)
check_border()
screen.ontimer(move, 25)
moving = False
def start_motion():
global moving
if not moving:
moving = True
move()
screen = Screen()
screen.setup(WIDTH, HEIGHT)
turtle = Turtle()
turtle.speed('fastest')
main()
See if this still works with trinket.io, IDLE and PyCharm, or if it can be made to do so.

How can I delay the onkey event until the function has finished executing

Basically I'm making a space invaders type game in python and for some reason, it's still allowing the user to press the spacebar no matter what I do. Therefore, I would like to see what kind of ideas you guys have since I have no idea what to do to make this work.
Also I have tried creating a delay variable so that if the delay variable is true then it will execute the onkey event but unfortunately it didn't work.
I have also tried making the both the function and the onkey sleep via the time library but also didn't work
import turtle
# Making the window and its proporties
wn = turtle.Screen()
wn.title("Galaxy Wars")
wn.bgcolor("black")
# adding the images to the shape function so that it will recongize them as a shape
turtle.register_shape("Spaceship.gif")
turtle.register_shape("invader2.gif")
turtle.register_shape("Laser beam.gif")
# creating the fighter jet and then puting it down
fighter = turtle.Turtle()
fighter.shape("Spaceship.gif")
fighter.penup()
fighter.setposition(0,-270)
fighter.setheading(90)
# create the laser
laser = turtle.Turtle()
laser.speed(0)
laser.setheading(90)
laser.hideturtle()
laser.shape("Laser beam.gif")
laser.penup()
# how far the fighter teleports each time a key is pressed
fighttp = 20
# delay
delay = "F"
# creating functions that either adds or substracts the current position
def up():
y = fighter.ycor()
y += fighttp
if y > -130:
y = -130
fighter.sety(y)
def left():
x = fighter.xcor()
x -= fighttp
if x < -370:
x = -370
fighter.setx(x)
def down():
y = fighter.ycor()
y -= fighttp
if y < -300:
y = -300
fighter.sety(y)
def right():
x = fighter.xcor()
x += fighttp
if x > 360:
x = 360
fighter.setx(x)
# give the player the laser beam to perform the pew pew on the bad guys just like the original game
def shoot():
if delay == "F":
delay == "T"
laser.speed(0)
laser.setposition(fighter.xcor(), fighter.ycor() + 20)
laser.showturtle()
laser.speed(3)
laser.forward(500)
laser.hideturtle()
delay == "F"
# turtle listens for the keys and then it moves according to the function and key pressed
turtle.listen()
turtle.onkey(left, "a")
turtle.onkey(right, "d")
turtle.onkey(up, "w")
turtle.onkey(down, "s")
if delay == "F":
turtle.onkey(shoot, "space")
wn.mainloop()
Skip the delay variable. Instead we can turn on and off the key event within the key event handler:
def shoot():
turtle.onkey(None, "space") # disable handler inside handler
laser.speed(0)
laser.setposition(fighter.xcor(), fighter.ycor() + 20)
laser.showturtle()
laser.speed(3)
laser.forward(500)
laser.hideturtle()
turtle.onkey(shoot, "space")
Below is a rework of your code with various style changes and optimizations:
from turtle import Screen, Turtle
# Making the window and its properties
screen = Screen()
screen.title("Galaxy Wars")
screen.bgcolor('black')
# Adding images to the shape function so that it will recognize them as a shape
screen.register_shape("Spaceship.gif")
screen.register_shape("Laser beam.gif")
# Create the fighter jet and then put it down
fighter = Turtle()
fighter.shape("Spaceship.gif")
fighter.penup()
fighter.sety(-270)
fighter.setheading(90)
# Create the laser
laser = Turtle()
laser.hideturtle()
laser.shape("Laser beam.gif")
laser.setheading(90)
laser.penup()
# How far the fighter teleports each time a key is pressed
fighttp = 20
# creating functions that either adds or subtracts the current position
def up():
y = fighter.ycor() + fighttp
if y > -130:
y = -130
fighter.sety(y)
def left():
x = fighter.xcor() - fighttp
if x < -370:
x = -370
fighter.setx(x)
def down():
y = fighter.ycor() - fighttp
if y < -300:
y = -300
fighter.sety(y)
def right():
x = fighter.xcor() + fighttp
if x > 360:
x = 360
fighter.setx(x)
# Give player laser beam to perform the pew pew on the bad guys just like the original game
def shoot():
screen.onkey(None, 'space') # disable handler inside handler
laser.speed('fastest')
laser.setposition(fighter.xcor(), fighter.ycor() + 20)
laser.showturtle()
laser.speed('slow')
laser.forward(500)
laser.hideturtle()
screen.onkey(shoot, 'space')
# Listen for keys and move according to the function and key pressed
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.onkey(up, 'w')
screen.onkey(down, 's')
screen.onkey(shoot, 'space')
screen.listen()
screen.mainloop()

Simple game is very laggy

I've just started coding a little game using turtle, but my very first prototype is already very laggy.
import turtle
import keyboard
# Player 1 x and y cords
p1x = -350
p1y = 250
wn = turtle.Screen()
wn.title("Actua")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0)
# Player 1 Setup
player_1 = turtle.Turtle()
player_1.speed(0)
player_1.shape("square")
player_1.color("red")
player_1.penup()
player_1.goto(p1x, p1y)
player_1.shapesize(1, 1)
win = turtle.Screen()
while True:
win.update()
# Controlls
if keyboard.read_key:
if keyboard.read_key() == "esc":
quit()
if keyboard.read_key() == "d" or keyboard.read_key() == "D":
p1x = p1x+10
if keyboard.read_key() == "a" or keyboard.read_key() == "A":
p1x = p1x-10
if keyboard.read_key() == "w" or keyboard.read_key() == "W":
p1y = p1y+10
if keyboard.read_key() == "s" or keyboard.read_key() == "S":
p1y = p1y-10
player_1.goto(p1x, p1y)
It's probably lagging because of the "while True:" but I don't know how to improve it. Are there just too many if-statements or do I first have to set specific FPS?
Further information:
I'm using VSCode,
my operating system is Windows 10,
my PC should normally be able to handle such a short code.
Oh, and please go easy on me with the technical terms, I'm kinda new to coding.
Edit: I just tested it again, it's definitely due to the if-statements themselves. However I still don't know how I could fix it.
Your code doesn't run at all on my system. My recommendation is to toss the keyboard module and use turtle's own built-in key event handler, as we should never have while True: in an event-driven world like turtle:
from turtle import Screen, Turtle
from functools import partial
# Players X and Y coordinates
p1x, p1y = -350, 250
p2x, p2y = 350, -250
def right(player):
player.setx(player.xcor() + 10)
screen.update()
def left(player):
player.setx(player.xcor() - 10)
screen.update()
def up(player):
player.sety(player.ycor() + 10)
screen.update()
def down(player):
player.sety(player.ycor() - 10)
screen.update()
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor('black')
screen.tracer(False)
player_1 = Turtle()
player_1.shape('square')
player_1.color('red')
player_1.penup()
player_1.goto(p1x, p1y)
player_2 = player_1.clone()
player_2.color('green')
player_2.goto(p2x, p2y)
screen.onkey(partial(left, player_1), 'a')
screen.onkey(partial(right, player_1), 'd')
screen.onkey(partial(up, player_1), 'w')
screen.onkey(partial(down, player_1), 's')
screen.onkey(partial(left, player_2), 'Left')
screen.onkey(partial(right, player_2), 'Right')
screen.onkey(partial(up, player_2), 'Up')
screen.onkey(partial(down, player_2), 'Down')
screen.onkey(screen.bye, 'Escape')
screen.listen()
screen.update()
screen.mainloop()
I've added a second player on the arrow keys to make sure my code is compatible with two players.
hi you are using too many keyboard.read_kry() fun: means every if statment the program should call the fun again and again:
i think now its not laggy:
import turtle
import keyboard
# Player 1 x and y cords
p1x = -350
p1y = 250
wn = turtle.Screen()
wn.title("Actua")
wn.bgcolor("black")
wn.setup(width=800, height=600)
wn.tracer(0)
# Player 1 Setup
player_1 = turtle.Turtle()
player_1.speed(0)
player_1.shape("square")
player_1.color("red")
player_1.penup()
player_1.goto(p1x, p1y)
player_1.shapesize(1, 1)
win = turtle.Screen()
win.update()
while True:
key = keyboard.read_key()
if key == "esc":
quit()
elif key == "d" or key == "D":
p1x = p1x + 10
win.update()
elif key == "a" or key == "A":
p1x = p1x - 10
win.update()
elif key == "w" or key == "W":
p1y = p1y + 10
win.update()
elif key == "s" or key == "S":
p1y = p1y - 10
win.update()
player_1.goto(p1x, p1y)
Not quite sure if that would help, but try changing wn.tracer(0) parameter to something bigger (ex.10/20). The number inside means (if I understand correctly) the amount of milliseconds before another refresh takes place. I had the same problem just today, as I tried to make a simple "pong" game and it seemed to help.
Ps. on my machine it wouldn't even work with 0 as an argument
PPs. - I was wrong - see the comment below

After a few seconds, one turtle stops and the other goes faster

After weeks of trying, I have not come up with a solution to this issue, in which one turtle comes to a complete stop and the other goes 2x - 3x faster. How can I fix this? You must move them both around for a little bit to encounter the issue. Also this is on the site: repl.it
I have tried moving the wn.listen() command but that only switched which turtle stopped and which one didn't. I have unsuccessfully tried to switch the forward() command to goto() and I have tried to use direction specific movement (also unsuccessfully):
import turtle
import sys
player1 = turtle.Turtle()
player1.up()
player1.goto(0,350)
player1.right(90)
player1.down()
player2 = turtle.Turtle()
wn = turtle.Screen()
#preGame setup
player2.up()
player2.goto(0,-350)
player2.left(90)
player2.down()
player2.color("blue")
player1.color("red")
#main game loop
player1.speed(0)
player2.speed(0)
k = 0
def kr():
player1.left(90)
def kl():
player1.right(90)
wn.onkey(kr, "d")
wn.onkey(kl, "a")
def k1():
player2.right(90)
def k2():
player2.left(90)
wn.onkey(k1, "k")
wn.onkey(k2, "l")
wn.listen()
while True:
player1.forward(1)
player2.forward(1)
while player1.xcor() < (-350) or player1.xcor() > (350) or player1.ycor() > (350) or player1.ycor() < (-350):
player1.back(30)
while player2.xcor() < (-350) or player2.xcor() > (350) or player2.ycor() > (350) or player2.ycor() < (-350):
player2.back(30)
if player1.pos() == player2.pos():
print ("DONT CRASH INTO THE OTHER PLAYER")
sys.exit()
I expected them both to continue moving indefinitely, but one always stops, and the other is going 2x the speed.
Move the keylisteners outside your loop - having them inside the while loop will reattach them and redefine the functions all the time and confuse turtle.
You need to set them up once not every few milliseconds:
import turtle
player1 = turtle.Turtle()
player2 = turtle.Turtle()
player1.goto(350, 0)
player2.goto(-350, 0)
player1.right(180)
wn = turtle.Screen()
def kl():
player1.left(90)
def kr():
player1.right(90)
def k1():
player2.right(90)
def k2():
player2.left(90)
wn.onkey(kl, "d") # changed to lowercase
wn.onkey(kr, "a")
wn.onkey(k1, "j") # changed to other letters
wn.onkey(k2, "l")
wn.listen()
while True: # not changing k so just use while True
player1.forward(1) # changed speed
player2.forward(1)
Your nested while loop structure is working against you and isn't valid for an event-driven environment like turtle. Here's a rework of your program to fix this issue and clean up the code:
from turtle import Screen, Turtle
import sys
# preGame setup
player1 = Turtle()
player1.hideturtle()
player1.up()
player1.goto(0, 350)
player1.down()
player1.right(90)
player1.color('red')
player1.speed('fastest')
player1.showturtle()
def r1():
player1.left(90)
def l1():
player1.right(90)
player2 = Turtle()
player2.hideturtle()
player2.up()
player2.goto(0, -350)
player2.down()
player2.left(90)
player2.color('blue')
player2.speed('fastest')
player2.showturtle()
def r2():
player2.right(90)
def l2():
player2.left(90)
# main game loop
def move():
player1.forward(5)
if not (-350 < player1.xcor() < 350 and -350 < player1.ycor() < 350):
player1.backward(30)
player2.forward(5)
if not (-350 < player2.xcor() < 350 and -350 < player2.ycor() < 350):
player2.backward(30)
if player1.distance(player2) < 5:
print("DON'T CRASH INTO THE OTHER PLAYER!")
sys.exit()
screen.ontimer(move, 100)
screen = Screen()
screen.onkey(r1, 'd')
screen.onkey(l1, 'a')
screen.onkey(r2, 'k')
screen.onkey(l2, 'l')
screen.listen()
move()
screen.mainloop()
See if this behaves more like you expect/desire.

Python Turtle Collision Help and Updating Score/Lives

I am working on a scrolling game that uses multiple turtles. The player turtle moves on the Y-Axis on key commands. While the Harm and Benefits move across the X-Axis then looping around and changing Y-Axis position. I have tried defining a function called colliding() that can test if the player and benefit turtles collide. Can someone help with the collision function? And I also have a question on how, after detecting collision, to change the value of the player score? I think I have figured this out: I used player['lives']+=1. But this doesn't change because -- is something wrong with my collision function or loop?
import turtle
import random
import math
#The list of the turtles being used
t = turtle.Turtle()
Harm1 = turtle.Turtle()
Harm2 = turtle.Turtle()
Ben = turtle.Turtle()
player1 = turtle.Turtle()
#Screen Specifications
screen = turtle.Screen()
screen.setup(500,500)
screen.bgcolor('darkgray')
Harm1.tracer(0)
Harm2.tracer(0)
Ben.tracer(0)
player1.tracer(0)
#Character dictionary
player ={"type":'Player',"x" : -200,"y" : 0,"size" : 20,"speed" : 10,
"color" : "green","Lives":3,"Score":0}
harm = {"type":'Harm',"x" : -200,"y" : 0,"size" : 30,"speed" : 6,
"color" : "red",}
benefit = {"type":'Benefit',"x" : -200,"y" : 0,"size" : 15,"speed":6,
"color" : "yellow",}
#These can change when collision happens
lives = player['Lives']
score = player['Score']
#These are the keys that let the player move up/down
def move_up():
player['y']+=player['speed']
return
def move_down():
player['y']-= player['speed']
#Player gets info from dictionary
def draw_player():
player1.clear()
player1.penup()
player1.goto(player["x"], player["y"])
player1.pendown()
player1.color(player["color"])
player1.begin_fill()
player1.circle(player["size"])
player1.end_fill()
#if player1(player['y']) > 250 or player1(player['y']) < -250:
#player1.sety(player['y'])
player1.update()
player1.hideturtle()
screen.listen()
screen.onkey(move_up, 'up')
screen.onkey(move_down, 'down')
def draw_harms():
Harm1.clear()
Harm1.color(harm['color'])
Harm1.begin_fill()
Harm1.circle(harm['size'])
Harm1.end_fill()
Harm1.update()
Harm1.setx(Harm1.xcor()-(harm['speed']))
if (Harm1.xcor() < -260 ): #This part of the code makes the object comeback.
Harm1.setx(260)
Harm1.sety(random.randint(-160,160)) #This makes the object change Y cor
Harm1.hideturtle()
Harm2.clear()
Harm2.color(harm['color'])
Harm2.begin_fill()
Harm2.circle(harm['size'])
Harm2.end_fill()
Harm2.update()
Harm2.setx(Harm2.xcor()-(harm['speed']))
if (Harm2.xcor() < -260 ): #This part of the code makes the object comeback.
Harm2.setx(220)
Harm2.sety(random.randint(-160,160)) #This makes the object change Y cor
Harm2.hideturtle()
def draw_benefit():
Ben.clear()
Ben.color(benefit['color'])
Ben.begin_fill()
Ben.circle(benefit['size'])
Ben.end_fill()
Ben.update()
Ben.setx(Ben.xcor()-(benefit['speed']))
if (Ben.xcor() < -260 ): #This part of the code makes the object comeback.
Ben.setx(220)
Ben.sety(random.randint(-160,160)) #This makes the object change Y cor
Ben.hideturtle()
#This Keeps the score and Lives
def draw_title_name(): #This writes the title on the screen
t.penup()
t.goto(-210,-200)
t.pendown()
t.write(("Score:", score),font=("Arial", 18, "normal"))
t.penup()
t.goto(-210,-223)
t.pendown()
t.write(('Lives:',lives),font=('Arial',18,'normal'))
t.hideturtle()
return
def colliding(player,benefit):
collision_detected = False;
var_dx = player['x'] - benefit['x']
var_dy = player['y'] - benefit['y']
distance = math.sqrt(var_dx * var_dx + var_dy * var_dy)
if (distance < player['radius']+ benefit['radius']):
collision_detected = True;
return collision_detected
while lives > 0: #ANIMATION LOOP
draw_player()
draw_harms()
draw_benefit()
draw_title_name()
if colliding == True:
player['lives'] += 1 This changes the lives in the player Dict
if lives == 0:
clearscreen
#Finish with a gameover screen!
Your code is a disaster, there are any number of bits of logic in it that will keep it from running. To address your question, turtle has it's own distance() method to measure the distance between turtles or turtles and positions. Using that, your colliding() method could be as simple as:
def colliding(player, benefit):
return player.distance(benefit) < player_dict['size'] + benefit_dict['size']
if you were to actually call your colliding() method, which you don't, as #Hoog points out. Other showstoppers in this code:
if (distance < player['radius']+ benefit['radius']):
The radius properties are never defined.
var_dx = player['x'] - benefit['x']
Although player's x position is updated in the dictionary, benefit's isn't, so this will never work.
player['lives'] += 1 This changes the lives in the player Dict
Missing comment character.
clearscreen
What is this? Probably should be screen.clearscreen().
collision_detected = False;
...
collision_detected = True;
semicolons in Python are usually a sign that things aren't going well.
Harm1 = turtle.Turtle()
Harm2 = turtle.Turtle()
Ben = turtle.Turtle()
player1 = turtle.Turtle()
...
Harm1.tracer(0)
Harm2.tracer(0)
Ben.tracer(0)
player1.tracer(0)
Turtle instances don't respond to the tracer() method. Screen instances do.
player1.update()
Harm1.update()
Harm2.update()
Ben.update()
Ditto for update(). And so forth.
Below is my rework of your code to make it basically run:
from turtle import Screen, Turtle
from random import randint
FONT = ('Arial', 18, 'normal')
CURSOR_SIZE = 20
# Character dictionaries
player_dict = {'type': 'Player', 'x': -200, 'y': 0, 'radius': 20, 'speed':10, 'color': 'green', 'lives': 3, 'score': 0}
harm_dict = {'type': 'Harm', 'x': 0, 'y': 0, 'radius' : 30, 'speed': 6, 'color': 'red'}
benefit_dict = {'type': 'Benefit', 'x': 0, 'y': 0, 'radius': 15, 'speed': 6, 'color': 'yellow'}
# These are the keys that let the player move up/down
def move_up():
player_dict['y'] += player_dict['speed']
def move_down():
player_dict['y'] -= player_dict['speed']
# Player gets info from dictionary
def draw_player():
player1.sety(player_dict['y'])
def draw_harms():
harm1.forward(harm_dict['speed'])
if harm1.xcor() < -250 - harm_dict['radius']: # This part of the code makes the object come back.
harm1.hideturtle()
harm1.setx(250 + harm_dict['radius'])
harm1.sety(randint(-160, 160)) # This makes the object change Y coordinate
harm1.showturtle()
harm2.forward(harm_dict['speed'])
if harm2.xcor() < -250 - harm_dict['radius']: # This part of the code makes the object comeback.
harm2.hideturtle()
harm2.setx(250 + harm_dict['radius'])
harm2.sety(randint(-160, 160)) # This makes the object change Y coordinate
harm2.showturtle()
def draw_benefit():
ben.forward(benefit_dict['speed'])
if ben.xcor() < -250 - benefit_dict['radius']: # This part of the code makes the object comeback.
ben.hideturtle()
ben.setx(250 + benefit_dict['radius'])
ben.sety(randint(-160, 160)) # This makes the object change Y coordinate
ben.showturtle()
# This Keeps the score and Lives
def draw_lives():
lives.undo()
lives.write("Lives: {}".format(player_dict['lives']), font=FONT)
def draw_score():
score.undo()
score.write("Score: {}".format(player_dict['score']), font=FONT)
def colliding(player, benefit):
return player.distance(benefit) < player_dict['radius'] + benefit_dict['radius']
# Screen Specifications
screen = Screen()
screen.setup(500, 500)
screen.bgcolor('darkgray')
# The list of the turtles being used
t = Turtle(visible=False)
t.penup()
harm1 = Turtle('circle', visible=False)
harm1.color(harm_dict['color'])
harm1.shapesize(harm_dict['radius'] * 2 / CURSOR_SIZE)
harm1.penup()
harm1.setx(250 + harm_dict['radius'])
harm1.sety(randint(-160, 160))
harm1.setheading(180)
harm1.showturtle()
harm2 = Turtle('circle', visible=False)
harm2.color(harm_dict['color'])
harm2.shapesize(harm_dict['radius'] * 2 / CURSOR_SIZE)
harm2.penup()
harm2.setx(250 + harm_dict['radius'])
harm2.sety(randint(-160, 160))
harm2.setheading(180)
harm2.showturtle()
ben = Turtle('circle', visible=False)
ben.color(benefit_dict['color'])
ben.shapesize(benefit_dict['radius'] * 2 / CURSOR_SIZE)
ben.penup()
ben.setx(250 + benefit_dict['radius'])
ben.sety(randint(-160, 160))
ben.setheading(180)
ben.showturtle()
player1 = Turtle('circle', visible=False)
player1.color(player_dict['color'])
player1.shapesize(player_dict['radius'] * 2 / CURSOR_SIZE)
player1.penup()
player1.goto(player_dict['x'], player_dict['y'])
player1.showturtle()
score = Turtle(visible=False)
score.penup()
score.goto(-210, -200)
score.write("Score: {}".format(player_dict['score']), font=FONT)
lives = Turtle(visible=False)
lives.penup()
lives.goto(-210, -223)
lives.write("Lives: {}".format(player_dict['lives']), font=FONT)
screen.onkey(move_up, 'Up')
screen.onkey(move_down, 'Down')
screen.listen()
def move():
draw_player()
draw_harms()
draw_benefit()
# draw_score()
if colliding(player1, ben):
player_dict['lives'] += 1 # This increases the lives in the player dictionary
ben.hideturtle()
ben.setx(250 + benefit_dict['radius'])
ben.sety(randint(-160, 160))
ben.showturtle()
draw_lives()
if colliding(player1, harm1):
player_dict['lives'] -= 1 # This decreases the lives in the player dictionary
harm1.hideturtle()
harm1.setx(250 + harm_dict['radius'])
harm1.sety(randint(-160, 160))
harm1.showturtle()
draw_lives()
if colliding(player1, harm2):
player_dict['lives'] -= 1
harm2.hideturtle()
harm2.setx(250 + harm_dict['radius'])
harm2.sety(randint(-160, 160))
harm2.showturtle()
draw_lives()
if player_dict['lives'] == 0:
screen.clearscreen()
# Finish with a gameover screen!
return
if player_dict['lives'] > 0:
screen.ontimer(move, 75)
move()
screen.mainloop()
It still needs a lot of work, however.
Pygame has a built in collision detection algorithm rect.colliderect() which might help you out.
For your code the issue seems to be this line if colliding == True: you never set the variable colliding, perhaps you meant to call the function with something like: if colliding(Player1,Ben1) == True:

Categories

Resources