How do you stop a timer for a function? - python

from turtle import Screen, Turtle
import random
from random import randint
#screen setup
screen = Screen()
screen.setup(width=450, height=450)
screen.bgcolor('black')
screen.tracer(3)
#user
player = Turtle()
player.shape('square')
player.color("green")
player.penup()
#First enemy
player2 = Turtle()
player2.color("green")
player2.shape('turtle')
player2.penup()
player2.setpos(random.randint(-200,200), random.randint(-200,200))
player2.setheading(random.randint(1,360))
#Second enemy
player3 = Turtle()
player3.color("green")
player3.shape('square')
player3.penup()
player3.setpos(random.randint(-200,200), random.randint(-200,200))
player3.setheading(random.randint(1,360))
#third enemy
player4 = Turtle()
player4.color("green")
player4.shape('triangle')
player4.penup()
player4.setpos(random.randint(-200,200), random.randint(-200,200))
player4.setheading(random.randint(1,360))
score_board = Turtle()
score_board.pu()
score_board.color("yellow")
score_board.hideturtle()
score_board.goto(0,160)
end_turtle = Turtle()
end_turtle.color("pink")
end_turtle.pu()
end_turtle.hideturtle()
end_turtle.goto(0,200)
score_num= Turtle()
score_num.pu()
score_num.color("yellow")
score_num.pu()
score_num.hideturtle()
score_num.goto(0,150)
#earth
earth = Turtle()
earth.penup()
earth.shape("circle")
earth.color("blue")
earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6)
earth.setpos(150,-150)
#bullet
bullet = Turtle()
bullet.shape("turtle")
bullet.color("purple")
bullet.hideturtle()
bullet.penup()
bullet.setpos(random.randint(-200,200),random.randint(-200,200))
bullet.hideturtle()
bullet.penup()
px = 0
py = 0
def up():
global px
global py
py = player.ycor() + 5
if py >= 200:
py -= 15
player.sety(py)
def down():
global px
global py
py = player.ycor() - 5
if py < -200:
py += 15
player.sety(py)
def left():
global px
global py
px = player.xcor() - 5
if px <= -200:
px += 15
player.setx(px)
def right():
global px
global py
px = player.xcor() + 5
if px >= 200:
px -= 15
player.setx(px)
#distance calculator
def checkcollision(t1, t2):
while t1.distance(t2) < 10:
t2.setpos(randint(-100, 100), randint(-100, 100))
# the x and y distance that the player2 turtle moves
dx = 5
dy = 5
earth_health = 100
def checkbullet(bullet,turtle):
while bullet.distance(turtle) < 10:
turtle.hideturtle()
count = 0
def check_earth(planet,turtle):
global earth_health
global count
if planet.distance(turtle)<40:
if count>1:
score_num.clear()
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
earth_health+=-10
score_board.write("Earth health")
score_num.write(earth_health)
count+=1
if earth_health<90:
end_turtle.write("You lost and humanity lost")
## if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
## turtle.setpos(turtle_x,turtle_y)
## break
##
## turtle_x = random.randint(-200,200)
## turtle_y = random.randint(-200,200)
## global damage
## while planet.distance(turtle)>10:
## turtle.setpos(random.randint(-200,200),random.randint(-200,200))
#1st enemy(switch heading)
head = 0
def enemy1():
global earth_health
if earth_health<90:
screen.ontimer(enemy1,0)
checkcollision(player,player2)
check_earth(earth,player2)
global head
player2.fd(5)
x2, y2 = player2.position()
head = player2.heading()
if y2 <= -200 or y2 >= 200:
player2.fd(0)
player2.backward(7.5)
player2.setheading((head)* -1)
if x2 <= -200 or x2 >= 200:
player2.fd(0)
player2.backward(7.5)
if head < 90:
player2.setheading(0 - ((head) * 2))
if head>90<179:
player2.setheading((head)/2)
if head>179<260:
player2.setheading((head)/3)
if head>260<361:
player2.setheading((head)/2)
screen.ontimer(enemy1,50)
#Second enemy(dx,dy)
def enemy2():
checkcollision(player, player3)
check_earth(earth,player3)
global dx
global dy
x3, y3 = player3.position()
player3.setposition(x3 + dx, y3 + dy)
if y3 <= -200 or y3 >= 200:
dy *= -1
player3.sety(y3 + dy)
if x3 <= -200 or x3 >= 200:
dx *= -1
player3.setx(x3 + dx)
screen.ontimer(enemy2,50)
def enemy3():
checkcollision(player,player4)
check_earth(earth,player4)
player4.fd(5)
x4, y4 = player4.position()
head3 = player4.heading()
if y4 <= -200 or y4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
player4.setheading((head3)* -1)
if x4 <= -200 or x4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
if head3 < 90:
player4.setheading(0 - ((head3) * 2))
if head3>90<179:
player4.setheading((head3)/2)
if head3>179<260:
player4.setheading((head3)/3)
if head3>260<361:
player4.setheading((head3)/2)
screen.ontimer(enemy3,50)
#When bullet hits wall
def bullet_end():
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
def shoot_key():
bullet.setposition(px,py)
bullet.shape("circle")
bullet.showturtle()
bullet.penup()
def shoot():
checkbullet(bullet,player2)
checkbullet(bullet,player3)
checkbullet(bullet,player4)
bx = bullet.xcor()
by = bullet.ycor()
bullet.fd(5)
if bx>=200 or bx<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
if by>=200 or by<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
screen.ontimer(shoot,50)
shoot()
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
enemy1()
enemy2()
enemy3()
screen.mainloop()
The problem lies here:
def check_earth(planet,turtle):
global earth_health
global count
if planet.distance(turtle)<40:
if count>1:
score_num.clear()
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
earth_health+=-10
score_board.write("Earth health")
score_num.write(earth_health)
count+=1
if earth_health<90:
end_turtle.write("You lost and humanity lost")
if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
turtle.setpos(turtle_x,turtle_y)
break
turtle_x = random.randint(-200,200)
turtle_y = random.randint(-200,200)
global damage
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
#1st enemy(switch heading)
head = 0
def enemy1():
global earth_health
if earth_health<90:
screen.ontimer(enemy1,0)
At first the enemy1 function runs on a timer of 50 milliseconds but when When the earth_health variable is less than than 90 this conditional should make the enemy1 function stop running as i set it its timer to 0. Instead the entire program crashes which in a sense is ok relating to my goals with this program but how could I make the enemy1 function stop running its loop on the conditional rather than the entire program?

