AIDAN HERRERA
AIDAN HERRERA

Reputation: 21

Is there a way to make an object rotate with another object in Python Turtle?

I'm trying to create a game in python turtle in which hitting space, an arrow fires in the direction the turtle is facing. However when I hit space the arrow always shoots the same direction.

I've already tried assigning the arrow and turtle to the same keybinds, but that makes the turtle incapable of movement

def left():
  t.left(15)
  k.left(20)

def right():
  t.right(15)
  k.right(20)

def shoot():
  k = turtle.Turtle()
  k.penup()
  k.color("orange")
  k.shape("arrow")



ts.onkey(shoot, "space")

I'm expecting the arrow to shoot from the direction the turtle is facing, but instead it just keeps shooting right.

Upvotes: 1

Views: 749

Answers (2)

cdlane
cdlane

Reputation: 41872

To do this correctly, with unlimited arrows, takes more work. We need to have a timer event driving each active arrow. Since turtles are global entities that aren't garbage collected, we want to reuse spent arrows. We need to block the fire button while firing to prevent event overlap. The following should do what you describe:

from turtle import Screen, Turtle, mainloop

def left():
    player.left(15)

def right():
    player.right(15)

def shoot():
    screen.onkey(None, 'space')  # disable handler inside handler

    if quiver:
        arrow = quiver.pop(0)
    else:
        arrow = Turtle('arrow', visible=False)
        arrow.speed('fastest')
        arrow.color('orange')
        arrow.penup()

    arrow.setposition(player.position())
    arrow.setheading(player.heading())

    flight(arrow)

    arrow.showturtle()

    screen.onkey(shoot, 'space')

def flight(arrow):
    if arrow.distance(0, 0) < 325:
        arrow.forward(10)
        screen.ontimer(lambda a=arrow: flight(a), 100)
    else:
        arrow.hideturtle()
        quiver.append(arrow)

screen = Screen()
screen.setup(500, 500)

quiver = []

player = Turtle('turtle')
player.color('dark green', 'light green')
player.speed('fastest')

screen.onkey(shoot, 'space')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()

mainloop()

enter image description here

To answer your original question, you don't need to rotate them together. You can align one with the other when you're ready to shoot using b.setposition(a.position()) and b.setheading(a.heading()).

Upvotes: 2

Jacob
Jacob

Reputation: 225

Try this:

k = turtle.Turtle()
def left():
    global t, k
    t.left(15)
    k.left(15)
def right():
    global t, k
    t.right(15)
    k.right(15)
def shoot():
    global k
    k.penup()
    k.color("orange")
    k.shape("arrow")
ts.onkey(shoot, "space")
ts.onkey(left, "left")
ts.onkey(right, "right")

Upvotes: 0

Related Questions