How do I make an object disappear after some time? - python

I am trying to make a game where I can press space to shoot my bullet. There is a lot of lag. I am trying to figure out how to make the bullet disappear after it exits the screen. There is also a lot of lag. I am pretty sure the lag is from the bullet not resetting the screen after reaching the end. I imported time but I just can't seem to figure out how to use time.
This is what I tried:
# Importing GUI library
import turtle
import time
bullets = []
bullets2 = []
# Set speed, GUI, creates new turtle
t_speed = 5
bullet_speed = 50000
screen = turtle.Screen()
t = turtle.Turtle()
t2=turtle.Turtle()
screen.setup(700, 400)
# Arrow Keys as turtle movement
def forward():
t.forward(t_speed)
def left():
t.left(t_speed)
def right():
t.right(t_speed)
def back():
t.back(t_speed)
def forward2():
t2.forward(t_speed)
def left2():
t2.left(t_speed)
def right2():
t2.right(t_speed)
def back2():
t2.back(t_speed)
# Shoot a turtle from a turtle
def shoot():
# sets position of bullet at x and y of t
# spawn turtle at x and y
bullet = turtle.Turtle()
bullet.ht()
bullet.penup()
# Launch him
screen.addshape("uparrow.png")
bullet.shape("uparrow.png")
bullet.setheading(t.heading())
bullet.setposition(t.xcor(), t.ycor())
bullet.st()
bullet.forward(700)
bullet.speed(bullet_speed)
#TODO: Make less laggy by deleting bullet object after x seconds
def shoot2():
# set a timer
current = time.localtime().tm_sec
# sets position of bullet at x and y of t
# spawn turtle at x and y
bullet = turtle.Turtle()
bullets2.append(bullet)
bullet.ht()
bullet.penup()
# Launch him
screen.addshape("uparrow.png")
bullet.shape("uparrow.png")
bullet.setheading(t2.heading())
bullet.setposition(t2.xcor(), t2.ycor())
bullet.st()
bullet.forward(700)
bullet.speed(bullet_speed)
#TODO: Make less laggy by deleting bullet object after x seconds
#new = time.localtime().tm_sec
#if new > current + 3:
#bullets2.
def playGame():
# TODO: Health Bar
# TODO: Characters
t.penup()
t.setheading(5)
t2.penup()
# TODO
still_alive = True
# Movement
screen.onkey(back, "Down")
screen.onkey(left, "Left")
screen.onkey(right, "Right")
screen.onkey(shoot, "space")
screen.onkey(forward, "Up")
screen.onkey(back2, "S")
screen.onkey(left2, "A")
screen.onkey(right2, "D")
screen.onkey(shoot2, "Z")
screen.onkey(forward2, "W")
# Game Engine
screen.listen()
t.mainloop()
def gameStart():
# Title
print("Welcome to my game!")
# Menu; press Q to quit, Press p to play
startGame = True
while startGame == True:
inp = raw_input("Press p to play or Press q to quit")
if inp == "q":
exit()
elif inp == "p":
playGame()
startGame = False
else:
print("Incorrect prompt")
# Instructions
print("Use Arrow Keys to move. Press space to shoot")
def main():
gameStart()
if __name__ == "__main__":
main()
The object should disappear after some time.

Your progam appears to be a collection of misconceptions glued together with bad code management. Your bullet not only has lag, but it locks out all other action while it's in motion! Let's toss the time module idea and instead take advantage of turtle's own timer events to really let the bullets fly:
from turtle import Screen, Turtle
# Arrow Keys as turtle movement
def forward_1():
player_1.forward(player_speed)
def back_1():
player_1.back(player_speed)
def left_1():
player_1.left(player_speed)
def right_1():
player_1.right(player_speed)
def shoot_1():
screen.onkey(None, "space") # disable handler inside handler!
shoot(player_1)
screen.onkey(shoot_1, "space")
def forward_2():
player_2.forward(player_speed)
def left_2():
player_2.left(player_speed)
def right_2():
player_2.right(player_speed)
def back_2():
player_2.back(player_speed)
def shoot_2():
screen.onkey(None, "z")
shoot(player_2)
screen.onkey(shoot_2, "z")
def travel(bullet, milliseconds):
bullet.forward(bullet_speed)
if milliseconds:
screen.ontimer(lambda b=bullet, s=milliseconds - 100: travel(b, s), 100)
else:
bullet.hideturtle()
bullets.append(bullet)
# Shoot a bullet from a player
def shoot(player):
# sets position of bullet at x and y of player
# spawn turtle at x and y
if bullets:
bullet = bullets.pop(0)
else:
bullet = Turtle(visible=False)
# bullet.shape("uparrow.png")
bullet.shape('arrow')
bullet.speed('fastest')
bullet.penup()
# Launch him
bullet.color(player.fillcolor())
bullet.setheading(player.heading())
bullet.setposition(player.position())
bullet.showturtle()
travel(bullet, 2000)
bullets = []
# Set speed, GUI, creates new turtle
player_speed = 10
bullet_speed = 15
screen = Screen()
screen.setup(700, 400)
# screen.addshape("uparrow.png")
player_1 = Turtle('triangle')
player_1.speed('fastest')
player_1.color('red', 'pink')
player_1.penup()
player_1.setheading(90)
player_2 = Turtle('triangle')
player_2.speed('fastest')
player_2.color('blue', 'cyan')
player_2.penup()
player_2.setheading(270)
# Movement
screen.onkey(forward_1, "Up")
screen.onkey(back_1, "Down")
screen.onkey(left_1, "Left")
screen.onkey(right_1, "Right")
screen.onkey(shoot_1, "space")
screen.onkey(forward_2, "w")
screen.onkey(back_2, "s")
screen.onkey(left_2, "a")
screen.onkey(right_2, "d")
screen.onkey(shoot_2, "z")
# Game Engine
screen.listen()
screen.mainloop()

