How to prevent turtle from moving in opposite direction

Viewed 272

Code:

import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color("black")
t.speed(0)
t.penup()

def moveu(num):
    t.setheading(num)
    t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()

I am not close to done with this project but I have run into some problems. I want to create a game in the turtle module. But I don't know how to prevent the block from moving backward. I have seen other people use t.direction or something. But I have tried that and it didn't really work, maybe I'm just stupid and I did something wrong. How can I prevent the square from moving in the opposite direction?

4 Answers

You can add the condition if (t.heading() + 180) % 360 != num:, meaning if the opposite direction of the turtle's current heading direction isn't the direction the number passed into the function, then proceed:

import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color("black")
t.speed(0)
t.penup()

def moveu(num):
    if (t.heading() + 180) % 360 != num:
        t.setheading(num)
        t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()
turtle.mainloop()

I don't know how to prevent the block from moving backward.

As it is, your block is only moving forward. If you change the shape of your block from 'square' to 'arrow' you'll see that it is always moving in the direction it is facing. If you desire to limit it in some manner, we'll need a better description of what types of motion you want or don't want.

A simplified version of your code with some minor tweaks:

from turtle import Screen, Turtle

def moveu(angle):
    turtle.setheading(angle)
    turtle.forward(20)

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

turtle = Turtle()
turtle.shape('arrow')
turtle.speed('fastest')
turtle.penup()

screen.onkey(lambda: moveu(90), 'w')
screen.onkey(lambda: moveu(270), 's')
screen.onkey(lambda: moveu(180), 'a')
screen.onkey(lambda: moveu(0), 'd')

screen.listen()
screen.mainloop()

Like cdlane said in their answer, your turtle does only move forward. However, you always ask it to face the direction you want and then make it move forward. Instead, you should check its current direction, and allow it to move only if it's not opposite to the current direction.

This only needs a slight modification to your moveu() function:

def moveu(angle):
    current_heading = turtle.heading()
    if abs(angle - current_heading) != 180:
        turtle.setheading(angle)
        turtle.forward(20)

Now, your turtle won't move down if you first press w and then s. However, if you press w and then a and then s, your turtle will first move to the left and then downwards.

Here's a demo: I modified cdlane's demo to add another turtle at the bottom of the canvas to print status messages Code. I added a couple lines in the moveu() function to print which key was pressed.

enter image description here

Solution

So, first issue is that I did not see turtle.mainloop() in the code. This means that it would not stay open. So, that is the first addition to the code.

Secondly, using a simple if statement might just be your answer. It is way simpler than you thought.

But, first, let's look at the directions.


             90
              ↑
              |
              |
180  ←---- 'turtle' ----→ 0
              |
              |
              ↓
             270

As, I am presuming, 180 degrees is the direction you consider to be backwards. If it isn't, just swap in your desired angle in the final code.


The if statement goes as follows. I have presented it within your moveu function.


def moveu(num):
    if num != 180:
        t.setheading(num)
        t.forward(20)

This means that, if the angle is not 180, it will move. Therefore, it will not move back.


Final Code


import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color('black')
t.speed(0)
t.penup()

def moveu(num):
    if num != 180:
        t.setheading(num)
        t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()
s.mainloop()

As you can see, I have added turtle.mainloop() and the if statement.

Related