入侵者距离增加,但不应该

0 投票
1 回答
22 浏览
提问于 2025-04-14 15:47

入侵者碰到画布左边缘时,距离却在增加,这其实是不应该发生的。这个问题在右边就没有出现。

import tkinter
import timeit

tk = tkinter.Tk()
WIDTH = 1000
HEIGHT = 650
global canvas
canvas = tkinter.Canvas(tk, width=WIDTH, height=HEIGHT, bg="black")
canvas.pack()

class Invader():
    def __init__(self, canvas, play, x, y):
        self.canvas = canvas
        self.play = play
        self.x_coord = x
        self.y_coord = y
        self.shape = canvas.create_rectangle(self.x_coord, self.y_coord, self.x_coord + 50, self.y_coord + 50, fill='green')
        self.direction = 'left'

    def move(self):
        if self.direction == 'right':
            self.x_coord += 10
            if self.x_coord + 40 >= WIDTH:
                play.move_all_down()
        elif self.direction == 'left':
            self.x_coord -= 10
            if self.x_coord - 10 == 0:
                play.move_all_down()
        canvas.coords(self.shape, self.x_coord, self.y_coord, self.x_coord + 50, self.y_coord + 50)

class Play():
    def __init__(self, canvas):
        self.canvas = canvas
        self.invaderlist = []
        self.last_move_time = timeit.default_timer()
        self.move_delay = 0.3443434

    def move_invaders(self):
            current_time = timeit.default_timer()
            if current_time - self.last_move_time > self.move_delay:
                for invader in self.invaderlist:
                    invader.move()
                    self.last_move_time = current_time
    def move_all_down(self):
        for invader in self.invaderlist:
            invader.y_coord += 10
            canvas.coords(invader.shape, invader.x_coord, invader.y_coord, invader.x_coord + 50, invader.y_coord + 50)
            if invader.direction == 'left':
                invader.direction = 'right'
            elif invader.direction == 'right':
                invader.direction = 'left'


    def run_all(self):
        x_coords = [50, 120, 200, 270, 350, 420, 500, 570, 650, 720]
        y = 200
        for i in range(10):
            x = x_coords[i]
            invader = Invader(self.canvas, self, x, y)
            self.invaderlist.append(invader)
        while True:
            self.move_invaders()
            canvas.after(5)
            self.canvas.update()          

play = Play(canvas)
play.run_all()
tkinter.mainloop()

我尝试在碰到左边时输出坐标,还加了一行代码来打印入侵者的ID和坐标。我也试着修改了第26行检查的距离。

1 个回答

0

在你的 Play.move_invaders() 循环里,每个入侵者都可以移动。但是,如果有任何一个入侵者移动超过了左右的边界,就会导致所有入侵者都向下移动,而且这个动作会改变它们的移动方向,这样其他入侵者的移动判断条件(比如 if self.direction == 'right': 等等)就会受到影响,导致并不是所有入侵者都朝同一个方向移动。

你的循环应该先让所有入侵者移动,然后如果有入侵者超过了边界,再调用 move_all_down() 来处理:

import tkinter
import timeit

tk = tkinter.Tk()
WIDTH = 1000
HEIGHT = 650
global canvas
canvas = tkinter.Canvas(tk, width=WIDTH, height=HEIGHT, bg="black")
canvas.pack()

class Invader():
    def __init__(self, canvas, play, x, y):
        self.canvas = canvas
        self.play = play
        self.x_coord = x
        self.y_coord = y
        self.shape = canvas.create_rectangle(self.x_coord, self.y_coord, self.x_coord + 50, self.y_coord + 50, fill='green')
        self.direction = 'left'

    def move(self):
        limit = False
        if self.direction == 'right':
            self.x_coord += 10
            if self.x_coord + 40 >= WIDTH:
                limit = True
        elif self.direction == 'left':
            self.x_coord -= 10
            if self.x_coord - 10 <= 0:
                limit = True

        canvas.coords(self.shape, self.x_coord, self.y_coord, self.x_coord + 50, self.y_coord + 50)
        return limit

class Play():
    def __init__(self, canvas):
        self.canvas = canvas
        self.invaderlist = []
        self.last_move_time = timeit.default_timer()
        self.move_delay = 0.3443434

    def move_invaders(self):
            current_time = timeit.default_timer()
            if current_time - self.last_move_time > self.move_delay:
                move_down = False
                for invader in self.invaderlist:
                    limit = invader.move()
                    move_down = move_down or limit
                    self.last_move_time = current_time
                if move_down:
                    self.move_all_down()

    def move_all_down(self):
        for invader in self.invaderlist:
            invader.y_coord += 10
            #canvas.coords(invader.shape, invader.x_coord, invader.y_coord, invader.x_coord + 50, invader.y_coord + 50)
            if invader.direction == 'left':
                invader.direction = 'right'
            elif invader.direction == 'right':
                invader.direction = 'left'


    def run_all(self):
        x_coords = [50, 120, 200, 270, 350, 420, 500, 570, 650, 720]
        y = 200
        for i in range(10):
            x = x_coords[i]
            invader = Invader(self.canvas, self, x, y)
            self.invaderlist.append(invader)
        while True:
            self.move_invaders()
            canvas.after(5)
            self.canvas.update()          

play = Play(canvas)
play.run_all()

撰写回答