Need help detecting collision in python - python

I’ve tried multiple things to try to detect collision between the player turtle and the apple turtle and nothing happens. What I wanted it to do is that when the turtles get too close, the player turtle disappears. If the apple gets to low below the player, it resets back up top.
Here is the code I’ve done. I’m new to code so I’m not very good.
import turtle as trtl
import random as rand
ground_height = -200
# lists for the turtle to use
colors = ["blue", "darkorange", "cyan", "green", "black"]
shapes = [ "triangle", "turtle", "classic"]
sizes = [0.5,1,1.25,1.5,2]
#creates the turtles
player = trtl.Turtle(shape = rand.choice(shapes)) #gives the circle its shape
player.turtlesize(1.5)
counter = trtl.Turtle()
apple = trtl.Turtle(shape = "circle")
apple.color("red")
apple.turtlesize(rand.choice(sizes))
#gives turtles their colors
player.color(rand.choice(colors))
player.penup()
apple.penup()
apple.setx(rand.randint(0,200))
apple.sety(rand.randint(0,200))
#sets up timer
font_setup = ("Arial", 20, "normal")
timer = 0
counter_interval = 1000
timer_up = False
counter.hideturtle()
counter.penup()
counter.goto(-200,160)
#gives player movement
def move_player():
player.forward(10)
def player_left():
player.left(180)
def player_right():
player.right(180)
apple.right(90)
#lets the timer start and end
def countdown():
global timer, timer_up
counter.clear()
if timer <= -1:
counter.write("Time's Up", font=font_setup)
timer_up = True
else:
counter.write("Timer: " + str(timer), font=font_setup)
timer += 1
apple.forward(10)
counter.getscreen().ontimer(countdown, counter_interval)
countdown()
# lets the player move on key press
wn = trtl.Screen()
wn.listen()
wn.onkeypress(move_player, "w")
wn.onkeypress(player_left,"a")
wn.onkeypress(player_right,"d")
wn.mainloop()

Testing for collision can be as simple as adding a clause to the if statement in the countdown() function:
elif apple.distance(player) < 15:
counter.write("Collision!", font=FONT)
Below is my rework of your code that incorporates this change as well addresses various style and coding issues I noticed:
from turtle import Screen, Turtle
from random import choice, randint
# lists for the turtle to use
COLORS = ['blue', 'dark orange', 'cyan', 'green', 'black']
SHAPES = ['triangle', 'turtle', 'classic']
SIZES = [0.5, 1, 1.25, 1.5, 2]
FONT = ('Arial', 20, 'normal')
COUNTER_INTERVAL = 1000
# give player movement
def move_player():
player.forward(10)
def player_left():
player.left(180)
def player_right():
player.right(180)
# set up timer
timer = 0
def countdown():
global timer
counter.clear()
if timer <= -1:
counter.write("Time's Up", font=FONT)
elif apple.distance(player) < 15:
counter.write("Collision!", font=FONT)
else:
counter.write("Timer: " + str(timer), font=FONT)
timer += 1
apple.forward(10)
screen.ontimer(countdown, COUNTER_INTERVAL)
# create turtles
player = Turtle(shape=choice(SHAPES))
player.turtlesize(1.5)
player.color(choice(COLORS))
player.penup()
counter = Turtle()
counter.hideturtle()
counter.penup()
counter.goto(-200, 160)
apple = Turtle(shape='circle')
apple.color('red')
apple.turtlesize(choice(SIZES))
apple.penup()
apple.setposition(randint(0, 200), randint(0, 200))
apple.setheading(270)
screen = Screen()
# let player move on key press
screen.onkeypress(move_player, 'w')
screen.onkeypress(player_left, 'a')
screen.onkeypress(player_right, 'd')
screen.listen()
countdown()
screen.mainloop()
What I wanted it to do is that when the turtles get too close, the
player turtle disappears. If the apple gets to low below the player,
it resets back up top
My fix above just detects and announces the collision, you'll need to augment it to include these additional actions.

