在单独的循环中在画布上移动两个对象

时间:2014-12-11 22:00:12

标签: python loops tkinter

我无法让这两个对象在我的画布上移动。一次射击后,它会停止另一个物体的移动。我很确定这是因为我使用了两个while循环而python无法处理它。有没有办法绕过它/将它包含在同一个循环中?

我尝试过使用self.canvas.after()命令,但每次射击子弹都会比以前更快。

from tkinter import *
import time

class Game:
    def __init__(self):

        #creating the static canvas background
        window = Tk()
        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
        frame = Frame(window)
        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(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(frame, text="Turn On Rapid Fire", command = rf, cursor= 'cross')
        Rf.grid(row=0,column=1)

        def restart():
            print ('restart')
        restart_b = Button(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)



        #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.canvas.move(self.shot_p1,0,0)




        #self.laser_p1 = self.canvas.create_image(50, self.y_p1 +50, image=self.p1_laser)
        #self.laser_p2 = self.canvas.create_image(850, self.y_p2 +50, image=self.p2_laser)
        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

            time.sleep(.009)
            p1_shoot_move()


        def p1_shoot_move():
            #moves the laser until its outside the canvas
            while self.x_p1_laser <= 900:
                self.canvas.move(self.laser_p1,5,0)
                self.x_p1_laser += 5 
                self.canvas.update()
                time.sleep(.009)


        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

            time.sleep(.009)
            p2_shoot_move()


        def p2_shoot_move():
            #moves the laser until its outside the canvas
            while self.x_p2_laser >= -100:
                self.canvas.move(self.laser_p2,-5,0)
                self.x_p2_laser += -5 
                self.canvas.update()
                time.sleep(.009)  



        # 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!!!
        window.mainloop()


Game()

感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

你是对的,这是因为有两个while循环同时进行,它会导致一个'激光'/ while循环停止,直到另一个'激光'/ {{1完成循环,为了解决这个问题,你可以进入while等,但正如你所提到的那样,threading方法会充分执行任务,那么我们可以使用{{1测试而不是window.after()循环。

以下是整个代码,通过一些改进,我将if/elsewhile设为全局,并使用window取消canvas并使用{{1而不是time.sleep()。它的拍摄速度相当缓慢,但你无疑可以解决这个问题:),如果没有,我可以提供帮助。

self.window.after(1, function...)

希望能帮到你