Поверхность, показанная неожиданно с пигмеем - PullRequest
0 голосов
/ 02 ноября 2018

Я нахожусь в процессе создания игры со змеями, до сих пор все шло хорошо, но в левом верхнем углу отображался блок змеи, от которого я не могу избавиться. Я проверил, что я не рисовал поверхность там (0,0). Я застрял. Пожалуйста, помогите мне, спасибо !!


Кстати, я впервые задаю вопрос, поэтому любые предложения по этому вопросу также приветствуются.


Редактировать: я обнаружил, что использование обычного класса вместо спрайта решило проблему, но мне нужны функции столкновения и другие функции в спрайте.

import pygame

class snake(pygame.sprite.Sprite):
    speed=5
    init_length=10
    direction=0
    x=[]
    y=[]
    updateCountMax = 2
    updateCount = 0
    length=10
#    image=pygame.Surface((11,11)).convert().fill((0,128,255))
    def __init__(self,init_x,init_y,image,screen):
        pygame.sprite.Sprite.__init__(self)

        for i in range(0,self.init_length):
            self.x.append(init_x)
            self.y.append(init_y)
#        for i in range(0,self.length):
#            print(f"{self.x[i]},{self.y[i]}")
        for x in self.x:
            print(x)
        for y in self.y:
            print(y)
        self.image=image
        self.screen=screen
        self.rect=self.image.get_rect()
#        self.rect.center=(self.x,self.y)

    def move_R(self):
#        self.x+=self.speed
        self.direction=0
    def move_L(self):
#        self.x-=self.speed
        self.direction=1
    def move_U(self):
#        self.y-=self.speed
        self.direction=2
    def move_D(self):
#        self.y+=self.speed
        self.direction=3

    def update(self):
#        self.updateCount = self.updateCount + 1
#        if self.updateCount < self.updateCountMax:
        for i in range(self.length-1,0,-1):
#                print("self.x[" + str(i) + "] = self.x[" + str(i-1) + "]")
            self.x[i] = self.x[i-1]
            self.y[i] = self.y[i-1]

        if(self.direction==0):
            self.x[0]+=self.speed
        elif(self.direction==1):
            self.x[0]-=self.speed
        elif(self.direction==2):
            self.y[0]-=self.speed
        elif(self.direction==3):
            self.y[0]+=self.speed
#        self.rect.center=(self.x,self.y)
#        self.updateCount = 0
#        for i in range(0,self.length):
#            print(f"{self.x[i]},{self.y[i]}")
        self.draw()

    def draw(self):
        for i in range(0,self.length):
            self.screen.blit(self.image,(self.x[i],self.y[i]))
#            print(f"rendered at {self.x[i]},{self.y[i]}")
#            self.rect.center=(self.x[i],self.y[i])

class app:
    width=1200
    height=900
    title="Snake"
    done=False

    def __init__(self):
        pygame.init()
        self.image=pygame.Surface((11,11))
        self.image.fill((0,128,255))
        pygame.display.set_caption(self.title)
        self.screen = pygame.display.set_mode((self.width, self.height))
        self.screen.fill((0,0,0))
        self.clock=pygame.time.Clock()
        self.snakes=pygame.sprite.Group()
        self.player1=snake(500,10,self.image,self.screen)
        self.snakes.add(self.player1)
        self.background = pygame.Surface(self.screen.get_size())
        self.background = self.background.convert()
        self.background.fill((255,255,255))

    def loop(self):
        while(not self.done):
            for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                                self.done = True
            pygame.event.pump()
            keys = pygame.key.get_pressed()

            if (keys[pygame.K_RIGHT]):
                self.player1.move_R()

            if (keys[pygame.K_LEFT]):
                self.player1.move_L()

            if (keys[pygame.K_UP]):
                self.player1.move_U()

            if (keys[pygame.K_DOWN]):
                self.player1.move_D()

            if (keys[pygame.K_ESCAPE]):
                self.done = True
            self.screen.blit(self.background,(0,0))
            self.screen.fill((0,0,0))
            self.player1.update()
            self.snakes.draw(self.screen)
            pygame.display.update()
            self.clock.tick(60)
        pygame.quit()

if __name__ == "__main__" :
    theApp = app()
    theApp.loop()

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

