Counting down lives in python turtle - python

I am trying to create a simple python turtle game where the turtle needs to make it to the circle, while avoiding the moving square. I would like the code to count down lives and move the turtle back to the beginning until there are 0 lives left. The code below allows for one play and then the motion loop does not repeat.
I have tried a recursive function (move(3)), but then the onkey commands don't work....
import turtle, random, time
#background
canvas = turtle.Screen()
canvas.bgcolor('black')
#Pen
pen = turtle.Turtle()
pen.penup()
pen.color('white')
pen.hideturtle()
pen.penup()
#Lilypad
pad = turtle.Turtle()
pad.hideturtle()
pad.color('yellow')
pad.shape('circle')
pad.penup()
pad.setposition(0,290)
pad.showturtle()
#Turtle
player = turtle.Turtle()
player.hideturtle()
player.shape('turtle')
player.color('green')
player.penup()
player.left(90)
player.setposition(0, -290)
player.showturtle()
#truck
truck1 = turtle.Turtle()
truck1.hideturtle()
truck1.shape('square')
truck1.color('blue')
truck1.penup()
truck1.showturtle()
speed = random.randint(1,5)
def move():
#move player and truck
player.forward(2)
truck1.forward(speed)
if truck1.xcor() > 300 or truck1.xcor() < -300:
truck1.right(180)
#win if hit the lilypad
if player.distance(pad)<10:
pen.penup()
pen.setposition(0,-50)
pen.write('You win!', align='left', font=('Arial', 36, 'normal'))
done()
#lose a life if hit the truck
if player.distance(truck1) < 30:
player.setposition(0,-290)
life = life - 1
while life > 0:
pen.penup()
pen.setposition(0,-60)
pen.write('Try again', align='left', font=('Arial', 36, 'normal'))
time.sleep(1)
pen.clear()
move()
#game over if 0 lives left
pen.penup()
pen.setposition(0,-60)
pen.write('Game over!', align='left', font=('Arial', 36, 'normal'))
done()
canvas.ontimer(move,10)
canvas.onkey(lambda:player.setheading(90),'Up')
canvas.onkey(lambda:player.setheading(180),'Left')
canvas.onkey(lambda:player.setheading(0),'Right')
canvas.onkey(lambda:player.setheading(270),'Down')
canvas.listen()
life = 3
move()
canvas.mainloop()

The key to this is to move all your initialization code into a function, which invokes your move() function as it's last step. The first thing that the initialization code does is call canvas.clear() which pretty much wipes out everything. Then your move() function makes a choice at the end whether to call itself on the next timer iteration, or call the initialize code on the next timer iteration to reset everything and start a new game.
Below is your code reworked along the above lines as well as various teaks:
from turtle import Screen, Turtle
from random import randint
from time import sleep
FONT = ('Arial', 36, 'normal')
def initialize():
global pen, pad, player, truck, speed, life
canvas.clear() # assume that this resets *everything*
# background
canvas.bgcolor('black')
# Pen
pen = Turtle(visible=False)
pen.color('white')
pen.penup()
# Lilypad
pad = Turtle('circle', visible=False)
pad.color('yellow')
pad.penup()
pad.setposition(0, 290)
pad.showturtle()
# Turtle
player = Turtle('turtle', visible=False)
player.color('green')
player.penup()
player.setheading(90)
player.setposition(0, -290)
player.showturtle()
# truck
truck = Turtle('square', visible=False)
truck.color('blue')
truck.penup()
truck.showturtle()
speed = randint(1, 5)
canvas.onkey(lambda: player.setheading(90), 'Up')
canvas.onkey(lambda: player.setheading(180), 'Left')
canvas.onkey(lambda: player.setheading(0), 'Right')
canvas.onkey(lambda: player.setheading(270), 'Down')
canvas.listen()
life = 3
move()
def move():
global life
# move player and truck
player.forward(2)
truck.forward(speed)
if not -300 < truck.xcor() < 300:
truck.right(180)
# lose a life if hit the truck
if player.distance(truck) < 20:
player.setposition(0, -290)
life -= 1
if life > 0:
pen.setposition(0, -60)
pen.write('Try again', font=FONT)
sleep(1)
pen.clear()
# win if hit the lilypad
if player.distance(pad) < 20:
pen.setposition(0, -50)
pen.write('You win!', font=FONT)
canvas.ontimer(initialize, 1000)
elif life == 0: # game over if 0 lives left
pen.setposition(0, -60)
pen.write('Game over!', font=FONT)
canvas.ontimer(initialize, 1000)
else:
canvas.ontimer(move, 10)
canvas = Screen()
pen = None
pad = None
player = None
truck = None
speed = -1
life = -1
initialize()
canvas.mainloop()
This should let you play over again whether you win or run out of lives.