Related

How do I make a python turtle program wait a bit?

So I'm making a game where the two turtles race each other, but I want them to wait a bit before they start (to display a 3,2,1) screen. But I can't figure it out! I used time.sleep, and turtle.delay, but both did not work. What can I do? Here is the code :)
import turtle
import random
import time
turt = turtle.Turtle()
turt2 = turtle.Turtle()
turtle.Screen() .bgcolor("green")
turt.speed(10)
turt.penup()
turt.goto(200,100)
turt.pendown()
turt.right(90)
turt.width(10)
turt.forward(450)
turt.right(180)
turt.forward(800)
#position 1
turt.penup()
turt.goto(-400,200)
turt.pendown()
turt.right(90)
turt.forward(100)
#position 2
turt2.width(10)
turt2.penup()
turt2.goto(-400,-200)
turt2.pendown()
turt2.forward(100)
Contrary to the advice so far, I'd avoid sleep() in my turtle program and use ontimer() instead to countdown the start of the race:
from turtle import Screen, Turtle
from random import choice
FONT = ('Arial', 36, 'bold')
def race():
while turtle_1.xcor() < 200 > turtle_2.xcor():
choice([turtle_1, turtle_2]).forward(10)
def countdown(seconds=3):
pen.clear()
if seconds < 1:
screen.ontimer(race)
else:
pen.write(seconds, align='center', font=FONT)
screen.ontimer(lambda: countdown(seconds - 1), 1000)
screen = Screen()
screen.bgcolor('green')
marker = Turtle()
marker.hideturtle()
marker.speed('fastest')
marker.color('white')
marker.width(5)
marker.penup()
marker.goto(200, 300)
marker.pendown()
marker.right(90)
marker.forward(600)
pen = Turtle()
pen.hideturtle()
turtle_1 = Turtle()
turtle_1.shape('turtle')
turtle_1.color('red')
turtle_1.penup()
turtle_1.goto(-400, 200)
turtle_2 = turtle_1.clone()
turtle_1.color('blue')
turtle_2.goto(-400, -200)
countdown()
screen.exitonclick()

Python Turtle race game. Ending game function does not seem to work

I have got a problem with how to end my turtle python game. The code seems to function if I place the turtles at the starting/ending point from the beginning of the code, but it does not register when the turtle reaches the endpoint in gameplay. From what I know I think my maths for the end function is right. I am new and appreciate the help. I am currently offline though.
CODE:
import time
import turtle
from turtle import *
wn = turtle.Screen()
name=textinput("Question", "what is your name")
#display
pencolor("white")
penup()
goto(0,170)
write("hello " +name,align='center',font=('Comic Sans', 20))
#wn = turtle.screen() if the code doesn't work
#diffrent turtles here
t1 = turtle.Turtle()
t2 = turtle.Turtle()
t3 = turtle.Turtle()
#starting psoition
turtle.penup()
t1.penup()
turtle.goto(-1, -230)
t1.goto(-1, -170)
#starting line postion
def f():
fd(10)
def b():
bk(10)
def l():
left(10)
def r():
right(10)
#testing
def fo():
t1.fd(10)
def ba():
t1.bk(10)
def le():
t1.left(10)
def ri():
t1.right(10)
#turtle coordinates
first=turtle.ycor()
second=turtle.xcor()
third=t1.ycor()
fourth=t1.xcor()
#when to end the game
if (turtle.ycor()>= (-160)) and (turtle.ycor()<= (-240)):
if (turtle.xcor()>= (0)) and (turtle.xcor()<= (11)):
print("Finally working")
#replaced with write who the winner is later
if (t1.ycor()>= (-160)) and (t1.ycor()<= (-240)):
if (t1.xcor()>= (0)) and (t1.xcor()<= (11)):
print("Finally")
# onkey creates the key board = turtle.onkey("function, key") You have to keep pressing keys for it to move
turtle.onkey(f, "w")
turtle.onkey(b, "s")
turtle.onkey(l, "a")
turtle.onkey(r, "d")
wn.onkey(fo, "Up")
wn.onkey(ba, "Down")
wn.onkey(le, "Left")
wn.onkey(ri, "Right")
listen()
#WINDOW SETUP
window = Screen()
window.setup(800, 800)
window.title("Turtle game")
turtle.bgcolor("forestgreen")
t3.color("black")
t3.speed(0)
t3.penup()
t3.setpos(-140, 250)
t3.write("THE TURTLE RACE", font=("Comic Sans", 30, "bold"))
t3.penup()
#turtle ask name
#add images here
#turtle controls
# def creates a function. : means opperation f means move turtle foward. fd push turtle forward
# onkey creates the key board = turtle.onkey("function, key") You have to keep pressing keys for it to move
t2.speed(0)
t2.color("grey")
t2.pensize(100)
t2.penup()
t2.goto(-200, -200)
t2.left(90)
t2.pendown()
t2.forward(300)
t2.right(90)
t2.forward(500)
t2.right(90)
t2.forward(300)
t2.right(90)
t2.forward(500)
turtle.penup()
Firstly, your maths is not quite right - a coordinate can never be both <= -240 and >= -160. It should be t.ycor() >= -240 and t.ycor() <= -160, or more briefly, -240 <= t.ycor() <= -160.
Secondly, the condition as it stands is only checked once, when the code is first run. Instead, you need to get the program to check it regularly. You can do this by adding a general onkeypress event handler which is checked every time any key is pressed.
def check_status():
for player, t in enumerate([turtle, t1]):
if 0 <= t.xcor() <= 11 and -240 <= t.ycor() <= -160:
print(f"Player {player} is at the endpoint")
...
wn.onkeypress(check_status)
listen()