Related

How to stop turtle movement when two turtles are in proximity of each other?

I'm making a game when the user has to move the car to dodge obstacles, Everything working except I can't get the game to and end. My goal is to end the game when the block hits the turtle.
The issue is I can't get the game to detect the turtles to detect their proximity and the exit or quit command doesn't work. Also I don't think the code pasted properly so adjust the indents if it doesn't work.
import turtle as trtl
import random as rand
import sys
#initialize turtles
turtle = trtl.Turtle(shape = "turtle")
block = trtl.Turtle(shape = "square")
drawer = trtl.Turtle()
blockList = []
wn = trtl.Screen()
#game configuration
turtle.pu()
turtle.goto(0,-150)
drawer.pu()
drawer.goto(0,-160)
drawer.pd()
drawer.pensize(10)
drawer.pencolor("blue")
drawer.forward(180)
drawer.left(90)
drawer.forward(300)
drawer.left(90)
drawer.forward(350)
drawer.left(90)
drawer.forward(300)
drawer.left(90)
drawer.forward(180)
drawer.hideturtle()
def turtleRight():
turtle.setheading(0)
turtle.pu()
turtle.forward(15)
def turtleLeft():
turtle.setheading(180)
turtle.pu()
turtle.forward(15)
#actions
wn.onkeypress(turtleRight, 'Right')
wn.onkeypress(turtleLeft, 'Left')
wn.listen()
for i in range(5):
app = block
blockList.append(app)
#functions
def draw_blocks(index):
blockList[index].penup()
blockList[index].shape("square")
wn.tracer(False)
blockList[index].setx(rand.randint(-150,150))
blockList[index].sety(rand.randint(0,125))
blockList[index].showturtle()
wn.tracer(True)
wn.update()
def drop_block(index):
blockList[index].penup()
blockList[index].clear()
blockList[index].speed(2)
blockList[index].sety(-150)
blockList[index].hideturtle()
draw_blocks(index)
xDistance = abs(turtle.xcor()-block.xcor())
yDistance = abs(turtle.ycor()-block.ycor())
if (xDistance < 20 and yDistance < 20):
sys.exit()
else:
drop_block(i)
for i in range(5):
drop_block(i)
wn.mainloop()
trtl.done()
Can anyone help..!?
The problem is that you're re-drawing the block and thus resetting its position before you're testing the distance.
Alter the function like so:
def drop_block(index):
blockList[index].penup()
blockList[index].clear()
blockList[index].speed(2)
blockList[index].sety(-150)
blockList[index].hideturtle()
xDistance = abs(turtle.xcor()-block.xcor())
yDistance = abs(turtle.ycor()-block.ycor())
print(xDistance, yDistance)
if (xDistance < 20 and yDistance < 20):
sys.exit()
else: # redraw blocks _after_ calculating distance
draw_blocks(index)
drop_block(i)

in python turtle my pong player1 is not going down