Related

I am trying to get my collision detection to work but the codes I have put in won't let the collision function work

from turtle import Turtle, Screen
wn = Screen()
wn.bgcolor('lightblue')
spaceship = Turtle()
spaceship.color('red')
spaceship.penup()
import turtle
rocket = turtle.Turtle()
rocket.color('blue')
rocket.penup()
rocket.setposition(-250, -250)
speed = 8
def travel():
spaceship.forward(speed)
if spaceship.xcor() > 500:
spaceship.goto(-500, 0)
if spaceship.xcor() < -500:
spaceship.goto(500, 0)
elif spaceship.ycor() > 500:
spaceship.goto(0, -500)
elif spaceship.ycor() < -500:
spaceship.goto(0, 500)
def rocket_spaceship():
while True:
rocket.setheading(rocket.towards(spaceship))
rocket.forward(speed)
wn.ontimer(travel, 3)
def is_collided_with(rocket_turtle, rocket_spaceship):
return abs(rocket_turtle.xcor() - rocket_spaceship.xcor()) < 10 and abs(rocket_turtle.ycor() - rocket_spaceship.ycor()) < 10
def follow_rocket():
follow.setheading(follow.towards(travel))
follow.forward(min(follow.distance(travel), 8))
if is_collided_with(follow, travel):
print('Collision!')
quitThis()
else:
playGround.ontimer(follow_rocket, 10)
wn.onkey(lambda: spaceship.setheading(90), 'Up')
wn.onkey(lambda: spaceship.setheading(180), 'Left')
wn.onkey(lambda: spaceship.setheading(0), 'Right')
wn.onkey(lambda: spaceship.setheading(270), 'Down')
wn.listen()
rocket_spaceship()
wn.mainloop()
I can move the turtle but when they collide nothing happens it just keeps going and won't do the function I told it to do. I'm trying to turn this into a tag game but I can't seem to get the collision to work to end the game but it just keeps running forever and doesn't stop.

Score/points update in beginner python turtle game