You can use a conditional statement to see if it should stop running -- if it is you can use "return" with no value. That will breakout of the function.
In the beginning set some value (global)
global enemy1stop
enemy1stop = False
In the check_earth function:
def check_earth(planet,turtle):
global earth_health
global count
if planet.distance(turtle)<40:
if count>1:
score_num.clear()
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
earth_health+=-10
score_board.write("Earth health")
score_num.write(earth_health)
count+=1
if earth_health<90:
end_turtle.write("You lost and humanity lost")
if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
turtle.setpos(turtle_x,turtle_y)
break
turtle_x = random.randint(-200,200)
turtle_y = random.randint(-200,200)
global damage
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
#1st enemy(switch heading)
head = 0
def enemy1():
global earth_health
if earth_health<90:
enemy1stop=True # <--
And in the enemy1 function:
def enemy1():
global earth_health
if earth_health<90:
screen.ontimer(enemy1,0)
...
if enemy1stop == True:
return # this will stop the function from repeating
screen.ontimer(enemy1,50)

Related

How to get the scoreboard to work in Turtle Graphics?

**I just need to update the score constantly when the ball crashes into the platform.
What also I do not know is how to clone the ball to make multiple balls in the arena
If anyone can give some input that would be great also
Here is the code I have:**
import turtle
import random
from random import randint
import time
from turtle import Turtle
HEIGHT, WIDTH = 500, 500
screen = turtle.Screen()
screen.screensize(HEIGHT, WIDTH)
COLORS = 'white', 'green' ,'cyan', 'orange', 'skyblue'
screen.bgcolor(random.choice(COLORS))
screen.title("Bounce a ball")
CURSOR_SIZE = 20
def tDirection(direct):
t.setheading(direct)
# make arena
def rectangle():
t.pendown()
for i in range(2):
t.forward(600)
t.left(90)
t.forward(600)
t.left(90)
t.penup()
#defines new turtle
pen = turtle.Turtle()
#right and left keys
def move_left():
pen.penup()
pen.setheading(0)
pen.bk(100)
def move_right():
pen.penup()
pen.setheading(0)
pen.fd(100)
#plaform###########################
pen.penup()
pen.goto(0, -250)
pen.shape("square")
pen.color("black")
pen.shapesize(1, 5)
screen.listen()
screen.onkey(move_right, "Right")
screen.onkey(move_left, "Left")
#####################################
n = turtle.Turtle()
score = 0
n.penup()
n.goto(-50,250)
n.write("Your score:", font=20)
n.hideturtle()
#circle######################################
t = Turtle("circle", visible=False)
t.speed('fastest')
t.pensize(5)
t.penup()
t.goto(-300, -300)
###########################################
rectangle()
index = 0
#####################################
t.color('black')
t.home()
t.showturtle()
#####################################
direct = randint(1, 600)
tDirection(direct)
while True:
t.forward(2)
ty = t.ycor()
def is_collided_with(a, b):
return abs(a.xcor() - b.xcor()) < 10 and abs(a.ycor() - b.ycor()) < 10
# breaking out top or bottom
if is_collided_with(t, pen):
score += 1
print("Coll")
continue
if not CURSOR_SIZE - 300 <= ty <= 300 - CURSOR_SIZE:
index += 1
t.color('pink')
angleCurr = t.heading()
if 0 < angleCurr < 180:
tDirection(0 - angleCurr)
else:
tDirection(360 - angleCurr)
t.forward(2)
n.getscreen().update()
tx = t.xcor()
# breaking out left or right
if not CURSOR_SIZE - 300 <= tx <= 300 - CURSOR_SIZE:
index += 1
t.color('blue')
angleCurr = t.heading()
if 0 < angleCurr < 180:
tDirection(180 - angleCurr)
else:
tDirection(540 - angleCurr)
t.forward(2)
Most of game is working I just do not know how to write a scoreboard and how to make it run smoothly.

