safam
safam

Reputation: 19

Snakes game - boundaries

I started making this snakes game and I ran into a struggle. I want that when the snake reaches the end of one side it will come from the other side, if it reaches the end of left side it will come out of the right side and if it reaches the up end it will come out from the bottom. I'll really appreciate it if someone could maybe show me how to do that.

import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

segment_width = 15
segment_height = 15
segment_margin = 3

x_change = segment_width + segment_margin
y_change = 0


class Segment(pygame.sprite.Sprite):

    def __init__(self, x, y):
        super().__init__()

       self.image = pygame.Surface([segment_width, segment_height])
       self.image.fill(WHITE)

       self.rect = self.image.get_rect()
       self.rect.x = x
       self.rect.y = y

pygame.init()


screen = pygame.display.set_mode([1200, 800])


pygame.display.set_caption('Snakes')

allspriteslist = pygame.sprite.Group()

snake_segments = []
for i in range(3):
    x = 250 - (segment_width + segment_margin) * i
    y = 30
    segment = Segment(x, y)
    snake_segments.append(segment)
    allspriteslist.add(segment)


clock = pygame.time.Clock()
done = False

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = (segment_width + segment_margin) * -1
                y_change = 0
            if event.key == pygame.K_RIGHT:
                x_change = (segment_width + segment_margin)
                y_change = 0
            if event.key == pygame.K_UP:
                x_change = 0
                y_change = (segment_height + segment_margin) * -1
            if event.key == pygame.K_DOWN:
                x_change = 0
                y_change = (segment_height + segment_margin)


    old_segment = snake_segments.pop()
    allspriteslist.remove(old_segment)

    x = snake_segments[0].rect.x + x_change
    y = snake_segments[0].rect.y + y_change
    segment = Segment(x, y)

    snake_segments.insert(0, segment)
    allspriteslist.add(segment)

    screen.fill(BLACK)

    allspriteslist.draw(screen)

    pygame.display.flip()

    clock.tick(5)

pygame.quit()

Upvotes: 0

Views: 859

Answers (1)

furas
furas

Reputation: 143187

You can use if to check position and move to other side

x = snake_segments[0].rect.x + x_change
y = snake_segments[0].rect.y + y_change

if x < screen_rect.left:
    x += screen_rect.width
elif x + segment_width + segment_margin > screen_rect.right:
    x -= screen_rect.width

if y < screen_rect.top:
    y += screen_rect.height
elif y + segment_height + segment_margin > screen_rect.bottom:
    y -= screen_rect.height

segment = Segment(x, y)

But problem is that segments doesn't fill screen ideally - sometimes you should display part of segment on one side and rest on other side. You have to add method draw() to Segment which will check if you have to draw segment on both sides and draw two segments - first on one side and second on other side.

    def draw(self, screen):

        # draw oryginal segment

        screen_rect = screen.get_rect()
        screen.blit(self.image, self.rect)

        # draw second segment on other side

        # left - right
        if self.rect.left < screen_rect.left:
            temp_rect = self.rect.copy()
            temp_rect.x += screen_rect.width
            screen.blit(self.image, temp_rect)
        elif self.rect.right > screen_rect.right:
            temp_rect = self.rect.copy()
            temp_rect.x -= screen_rect.width
            screen.blit(self.image, temp_rect)

        # top - bottom
        if self.rect.top < screen_rect.top:
            temp_rect = self.rect.copy()
            temp_rect.y += screen_rect.height
            screen.blit(self.image, temp_rect)
        elif self.rect.bottom > screen_rect.bottom:
            temp_rect = self.rect.copy()
            temp_rect.y -= screen_rect.height
            screen.blit(self.image, temp_rect)

But it means that you have to manually execut this function because group.draw() runs directly screen.blit(self.image, self.rect)

for x in allspriteslist:
    x.draw(screen)

Full code

import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

segment_width = 15
segment_height = 15
segment_margin = 3

x_change = segment_width + segment_margin
y_change = 0


class Segment(pygame.sprite.Sprite):

    def __init__(self, x, y):
       super().__init__()

       self.image = pygame.Surface([segment_width, segment_height])
       self.image.fill(WHITE)

       self.rect = self.image.get_rect()
       self.rect.x = x
       self.rect.y = y

    def draw(self, screen):
        screen_rect = screen.get_rect()
        screen.blit(self.image, self.rect)

        if self.rect.left < screen_rect.left:
            temp_rect = self.rect.copy()
            temp_rect.x += screen_rect.width
            screen.blit(self.image, temp_rect)
        elif self.rect.right > screen_rect.right:
            temp_rect = self.rect.copy()
            temp_rect.x -= screen_rect.width
            screen.blit(self.image, temp_rect)

        if self.rect.top < screen_rect.top:
            temp_rect = self.rect.copy()
            temp_rect.y += screen_rect.height
            screen.blit(self.image, temp_rect)
        elif self.rect.bottom > screen_rect.bottom:
            temp_rect = self.rect.copy()
            temp_rect.y -= screen_rect.height
            screen.blit(self.image, temp_rect)


pygame.init()


screen = pygame.display.set_mode((1200, 800))
screen_rect = screen.get_rect()

pygame.display.set_caption('Snakes')

allspriteslist = pygame.sprite.Group()

snake_segments = []
for i in range(3):
    x = 250 - (segment_width + segment_margin) * i
    y = 30
    segment = Segment(x, y)
    snake_segments.append(segment)
    allspriteslist.add(segment)


clock = pygame.time.Clock()
done = False

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = (segment_width + segment_margin) * -1
                y_change = 0
            if event.key == pygame.K_RIGHT:
                x_change = (segment_width + segment_margin)
                y_change = 0
            if event.key == pygame.K_UP:
                x_change = 0
                y_change = (segment_height + segment_margin) * -1
            if event.key == pygame.K_DOWN:
                x_change = 0
                y_change = (segment_height + segment_margin)


    old_segment = snake_segments.pop()
    allspriteslist.remove(old_segment)

    x = snake_segments[0].rect.x + x_change
    y = snake_segments[0].rect.y + y_change

    if x < screen_rect.left:
        x += screen_rect.width
    elif x + segment_width + segment_margin > screen_rect.right:
        x -= screen_rect.width

    if y < screen_rect.top:
        y += screen_rect.height
    elif y + segment_height + segment_margin > screen_rect.bottom:
        y -= screen_rect.height

    segment = Segment(x, y)

    snake_segments.insert(0, segment)
    allspriteslist.add(segment)

    screen.fill(BLACK)

    #allspriteslist.draw(screen)

    for x in allspriteslist:
        x.draw(screen)

    pygame.display.flip()

    clock.tick(5)

pygame.quit()

Upvotes: 1

Related Questions