6

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?

John Hennig
  • 2,305
  • 13
  • 29
red_panda
  • 335
  • 15

4 Answers4

3

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()
Ann Zen
  • 17,892
  • 6
  • 20
  • 39
2

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()
cdlane
  • 33,404
  • 4
  • 23
  • 63
1

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

Pranav Hosangadi
  • 12,149
  • 4
  • 34
  • 61
0

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.

Pranav Hosangadi
  • 12,149
  • 4
  • 34
  • 61
  • This is wrong! OP wants the turtle to not turn back 180 degrees regardless of what direction it faces. Your code doesn't do this -- it only prevents the turtle from facing "west". The way to get what OP wants is covered by [my answer](https://stackoverflow.com/a/67491064/843953) and [Ann Zen's](https://stackoverflow.com/a/67492425/843953) – Pranav Hosangadi May 14 '21 at 18:45
  • @PranavHosangadi Sorry, if you think that it wouldn't work and thanks for any edits you have completed. It seems to have been approved though. – Python Programmer May 15 '21 at 16:23
  • I'm very surprised this was accepted because it's not what OP said they want, as is evident from their other comments, e.g. [this one](https://stackoverflow.com/questions/67372873/how-to-prevent-turtle-from-moving-in-opposite-direction/67521980?noredirect=1#comment119107737_67375590) – Pranav Hosangadi May 17 '21 at 14:28
  • I thought this was the simplest and clearest one, you explain it very well. @PranavHosangadi – red_panda May 17 '21 at 15:28
  • @red_panda This code _doesn't_ do what you need it to though -- when the direction is up you can still move it down. Also you can never turn this left. – Pranav Hosangadi May 17 '21 at 15:31
  • Oh, okay I never noticed this since I didn't test it. I'll change accepted answer – red_panda May 17 '21 at 15:32
  • Ah, actually, I do get what you are trying to do now. Sorry, I misunderstood the question - I thought you wanted it to not be able to move in a specified direction, but you want the sprite to move and not be able to turn around, like the head of the snake in the game snake. @PranavHosangadi Yes, your answer is correct. – Python Programmer May 17 '21 at 17:00