How to get the circle to bounce off the platform and end the game once it hits the red bar at the bottom python?

Any input would be grateful
I need help understanding why it won't break the loop and what I can do to make it bounce off the platform
It could be because of turtle graphics
I figured out most of program to run
import turtle
import random
from random import randint
import time
from turtle import Turtle
HEIGHT, WIDTH = 500, 500
screen = turtle.Screen()
screen.screensize(HEIGHT, WIDTH)
COLORS = 'white', 'green' ,'cyan', 'orange', 'skyblue'
screen.bgcolor(random.choice(COLORS))
screen.title("Bounce a ball")
CURSOR_SIZE = 20
#new direction
def tDirection(direct):
t.setheading(direct)
# make arena
def rectangle():
t.pendown()
for i in range(2):
t.forward(600)
t.left(90)
t.forward(600)
t.left(90)
t.penup()
#defines new turtle
pen = turtle.Turtle()
#right and left keys
def move_left():
pen.penup()
pen.setheading(0)
pen.bk(100)
def move_right():
pen.penup()
pen.setheading(0)
pen.fd(100)
#plaform###########################
pen.penup()
pen.goto(0, -250)
pen.shape("square")
pen.color("black")
pen.shapesize(1, 5)
screen.listen()
screen.onkey(move_right, "Right")
screen.onkey(move_left, "Left")
#score = 0
#####################################
#circle######################################
t = Turtle("circle", visible=False)
t.speed('fastest')
t.pensize(5)
t.penup()
t.goto(-300, -300)
###########################################
n = turtle.Turtle()
n.penup()
n.goto(0, -290)
n.shape('square')
n.color('red')
n.shapesize(1,30)
score = 0
rectangle()
score_turtle = turtle.Turtle()
score_turtle.penup()
score_turtle.goto(-50, 250)
score_turtle.write("Your score: {}".format(score), font=20)
score_turtle.hideturtle()
index = 0
#####################################
t.color('black')
t.home()
t.showturtle()
#####################################
direct = randint(1, 600)
tDirection(direct)
while True:
t.forward(2)
ty = t.ycor()
def is_collided_with(a, b):
return abs(a.xcor() - b.xcor()) < 10 and abs(a.ycor() - b.ycor()) < 10
if is_collided_with(t, n):
print("Oh no the game is over")
print(f"Your Final Score:", {score})
break
# breaking out top or bottom
if not CURSOR_SIZE - 300 <= ty <= 300 - CURSOR_SIZE:
index += 1
t.color('pink')
angleCurr = t.heading()
if 0 < angleCurr < 180:
tDirection(0 - angleCurr)
else:
tDirection(360 - angleCurr)
t.forward(2)
tx = t.xcor()
# breaking out left or right
if not CURSOR_SIZE - 300 <= tx <= 300 - CURSOR_SIZE:
index += 1
t.color('blue')
angleCurr = t.heading()
if 0 < angleCurr < 180:
tDirection(180 - angleCurr)
else:
tDirection(540 - angleCurr)
t.forward(2)
if is_collided_with(t, pen):
print("Collision!")
score += 1
score_turtle.clear()
score_turtle.write("Your score: {}".format(score), font=20)
continue
I am also wondering if I should add multiple balls too to make it more interesting but for now I just want to one

