Home > OS >  When I press a key, all the other previously moving elements stop moving in python turtle
When I press a key, all the other previously moving elements stop moving in python turtle

Time:06-20

So I'm making a 2 player tron game in turtle, and my code seemed to be working fine (except the border that's why I commented it out). The only thing is that when I tried to play the game by myself to test it out, whenever I moved the "other" tron bike, the one that I just had clicked to make move stops moving. How can I fix this?

Here is my code:

def tron():
    #Drawing the starting turtles
    blueplayer = turtle.Turtle()
    redplayer = turtle.Turtle()
    screen = turtle.Screen()
    screen.setup(width, height)
    screen.bgpic('TronBg.png')
    screen.bgcolor('black')
    screen.addshape('BlueBike.gif')
    screen.addshape('RedBike.gif')
    blueplayer.shape('BlueBike.gif')
    redplayer.shape('RedBike.gif')
    redplayer.pencolor("red")
    redplayer.pensize(3)
    blueplayer.pencolor("blue")
    blueplayer.pensize(3)
    redplayer.pu()
    blueplayer.pu()
    redplayer.goto(width/2, height/8)
    blueplayer.goto(-1*(width)/2, height/8)
    redplayer.pd()
    blueplayer.pd()

    #Border
    #box = Turtle()
    #box.ht()
    #box.color('purple')
    #box.speed('fastest')
    #box.pensize(10)

   # box.pu()
   # box.goto(-1*height, -1*width)
   # box.pd()

   # for i in range(4):
   #   box.forward(height)
   #   box.left(90)
   #   box.forward(width)
   #   box.left(90)
      
    #Player movements
    def RedUp():
      while True:
        blueplayer.setheading(90)
        blueplayer.forward(3)
    def BlueUp():
      while True:
        redplayer.setheading(90)
        redplayer.forward(3)

    def RedDown():
      while True:
        blueplayer.setheading(270)
        blueplayer.forward(3)
    def BlueDown():
      while True:
        redplayer.setheading(270)
        redplayer.forward(3)

    def RedLeft():
      while True:
        blueplayer.setheading(180)
        blueplayer.forward(3)
    def BlueLeft():
      while True:
        redplayer.setheading(180)
        redplayer.forward(3)

    def RedRight():
      while True:
        blueplayer.setheading(0)
        blueplayer.forward(3)
    def BlueRight():
      while True:
        redplayer.setheading(0)
        redplayer.forward(3)

    for x in range(10):
      turtle.color('white')
      style = ('Arial', 25, 'italic')
      turtle.write(10-x, font=style, align='center') 
      time.sleep(1)
      turtle.undo()
  
    screen.listen()

    screen.onkey(RedUp, "w")
    screen.onkey(RedDown, "s")
    screen.onkey(RedLeft, "a")
    screen.onkey(RedRight, "d")

    screen.onkey(BlueUp, "Up")
    screen.onkey(BlueDown, "Down")
    screen.onkey(BlueLeft, "Left")
    screen.onkey(BlueRight, "Right")
    
    screen.mainloop()

tron()

CodePudding user response:

Using while True can be the problem - it runs endless loop which may block previous function and this may stop previous player.

Keys should set global variables with player direction - and timer should repeate code which checks directions for both players and update they positions.


Minimal working code - without images - so everyone can simply copy and run.

import turtle
import time

width = 600
height = 600

red_direction = None
blue_direction = None

# blue player movements   # PEP8: one space after `#`
def blue_up():   # PEP8: `lower_case_names` for functions
    global blue_direction
    blue_direction = 'up'

def blue_down():
    global blue_direction
    blue_direction = 'down'

def blue_left():
    global blue_direction
    blue_direction = 'left'

def blue_right():
    global blue_direction
    blue_direction = 'right'

# blue player movements   # PEP8: one space after `#`
def red_up():   # PEP8: `lower_case_names` for functions
    global red_direction
    red_direction = 'up'

def red_down():
    global red_direction
    red_direction = 'down'

def red_left():
    global red_direction
    red_direction = 'left'

def red_right():
    global red_direction
    red_direction = 'right'

# movements   # PEP8: one space after `#`
def move_player(player, direction):
    if direction == 'up':
        player.setheading(90)
        player.forward(5)
    elif direction == 'down':
        player.setheading(270)
        player.forward(5)
    elif direction == 'left':
        player.setheading(180)
        player.forward(5)
    elif direction == 'right':
        player.setheading(0)
        player.forward(5)

def gameloop():
    move_player(red_player, red_direction)
    move_player(blue_player, blue_direction)

    # repeate after 40ms (0.04s) (1000ms/20ms = 25 FPS [Frames Per Second])
    screen.ontimer(gameloop, 40)

def tron():
    global screen
    global blue_player
    global red_player

    screen = turtle.Screen()
    screen.setup(width, height)
    screen.bgcolor('black')
    
    blue_player = turtle.Turtle()
    blue_player.pencolor("blue")
    blue_player.pensize(3)
    blue_player.pu()
    blue_player.goto(-1*(width)/3, height/8)
    blue_player.pd()
    
    red_player = turtle.Turtle()
    red_player.pencolor("red")
    red_player.pensize(3)
    red_player.pu()
    red_player.goto(width/3, height/8)
    red_player.pd()

    style = ('Arial', 25, 'italic')
    turtle.color('white')
    for x in range(10):  # PEP8: 4 spaces indention
        turtle.write(10-x, font=style, align='center') 
        time.sleep(0.5)
        turtle.undo()
  
    screen.listen()

    screen.onkey(red_up, "w")
    screen.onkey(red_down, "s")
    screen.onkey(red_left, "a")
    screen.onkey(red_right, "d")

    screen.onkey(blue_up, "Up")
    screen.onkey(blue_down, "Down")
    screen.onkey(blue_left, "Left")
    screen.onkey(blue_right, "Right")
    
    screen.ontimer(gameloop, 250)
    screen.mainloop()

tron()

PEP 8 -- Style Guide for Python Code

  • Related