I'm a newbie to python and I'm having a problem with the score in my turtle game. The score is updated the first time I collect the ball, but it does not update when I collect the ball on any subsequent occasion. I would like the score to increase by a number e.g. 2 every time a ball is collected.
Might someone be able to offer a solution?
I suspect the issue could lie in:
the scope of the variable 'score
the improper looping of any/some function
import turtle
import random
import math
screen = turtle.Screen()
screen.title("My game by python code")
screen.bgcolor("black")
screen.setup(width=600, height=600)
# Making the user 'bubble'
bubble = turtle.Turtle()
bubble.color("red")
bubble.shape("circle")
bubble.penup()
speed = 3
# Making the collection balls
collection_ball = turtle.Turtle()
collection_ball.color("red")
collection_ball.penup()
collection_ball.shape("circle")
collection_ball.shapesize(0.5, 0.5, 0.5)
ball_cor1 = random.randint(30, 280)
ball_cor2 = random.randint(30, 280)
collection_ball.setposition(ball_cor1, ball_cor2)
collection_ball.color("yellow")
# Scoring
points = turtle.Turtle()
points.color("yellow")
style = ('Courier', 30, 'italic')
points.penup()
points.goto(-200, 250)
points.write("Points: 0", font=style)
points.hideturtle()
# Turning
def turn_left():
bubble.left(90)
def turn_right():
bubble.right(90)
# Collection of the balls
def collection(a, b):
return abs(a.xcor() - b.xcor()) < 10 and abs(a.ycor() - b.ycor()) < 20
def collection_ball_restart():
collection_ball.color("black")
ball_cor1 = random.randint(30, 280)
ball_cor2 = random.randint(30, 280)
collection_ball.goto(ball_cor1, ball_cor2)
collection_ball.color("yellow")
bubble.forward(speed)
screen.ontimer(play_game, 10)
def play_game():
if collection(bubble, collection_ball):
score = 0
score += 2
points.clear()
points.write("Points: " + str(score), font=style)
collection_ball_restart()
bubble.forward(speed)
else:
bubble.forward(speed)
screen.ontimer(play_game, 10)
turtle.onkeypress(turn_left, "Left")
turtle.onkeypress(turn_right, "Right")
screen.listen()
play_game()
screen.mainloop()
In addition to the score initialization issue that #TimRoberts points out (+1), below is a rework of your code to simplify the logic:
from turtle import Screen, Turtle
from random import randint
FONT_STYLE = ('Courier', 30, 'italic')
screen = Screen()
screen.title("My game by python code")
screen.bgcolor('black')
screen.setup(width=600, height=600)
# Making the user 'bubble'
bubble = Turtle()
bubble.color('red')
bubble.shape('circle')
bubble.penup()
# Making the collection balls
collection_ball = Turtle()
collection_ball.color('yellow')
collection_ball.shape('circle')
collection_ball.shapesize(0.5)
collection_ball.penup()
ball_cor1 = randint(30, 280)
ball_cor2 = randint(30, 280)
collection_ball.setposition(ball_cor1, ball_cor2)
# Scoring
score = 0
speed = 3
points = Turtle()
points.hideturtle()
points.color('yellow')
points.penup()
points.goto(-200, 250)
points.write("Points: 0", font=FONT_STYLE)
# Turning
def turn_left():
bubble.left(90)
def turn_right():
bubble.right(90)
# Collection of the balls
def was_collected(bubble):
return bubble.distance(collection_ball) < 15
def collection_ball_reset():
collection_ball.hideturtle()
collection_ball.goto(randint(30, 280), randint(30, 280))
collection_ball.showturtle()
def play_game():
global score
if was_collected(bubble):
score += 2
points.clear()
points.write("Points: " + str(score), font=FONT_STYLE)
collection_ball_reset()
bubble.forward(speed)
screen.ontimer(play_game, 10)
screen.onkeypress(turn_left, 'Left')
screen.onkeypress(turn_right, 'Right')
screen.listen()
play_game()
screen.mainloop()
E.g. use hideturtle() and showturtle() instead of color tricks; minimize necessary calls to ontimer(); use built-in distance function.

Why does a while True loop not work in my rock paper scissors game?

