Pygame的蛇 - 蛇里面产卵苹果

问题描述 投票:1回答:2

我正在学习如何做一个蛇游戏pygame中从thenewboston教程YouTube上,让我自己的。有一个在这里的“苹果”滋生蛇的位置,这是一件好事,我不想后面的比赛有问题。

我敢肯定,我必须指出,苹果地位不可能是一样的蛇,但无法弄清楚如何:

# Snake eating the apple
if snake_x_pos == apple_x and snake_y_pos == apple_y:
      pygame.mixer.Sound.play(eat_apple_sound)
      snakelength += 1
      apple_x = random.randrange(box_size, field_x, box_size)
      apple_y = random.randrange(box_size, field_y, box_size)

全码:

import pygame
import random

pygame.init()

# Game Title
pygame.display.set_caption("Original Snake")

# Game display 4:3
screen_w = 640
screen_h = 480
surface = pygame.display.set_mode((screen_w, screen_h))
bg_color = (170, 204, 102)
box_color = (43, 51, 26)
box_size = screen_h / 24

# PLAYING FIELD
field_x = screen_w - (box_size*2)
field_y = screen_h - (box_size*2)

# Frames per Second
clock = pygame.time.Clock()
FPS = 8

# Font settings
kongtext = "C:\Windows\Fonts\kongtext.ttf"
verysmall = pygame.font.Font(kongtext, 12)
small = pygame.font.Font(kongtext, 15)
medium = pygame.font.Font(kongtext, 30)
large = pygame.font.Font(kongtext, 60)
verylarge = pygame.font.Font(kongtext, 80)

# sound settings
game_over_sound = pygame.mixer.Sound("sounds/game_over.wav")
eat_apple_sound = pygame.mixer.Sound("sounds/eat_apple.wav")


def snake(box_size, snakelist):
    for XnY in snakelist:
        pygame.draw.rect(surface, box_color, [XnY[0], XnY[1], box_size, box_size])


# Text Object
def text_objects(text, color, size):
    if size == "small":
        text_surface = small.render(text, True, color)
    elif size == "verysmall":
        text_surface = verysmall.render(text, True, color)
    elif size == "medium":
        text_surface = medium.render(text, True, color)
    elif size == "large":
        text_surface = large.render(text, True, color)
    elif size == "verylarge":
        text_surface = large.render(text, True, color)
    return text_surface, text_surface.get_rect()


# Start screen
def start_screen():
    intro = True
    while intro:
        # IF USER CLICKS ON THE X
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

            # Start Game
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    intro = False

        surface.fill(bg_color)

        # SCREEN FIELD WITH BORDER 3
        pygame.draw.rect(surface, box_color, [16, 16, screen_w-33, screen_h-33-box_size], 3)

        # START SCREEN
        message_to_screen("SNAKE", box_color, -25, size="verylarge")
        message_to_screen("PRESS SPACE TO PLAY", box_color, 35, size="verysmall")
        pygame.display.update()
        clock.tick(15)


# Message to screen
def message_to_screen(msg, color, text_y_pos=0, size="small"):
    text_surf, text_rect = text_objects(msg, color, size)
    text_rect.center = (screen_w / 2), (screen_h / 2)+text_y_pos
    surface.blit(text_surf, text_rect)


def score(score):
    text = small.render("Score: "+str((score*10)-20), True, box_color)
    surface.blit(text, [box_size, screen_h-box_size-7])


