由于某种原因,pygame将所有类的实例的位置设置为相同的值?

时间:2018-05-08 05:49:39

标签: python-3.x pygame

我正在玩pygame的蛇游戏,我遇到了一个问题。每当蛇吃食物时,玩家都会得到一分。从那时起,只要它移动,就会在蛇后面创建一条尾巴。只有尾巴才能绘制远离蛇头的玩家点数,而其余部分则被删除。当我创建尾巴时出现问题。每当我创建一个尾部实例时,我必须得到蛇头的位置并减去相反方向上蛇大小的值。这就是尾巴将被绘制的地方。但是由于某种原因,所有尾部的位置都设置为相同的值,我无法弄清楚为什么会这样。我正在使用我自己的图书馆,所以我不能在这里发布它,但我确定它不是原因。

    import pygame as pg

    from random import randrange

    import widget


    # disp -> display properties
    disp = widget.get_json("config", ["display"])

    food = widget.Surface(image="../images/food.png", pos=[0, 0])

    def set_food_pos(snake):
        while True:
            pos = [randrange(0, disp["size"][_], disp["cell"]) for _ in range(2)]
            safe = 0

            for tail in snake.tails:
                if tail.pos != pos: safe += 1

            if safe == len(snake.tails):
                food.pos = pos
                food.rect.topleft = food.pos

                break


    class Snake(widget.Sprite):
        """ Snake: main playable sprite """

        SIZE = [disp["cell"]] * 2
        KEYS = [[276, 275], [273, 274]]

        def __init__(self):
            self.image = pg.image.load("../images/snake_head.png")
            self.pos = widget.VEC(0, 0)

            super().__init__(pg.sprite.GroupSingle)

            self.axis, self.orient, self.do_move = 0, 1, False
            self.past, self.delay = pg.time.get_ticks(), 150
            self.speed, self.vel = disp["cell"], [-1, 1]
            self.alive, self.points = True, 0
            self.tails = [self]

        def control(self, key):
            axis = [0 if key in Snake.KEYS[0] else 1][0]
            if axis != self.axis:
                if self.do_move:
                    self.axis = axis
                    self.orient = Snake.KEYS[axis].index(key)
                    self.do_move = False

        def time_base_movement(self):
            now = pg.time.get_ticks()
            if now - self.past >= self.delay:
                self.do_move = True
                self.pos[self.axis] += self.vel[self.orient] * self.speed
                self.past = pg.time.get_ticks()

        def eat_food(self):
            if food.rect.contains(self.rect):
                set_food_pos(self)
                self.points += 1

        def create_tail(self):
            if self.points:
                if self.do_move:
                    pos = [_ for _ in self.rect.topleft]
                    pos[self.axis] += self.vel[::-1][self.orient] * 20
                    tail = widget.Sprite(image="../images/snake_head.png", pos=pos)

                    self.tails.insert(0, tail)

        def render_tails(self, surface):
            if self.points > 0:
                tails = self.tails[:-1]

                for tail in tails[0:self.points]: tail.group.draw(surface)
                [self.tails.remove(tail) for tail in tails[self.points:]]

        def check_boundary_collision(self):
            for _ in range(2):
                if self.pos[_] > disp["size"][_] - Snake.SIZE[_]:self.alive = False
                elif self.pos[_] < 0: self.alive = False

            for tail in self.tails[:-1]:
                if tail.rect.contains(self.rect): self.alive = False

        def reset_properties(self):
            if self.alive == False:
                print([tail.pos for tail in self.tails[:-1]])
                self.tails = [self]
                self.do_move = False

                self.pos = widget.VEC([0, 0])
                self.rect.topleft = self.pos

                self.axis, self.orient = 0, 1
                self.points, self.alive = 0, True

                set_food_pos(self)

        def update(self):
            if self.alive:
                self.time_base_movement()
                self.check_boundary_collision()
                self.reset_properties()

                self.rect.topleft = self.pos

1 个答案:

答案 0 :(得分:0)

我想通了,似乎python每次分配给不同的属性时都不会创建属性的新副本。相反,新属性指向已分配的属性。解决这个问题的方法是&#34; deepcopy&#34;内置模块中的方法&#34; copy&#34;。

Exe:new_value = copy.deepcopy(old_value)