mardi 20 décembre 2016

Python 3.5.2: Pygame Snake Apple location

I made a basic eating apples snake game. After the snake "eats" the apple it gains one more segment in its length and the position of the apple resets to a new random location on the screen.

My problem is that it is possible that the new random coordinates of the apple can be the same as one's of the snake's segments, therefore the snake gains one more segment in it's length without actually "eating" the apple.

How can it make it so that the new apple location does not coincide with one of the snake's segments ? I do not necessary need the code that will make it work, but the logic behind it. Can anyone help ?

Please note that the game is very basic. It does not have boundaries and the snake can eat the apple even thought the apple does not always "fit" its mouth (it only has to touch it).

import pygame,random

# --- Globals ---
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255,0,0)

# Set the width and height of each snake segment
segment_width = 15
segment_height = 15
# Margin between each segment
segment_margin = 3

# Set initial speed
x_change = segment_width + segment_margin
y_change = 0


class Segment(pygame.sprite.Sprite):
    """ Class to represent one segment of the snake. """

    # -- Methods
    # Constructor function
    def __init__(self, x, y):
        # Call the parent's constructor
        super().__init__()

        # Set height, width
        self.image = pygame.Surface([segment_width, segment_height])
        self.image.fill(WHITE)

        # Make our top-left corner the passed-in location.
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class Apple(pygame.sprite.Sprite):

    def __init__(self,x,y):

        super().__init__()

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

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

    def update(self):
        self.rect.x = random.randrange(800)
        self.rect.y = random.randrange(600)


# Call this function so the Pygame library can initialize itself
pygame.init()

# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])

# Set the title of the window
pygame.display.set_caption('Snake Example')

apple_list = pygame.sprite.Group()

snake_group = pygame.sprite.Group()

allspriteslist = pygame.sprite.Group()

# Create an initial snake
snake_segments = []
for i in range(15):
    x = 250 - (segment_width + segment_margin) * i
    y = 30
    segment = Segment(x, y)
    snake_segments.append(segment)
    snake_group.add(segment)
    allspriteslist.add(segment)

m = random.randrange(0,800,15)
n = random.randrange(0,600,15)


apple = Apple(m, n)

apple_list.add(apple)
allspriteslist.add(apple)

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

while not done:

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

        # Set the speed based on the key pressed
        # We want the speed to be enough that we move a full
        # segment, plus the margin.
        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)

    # Get rid of last segment of the snake
    # .pop() command removes last item in list
    old_segment = snake_segments.pop()
    snake_group.remove(old_segment)

    # Figure out where new segment will be
    x = snake_segments[0].rect.x + x_change
    y = snake_segments[0].rect.y + y_change
    segment = Segment(x, y)

    # Insert new segment into the list
    snake_segments.insert(0, segment)
    snake_group.add(segment)

    apple_collide = pygame.sprite.spritecollide(apple,snake_group,False)

    for element in  apple_collide:
        apple_list.remove(element)
        score += 1
        print(score)
        apple.update()
        a = snake_segments[len(snake_segments)-1].rect.x
        b = snake_segments[len(snake_segments)-1].rect.y
        new_segment = Segment(a,b)
        snake_group.add(new_segment)
        snake_segments.append(new_segment)




    # -- Draw everything
    # Clear screen
    screen.fill(BLACK)

    apple_list.draw(screen)
    snake_group.draw(screen)

    # Flip screen
    pygame.display.flip()

    # Pause
    clock.tick(5)

pygame.quit()




Aucun commentaire:

Enregistrer un commentaire