I am new in python game developing.I am using python 3.8.I write a code using python turtle module, but when in run it everything works fine but my left bar which is player 1 doesn't move down after pressing 's' key but moves upward on pressing 'w' key.It is not even giving a error.It is just a structure.Please help me!
import turtle
import time
import random
#variabals
delay=0.05
#screen
wn=turtle.Screen()
wn.bgcolor('black')
wn.title('pong')
wn.setup(height=700,width=600)
wn.tracer(0)
#left player
lbar=turtle.Turtle()
lbar.speed(0)
lbar.direction='stop'
lbar.color('white')
lbar.shape('square')
lbar.shapesize(6,1)
lbar.up()
lbar.goto(-270,100)
#right player
rbar=turtle.Turtle()
rbar.speed(0)
rbar.direction='stop'
rbar.color('white')
rbar.shape('square')
rbar.shapesize(6,1)
rbar.up()
rbar.goto(270,-270)
#pong ball
ball=turtle.Turtle()
ball.speed(0)
ball.shape('circle')
ball.color('red')
ball.shapesize(0.5)
ball.up()
ball.goto(0,0)
#functions
def move():
if rbar.direction=='up':
y=rbar.ycor()
rbar.sety(y+20)
if rbar.direction=='down':
y=rbar.ycor()
rbar.sety(y-20)
if lbar.direction=='up':
lbar.sety(lbar.ycor()+20)
if lbar.direction=='down':
y=lbar.ycor()
lbar.sety(y-20)
def rup():
rbar.direction='up'
def rdown():
rbar.direction='down'
def lup():
lbar.direction='up'
def ldown():
lbar.directon='down'
#inputs
wn.listen()
wn.onkey(lup,'w')
wn.onkey(ldown,'s')
wn.onkey(rup,'Up')
wn.onkey(rdown,'Down')
#gameloop
while True:
wn.update()
move()
time.sleep(delay)
wn.mainloop()
my left bar which is player 1 doesn't move down after pressing 's' key
My guess it's due to the typo in the following function:
def ldown():
lbar.directon='down'
lbar.directon -> lbar.direction
This should have shown up as an error message in your console.
My rework of your code to address the above, and several other issues:
from turtle import Screen, Turtle
# constants
DELAY = 50 # milliseconds
# functions
def move():
if rbar.direction == 'up':
rbar.sety(rbar.ycor() + 20)
elif rbar.direction == 'down':
rbar.sety(rbar.ycor() - 20)
if lbar.direction == 'up':
lbar.sety(lbar.ycor() + 20)
elif lbar.direction == 'down':
lbar.sety(lbar.ycor() - 20)
def rup():
rbar.direction = 'up'
def rdown():
rbar.direction = 'down'
def lup():
lbar.direction = 'up'
def ldown():
lbar.direction = 'down'
def gameloop():
screen.update()
move()
screen.ontimer(gameloop, DELAY)
# screen
screen = Screen()
screen.bgcolor('black')
screen.title('pong')
screen.setup(height=700, width=600)
screen.tracer(False)
# left player
lbar = Turtle()
lbar.color('white')
lbar.shape('square')
lbar.shapesize(6, 1)
lbar.penup()
lbar.goto(-270, 100)
lbar.direction = 'stop'
# right player
rbar = lbar.clone()
rbar.goto(270, -270)
rbar.direction = 'stop'
# pong ball
ball = Turtle()
ball.shape('circle')
ball.color('red')
ball.shapesize(0.5)
ball.penup()
# inputs
screen.onkey(lup, 'w')
screen.onkey(ldown, 's')
screen.onkey(rup, 'Up')
screen.onkey(rdown, 'Down')
screen.listen()
gameloop()
screen.mainloop()

Couldn't get rid of (_tkinter.TclError: bad event type or keysym "UP") problem

