Search code examples
pythonpython-turtle

How to make a toroidal space with the turtle module?


I'm trying to make a program in which a turtle moves around the plane commanded by the user, I'm also trying to make it so that whenever it reaches an end of the screen, it gets teleported to the opposite end. This is my code:

import turtle as trtl
import keyboard
import math

screen = trtl.Screen()
screen.listen()
screen.setup(width=960, height=600)
screen.bgpic("C:/Users/alfon/OneDrive/Pictures/BGBW.png")

Point = trtl.Turtle()
trtl.register_shape("C:/Users/alfon/Downloads/BWCharacter.gif")
Point = trtl.Turtle("C:/Users/alfon/Downloads/BWCharacter.gif")
Point.penup()

def MH(Theta):    #MH stands more Move \[Towards\] Heading
    x, y = Point.position()
    dx = 5*math.cos(math.radians(Theta))
    dy = 5*math.sin(math.radians(Theta))
    x = x+dx
    y = y+dy
Point.setposition(x, y)
while True:
    while keyboard.is_pressed("d") and not(keyboard.is_pressed("s") or keyboard.is_pressed("w")):
        MH(0)
    while keyboard.is_pressed("d") and keyboard.is_pressed("w"):
        MH(45)
    while keyboard.is_pressed("w") and not(keyboard.is_pressed("d") or keyboard.is_pressed("a")):
        MH(90)
    while keyboard.is_pressed("w") and keyboard.is_pressed("a"):
        MH(135)
    while keyboard.is_pressed("a") and not(keyboard.is_pressed("w") or keyboard.is_pressed("s")):
        MH(180)
    while keyboard.is_pressed("a") and keyboard.is_pressed("s"):
        MH(225)
    while keyboard.is_pressed("s") and not(keyboard.is_pressed("a") or keyboard.is_pressed("d")):
        MH(270)
    while keyboard.is_pressed("s") and keyboard.is_pressed("d"):
        MH(315)
    if Point.xcor() \< -500:
        Point.hideturtle()
        Point.setpos(500, Point.ycor())
        Point.showturtle()
    if Point.xcor() \> 500:
        Point.hideturtle()
        Point.setpos(-500, Point.ycor())
        Point.showturtle()
    if Point.ycor() \< -320:
        Point.hideturtle()
        Point.setpos(320, Point.ycor())
        Point.showturtle()
    if Point.ycor() \> 320:
        Point.hideturtle()
        Point.setpos(-320, Point.ycor())
        Point.showturtle()

The moving the turtle parts works fine, and it is also taken to the other side of the screen, however, this only happens once I release the key that I was moving the turtle with, I can see why it happens, but I don't know how to fix it. I'm looking for continuity in the way the turtle moves, this is, I don't want to have to stop when the turtle gets to the other side.

I tried making a boolean variable for OB (Out of Bounds) that would stop the while loops for movement when OB==True but that didn't work


Solution

  • You just need to use the modulo operator with the size of the screen so x = (x + speed_x * dt) % SIZE, this operator gives the remainder of the division with the screen size that is exactly what you need for a wrap around. This is a well-known trick in 2d game-development.


    Specifically in your code:

    x = x+dx
    y = y+dy
    

    should become:

    x = (x+dx) % WIDTH
    y = (y+dy) % HEIGHT