Start the game when SPACE is pressed (Turtle module)

I've been trying to code the Pong minigame using Turtle Graphics. Everything seems to work perfectly except for the beginning. I want the main loop to start iterating ONLY once the space key is pressed.
Here is the part i've been having trouble with:
## Start the game
start = False
def start_game():
startmessage.clear() #This is a turtle i created to show the message "Press SPACE to start"
start = True
ball_start() #This is a function i created to get the ball moving
wn.onkeypress(start_game, "space")
## Main loop
while start == True:
I've included .listen() and .mainloop(), so that's not the problem.
The full code is below. If i run the program with that code, this is what it does:
It asks for the user to enter the max points. The black window appears, the score table also appears, but for some reason the border doesn't.
When the max points value is entered in the shell, the message "Press SPACE to start" appeats in the black screen.
As soon as Space is pressed, that message disappears and nothing else occurs.
Here is the full code in case I'm missing something important:
import turtle
import random
import time
## Screen setup
wn = turtle.Screen()
wn.title("Pong!")
wn.bgcolor("black")
wn.setup(width = 900, height = 700)
wn.tracer(0)
# Border
collisions = 0
border = turtle.Turtle()
border.penup()
border.color("white")
border.setposition(-400,-300)
border.pendown()
for side in range(2):
border.forward(800)
border.left(90)
border.forward(600)
border.left(90)
border.hideturtle()
# Scores
scoreA = 0
scoreB = 0
score_marker = turtle.Turtle()
score_marker.shape("blank")
score_marker.color("yellow")
score_marker.speed(0)
score_marker.penup()
score_marker.setposition(0, 310)
score_marker.pendown()
score_marker.write("Player A : {} Player B: {}".format(scoreA,scoreB), align = "center", font = ("Courier", 20, "bold"))
# Select number of points
maxpoints = int(input("Enter max points: "))
print("The player who first gets to {} points wins the game!".format(maxpoints))
# Start message
startmessage = turtle.Turtle()
startmessage.speed(0)
startmessage.color("white")
startmessage.shape("blank")
startmessage.penup()
startmessage.setposition(0,75)
startmessage.pendown()
startmessage.write("Press SPACE to start", align = "center", font = ("Courier", 20, "bold"))
# End message
endmessage = turtle.Turtle()
endmessage.speed(0)
endmessage.color("green")
endmessage.shape("blank")
endmessage.penup()
endmessage.setposition(0,0)
endmessage.pendown()
## Paddles
paddleB_speed = 25
paddleA_speed = paddleB_speed
wn.listen()
# Paddle A
paddleA = turtle.Turtle()
paddleA.speed(0)
paddleA.shape("square")
paddleA.color("white")
paddleA.shapesize(3.2,0.7)
paddleA.penup()
paddleA.goto(-350,0)
# Paddle A movement
def a_up():
y = paddleA.ycor() + paddleA_speed
paddleA.sety(y)
def a_down():
y = paddleA.ycor() - paddleA_speed
paddleA.sety(y)
wn.onkeypress(a_up,"w")
wn.onkeypress(a_down,"s")
# Paddle B
paddleB = turtle.Turtle()
paddleB.speed(0)
paddleB.shape("square")
paddleB.color("white")
paddleB.shapesize(3.2,0.7)
paddleB.penup()
paddleB.goto(350,0)
# Paddle B movement
def b_up():
y = paddleB.ycor() + paddleB_speed
paddleB.sety(y)
def b_down():
y = paddleB.ycor() - paddleB_speed
paddleB.sety(y)
wn.onkeypress(b_up,"Up")
wn.onkeypress(b_down,"Down")
## Ball
ball = turtle.Turtle()
ball.speed(0)
ball.shape("circle")
ball.color("white")
ball.shapesize(0.5,0.5)
ball.penup()
ball.setposition(0,0)
ballspeed = 0.3
ballspeed_increase = 0.01
# Ball starting movement
def ball_start():
angle_ranges = list(range(30,60)) + list(range(120,150)) + list(range(210,240)) + list(range(300,330))
angle = random.choice(angle_ranges)
ball.setheading(angle)
ball_start()
## Exit the game
def exit_game():
wn.bye()
## Start the game
start = False
def start_game():
startmessage.clear()
start = True
ball_start()
wn.onkeypress(start_game, "space")
## Main loop
while start == True:
wn.update()
### MOVEMENT
## Ball movement
ball.forward(ballspeed)
### COLLISIONS
## Paddles and border
# Paddle A
if paddleA.ycor() > 268:
paddleA.sety(268)
if paddleA.ycor() < -268:
paddleA.sety(-268)
# Paddle B
if paddleB.ycor() > 268:
paddleB.sety(268)
if paddleB.ycor() < -268:
paddleB.sety(-268)
## Ball and paddles
if paddleA.distance(ball) <= 10:
collisions += 1
#direction = ball.heading()
#ball.setheading(180 - random.randint(0,30) - direction)
ball.setheading(random.randint(110,250) + 180)
ball.forward(ballspeed + ballspeed_increase)
if paddleB.distance(ball) <= 10:
collisions += 1
#direction = ball.heading()
#ball.setheading(180 - random.randint(0,30) - direction)
ball.setheading(random.randint(110,250))
ball.forward(ballspeed + ballspeed_increase)
## Ball and border
# Top and bottom borders
if ball.ycor() < - 296 or ball.ycor() > 296:
collisions += 1
direction = ball.heading()
ball.setheading(360 - direction)
ball.forward(ballspeed + ballspeed_increase)
# Left and right borders
if ball.xcor() < -396: #--> Player B wins the point
delay = 0.1
time.sleep(1)
collisions += 1
ball.setposition(0,0)
scoreB += 1
score_marker.clear()
score_marker.write("Player A : {} Player B: {}".format(scoreA,scoreB), align = "center", font = ("Courier", 20, "bold"))
ball_start()
if ball.xcor() > 396: #--> Player A wins the poin
delay = 0.1
time.sleep(1)
collisions += 1
ball.setposition(0,0)
scoreA += 1
score_marker.clear()
score_marker.write("Player A : {} Player B: {}".format(scoreA,scoreB), align = "center", font = ("Courier", 20, "bold"))
ball_start()
# End of the game
if scoreA == maxpoints or scoreB == maxpoints:
if scoreA == maxpoints:
print("Player A wins the game!")
endmessage.write("Player A wins the game!\nA scored {} points\nB scored {} points".format(scoreA,scoreB), align = "center", font = ("Courier", 18, "bold"))
time.sleep(1)
endmessage.penup()
endmessage.setposition(0,-100)
endmessage.pendown()
endmessage.color("red")
endmessage.write("Press ESC to exit game", align = "center", font = ("Courier", 14, "normal"))
wn.onkeypress(exit_game, "Escape")
break
if scoreB == maxpoints:
print("Player B wins the game!")
endmessage.write("Player B wins the game!\nA scored {} points\nB scored {} points".format(scoreA,scoreB), align = "center", font = ("Courier", 18, "bold"))
time.sleep(1)
endmessage.penup()
endmessage.setposition(0,-100)
endmessage.pendown()
endmessage.color("red")
endmessage.write("Press ESC to exit game", align = "center", font = ("Courier", 14, "normal"))
wn.onkeypress(exit_game, "Escape")
break
wn.mainloop()
This code looks like it resets start but it doesn't -- it sets a local start and ignores the global start:
start = False
def start_game():
startmessage.clear()
start = True
ball_start()
You need a global statement:
start = False
def start_game():
global start
startmessage.clear()
start = True
ball_start()
The above is necessary but not sufficient. The next problem is the way you use a top level while loop instead of a timer event. The way I'd expect this game to start up and run would be more like:
from turtle import Screen, Turtle
running = False
def start_game():
global running
start_message.clear()
running = True
ball_start()
def ball_start():
start_message.write("We've started the game!", align="center", font=("Courier", 20, "bold"))
# what really ball_start() really does replaces the above...
def move_one_step():
if running:
screen.update()
# ...
screen.ontimer(move_one_step, 100)
screen = Screen()
start_message = Turtle()
start_message.hideturtle()
start_message.penup()
start_message.sety(75)
start_message.write("Press SPACE to start", align="center", font=("Courier", 20, "bold"))
screen.onkeypress(start_game, 'space')
screen.listen()
move_one_step()
screen.mainloop()
I think it might be the way you used the space key value. You put in space instead of return.
wn.onkeypress(start_game, "return")