В левом верхнем углу вы видите self.image спрайта player1. * * * * * Метод групп спрайтов draw отбрасывает image s в координатах rect.topleft спрайтов, и, поскольку вы никогда не перемещаете player1.rect, изображение будет мигать с координатами по умолчанию (0, 0). Так что просто удалите строку self.snakes.draw(self.screen), чтобы это исправить.

Я также предлагаю использовать pygame.Rect s вместо списков self.x и self.y. Вы можете создавать прямоугольные экземпляры с координатами init_x и init_y в качестве атрибута topleft и помещать их в список self.rects. Это позволяет упростить методы обновления и прорисовки, а также тезисы можно использовать для обнаружения столкновений. Я уже переработал ваш код (он стал мини-обзором кода):

import pygame


class Snake(pygame.sprite.Sprite):  # Use upper camelcase names for classes (see PEP 8).

    def __init__(self, init_x, init_y, image,screen):
        pygame.sprite.Sprite.__init__(self)
        # These are instance attributes now (use class attributes if
        # the values should be shared between the instances).
        self.speed = 5
        self.init_length = 10
        self.direction = 0
        self.updateCountMax = 2
        self.updateCount = 0
        self.length = 10
        # The body parts are rects now.
        self.rects = []
        for i in range(self.init_length):
            # Append pygame.Rect instances.
            self.rects.append(pygame.Rect(init_x, init_y, 11, 11))

        self.image = image
        self.screen = screen
        self.rect = self.rects[0]  # I use the first rect as the self.rect.

    def update(self):
        for i in range(self.length-1, 0, -1):
            # Update the topleft (x, y) positions of the rects.
            self.rects[i].topleft = self.rects[i-1].topleft

        if self.direction == 0:
            self.rects[0].x += self.speed
        elif self.direction == 1:
            self.rects[0].x -= self.speed
        elif self.direction == 2:
            self.rects[0].y -= self.speed
        elif self.direction == 3:
            self.rects[0].y += self.speed

    def draw(self):
        # Iterate over the rects to blit them (I draw the outlines as well).
        for rect in self.rects:
            self.screen.blit(self.image, rect)
            pygame.draw.rect(self.screen, (0, 255, 0), rect, 1)


class App:
    width = 1200
    height = 900
    title = "Snake"
    done = False

    def __init__(self):
        pygame.init()
        self.image = pygame.Surface((11, 11))
        self.image.fill((0, 128, 255))
        pygame.display.set_caption(self.title)
        self.screen = pygame.display.set_mode((self.width, self.height))
        self.clock = pygame.time.Clock()
        self.snakes = pygame.sprite.Group()
        self.player1 = Snake(500, 10, self.image, self.screen)
        self.snakes.add(self.player1)

    def loop(self):
        while not self.done:
            # Handle the events.
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        self.done = True

            keys = pygame.key.get_pressed()
            # In Python we simply set the values of the
            # attributes directly instead of using getter
            # and setter methods.
            if keys[pygame.K_RIGHT]:
                self.player1.direction = 0
            if keys[pygame.K_LEFT]:
                self.player1.direction = 1
            if keys[pygame.K_UP]:
                self.player1.direction = 2
            if keys[pygame.K_DOWN]:
                self.player1.direction = 3
            if keys[pygame.K_ESCAPE]:
                self.done = True

            # Update the game.
            self.player1.update()

            # Draw everything.
            self.screen.fill((0, 0, 0))
            self.player1.draw()
            pygame.draw.rect(self.screen, (255, 0, 0), self.player1.rect, 1)
            pygame.display.update()
            self.clock.tick(60)
        pygame.quit()

if __name__ == "__main__" :
    the_app = App()
    the_app.loop()
0 голосов
/ 02 ноября 2018

Вы добавляете player1 в группу спрайтов snakes и рисуете это с помощью self.snakes.draw(self.screen). Тем не менее, вы также рисуете игрока в self.player1.update(), в последней строке.

Удалите self.snakes.draw(self.screen), чтобы избавиться от призрачной змеи.

Кстати: вы создаете и устанавливаете self.background, но вы сразу же перезаписываете его self.screen.fill((0,0,0)), поэтому вам совсем не нужен фон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...