I am running a Linux mint for the first time . I tried coding a python problem but for two days I am continiously facing problems due to Linux interface please
This is my code:-
import turtle
import time
boxsize=200
caught=False
score=0
#function that are called in keypress
def up():
mouse.forward(10)
checkbound()
def left():
move.left(45)
def right():
move.right(45)
def back():
mouse.backward(10)
checkbound()
def quitTurtles():
window.bye()
#stop the mouse from leaving the square set size
def checkbound():
global boxsize
if mouse.xcor()>boxsize:
mouse.goto(boxsize, mouse.ycor())
if mouse.xcor()<-boxsize:
mouse.goto(-boxsize, mouse.ycor())
if mouse.ycor()>boxsize:
mouse.goto(mouse.xcor(),boxsize)
if mouse.ycor()<-boxsize:
mouse.goto(mouse.xcor(),-boxsize)
#set up screen
window=turtle.Screen()
mouse=turtle.Turtle()
cat=turtle.Turtle()
mouse.penup()
mouse.penup()
mouse.goto(100,100)
#add key listeners
window.onkeypress(up ,'UP')
window.onkeypress(right ,'left')
window.onkeypress(left ,'Right')
window.onkeypress(back ,'DOWN')
window.onkeypress(quitTurtles, "Escape")
difficulty=window.numinput("difficulty","Enter a difficulty from 1 to 5",minval=1,maxval=5)
window.listen()
#main loop
#note how it changes with difficulty
while not caught:
cat.setheading(cat.towards(mouse))
cat.forward(8+diffficulty)
score=score+1
if cat.distance(mouse)<5:
caught=true
time.sleep(0.2-(0.1*difficulty))
window.textinput("GAME OVER","WELL DONE YOU SCORED:"+str(score*difficulty))
window.bye()
This code has several problems, many of which will keep it from running correctly:
Substituted move for mouse:
def up():
mouse.forward(10)
checkbound()
def left():
move.left(45)
Unnecessary global declaration as boxsize is not assigned:
def checkbound():
global boxsize
In code copy-and-paste, didn't change mouse to cat:
mouse=turtle.Turtle()
cat=turtle.Turtle()
mouse.penup()
mouse.penup()
The difficulty variable not spelled consistently:
cat.forward(8+diffficulty)
time.sleep(0.2-(0.1*difficulty))
Incorrect case for boolean:
caught=true
As noted in comments, total inconsistency in key naming case:
window.onkeypress(right ,'left')
window.onkeypress(left ,'Right')
window.onkeypress(back ,'DOWN')
Bigger picture issues are use of sleep() in an event-driven environment and lack of drawn boundaries so player knows the limits. Rather than address these issues one by one in SO questions, let's rework this code to work within the turtle event environment and be playable as a game:
from turtle import Screen, Turtle
BOX_SIZE = 600
# functions that are called in keypress
def up():
mouse.forward(15)
checkbound()
def left():
mouse.left(45)
def right():
mouse.right(45)
def back():
mouse.backward(15)
checkbound()
def checkbound():
''' stop the mouse from leaving the square set size '''
if mouse.xcor() > BOX_SIZE/2:
mouse.goto(BOX_SIZE/2, mouse.ycor())
elif mouse.xcor() < -BOX_SIZE/2:
mouse.goto(-BOX_SIZE/2, mouse.ycor())
if mouse.ycor() > BOX_SIZE/2:
mouse.goto(mouse.xcor(), BOX_SIZE/2)
elif mouse.ycor() < -BOX_SIZE/2:
mouse.goto(mouse.xcor(), -BOX_SIZE/2)
def move():
global score
cat.setheading(cat.towards(mouse))
cat.forward(2 * difficulty)
score += 1
if cat.distance(mouse) < 5:
screen.textinput("GAME OVER", "WELL DONE YOU SCORED: {}".format(score * difficulty))
screen.bye()
else:
screen.ontimer(move, 200 - 100 * difficulty)
score = 0
# set up screen
screen = Screen()
marker = Turtle()
marker.hideturtle()
marker.penup()
marker.goto(-BOX_SIZE/2, -BOX_SIZE/2)
marker.pendown()
for _ in range(4):
marker.forward(BOX_SIZE)
marker.left(90)
difficulty = int(screen.numinput("difficulty", "Enter a difficulty from 1 to 5", minval=1, maxval=5))
cat = Turtle()
cat.shapesize(2)
cat.penup()
mouse = Turtle()
mouse.penup()
mouse.goto(200, 200)
# add key listeners
screen.onkeypress(up, 'Up')
screen.onkeypress(right, 'Left')
screen.onkeypress(left, 'Right')
screen.onkeypress(back, 'Down')
screen.onkeypress(screen.bye, 'Escape')
screen.listen()
screen.ontimer(move, 1000) # give player a chance to move hand from keyboard to mouse
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.

time.sleep function within while loop keeps crashing program, solution or alternative method?

