У меня возникли проблемы, когда если выстрел несколько раз выстрелил, прежде чем он покинет холст, он будет ускоряться каждый раз, когда он будет перерисован до тех пор, пока его скорость не сможет обновиться. Ive приписал проблему команде canvas.after, потому что, если я буду использовать этот цикл while, используя команду time.sleep, он отлично работает (к сожалению, я могу использовать реализацию кода, потому что он работает как два отдельных цикла)Странные вещи с canvas.after()
#imports
from tkinter import *
#The Game
class Game:
def __init__(self):
#creating the static canvas background
self.window = Tk()
self.window.title('Shoot your friends')
self.canvas = Canvas(width= 900,
height= 900,
cursor= 'circle')
self.canvas.pack()
self.canvas.create_line(450, 900,
450, 0,
dash = (10))
self.p1_ship = PhotoImage(file = "red_ship.gif")
self.p2_ship = PhotoImage(file = "blue_ship.gif")
self.p1_laser = PhotoImage(file = "red_laser.gif")
self.p2_laser = PhotoImage(file = "blue_laser.gif")
#Buttons at the bottom
self.frame = Frame(self.window)
self.frame.pack()
#Determining the state of edge teleporting and toggling it
self.etb = True
def et():
if self.etb == True:
self.etb = False
Et["text"] = "Turn On Edge Teleporting"
else:
self.etb = True
Et["text"] = "Turn Off Edge Teleporting"
print ("Edge Telepoting Toggled")
Et = Button(self.frame, text="Turn Off Edge Teleporting", command = et, cursor= 'double_arrow')
Et.grid(row=0,column=0)
self.Rfb = False
def rf():
if self.Rfb == True:
self.Rfb = False
Rf["text"] = "Turn On Rapid Fire "
else:
self.Rfb = True
Rf["text"] = "Turn Off Rapid Fire"
print ("Rapid Fire Toggled")
Rf = Button(self.frame, text="Turn On Rapid Fire", command = rf, cursor= 'cross')
Rf.grid(row=0,column=1)
def restart():
print ('restart')
restart_b = Button(self.frame, text="Restart Game", command = restart, fg='Blue', bg= 'red', cursor='exchange')
restart_b.grid(row=0,column=2)
self.y_p1 = 400
self.y_p2 = 400
self.ship_p1 = self.canvas.create_image(40, 450, image=self.p1_ship)
self.ship_p2 = self.canvas.create_image(860, 450, image=self.p2_ship)
self.canvas.move(self.ship_p1,0,0)
self.canvas.move(self.ship_p2,0,0)
# Functions that handle movement of the ships taking into account multiple variables
#For example If edge teleporting is ON the ship will teleport to the top of the screen if it is at the bottom and the down key is pressed and vice versa
#My implementation of this may not be the most efficient but I like the options it gives me for adding future features and it looks cool.
def p1_up(event):
if self.etb == True and self.y_p1 >= 100:
self.canvas.move(self.ship_p1,0,-100)
self.y_p1 += -100
elif self.etb == True:
self.canvas.move(self.ship_p1,0,+800)
self.y_p1 += +800
elif self.y_p1 >= 100:
self.canvas.move(self.ship_p1,0,-100)
self.y_p1 += -100
def p1_down(event):
if self.etb == True and self.y_p1 <= 799:
self.canvas.move(self.ship_p1,0,+100)
self.y_p1 += 100
elif self.etb == True:
self.canvas.move(self.ship_p1,0,-800)
self.y_p1 += -800
elif self.y_p1 <= 799:
self.canvas.move(self.ship_p1,0,+100)
self.y_p1 += 100
def p2_up(event):
if self.etb == True and self.y_p2 >= 100:
self.canvas.move(self.ship_p2,0,-100)
self.y_p2 += -100
elif self.etb == True:
self.canvas.move(self.ship_p2,0,+800)
self.y_p2 += +800
elif self.y_p2 >= 100:
self.canvas.move(self.ship_p2,0,-100)
self.y_p2 += -100
def p2_down(event):
if self.etb == True and self.y_p2 <= 799:
self.canvas.move(self.ship_p2,0,+100)
self.y_p2 += 100
elif self.etb == True:
self.canvas.move(self.ship_p2,0,-800)
self.y_p2 += -800
elif self.y_p2 <= 799:
self.canvas.move(self.ship_p2,0,+100)
self.y_p2 += 100
# Functions for shooting
self.p1_shot_out = False
self.p2_shot_out = False
def p1_shoot(event):
if self.p1_shot_out == True:
self.canvas.delete(self.laser_p1)
#draws the laser
self.laser_p1 = self.canvas.create_image(50, self.y_p1 +50, image=self.p1_laser)
self.x_p1_laser = 50
self.p1_shot_out = True
self.window.after(1, p1_shoot_move)
def p1_shoot_move():
#moves the laser until its outside the canvas
if self.x_p1_laser >= 930:
pass
else:
self.canvas.move(self.laser_p1,5,0)
self.x_p1_laser += 5
self.canvas.update()
self.window.after(3, p1_shoot_move)
def p2_shoot(event):
if self.p2_shot_out == True:
self.canvas.delete(self.laser_p2)
#draws the laser
self.laser_p2 = self.canvas.create_image(750, self.y_p2 +50, image=self.p2_laser)
self.x_p2_laser = 750
self.p2_shot_out = True
self.window.after(4, p2_shoot_move)
def p2_shoot_move():
#moves the laser until its outside the canvas
if self.x_p2_laser <= -110:
pass
else:
self.canvas.move(self.laser_p2,-5,0)
self.x_p2_laser += -5
self.canvas.update()
self.window.after(4, p2_shoot_move)
# Key bindings that trigger their respective functions
self.canvas.bind('w', p1_up)
self.canvas.bind('s', p1_down)
self.canvas.bind('<Up>', p2_up)
self.canvas.bind('<Down>', p2_down)
self.canvas.bind('<space>', p1_shoot)
self.canvas.bind('<Control_R>', p2_shoot)
self.canvas.focus_set()
# this mainloop thing is some sort of witchcraft! OH MY!!!
self.window.mainloop()
Game()
Я не уверен, что хорошо использовать 'time.sleep' с' tkinter' – nbro
Прочтите https://stackoverflow.com/help/mcve. Для тестирования требуется только один из p1, p2, но для тестирования требуется больше. –
@nbro time.sleep - это, как правило, плохая идея, но я не думаю, что это проблема здесь, поскольку она выполняется только один раз для снаряда. –