How to prevent turtle from moving in opposite direction
Asked Answered
T

4

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?

Trela answered 3/5, 2021 at 16:59 Comment(1)
Are you, by any chance, going to make a snake game with the turtle module? @TrelaFleam
C
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()
Chaisson answered 11/5, 2021 at 18:26 Comment(0)
R
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()
Reproof answered 3/5, 2021 at 20:41 Comment(1)
No this doesn't work. When the direction is up I can still move it downTrela
I
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

Inadvertency answered 11/5, 2021 at 16:45 Comment(0)
F
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.

Fleam answered 13/5, 2021 at 15:31 Comment(7)
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 and Ann Zen'sInadvertency
@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.Fleam
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 oneInadvertency
I thought this was the simplest and clearest one, you explain it very well. @PranavHosangadiTrela
@Trela 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.Inadvertency
Oh, okay I never noticed this since I didn't test it. I'll change accepted answerTrela
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.Fleam

© 2022 - 2024 — McMap. All rights reserved.