Continuous background music with winsound module

So, I have been working on this game called Space Invader. Everything is doing great except for one thing which is the sound. As in the below code, I've imported winsound module and it is not doing well. When I fire the bullet it makes the fire noise which I wanted but the problem is that I've also added background music, and whenever I hit fire it stops the background music and starts making fire noises until it hits the target. I want background music to run continuously. I've also seen many Youtube videos but couldn't get any help. Can anyone tell me the mistake which I've made in the below code?
import turtle
import random
import math
import winsound
score = 0
highscore = 0
targets = []
live_remaining = 3
screen = turtle.Screen()
screen.title("Space War")
screen.bgcolor("Black")
screen.setup(width=800, height=770)
screen.bgpic("Space.gif")
screen.addshape("Spaceship.gif")
screen.addshape("Missile.gif")
screen.addshape("ufo.gif")
screen.addshape("gameover.gif")
screen.addshape("youwin.gif")
screen.tracer(0)
winsound.PlaySound("bgmusic.wav", winsound.SND_ASYNC)
spaceship = turtle.Turtle()
spaceship.speed(0)
spaceship.shape("Spaceship.gif")
spaceship.penup()
spaceship.ht()
spaceship.goto(0, -320)
spaceship.st()
spaceship.direction = "stop"
spaceshipspeed = 15
num_of_targets = 50
for i in range(num_of_targets):
targets.append(turtle.Turtle())
target_start_x = -250
target_start_y = 275
target_number = 0
for target in targets:
target.shape("ufo.gif")
target.penup()
target.speed(0)
x=target_start_x + (50 * target_number)
y=target_start_y
target.goto(x, y)
target_number += 1
if target_number == 10:
target_start_y -= 20
target_number = 0
targetspeed = 0.5
fires=turtle.Turtle()
fires.shape("Missile.gif")
fires.penup()
fires.ht()
fires.speed(0)
fires.goto(0, -340)
fires.direction = "stop"
firesspeed=3
fire = turtle.Turtle()
fire.shape("Missile.gif")
fire.penup()
fire.ht()
fire.speed(0)
fire.goto(0, -340)
fire.direction = "stop"
firespeed = 4
firestate = "ready"
sb=turtle.Turtle()
sb.shape("square")
sb.color("white")
sb.ht()
sb.penup()
sb.goto(0,320)
sb.write("Score: 0 | High Score: 0", align="center", font=("courier", 30, "bold"))
life = turtle.Turtle()
life.shape("square")
life.ht()
life.penup()
life.goto(-350,-350)
life.color("white")
life.write("Life remaining: 3", font=("courier",10,"bold"))
def go_left():
x = spaceship.xcor()
x -= spaceshipspeed
if x < -340:
x = -340
spaceship.setx(x)
def go_right():
x = spaceship.xcor()
x += spaceshipspeed
if x > 340:
x = 340
spaceship.setx(x)
def go_forward():
global firestate
if firestate == "ready":
firestate = "fire"
x = spaceship.xcor()
y = spaceship.ycor()
fire.setposition(x, y)
fire.st()
winsound.PlaySound("fire.wav", winsound.SND_ASYNC)
def move():
pass
screen.listen()
screen.onkeypress(go_left, "a")
screen.onkeypress(go_right, "d")
screen.onkeypress(go_forward, "space")
while True:
screen.update()
for target in targets:
x = target.xcor()
x += targetspeed
target.setx(x)
if target.xcor() > 340:
targetspeed *= -1
for t in targets:
y = t.ycor()
y -= 20
t.sety(y)
if target.xcor() < -340:
targetspeed *= -1
for t in targets:
y = t.ycor()
y -= 20
t.sety(y)
if fire.distance(target) < 20:
fire.direction = "stop"
fire.ht()
fire.clear()
firestate = "ready"
fire.goto(10000000, 1000000)
target.goto(0, 10000000)
score += 10
winsound.PlaySound("explosion.wav", winsound.SND_ASYNC)
if score > highscore:
highscore = score
sb.clear()
sb.write("Score: {} | High Score: {}".format(score,highscore), align="center",
font=("courier", 30, "bold"))
if score == 500:
screen.clear()
screen.bgcolor("black")
gf = turtle.Turtle()
gf.shape("youwin.gif")
gf.goto(0, 0)
winsound.PlaySound("gamewin.wav",winsound.SND_ASYNC)
if spaceship.distance(target) < 60:
spaceship.goto(0, -320)
target.goto(-320, 300)
live_remaining -= 1
winsound.PlaySound("explosion.wav",winsound.SND_ASYNC)
life.clear()
life.write("Life remaining: {}".format(live_remaining), font=("courier",10,"bold"))
if live_remaining == 0:
screen.clear()
screen.bgcolor("black")
gover=turtle.Turtle()
gover.shape("gameover.gif")
gover.goto(0, 0)
winsound.PlaySound("gamelose.wav", winsound.SND_ASYNC)
replay = input("Press r to retry",)
y = fire.ycor()
y += firespeed
fire.sety(y)
if fire.ycor() > 300:
fire.ht()
firestate = "ready"
move()
screen.mainloop()