I'm trying to make a rock paper scissors game with 3 buttons to click on on-screen with import turtle. That went well and it worked, the buttons worked and the right text showed up on screen when clicking a certain button. (I haven't added the computer choosing part yet, so my code is only the users input) But now I wanted to add that when you clicked a button for the second time, the text of the last button disappears. Because if you keep clicking, the text stays there and it overlaps. So I wanted to add a "Do you want to play again?" input thing by putting the buttons in a while True loop so it asks the user if they want to play again every time you click a button, but that doesn't work. I don't get any errors, the screen opens and it draws everything for me but I can't click any buttons, the text doesn't show up and then it crashes. If I remove the while loop and the input question, it works again. It should work right? Or is this not possible? I read it somewhere else with another game so I don't know why it doesn't work. This is my code with the while True loop. The while True loop is at the end and I'm sorry if my code is longer than it should be, I don't know all the tricks yet:
import turtle
fontButtons = ("Courier", 22, "bold")
fontText = ("Arial", 26, "bold")
screen = turtle.Screen()
screen.bgcolor("light blue")
screen.setup(800,800)
#center = turtle.Turtle()
#center.goto(0,0)
#center.shape("circle")
#center.size(1)
#game
pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)
pen.penup()
pen.fillcolor("light yellow")
pen.goto(-250,0)
pen.begin_fill()
pen.pendown()
for i in range(2):
pen.forward(225)
pen.left(90)
pen.forward(200)
pen.left(90)
pen.end_fill()
pen.penup()
pen.goto(25,0)
pen.begin_fill()
pen.pendown()
for i in range(2):
pen.forward(225)
pen.left(90)
pen.forward(200)
pen.left(90)
pen.end_fill()
pen.penup()
pen.goto(-135,165)
pen.write("You", font=fontText, align="center")
pen.goto(135,165)
pen.write("Computer", font=fontText, align="center")
#rock
rock = turtle.Turtle()
rock.hideturtle()
rock.penup()
rock.speed(0)
rock.fillcolor("light yellow")
rock.goto(-200,-100)
rock.pendown()
rock.begin_fill()
for i in range(2):
rock.forward(100)
rock.left(90)
rock.forward(40)
rock.left(90)
rock.end_fill()
rock.penup()
rock.goto(-150,-95)
rock.write("ROCK",font=fontButtons, align="center")
#paper
paper = turtle.Turtle()
paper.hideturtle()
paper.penup()
paper.speed(0)
paper.fillcolor("light yellow")
paper.goto(-50,-100)
paper.pendown()
paper.begin_fill()
for i in range(2):
paper.forward(100)
paper.left(90)
paper.forward(40)
paper.left(90)
paper.end_fill()
paper.penup()
paper.goto(0,-95)
paper.write("PAPER",font=fontButtons, align="center")
#scissor
scissor = turtle.Turtle()
scissor.hideturtle()
scissor.penup()
scissor.speed(0)
scissor.fillcolor("light yellow")
scissor.goto(100,-100)
scissor.pendown()
scissor.begin_fill()
for i in range(2):
scissor.forward(100)
scissor.left(90)
scissor.forward(40)
scissor.left(90)
scissor.end_fill()
scissor.penup()
scissor.goto(150,-95)
scissor.write("SCISSOR",font=fontButtons, align="center")
while True:
#rock click
def buttonClickR(x,y):
if x > -200 and x < -100 and y > -100 and y < -60:
pen.goto(-135,100)
pen.write("Rock", font=fontText, align="center")
turtle.onscreenclick(buttonClickR, 1, True)
turtle.listen()
#paper click
def buttonClickP(x,y):
if x > -50 and x < 50 and y > -100 and y < -60:
pen.goto(-135,100)
pen.write("Paper", font=fontText, align="center")
turtle.onscreenclick(buttonClickP, 1, True)
turtle.listen()
#scissor click
def buttonClickS(x,y):
if x > 100 and x < 200 and y > -100 and y < -60:
pen.goto(-135,100)
pen.write("Scissor", font=fontText, align="center")
turtle.onscreenclick(buttonClickS, 1, True)
turtle.listen()
again = input("Do you want to play again? ")
if again == 'yes':
screen.clear()
else:
print('Bye!')
turtle.done()
The "loop" for turtle needs no while loop - turtle.done() does not "end" the turtle code - it signals that you are "done" setting all up and starts the everlasting turtle mainloop.
Your code is long because you solve the same problem over and over again instead of putting it into a method to be called with parameters.
You draw 2 big boxes and 3 small boxes, the small boxes also get centered text inside, the bigger boxes different text on top.
Asking for text input while in turtle can be done via turtle.textinput(...) more elegantly then skipping to input() on console.
To quit, use turtle.exitonclick() where appropriate - or call turtle.bye().
Your code repeats lots of things you should put into functions:
import turtle
# this uses the ealy defined "pen" turtle - no need to use different ones
# and a global for logic - you can refine that if you want, for demo it works
fontButtons = ("Courier", 22, "bold")
fontText = ("Arial", 26, "bold")
screen = turtle.Screen()
pen = turtle.Turtle()
pen.hideturtle()
pen.speed(0)
pen.penup()
pen.fillcolor("light yellow")
# reapeating things put into methods to be used multiple times
def box_at(x, y, width, height):
"""Makes a box in the current fillcolor at x,y to x+width,y+height.
Pen is up afterwards."""
pen.penup()
pen.goto(x,y)
pen.begin_fill()
pen.pendown()
for i in range(2):
pen.forward(width)
pen.left(90)
pen.forward(height)
pen.left(90)
pen.end_fill()
pen.penup()
def button(x,y,width,height, text):
"""Makes box + text centered inside, space width appropriate to text."""
# no need to repeat painting a box - we solved that earlier
box_at(x,y,width,height)
pen.goto(x+width/2,y)
pen.write(text, font=fontButtons, align="center")
def board():
# YOU
box_at(-250,10,225,200)
# COMPUTER
box_at(25,10,225,200)
# custom text placement
pen.goto(-135,165)
pen.write("You", font=fontText, align="center")
pen.goto(135,165)
pen.write("Computer", font=fontText, align="center")
def buttons():
# all the buttons
button(-200, -100, 120, 40, "ROCK")
button( -50, -100, 120, 40, "PAPER")
button( 100, -100, 120, 40, "SCISSOR")
def reset():
# clear screen and make it beautiful
screen.bgcolor("light blue")
screen.setup(800,800)
board()
buttons()
The game uses these functions like so:
reset()
moves = 0
# all the logic
def buttonClick(x,y):
global moves # not fancy - buts its just a demo
# handle all button clicks inside this one function
# adapted the x/y values to fit my bigger buttons
if x > -200 and x < -80 and y > -100 and y < -60:
board() # this clears the former things
pen.goto(-135,100)
pen.write("Rock", font=fontText, align="center")
moves += 1
elif x > -50 and x < 70 and y > -100 and y < -60:
board() # this clears the former things
pen.goto(-135,100)
pen.write("Paper", font=fontText, align="center")
moves += 1
elif x > 100 and x < 220 and y > -100 and y < -60:
board() # this clears the former things
pen.goto(-135,100)
pen.write("Scissor", font=fontText, align="center")
moves += 1
# TODO make the computer do something, evaluate moves, print tally
# program logic, every 3rd click ask for continue
if moves == 3:
# TODO: print tally and announce winner
again = turtle.textinput("Continue?" , "Do you want to play again? ")
if again == 'yes':
moves = 0
reset()
else:
print('Bye!')
screen.clear()
turtle.exitonclick() # or turtle.bye() directly
# register the game logic click handler
turtle.onscreenclick(buttonClick, 1, True)
# start the mainloop until turtly.bye() or exitonclick() is done
turtle.mainloop()