def game_loop():
    direction = "right"
    quit_game = False
    game_over = False

    # Box settings
    box_color = (43, 51, 26)

    # Defining snake position
    snakelist = []
    snakelength = 3
    snake_x_pos = screen_w / 2
    snake_y_pos= screen_h / 2
    snake_x_chg = box_size
    snake_y_chg = 0

    # Randomizing the apple position
    apple_x = random.randrange(box_size, field_x, box_size)
    apple_y = random.randrange(box_size, field_y, box_size)

    while not quit_game:
        # Game Over
        while game_over:
            surface.fill(bg_color)
            message_to_screen("GAME OVER", box_color, -10, size="large")
            message_to_screen("PRESS SPACE TO PLAY AGAIN OR Q TO QUIT", box_color, 50, size="small")

            # PLAYING FIELD
            pygame.draw.rect(surface, box_color,
                             [16, 16, screen_w - 33, screen_h - 33 - box_size], 3)

            # SCORE
            score(snakelength - 1)

            pygame.display.update()

            # Closing Game Over screen with X
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit_game = True
                    game_over = False

                # Closing Game Over screen with Q or Restart with space
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_a:
                        quit_game = True
                        game_over = False
                    if event.key == pygame.K_SPACE:
                        direction = "right"
                        game_loop()

        for event in pygame.event.get():
            # Closing the game
            if event.type == pygame.QUIT:
                quit_game = True
                game_over = False
            # Controlling the snake
            if event.type == pygame.KEYDOWN:
                if (event.key == pygame.K_LEFT) and direction != "right":
                    snake_x_chg = -box_size
                    snake_y_chg = 0
                    direction = "left"
                elif (event.key == pygame.K_RIGHT) and direction != "left":
                    snake_x_chg = box_size
                    snake_y_chg = 0
                    direction = "right"
                elif (event.key == pygame.K_UP) and direction != "down":
                    snake_y_chg = -box_size
                    snake_x_chg = 0
                    direction = "up"
                elif (event.key == pygame.K_DOWN) and direction != "up":
                    snake_y_chg = box_size
                    snake_x_chg = 0
                    direction = "down"

        # Screen boundaries
        if snake_x_pos > (field_x) or snake_x_pos < box_size or snake_y_pos > (field_y) or snake_y_pos < box_size:
            pygame.mixer.Sound.play(game_over_sound)
            game_over = True

        # Snake new position
        snake_x_pos += snake_x_chg
        snake_y_pos += snake_y_chg

        # Clear screen
        surface.fill(bg_color)

        # Draw and update
        pygame.draw.rect(surface, box_color, [apple_x, apple_y, box_size, box_size])
        snakehead = []
        snakehead.append(snake_x_pos)
        snakehead.append(snake_y_pos)
        snakelist.append(snakehead)

        if len(snakelist) > snakelength:
            del snakelist[0]

        for snaketail in snakelist[:-1]:
            if snaketail == snakehead:
                pygame.mixer.Sound.play(game_over_sound)
                game_over = True

        snake(box_size, snakelist)

        # PLAYING FIELD
        pygame.draw.rect(surface, box_color, [16, 16, screen_w-33, screen_h-33-box_size], 3)

        # SCORE
        score(snakelength-1)

        pygame.display.update()

        # Snake eating the apple
        if snake_x_pos == apple_x and snake_y_pos == apple_y:
            pygame.mixer.Sound.play(eat_apple_sound)
            snakelength += 1
            apple_x = random.randrange(box_size, field_x, box_size)
            apple_y = random.randrange(box_size, field_y, box_size)

        clock.tick(FPS)

    pygame.quit()
    quit()


start_screen()
game_loop()
python pygame
2个回答
0
投票

在创建新的随机“苹果”位置的矩形:

apple_rect = pygame.Rect(apple_x, apple_y, box_size, box_size)

检查在pos每个位置(snakelist)如果“苹果”矩形与pygame.Rect.collidepoint蛇的部分碰撞:

apple_rect.collidepoint(*pos)

使用any()检查,如果苹果“碰撞”与蛇的任何部分:

any(apple_rect.collidepoint(*pos) for pos in snakelist)

如果苹果“碰撞”与蛇创建一个新的随机点,并重复上述过程:

# Snake eating the apple
if snake_x_pos == apple_x and snake_y_pos == apple_y:
    pygame.mixer.Sound.play(eat_apple_sound)
    snakelength += 1
    while True:
        apple_x, apple_y = (random.randrange(box_size, fs, box_size) for fs in (field_x, field_y))
        apple_rect = pygame.Rect(apple_x, apple_y, box_size, box_size)
        if not any(apple_rect.collidepoint(*pos) for pos in snakelist): 
            break

0
投票

蛇似乎是“盒子”,在列表中snakelist持有的一份名单。因此,为了保证苹果不会出现在蛇的内部零件,将生成的随机点需要被蛇的箱子之外创建的。

一个简单的(但低效的)的方式来做到这一点是保持生成随机点,并测试他们的碰撞。

collision = True
while collision == True:
    # Randomizing the apple position
    apple_x = random.randrange(box_size, field_x, box_size)
    apple_y = random.randrange(box_size, field_y, box_size)
    # Check apple not within snake
    collision = False
    for XnY in snakelist:
        part = pygame.Rect( XnY[0], XnY[1], box_size, box_size )
        # is the apple-point within the snake part?
        if part.collidepoint( apple_x, apple_y ) == True:
            collision = True
            break  # any collision is final, stop checking

这将是值得的移动点从蛇而不是遍历岁及以上远更有效的方式思考。选择一个随机点可以简单地选择相同点,或近的坏点一次。此外蛇变长,越差这个循环会因为有在屏幕上少了“非蛇”之分。我想有一些已知的安全斑点,像蛇刚搬出的空间,但这些显然不是随机的。

© www.soinside.com 2019 - 2024. All rights reserved.