Why do my functions run a million miles an hour?

The enemy1, enemy2, and enemy3 functions should run instantaniously using the ontimer function, moving the turtles inside them while running a nested checkcollision function to check if the turtles collide with the user. Along that running a nested checkbullet function to check distance see if they collide with the bullet turtle, and a nested check earth function to check their distance from the earth turtle which is the blue circle in the bottom right of the screen. However these 3 functions are running at hypersonic speed and I can't seem to find out why.
from turtle import Screen, Turtle
import random
from random import randint
#screen setup
screen = Screen()
screen.setup(width=450, height=450)
screen.bgcolor('black')
screen.tracer(3)
#user
player = Turtle()
player.shape('square')
player.color("green")
player.penup()
#First enemy
player2 = Turtle()
player2.color("green")
player2.shape('turtle')
player2.penup()
player2.setpos(random.randint(-200,200), random.randint(-200,200))
player2.setheading(random.randint(1,360))
#Second enemy
player3 = Turtle()
player3.color("green")
player3.shape('square')
player3.penup()
player3.setpos(random.randint(-200,200), random.randint(-200,200))
player3.setheading(random.randint(1,360))
#third enemy
player4 = Turtle()
player4.color("green")
player4.shape('triangle')
player4.penup()
player4.setpos(random.randint(-200,200), random.randint(-200,200))
player4.setheading(random.randint(1,360))
#earth
earth = Turtle()
earth.penup()
earth.shape("circle")
earth.color("blue")
earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6)
earth.setpos(150,-150)
#bullet
bullet = Turtle()
bullet.shape("turtle")
bullet.color("purple")
bullet.hideturtle()
bullet.penup()
bullet.setpos(random.randint(-200,200),random.randint(-200,200))
bullet.hideturtle()
bullet.penup()
px = 0
py = 0
def up():
global px
global py
py = player.ycor() + 5
if py >= 200:
py -= 15
player.sety(py)
def down():
global px
global py
py = player.ycor() - 5
if py < -200:
py += 15
player.sety(py)
def left():
global px
global py
px = player.xcor() - 5
if px <= -200:
px += 15
player.setx(px)
def right():
global px
global py
px = player.xcor() + 5
if px >= 200:
px -= 15
player.setx(px)
#distance calculator
def checkcollision(t1, t2):
while t1.distance(t2) < 10:
t2.setpos(randint(-100, 100), randint(-100, 100))
# the x and y distance that the player2 turtle moves
dx = 5
dy = 5
damage = 0
def checkbullet(bullet,turtle):
while bullet.distance(turtle) < 10:
turtle.hideturtle()
def check_earth(planet,turtle):
global damage
damage+=1
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
#1st enemy(switch heading)
head = 0
def enemy1():
checkcollision(player,player2)
check_earth(earth,player2)
global head
player2.fd(5)
x2, y2 = player2.position()
head = player2.heading()
if y2 <= -200 or y2 >= 200:
player2.fd(0)
player2.backward(7.5)
player2.setheading((head)* -1)
if x2 <= -200 or x2 >= 200:
player2.fd(0)
player2.backward(7.5)
if head < 90:
player2.setheading(0 - ((head) * 2))
if head>90<179:
player2.setheading((head)/2)
if head>179<260:
player2.setheading((head)/3)
if head>260<361:
player2.setheading((head)/2)
screen.ontimer(enemy1,50)
#Second enemy(dx,dy)
def enemy2():
checkcollision(player, player3)
check_earth(earth,player3)
global dx
global dy
x3, y3 = player3.position()
player3.setposition(x3 + dx, y3 + dy)
if y3 <= -200 or y3 >= 200:
dy *= -1
player3.sety(y3 + dy)
if x3 <= -200 or x3 >= 200:
dx *= -1
player3.setx(x3 + dx)
screen.ontimer(enemy2,50)
def enemy3():
checkcollision(player,player4)
check_earth(earth,player4)
player4.fd(5)
x4, y4 = player4.position()
head3 = player4.heading()
if y4 <= -200 or y4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
player4.setheading((head3)* -1)
if x4 <= -200 or x4 >= 200:
player4.fd(0)
player4.backward(7.5)
player4.fd(0)
if head3 < 90:
player4.setheading(0 - ((head3) * 2))
if head3>90<179:
player4.setheading((head3)/2)
if head3>179<260:
player4.setheading((head3)/3)
if head3>260<361:
player4.setheading((head3)/2)
screen.ontimer(enemy3,50)
#When bullet hits wall
def bullet_end():
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
def shoot_key():
bullet.setposition(px,py)
bullet.shape("circle")
bullet.showturtle()
bullet.penup()
def shoot():
checkbullet(bullet,player2)
checkbullet(bullet,player3)
checkbullet(bullet,player4)
bx = bullet.xcor()
by = bullet.ycor()
bullet.fd(5)
if bx>=200 or bx<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
if by>=200 or by<=-200:
bullet.hideturtle()
bullet.backward(7.5)
bullet_end()
screen.ontimer(shoot,50)
shoot()
screen.listen()
screen.onkeypress(up, 'Up')
screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down, 'Down')
screen.onkeyrelease(shoot_key,"w")
enemy1()
enemy2()
enemy3()
screen.mainloop()
The problem is caused by the function check_earth. As far as I can see, you are trying to prevent the enemy from being too close to earth - if it gets there, it should receive a new, random position. Obviously, this new position also shouldn't be too near to earth, so you are doing it in a loop. However, there are three errors in the loop.
Firstly, the condition for looking for a new position: while planet.distance(turtle)>10: is always met for a valid place.
Secondly, you immediately move the enemy to new random position, without checking the condition, which creates a lot of traffic. Instead, you should set position only when you are sure that it's correct.
Lastly, where did the '10' value come from? To declare your circle's size, you used: earth.shapesize(stretch_wid = 5.6, stretch_len = 5.6). There is a following dependency between earth radius and stretch length: 2*RADIUS/CURSOR_SIZE. As default value of CURSOR_SIZE is 20, it would mean that the radius of your circle is 56. If we want to detect the collision as soon as any part of enemy's turtle touches the earth, we should also add the length of the enemy's cursor.
So, instead of:
def check_earth(planet,turtle):
global damage
damage+=1
while planet.distance(turtle)>10:
turtle.setpos(random.randint(-200,200),random.randint(-200,200))
You should define function check_earth as:
CURSOR_SIZE = 20
EARTH_RADIUS = 56
def check_earth(planet,turtle):
global damage
damage+=1
(turtle_x, turtle_y) = turtle.pos()
while True:
if planet.distance(turtle_x, turtle_y) > EARTH_RADIUS + CURSOR_SIZE:
turtle.setpos(turtle_x,turtle_y)
break
turtle_x = random.randint(-200,200)
turtle_y = random.randint(-200,200)
Not: while planet.distance(turtle)>10:
Yes: while planet.distance(turtle)<10:
The solution was simple and we both overlooked it,
I ask dumb questions sometimes. Anyways thanks for helping

