How would I get my turtle to restart in the middle of screen once it collides with it's own body?
from turtle import Screen, Turtle
import random
import time
DELAY = 100
def move():
if direction == 'up':
y = turtle.ycor()
turtle.sety(y + 20)
elif direction == 'down':
y = turtle.ycor()
turtle.sety(y - 20)
elif direction == 'left':
x = turtle.xcor()
turtle.setx(x - 20)
elif direction == 'right':
x = turtle.xcor()
turtle.setx(x + 20)
screen.update()
screen.ontimer(move, DELAY)
if turtle.xcor()>490 or turtle.xcor()<-490 or turtle.ycor()>490 or turtle.ycor()<-490:
time.sleep(1)
turtle.goto(0,0)
turtle.direction = "stop"
for section in sections
section.goto(1000, 1000)
sections.clear()
if turtle.distance(food) < 20:
x = random.randint(-390, 390)
y = random.randint(-390, 390)
food.goto(x, y)
new_section = Turtle()
new_section.speed(0)
new_section.shape("square")
new_section.color("orange", "grey")
new_section.penup()
sections.append(new_section)
for index in range(len(sections)-1,0, -1):
x = sections[index-1].xcor()
y = sections[index-1].ycor()
sections[index].goto(x, y)
if len(sections) > 0:
x = turtle.xcor()
y = turtle.ycor()
sections[0].goto(x, y)
def up():
global direction
direction = 'up'
def down():
global direction
direction = 'down'
def left():
global direction
direction = 'left'
def right():
global direction
direction = 'right'
screen = Screen()
screen.title(" Snakebite mini Game")
screen.bgcolor('brown')
screen.setup(width=800, height=700)
screen.tracer(0)
turtle = Turtle()
turtle.shape('turtle')
turtle.speed(0)
turtle.penup()
food = Turtle()
food.shape('circle')
food.color("red", "yellow")
food.speed(0)
food.penup()
food.goto(0,100)
sections = []
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()
The basic answer is something like:
if any(turtle.distance(section) < 20 for section in sections):
turtle.goto(0, 0)
direction = 'stop'
...
But be warned, this means that doing a 180 is now a fatal move!
Complete code rework with optimizations, style tweaks and changes to make it more playable:
from turtle import Screen, Turtle
from random import randint
DELAY = 100
def up():
global direction
direction = 'up'
turtle.setheading(90)
def down():
global direction
direction = 'down'
turtle.setheading(270)
def left():
global direction
direction = 'left'
turtle.setheading(180)
def right():
global direction
direction = 'right'
turtle.setheading(0)
def move():
global direction
x, y = old_position = turtle.position()
if direction == 'up':
turtle.sety(y + 20)
elif direction == 'down':
turtle.sety(y - 20)
elif direction == 'left':
turtle.setx(x - 20)
elif direction == 'right':
turtle.setx(x + 20)
if direction != 'stop':
if sections:
if any(turtle.distance(section) < 20 for section in sections):
turtle.goto(0, 0)
direction = 'stop'
for section in sections:
section.hideturtle()
sections.clear()
else:
last_position = sections[-1].position()
if len(sections) > 1:
for index in range(len(sections) - 1, 0, -1):
sections[index].goto(sections[index - 1].position())
sections[0].goto(old_position)
old_position = last_position
if not (-390 < turtle.xcor() < 390 and -390 < turtle.ycor() < 390):
turtle.goto(0, 0)
direction = 'stop'
for section in sections:
section.hideturtle()
sections.clear()
if turtle.distance(food) < 20:
food.goto(randint(-380, 380), randint(-380, 380))
new_section = Turtle()
new_section.shape('square')
new_section.speed('fastest')
new_section.color('orange', 'grey')
new_section.penup()
new_section.goto(old_position)
sections.append(new_section)
screen.update()
screen.ontimer(move, DELAY)
screen = Screen()
screen.title("Snakebite mini Game")
screen.bgcolor('brown')
screen.setup(width=800, height=800)
screen.tracer(False)
turtle = Turtle()
turtle.shape('triangle')
turtle.speed('fastest')
turtle.color('orange', 'grey')
turtle.penup()
food = Turtle()
food.shape('circle')
food.speed('fastest')
food.color('red', 'yellow')
food.penup()
food.goto(randint(-380, 380), randint(-380, 380))
sections = []
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()
Related
I have made a program to move turtle position by pressing the keyboard, but is there a way to make it move in smaller increments of pixels?
and also, is it possible to move turtle up and down instead of only left and right?
from turtle import Screen, Turtle
TURTLE_SIZE = 200
# functions
def go_left():
t.direction = 'left'
def go_right():
t.direction = 'right'
screen = Screen()
screen.setup(1152,648)
screen.tracer(0)
# player
t = Turtle()
t.shape("circle")
t.speed("slowest")
t.color("blue")
t.penup()
t.setx(338)
t.sety(0)
t.direction = 'stop'
# Keyboard
screen.onkeypress(go_left, 'Left')
screen.onkeypress(go_right, 'Right')
screen.listen()
while True:
x = t.xcor()
if t.direction == 'left':
if x > TURTLE_SIZE - 576:
x -= 3
t.setx(x)
else:
t.direction = 'stop'
elif t.direction == 'right':
if x < 576 - TURTLE_SIZE:
x += 3
t.setx(x)
else:
t.direction = 'stop'
screen.update()
screen.mainloop()
The reason your dot was moving so fast was because of your while True loop.
I moved most of that logic inside the the go_ functions and added an up and down for you as well.
from turtle import Screen, Turtle
TURTLE_SIZE = 200
def go_left():
x = t.xcor()
if x > TURTLE_SIZE - 576:
x -= 3
t.setx(x)
screen.update()
def go_right():
x = t.xcor()
if x < 576 - TURTLE_SIZE:
x += 3
t.setx(x)
screen.update()
def go_up(): # added this function
y = t.ycor()
if y < 576 - TURTLE_SIZE:
y += 3
t.sety(y)
screen.update()
def go_down(): # added this function
y = t.ycor()
if y < 576 - TURTLE_SIZE:
y -= 3
t.sety(y)
screen.update()
screen = Screen()
screen.setup(1152,648)
screen.tracer(0)
t = Turtle()
t.shape("circle")
t.speed("slowest")
t.color("blue")
t.penup()
t.setx(338)
t.sety(0)
screen.update()
# Keyboard
screen.onkeypress(go_left, 'Left')
screen.onkeypress(go_down, 'Down') # added this listener
screen.onkeypress(go_up, 'Up') # added this listner
screen.onkeypress(go_right, 'Right')
screen.listen()
screen.mainloop()
#importing
import turtle
import random
import time
def snake_game():
#making head global so it can be used in other functions
global head
#scores
score = 0
high_score = 0
#setting up screen
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor('yellow')
wn.setup(width=600, height=600)
wn.tracer(0)
# making snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("black")
head.penup()
head.goto(0,0)
head.direction = "stop"
#snake food
food= turtle.Turtle()
food.speed(0)
food.shape("square")
food.color("red")
food.penup()
food.goto(0,100)
segments = []
#scoreboards
sc = turtle.Turtle()
sc.speed(0)
sc.shape("square")
sc.color("black")
sc.penup()
sc.hideturtle()
sc.goto(0,260)
sc.write("score: 0 High score: 0", align = "center", font=("ds-digital", 24, "normal"))
#keyboard bindings
wn.listen()
wn.onkeypress(go_up, "w")
wn.onkeypress(go_down, "s")
wn.onkeypress(go_left, "a")
wn.onkeypress(go_right, "d")
#MainLoop
while True:
wn.update()
#check collision with border area
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
#hide the segments of body
for segment in segments:
segment.goto(1000,1000) #out of range
#clear the segments
segments.clear()
#reset score
score = 0
#reset delay
delay = 0.1
sc.clear()
sc.write("score: {} High score: {}".format(score, high_score), align="center", font=("ds-digital", 24, "normal"))
#check collision
if head.distance(food) <20:
# move the food to random place
x = random.randint(-290,290)
y = random.randint(-290,290)
food.goto(x,y)
#add a new segment to the head
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("black")
new_segment.penup()
segments.append(new_segment)
#shorten the delay
delay -= 0.001
#increase the score
score += 10
if score > high_score:
high_score = score
sc.clear()
sc.write("score: {} High score: {}".format(score,high_score), align="center", font=("ds-digital", 24, "normal"))
#move the segments in reverse order
for index in range(len(segments)-1,0,-1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x,y)
#move segment 0 to head
if len(segments)>0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
for segment in segments:
if segment.distance(head)<20:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
#hide segments
for segment in segments:
segment.goto(1000,1000)
segments.clear()
score = 0
delay = 0.1
#update the score
sc.clear()
sc.write("score: {} High score: {}".format(score,high_score), align="center", font=("ds-digital", 24, "normal"))
time.sleep(delay)
wun.mainloop()
def go_up():
if head.direction != "down":
head.direction = "up"
def go_down():
if head.direction != "up":
head.direction = "down"
def go_left():
if head.direction != "right":
head.direction = "left"
def go_right():
if head.direction != "left":
head.direction = "right"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y+20)
if head.direction == "down":
y = head.ycor()
head.sety(y-20)
if head.direction == "left":
x = head.xcor()
head.setx(x-20)
if head.direction == "right":
x = head.xcor()
head.setx(x+20)
Well it was working fine as a normal program as long as the code in the function snake_game was the main program it was moving, but I have to append this game with other games. I have to call this game using a function, so when I converted it to a function it didn't move . The code is running and squares dots are also coming but on pressing keys the snake is not moving. I don't know where it went wrong.
This snake game code is written in python-turtle. I want to move snake head, which is drawn using turtle module, but unfortunately it doesn't work. Also I add multiple foods for snake using for loop ,Might they have problem in collision, but i don't no how to rid this...?????
importing modules
import turtle
from turtle import *
import random
import time
delay = 0.1
level = 1
lives = 3
#score
score = 0
high_score = 0
#setting the screen
wn = turtle.Screen()
wn.title('Snake Game')
wn.bgcolor('black')
wn.bgpic('pic55.png')
#wn.addshape('snake head6.png')
wn.setup(width= 600, height= 600)
wn.tracer(0) #turns off the screen update
Snake head drawn using turtle
#snake head
head = turtle.Turtle()
def draw_circle(color, radius, x, y):
#head(turtle.Turtle())
head.penup()
head.fillcolor(color)
head.goto(x, y)
head.begin_fill()
head.circle(radius)
head.end_fill()
head.hideturtle()
draw_circle("#FF4500", 30, 0, -40) #face OrangeRed #FF4500 green #2CD717
draw_circle("#ffffff", 10, -10, -5) #left eye 9659BD purple
draw_circle("#ffffff", 10, 10, -5) #right eye B4BCE2 light blue
draw_circle("#4a70e3", 7, -8, -4) #5e7ede 9eb1eb 4a70e3 royalblue light colors
draw_circle("#4a70e3", 7, 8, -4)
draw_circle("#17202A", 5, -10, -5) ##17202A black
draw_circle("#17202A", 5, 10, -5)
#colors = random.choice(['green','black'])
#shapes = random.choice(['square'])
#head.shape(shapes)
#head.color(colors)
head.goto(0,0)
head.penup()
head.speed(0) #animation speed
head.direction = 'stop'
#segment = []
Multiple food
#max food
maxfoods =10
foods = []
#snake food
for count in range(maxfoods):
foods.append(turtle.Turtle())
foods[count].color('red')
foods[count].shape('square')
#food[count].shape(shapes)
#food[count].color(colors)
foods[count].penup()
foods[count].speed()
foods[count].speed(0)#animation speed
foods[count].setposition(random.randint(-300, 300) ,random.randint(-300, 300))
segment = []
#pen
pen = turtle.Turtle()
pen.speed(0)
pen.shape('square')
pen.color('white')
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write("Score: 0 High Score: 0 Level: 1 Lives: 3",align = "center", font=("courier", 16, "normal"))
#functions
def go_up():
if head.direction != 'down':
head.direction = 'up'
def go_down():
if head.direction != 'up':
head.direction = 'down'
def go_left():
if head.direction != 'right':
head.direction = 'left'
def go_right():
if head.direction != 'left':
head.direction = 'right'
def move():
if head.direction == 'up':
y = head.ycor()
head.sety(y + 20)
if head.direction == 'down':
y = head.ycor()
head.sety(y - 20)
if head.direction == 'left':
x = head.xcor()
head.setx(x - 20)
if head.direction == 'right':
x = head.xcor()
head.setx(x + 20)
#keyboard binding
wn.listen()
wn.onkeypress(go_up, 'Up')
wn.onkeypress(go_down, 'Down')
wn.onkeypress(go_left, 'Left')
wn.onkeypress(go_right, 'Right')
while loop
while True:
wn.update()
#check the border collision
if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
time.sleep(1)
head.goto(0, 0)
head.direction = 'stop'
for segments in segment:
segment.goto(1000, 1000)
segment.clear()
#reset the score
score = 0
#reset the delay
delay = 0.1
#reset level
level = 1
pen.clear()
pen.write("Score: {} High Score: {} Level: {} Lives: {}".format(score, high_score, level, lives),align = "center", font=("courier", 16, "normal"))
#check for head collision with the food
for count in range(maxfoods):
#maxfood.forward(3)
if head.distance(foods) < 20:
#MOve the head random
x = random.randint(-290, 290)
y = random.randint(-290, 290)
foods.goto(x, y)
#add body to snake
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape('square')
new_segment.color('green')
new_segment.penup()
segment.append(new_segment)
#shorten the delay
delay -= 0.001
#increase the score
score +=10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score: {} High Score: {} Level: {} Lives: {}".format(score, high_score, level, lives),align = "center", font=("courier", 16, "normal"))
#Move the end body in reverse order
for index in range(len(segment)-1, 0, -1):
x = segment[index-1].xcor()
y = segment[index-1].ycor()
segment[index].goto(x, y)
#move the body 0 t where the head is
if len(segment) > 0:
x = head.xcor()
y = head.ycor()
segment[0].goto(x, y)
move()
#check for head collision with body/segment
for segments in segment:
if segments.distance(head) < 20:
time.sleep(1)
head.goto(0, 0)
head.direction = 'stop'
#hide the segment
for segments in segment:
segments.goto(1000, 1000)
#clear the segment list
segment.clear()
#reset the score
score = 0
#reset the level
level = 1
#update the score display
pen.clear()
pen.write("Score: {} High Score: {} Level: {} Lives: {}".format(score, high_score, level, lives),align = "center", font=("courier", 16, "normal"))
#levels
if level == 1 and score == 50:
level += 1
delay *= 0.9
if level == 2 and score == 100:
level += 1
delay *= 0.9
if level == 3 and score == 250:
level += 1
delay *= 0.9
if level == 4 and score == 350:
level += 1
delay *= 0.9
if level == 5 and score == 450:
level += 5
delay *= 0.9
time.sleep(delay)
wn.maingameloop()
Your code is a disaster. How did you write so much detailed code without testing whether the basics work? Examples of obvious problems:
if head.distance(foods) < 20:
The foods variable is a list, you should be testing:
if head.distance(foods[count]) < 20:
And this code:
#shorten the delay
delay -= 0.001
eventually drives delay negative and time.sleep() fails. And again here:
foods.goto(x, y)
The foods variable is a list, it doesn't respond to goto(). Also, you always draw your snake head in the same place, regardless of where the snake is located!
Below is a complete rework of a stripped down version of your program that attempts to get the basics working. The snake head moves; it can eat food to increase its score; border collisions are detected and reset the score and snake position:
from turtle import Screen, Turtle
from random import randint
FONT = ("courier", 16, "normal")
# score
score = 0
high_score = 0
# functions
def draw_circle(color, radius, x, y):
head.fillcolor(color)
head.goto(x, y)
head.begin_fill()
head.circle(radius)
head.end_fill()
def go_up():
if head.direction != 'down':
head.direction = 'up'
def go_down():
if head.direction != 'up':
head.direction = 'down'
def go_left():
if head.direction != 'right':
head.direction = 'left'
def go_right():
if head.direction != 'left':
head.direction = 'right'
def move():
x, y = head.position()
if head.direction == 'up':
head.sety(y + 20)
elif head.direction == 'down':
head.sety(y - 20)
elif head.direction == 'left':
head.setx(x - 20)
elif head.direction == 'right':
head.setx(x + 20)
head.clear()
x, y = head.position()
draw_circle("#FF4500", 30, x + 0, y - 40) # face OrangeRed #FF4500 green #2CD717
draw_circle("#ffffff", 10, x - 10, y - 5) # left eye 9659BD purple
draw_circle("#ffffff", 10, x + 10, y - 5) # right eye B4BCE2 light blue
draw_circle("#4a70e3", 7, x - 8, y - 4) # royalblue
draw_circle("#4a70e3", 7, x + 8, y - 4)
draw_circle("#17202A", 5, x - 10, y - 5) # black
draw_circle("#17202A", 5, x + 10, y - 5)
head.setposition(x, y)
# setting the screen
screen = Screen()
screen.title('Snake Game')
screen.setup(width=600, height=600)
screen.bgcolor('black')
screen.tracer(False) # turns off screen update
# snake head
head = Turtle()
head.hideturtle()
head.penup()
head.direction = 'stop' # user defined property
move()
# max food
maxfoods = 10
foods = []
# snake food
for count in range(maxfoods):
food = Turtle()
food.color('red')
food.shape('square')
food.penup()
food.setposition(randint(-300, 300), randint(-300, 300))
foods.append(food)
# pen
pen = Turtle()
pen.hideturtle()
pen.shape('square')
pen.color('white')
pen.penup()
pen.sety(260)
pen.write("Score: 0 High Score: 0", align="center", font=FONT)
# keyboard binding
screen.onkeypress(go_up, 'Up')
screen.onkeypress(go_down, 'Down')
screen.onkeypress(go_left, 'Left')
screen.onkeypress(go_right, 'Right')
screen.listen()
def motion():
global score, high_score
# check the border collision
if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
head.goto(0, 0)
head.direction = 'stop'
# reset the score
score = 0
pen.clear()
pen.write("Score: {} High Score: {}".format(score, high_score), align="center", font=FONT)
# check for head collision with the food
for food in foods:
if head.distance(food) < 30:
# Move the food randomly
food.goto(randint(-290, 290), randint(-290, 290))
# increase the score
score += 10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score: {} High Score: {}".format(score, high_score), align="center", font=FONT)
break
move()
screen.update()
screen.ontimer(motion, 100)
motion()
screen.mainloop()
Now you should be able to add back features, one at a time, and test them.
import turtle
import time
delay = 0.1
ms = turtle.Screen()
ms.title("hungry snake Game by #Rafa")
ms.bgcolor("green")
ms.setup(width=600, height=600)
ms.tracer(0)
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("black")
head.penup()
head.goto(0, 0)
head.direction = "stop"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x + 20)
if head.direction == "right":
x = head.xcor()
head.setx(x - 20)
# main game loop
while True:
ms.update()
move()
time.sleep(delay)
//Here is where am having trouble with the code?
ms.mainloop()
The real error here is the use of while True: and sleep() in an event-driven environment like turtle. We can replace the infinite loop and the time.sleep() with a turtle ontimer() method:
from turtle import Screen, Turtle
DELAY = 100 # milliseconds
def move():
if direction == 'up':
y = turtle.ycor()
turtle.sety(y + 20)
elif direction == 'down':
y = turtle.ycor()
turtle.sety(y - 20)
elif direction == 'left':
x = turtle.xcor()
turtle.setx(x - 20)
elif direction == 'right':
x = turtle.xcor()
turtle.setx(x + 20)
screen.update()
screen.ontimer(move, DELAY)
def up():
global direction
direction = 'up'
def down():
global direction
direction = 'down'
def left():
global direction
direction = 'left'
def right():
global direction
direction = 'right'
screen = Screen()
screen.title("Hungry Snake Game")
screen.bgcolor('green')
screen.setup(width=600, height=600)
screen.tracer(0)
turtle = Turtle()
turtle.shape('square')
turtle.speed('fastest')
turtle.penup()
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()
I am writing the Space Invaders game from Christian Thompson
I have problem exactly in line 188 where the player and enemy hide when a collision is detected. My player turtle is hiding but the enemy turtle doesn't "want" to hide. Here is the code:
import turtle
import os
import math
import random
import winsound
#Set up the screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("Space Invaders")
wn.bgpic("space_invaders_background.gif")
#Register the shapes
turtle.register_shape("invader.gif")
turtle.register_shape("player.gif")
#Draw border
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300,-300)
border_pen.pendown()
border_pen.pensize(3)
for side in range(4):
border_pen.fd(600)
border_pen.lt(90)
border_pen.hideturtle()
#Set the score to 0
score = 0
#Draw score
score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 280)
scorestring = "Score: %s" %score
score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))
score_pen.hideturtle()
#Game Over
game_over = turtle.Turtle()
game_over.speed(0)
game_over.color("red")
game_over.penup()
game_over.setposition(0, 0)
gameOverMsg = "Game Over!"
game_over.hideturtle()
#Create player
player = turtle.Turtle()
player.color("blue")
player.shape("player.gif")
player.penup()
player.speed(0)
player.setposition(0,-230)
player.setheading(90)
playerspeed = 15
#Choose a number of enemies
number_of_enemies = 20
#Create empty list of enemies
enemies = []
#Add enemies to list
for i in range(number_of_enemies):
# Create the enemy
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.color("red")
enemy.shape("invader.gif")
enemy.penup()
enemy.speed(0)
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
enemyspeed = number_of_enemies * 0.5
#Create the player's bullet
bullet = turtle.Turtle()
bullet.color("yellow")
bullet.shape("triangle")
bullet.penup()
bullet.speed(0)
bullet.setheading(90)
bullet.shapesize(0.5, 0.5)
bullet.hideturtle()
bulletspeed = 20
def laser():
winsound.PlaySound("laser.wav", winsound.SND_ASYNC)
def explosion():
winsound.PlaySound("explosion.wav", winsound.SND_ASYNC)
#Move the player left and right
def move_left():
x = player.xcor()
x -= playerspeed
if x < -280:
x = -280
player.setx(x)
def move_right():
x = player.xcor()
x += playerspeed
if x > 280:
x = 280
player.setx(x)
def fire_bullet():
if not bullet.isvisible():
laser()
#Move the bullet to the just above the player
x = player.xcor()
y = player.ycor() + 10
bullet.setposition(x, y)
bullet.showturtle()
#Checking collision between enemy and bullet
def isCollision(t1, t2) :
distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2)+math.pow(t1.ycor()-t2.ycor(),2))
if distance < 20:
return True
else:
return False
#Create keyboard bindings
turtle.listen()
turtle.onkeypress(move_left, "Left")
turtle.onkeypress(move_right, "Right")
turtle.onkeypress(fire_bullet, "space")
#Main game loop
while True:
for enemy in enemies:
#Move the enemy
x = enemy.xcor()
x += enemyspeed
enemy.setx(x)
#Move the enemy back and down
if enemy.xcor() > 280:
#Move all enemies down
for e in enemies:
y = e.ycor()
y -= 40
e.sety(y)
#Change enemy direction
enemyspeed *= -1
if enemy.xcor() < -280:
#Move all enemies down
for e in enemies:
y = e.ycor()
y -= 40
e.sety(y)
#Change enemy direction
enemyspeed *= -1
# Check for a collision between the bullet and the enemy
if isCollision(bullet, enemy):
explosion()
# Reset the bullet
bullet.hideturtle()
bullet.setposition(0, -400)
# Reset the enemy
x = random.randint(-200, 200)
y = random.randint(100, 250)
enemy.setposition(x, y)
#Update the score
score += 10
scorestring = "Score: %s" %score
score_pen.clear()
score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))
if isCollision(player, enemy):
explosion()
player.hideturtle()
enemy.hideturtle()
game_over.write(gameOverMsg, False, align="center", font=("Arial", 60, "normal"))
break
#Move the bullet
if bullet.isvisible():
y = bullet.ycor()
y += bulletspeed
bullet.sety(y)
#Check border collision
if bullet.ycor() > 290:
bullet.hideturtle()
wn.mainloop()
I wasn't able to reproduce your problem. I've reworked your code below: I've dropped the images and sound so anyone can run it and help you debug it; I tossed your isCollision() code and substituted turtle's own distance() method; I replaced the while True: loop, which has no place in an event-driven world like turtle, with a timer event; I've streamlined the code where I could:
from turtle import Screen, Turtle
from random import randint
PLAYER_SPEED = 15
BULLET_SPEED = 20
# Choose a number of enemies
NUMBER_OF_ENEMIES = 20
SMALL_FONT = ('Arial', 14, 'normal')
LARGE_FONT = ('Arial', 60, 'normal')
# Move the player left and right
def move_left():
x = player.xcor() - PLAYER_SPEED
if x < -280:
x = -280
player.setx(x)
def move_right():
x = player.xcor() + PLAYER_SPEED
if x > 280:
x = 280
player.setx(x)
def fire_bullet():
if not bullet.isvisible():
# Move the bullet to the just above the player
x, y = player.position()
bullet.setposition(x, y + 10)
bullet.showturtle()
# Check collision between enemy and bullet
def isCollision(t1, t2):
return t1.distance(t2) < 20
# Set up the screen
wn = Screen()
wn.bgcolor('black')
wn.title("Space Invaders")
# Draw border
border_pen = Turtle(visible=False)
border_pen.speed('fastest')
border_pen.color('white')
border_pen.pensize(3)
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
for _ in range(4):
border_pen.fd(600)
border_pen.lt(90)
# Set the score to 0
score = 0
# Draw score
score_pen = Turtle(visible=False)
score_pen.speed('fastest')
score_pen.color('white')
score_pen.penup()
score_pen.setposition(-290, 280)
scorestring = "Score: %s" % score
score_pen.write(scorestring, False, align='left', font=SMALL_FONT)
# Game Over
game_over = Turtle(visible=False)
game_over.speed('fastest')
game_over.color('red')
game_over.penup()
gameOverMsg = "Game Over!"
# Create player
player = Turtle('turtle')
player.speed('fastest')
player.color('blue')
player.penup()
player.setposition(0, -230)
player.setheading(90)
# Create empty list of enemies
enemies = []
# Add enemies to list
for _ in range(NUMBER_OF_ENEMIES):
# Create the enemy
enemy = Turtle('turtle', visible=False)
enemy.settiltangle(270) # for non GIF version of game
enemy.speed('fastest')
enemy.color('red')
enemy.penup()
enemy.setposition(randint(-200, 200), randint(100, 250))
enemies.append(enemy)
for enemy in enemies:
enemy.showturtle()
# Create the player's bullet
bullet = Turtle('triangle', visible=False)
bullet.color('yellow')
bullet.penup()
bullet.speed('fastest')
bullet.setheading(90)
bullet.shapesize(0.5)
# Create keyboard bindings
wn.onkeypress(move_left, 'Left')
wn.onkeypress(move_right, 'Right')
wn.onkeypress(fire_bullet, 'space')
wn.listen()
enemy_speed = NUMBER_OF_ENEMIES * 0.5
# Main game loop
def move():
global score, enemy_speed
collision = False
for enemy in enemies:
# Move the enemy
enemy.forward(enemy_speed)
# Check for a collision between the bullet and the enemy
if isCollision(bullet, enemy):
# Reset the bullet
bullet.hideturtle()
# Reset the enemy
enemy.setposition(randint(-200, 200), randint(100, 250))
# Update the score
score += 10
scorestring = "Score: %s" % score
score_pen.clear()
score_pen.write(scorestring, False, align='left', font=SMALL_FONT)
if isCollision(player, enemy):
player.hideturtle()
enemy.hideturtle()
game_over.write(gameOverMsg, False, align='center', font=LARGE_FONT)
collision = True
break
if any(enemy.xcor() < -280 or enemy.xcor() > 280 for enemy in enemies):
# Move all enemies down
for enemy in enemies:
enemy.sety(enemy.ycor() - 40)
# Change enemy direction
enemy_speed *= -1
# Move the bullet
if bullet.isvisible():
bullet.forward(BULLET_SPEED)
# Check border collision
if bullet.ycor() > 290:
bullet.hideturtle()
if not collision:
wn.ontimer(move, 50)
move()
wn.mainloop()
This program is déjà vu for me with respect to this question so see my answer to it for more ideas. Also, see this answer to another space invaders game in turtle to see what you can learn from it to polish your game.