Turtle window hanging

When I try to run my code, my python turtle window just hangs; I can't move also. I've tried removing the win_pen and it worked, but I don't know what inside the win_pen is making it hang.
It also gives me the spinning wheel since I am on Mac, and I am not sure if that is the problem for this. I'm on Big Sur 11.1 by the way.
edit: The indents are right on my screen, just a copy and paste problem
Code:
import turtle
import os
import math
import random
from random import randint
score = 0
# Set Up Screen
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("test")
# 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.hideturtle()
border_pen.pensize(3)
for side in range(4):
border_pen.fd(600)
border_pen.lt(90)
# Draw Winning Area
win_pen = turtle.Turtle()
win_pen.hideturtle()
win_pen.shape("square")
win_pen.penup()
win_pen.setposition(0,267.7)
win_pen.shapesize(3,29.8)
# Show Score on Screen
score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("white")
score_pen.penup()
score_pen.setposition(-290, 303)
scorestring = "Score: %s" %score
score_pen.write(scorestring, False, align="left", font=("Ubuntu", 14, "normal"))
score_pen.hideturtle()
# Set up Player 1
player1 = turtle.Turtle()
player1.color("blue")
player1.shape("triangle")
player1.penup()
player1.speed(0)
player1.setposition(0, -250)
player1.setheading(90)
player1speed = 15
# Set Up Enemies
en = 8
enemies = []
for i in range(en):
enemies.append(turtle.Turtle())
for enemy in enemies:
enemy.color("red")
enemy.shape("square")
enemy.penup()
enemy.speed(0)
enemy.goto(randint(-280,280),randint(-280,280))
enemy.shapesize(2,2)
enemyspeed = 2
# Draw Winning Area
win_pen = turtle.Turtle()
win_pen.hideturtle()
win_pen.shape("square")
win_pen.penup()
win_pen.setposition(0,267.7)
win_pen.shapesize(3,29.8)
#Define bullet state
#ready - ready to fire
#fire - bullet is firing
bulletstate = "ready"
def left():
x = player1.xcor()
player1.setheading(180)
player1.forward(player1speed)
if x < -280:
x = - 280
player1.setx(x)
def right():
x = player1.xcor()
player1.setheading(0)
player1.forward(player1speed)
if x > 280:
x = 280
player1.setx(x)
def up():
y = player1.ycor()
player1.setheading(90)
player1.forward(player1speed)
if y > 280:
y = 280
player1.sety(y)
def down():
y = player1.ycor()
player1.setheading(270)
player1.forward(player1speed)
if y < -280:
y = 280
player1.sety(y)
def isCollision(t1, t2):
distance = math.sqrt(math.pow(t1.xcor()-t2.xcor(),2)+math.pow(t1.ycor()-t2.ycor(),2))
if distance < 15:
return True
else:
return False
turtle.listen()
turtle.onkey(left, "a")
turtle.onkey(right, "d")
turtle.onkey(up, "w")
turtle.onkey(down, "s")
# Main Game Loop
while True:
if isCollision(player1, win_pen):
player1.setposition(0, -250)
player1.setheading(90)
There are several problems with your code: don't use while True: in an event-driven world like turtle -- let the event handler do its job; your collision logic is incorrect as it measures from the center of the turtles whereas we're really only concerned with the y position of the two turtles; you seem to be resetting the player in the wrong direction; you implement the winning area twice.
I've rewritten, and simplified, your code below incorporating the above changes and some other tweaks:
from turtle import Screen, Turtle
from random import randint
ENEMY_COUNT = 8
PLAYER_SPEED = 15
def left():
player.setheading(180)
player.setx(max(-280, player.xcor() - PLAYER_SPEED))
check_collision(player, win_pen)
def right():
player.setheading(0)
player.setx(min(280, player.xcor() + PLAYER_SPEED))
check_collision(player, win_pen)
def up():
player.setheading(90)
player.sety(min(280, player.ycor() + PLAYER_SPEED))
check_collision(player, win_pen)
def down():
player.setheading(270)
player.sety(max(-280, player.ycor() - PLAYER_SPEED))
check_collision(player, win_pen)
def check_collision(player, win_pen):
if abs(player.ycor() - win_pen.ycor()) < 15:
player.sety(-250)
player.setheading(90)
score = 0
# Set Up Screen
screen = Screen()
screen.bgcolor('black')
# Draw border
border_pen = Turtle()
border_pen.hideturtle()
border_pen.pensize(3)
border_pen.color('white')
border_pen.speed('fastest')
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
for _ in range(4):
border_pen.forward(600)
border_pen.left(90)
# Draw Winning Area
win_pen = Turtle()
win_pen.shape('square')
win_pen.shapesize(3, 29.8)
win_pen.color('gray')
win_pen.penup()
win_pen.sety(267.7)
# Show Score on Screen
score_pen = Turtle()
score_pen.hideturtle()
score_pen.color('white')
score_pen.penup()
score_pen.setposition(-290, 303)
scorestring = "Score: %s" %score
score_pen.write(scorestring, False, align='left', font=('Ubuntu', 14, 'normal'))
# Set up Player
player = Turtle()
player.shape('triangle')
player.color('blue')
player.speed('fastest')
player.setheading(90)
player.penup()
player.setx(-250)
# Set Up Enemies
enemies = []
for _ in range(ENEMY_COUNT):
enemy = Turtle()
enemy.color('red')
enemy.shape('square')
enemy.shapesize(2)
enemy.speed('fastest')
enemy.penup()
enemy.goto(randint(-280, 280), randint(-280, 280))
enemies.append(enemy)
screen.onkey(left, 'a')
screen.onkey(right, 'd')
screen.onkey(up, 'w')
screen.onkey(down, 's')
screen.listen()
screen.mainloop()