Collision detection does not work when controls are added

I have a code that kind of detects collision, it works if I set the x and y away from the object which it detects collision from (I need to set it straight away from the code before I run the script)
If I add controls into it, and move it around while its running, it doesn't detect the collision.
Here is the code:
import time
import random
import sys
import turtle
wn = turtle.Screen()
wn.title('collision')
wn.bgcolor('black')
wn.setup(width=800, height=600)
wn.tracer(0)
p_s = 20
e_s = 20
px = 0
py = 0
ex = 0
ey = 0
pec = 0
def collision():
global pec
pupc = px + p_s / 2
pdownc = px - p_s / 2
pupcy = py + p_s / 2
pdowncy = py - p_s / 2
if ex == px or ex > px and ex < pupc or ex == px or ex < px and ex > pdownc:
if ey == py or ey > py and ey < pupcy or ey == py or ey < py and ey > pdowncy:
pec = 1
else:
pec = 0
else:
pec = 0
if pec == 1:
print ('collision')
elif pec == 0:
print ('nope')
#enemy
e = turtle.Turtle()
e.goto(ex, ey)
e.speed(0)
e.color('red')
e.penup()
#player
p = turtle.Turtle()
p.goto(px, py)
p.speed(0)
p.shape('square')
p.color('blue')
p.penup()
print('move')
def p_up():
py = p.ycor()
py += 20
p.sety(py)
print(py)
wn.update()
collision()
def p_down():
py = p.ycor()
py -= 20
p.sety(py)
print(py)
wn.update()
collision()
def p_right():
px = p.xcor()
px += 20
p.setx(px)
print(px)
wn.update()
collision()
def p_left():
px = p.xcor()
px -= 20
p.setx(px)
print(px)
wn.update()
collision()
#keyboard binding
wn.listen()
wn.onkeypress(p_up, "Up")
wn.onkeypress(p_down, "Down")
wn.onkeypress(p_right, "Right")
wn.onkeypress(p_left, "Left")
#main part
while True:
wn.update()
I believe you're making this problem more difficult than necessary. First, turtle provides basic collision detection with the .distance() method. Second, the only globals necessary are constants as we can always interrogate the turtle about it's current position (and heading, etc.):
from turtle import Screen, Turtle
from random import randrange
CURSOR_SIZE = 20
WIDTH, HEIGHT = 800, 600
def player_up():
player.sety(player.ycor() + 20)
check_collision()
def player_down():
player.sety(player.ycor() - 20)
check_collision()
def player_right():
player.setx(player.xcor() + 20)
check_collision()
def player_left():
player.setx(player.xcor() - 20)
check_collision()
def enemy_relocate():
enemy.hideturtle()
x = randrange(CURSOR_SIZE - WIDTH/2, WIDTH/2 - CURSOR_SIZE)
y = randrange(CURSOR_SIZE - HEIGHT/2, HEIGHT/2 - CURSOR_SIZE)
enemy.goto(x, y)
enemy.showturtle()
def check_collision():
if player.distance(enemy) < CURSOR_SIZE:
print("Collision!")
enemy_relocate()
screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.title("Collision!")
screen.bgcolor('black')
# enemy
enemy = Turtle()
enemy.shape('circle')
enemy.color('red')
enemy.speed('fastest')
enemy.penup()
enemy_relocate()
# player
player = Turtle()
player.shape('square')
player.color('blue')
player.speed('fastest')
player.penup()
# keyboard binding
screen.onkeypress(player_up, 'Up')
screen.onkeypress(player_down, 'Down')
screen.onkeypress(player_right, 'Right')
screen.onkeypress(player_left, 'Left')
screen.listen()
# main part
screen.mainloop()

Categories

Resources