Update the score when two turtles collide

I'm doing an assignment where I have to write a small game. When a turtle collides with a dot (bug) on the screen, it will add one point to the score value in the top left and teleport the bug to another random spot. I'm having trouble getting the score to update when they collide.
I tried to put the score update within the game loop but that did not work as it kept telling me that the value is not defined. I tried solving that with a global value, but that didn't do anything:
import turtle
import math
import random
#Set up the constants for the game.
WINDOW_HEIGHT = 300
WINDOW_WIDTH = 300
FORWARD_STEP = 10 #how much does the turtle move forward
TURN_STEP = 30 #how much does the turtle turn (in degrees)
SHRINK_FACTOR = 0.95 #how much does the turtle shrink when it moves
DEATH_WIDTH = 0.05 #the size at which you stop the game because the user lost
COLLISION_THRESHOLD = 10;#we say that two turtles collided if they are this much away
#from each other
#Define functions
def game_setup():
'''set up the window for the game, a bug and the player turtle '''
#create the screen
wn = turtle.Screen()
wn.screensize(WINDOW_HEIGHT,WINDOW_WIDTH)
wn.bgcolor("light green")
#Create player turtle
player = turtle.Turtle()
player.color("blue")
player.shape("turtle")
player.penup()
player.setpos (random.randrange(1,301), random.randrange(1,301))
#create a bug
bug1 = turtle.Turtle()
bug1.color("black")
bug1.shape("circle")
bug1.shapesize(stretch_wid=0.2, stretch_len=0.2)
bug1.penup()
bug1.speed(0) #the bug is not moving
bug1.setposition(-200, 200)
#create score turtle
score_keeper = turtle.Turtle()
score_keeper.hideturtle()
score_keeper.penup()
score_keeper.setposition (-400,360)
score = 0
scorestring = "Score: %s" %score
score_keeper.write(scorestring, False, align="left", font=("Arial",14, "normal"))
return (wn,player,bug1,score_keeper)
def is_collision (player, bug1):
distance = (math.sqrt((player.xcor()-bug1.xcor())**2 + (player.ycor() - bug1.ycor())**2))
if distance < COLLISION_THRESHOLD:
return True
else:
return False
def main():
#set up the window, player turtle and the bug
(wn,player,bug1,score_keeper) = game_setup()
#make the arrow keys move the player turtle
bindKeyboard(player)
#Set this veriableto True inside the loop below if you want the game to end.
game_over = False
player_width = get_width(player)
#This is the main game loop - while the game is not over and the turtle is large enough print the width of the turtle
#on the screen.
while not game_over and player_width > DEATH_WIDTH:
#your collision detection should go here
if is_collision (player, bug1):
bug1.setpos (random.randrange(1,301), random.randrange(1,301))
player.shapesize(stretch_wid=1, stretch_len=1)
player_width = get_width(player)
player.showturtle()
print(player_width)
print("Done")
wn.exitonclick()
main()
This is most of the code. All I want it to do is when the is_collision() function happens, it adds 1 to the value of score and the score_keeper turtle then prints that value in the window.
Im havign trouble getting the score to update when they collide.
I've done a stripped down rework of your code below (substuting for methods you left out) to show how to update the score on the screen. Code like this shouldn't have an explicit main loop as it's all event driven and should instead call turtle's main event loop:
from turtle import Screen, Turtle
from random import randrange
from functools import partial
# Set up the constants for the game.
WINDOW_WIDTH, WINDOW_HEIGHT = 500, 500
FORWARD_STEP = 10 # how much does the turtle move forward
TURN_STEP = 30 # how much does the turtle turn (in degrees)
COLLISION_THRESHOLD = 10 # we say that two turtles collided if they are this much away from each other
CURSOR_SIZE = 20
FONT = ('Arial', 14, 'normal')
# Define functions
def is_collision(player, bug):
return player.distance(bug) < COLLISION_THRESHOLD
def random_position(turtle):
scale, _, _ = turtle.shapesize()
radius = CURSOR_SIZE * scale
return randrange(radius - WINDOW_WIDTH/2, WINDOW_WIDTH/2 - radius), randrange(radius - WINDOW_HEIGHT/2, WINDOW_HEIGHT/2 - radius)
def forward():
global score
player.forward(FORWARD_STEP)
if is_collision(player, bug):
bug.setposition(random_position(bug))
score += 1
score_keeper.clear()
score_keeper.write(f"Score: {score}", font=FONT)
# Set up the window for the game, a bug and the player turtle.
# Create the screen
screen = Screen()
screen.setup(WINDOW_WIDTH, WINDOW_HEIGHT)
screen.bgcolor('light green')
# Create score turtle
score_keeper = Turtle(visible=False)
score_keeper.penup()
score_keeper.setposition(-230, 230)
score = 0
score_keeper.write(f"Score: {score}", font=FONT)
# Create a bug
bug = Turtle('circle', visible=False)
bug.shapesize(4 / CURSOR_SIZE)
bug.penup()
bug.setposition(random_position(bug))
bug.showturtle()
# Create player turtle
player = Turtle('turtle', visible=False)
player.color('blue')
player.speed('fastest')
player.penup()
player.setposition(random_position(player))
player.showturtle()
# make the arrow keys move the player turtle
screen.onkey(partial(player.left, TURN_STEP), 'Left')
screen.onkey(partial(player.right, TURN_STEP), 'Right')
screen.onkey(forward, 'Up')
screen.listen()
screen.mainloop()

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