I am trying to make a space invaders game using turtle, and in order to move the bullet up the screen I am trying to update the y coordinate of the bullet every 0.5 seconds. I tried to do this with a while loop and the time.sleep() function, but everytime I try to fire a bullet, the program crashes. Is there any way I can stop it from doing this? Or why is it not working? Is there an equally effective method that will not crash my program?
import turtle
import time
userx = 0
x = 0
y = -300
enemies = [(300,50, "left"), (400,50, "left"), (350, -50, "right")]
bullets = []
gameover = False
def frame():
pass
ship = turtle.Turtle()
ship.pu()
ship.ht()
ship.setpos(userx, -300)
ship.pd()
ship.circle(5)
bullet = turtle.Turtle()
bullet.pu()
bullet.ht()
bullet.setpos(x, y)
bullet.pd()
bullet.circle(2)
def key_left():
global userx
pass
userx += -10
print(userx)
def key_right():
global userx
pass
userx += 10
print(userx)
def key_space():
pass # your code here
global x
global y
global bullets
x = userx
while y <= 300:
time.sleep(0.5)
y += 4
else: y = 0
bullets += (x,y)
def physics():
global bullets
global enemies
pass
def ai():
global enemies
global gameover
pass
def reset():
global enemies
global bullets
global userx
global gameover
pass
def main():
turtle.tracer(0,0)
turtle.hideturtle()
turtle.onkey(key_left, "Left")
turtle.onkey(key_right, "Right")
turtle.onkey(key_space, "space")
turtle.listen()
reset()
while not gameover:
turtle.clear()
physics()
ai()
frame()
turtle.update()
time.sleep(0.05)
main()
It is not ideal but it starts working.
In key_space you only add new bullet to list.
In while not gameover you run function which will move all bullets.
In frame you draw all bullets.
import turtle
import time
userx = 0
x = 0
y = -300
enemies = [(300,50, "left"), (400,50, "left"), (350, -50, "right")]
bullets = []
gameover = False
def frame():
pass
ship = turtle.Turtle()
ship.pu()
ship.ht()
ship.setpos(userx, -300)
ship.pd()
ship.circle(5)
# redraw bullets
for x, y in bullets:
bullet = turtle.Turtle()
bullet.pu()
bullet.ht()
bullet.setpos(x, y)
bullet.pd()
bullet.circle(2)
def key_left():
global userx
pass
userx += -10
print(userx)
def key_right():
global userx
pass
userx += 10
print(userx)
def key_space():
pass # your code here
global x
global y
global bullets
x = userx
# add bullet to list
bullets.append([x, -300])
def move_bullets():
global bullets
live_bullets = []
# move every bullet and check if should still live
for x, y in bullets:
y += 4
# keep only some bullets and other forget (kill/remove)
if y <= 300:
live_bullets.append([x, y])
bullets = live_bullets
def physics():
global bullets
global enemies
pass
def ai():
global enemies
global gameover
pass
def reset():
global enemies
global bullets
global userx
global gameover
pass
def main():
turtle.tracer(0,0)
turtle.hideturtle()
turtle.onkey(key_left, "Left")
turtle.onkey(key_right, "Right")
turtle.onkey(key_space, "space")
turtle.listen()
reset()
while not gameover:
turtle.clear()
physics()
ai()
move_bullets() # <-- move bullets (or maybe before physics)
frame()
turtle.update()
time.sleep(0.05)
main()
I would:
def key_space():
# simply spawn a new bullet and put it into your bullets list
def advance_bullet(): # call this after paintnig all bullets in frame
# iterate over all bullets inside bullets, advance the Y position by 3
def frame():
# add code to paint all bullets inside bullets - and call advance_bullets()
In the code that checks for collision with enemies:
# remove a bullet from bullets when its outside your screen (or passed all enemies max y coord) - no need to track that bullet anymore
if you ned to advance the bullets slower then your main loops intervall, make a "framespassed" counter and see if framespassed % something == 0 and only then advance your bullets.
Adapted to what you already have
You need to change these parts:
def frame():
global bullets
pass
ship = turtle.Turtle()
ship.pu()
ship.ht()
ship.setpos(userx, -300)
ship.pd()
ship.circle(5)
# debugging all bullets:
# print(bullets) # remove this
for idx in range(0,len(bullets)): # paint ALL bullets in the bullets list
bulletTurtle = turtle.Turtle()
b = bullets[idx] # current bullet we are painting
bulletTurtle.pu()
bulletTurtle.ht()
bulletTurtle.setpos(b[0], b[1])
bulletTurtle.pd()
bulletTurtle.circle(2)
b[1] += 13 # quick and dirty approach, move bulltet after painting
# to save another complete bullets-foreach-loop
# quick n dirty bullet removal for out of screen bullets
# normally I would do this probably in your "check if enemy hit"
# method as you are going over bullets there as well and can remove
# them as soon as they passed all enemies
bullets = [x for x in bullets if x[1] < 500]
def key_space():
global x
global y
global bullets
bullets.append([userx,-300]) # start a new bullet at current player position
Edit:
You might want to take a look at turtle.shape, turtle.size and turtle.stamp - by using a "circle" shape and a size that fits, you might be able to "stamp" this shape down. Advantage: you can simply delete the stamped shape - by its integer-id. I haven*t worked with turtle ever - consider yourself if that would be a way to easily redraw your players position and/or bullets

Categories