Reputation: 19
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
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