Turtle stops when I shoot

I have gotten an issue where an enemy turtle stops when I shoot. I am relatively new to python so I know that my code is pretty bad. I cant seem to spot why this happens but I'm assuming its got something to do with the while loop.
here is the code:
(i have added notes so it is easy to skip to important parts of it)
import turtle
import os
#wn is window
#bp = border
bullet = 'ready'
#screen setup
wn = turtle.Screen()
wn.bgcolor('black')
wn.title('SPACE.INVADERS')
#border
bp = turtle.Turtle()
bp.speed(0)
bp.color('green')
bp.penup()
bp.setposition(-300,-300)
bp.pendown()
count=0
while count != 5:
count= (count+1)
bp.fd(600)
bp.lt(90)
bp.hideturtle()
#player
p = turtle.Turtle()
p.color('red')
p.shape('triangle')
p.penup()
p.speed(0)
p.setposition(0,-250)
p.setheading(90)
#enemy
e = turtle.Turtle()
e.penup()
e.speed(0)
e.shape('square')
e.shapesize(1.25,1.25)
e.color('orange')
e.setpos(-250,250)
e.speed(1)
#p = player
#ps = player speed
ps = 15
#moving left and right
def left_mov():
x = p.xcor()
x -= ps
p.setx(x)
def right_mov():
x = p.xcor()
x += ps
p.setx(x)
#shooting
def shoot():
global bullet
if bullet == 'ready':
bullet = 'fire'
shot= turtle.Turtle()
shot.penup()
shot.speed(0)
shot.goto(p.pos())
shot.color('white')
shot.shape('triangle')
shot.shapesize(0.5)
shot.lt(90)
shot.speed(1)
shot.fd(550)
bullet = 'ready'
#bindings
turtle.listen()
turtle.onkey(left_mov, 'Left')
turtle.onkey(right_mov, 'Right')
turtle.onkey(shoot, 'space')
#enemy movement
while True:
e.fd(500)
e.rt(90)
e.fd(25)
e.rt(90)
e.fd(500)
e.lt(90)
e.fd(25)
e.lt(90)
I'm assuming its got something to do with the while loop
Yes, it shouldn't be there! In an event-driven world like turtle, there should never be a while True: loop. Instead, we need a timer event that fires off on regular intervals that does incremental updates of the objects in motion (enemy and bullet) so they appear to move at the same time. Below is my rework of your code using a timer event:
from turtle import Screen, Turtle
# moving left and right
def left_move():
player.setx(player.xcor() - player_speed)
def right_move():
player.setx(player.xcor() + player_speed)
# screen setup
screen = Screen()
screen.bgcolor('black')
screen.title('SPACE.INVADERS')
# border
border = Turtle(visible=False)
border.speed('fastest')
border.color('green')
border.penup()
border.setposition(-300, -300)
border.pendown()
for _ in range(4):
border.forward(600)
border.left(90)
# player
player = Turtle('triangle')
player.speed('fastest')
player.color('red')
player.penup()
player.setposition(0, -250)
player.setheading(90)
player_speed = 15
# enemy
enemy = Turtle('square')
enemy.speed('fast')
enemy.shapesize(1.25)
enemy.color('orange')
enemy.penup()
enemy.setpos(-250, 250)
enemy_speed = 6 # enemy speed
enemy_direction = 1 # enemy direction
# bullet
bullet = Turtle('triangle', visible=False)
bullet.speed('fastest')
bullet.color('white')
bullet.shapesize(0.5)
bullet.penup()
bullet.left(90)
bullet_speed = 9 # bullet speed
# shooting
def shoot():
if not bullet.isvisible():
bullet.goto(player.position())
bullet.showturtle()
def move():
global enemy_direction
if bullet.isvisible():
if bullet.ycor() > 275:
bullet.hideturtle()
else:
bullet.forward(bullet_speed)
# enemy movement
enemy.forward(enemy_direction * enemy_speed)
enemy.settiltangle(enemy.tiltangle() + 3) # just for fun
x, y = enemy.position()
if x > 250 or x < -250:
enemy_direction *= -1
enemy.sety(y - 25)
screen.ontimer(move, 50)
# bindings
screen.onkey(left_move, 'Left')
screen.onkey(right_move, 'Right')
screen.onkey(shoot, 'space')
screen.listen()
move()
screen.mainloop()
This should give you the basic functionality you need to move forward and add collision detection (bullet to enemy, enemy to player, player to wall) and scoring.
Also note that turtles are global entities so creating a new bullet every time you need one is a bad idea. Even if you evenually allow overlapping bullets, keep a reusable set of bullets for that purpose.

Categories