为什么在这种情况下碰撞不起作用?游戏不断打印“碰撞!”即使两个精灵不在一起?

2024-05-18 21:41:44 发布

您现在位置:Python中文网/ 问答频道 /正文

这是蛇的翻拍。我在这里的目标是让苹果在蛇与它相撞后随机重生。出于某种原因,在我开始游戏后,collideïrect函数似乎认为它们一直在不断地碰撞

任何其他有助于清理这一混乱局面的建议也都是受欢迎的:

import pygame
import time
import random

pygame.init()

WHITE = (pygame.Color("white"))
BLACK = (  0,   0,  0)
RED   = (245,   0,  0)
TURQ  = (pygame.Color("turquoise"))
GREEN = (  0, 155,  0)
GREY  = ( 90,  90, 90)
SCREEN = (800, 600)
gameDisplay = pygame.display.set_mode(SCREEN)
#Set the window title and picture
pygame.display.set_caption('Block Worm')
ICON = pygame.image.load("apple10pix.png")

pygame.display.set_icon(ICON)
CLOCK = pygame.time.Clock()
FPS = 20
FONT = pygame.font.SysFont("arial", 25)
APPLE_SIZE = 10
TINY_FONT = pygame.font.SysFont("candara", 15)
SMALL_FONT = pygame.font.SysFont("candara", 25)
MED_FONT = pygame.font.SysFont("candara", 50)
LARGE_FONT = pygame.font.SysFont("krabbypatty", 75)
HUGE_FONT = pygame.font.SysFont("krabbypatty", 150)
IMG = pygame.image.load("snakehead.png")
APPLE_IMG = pygame.image.load("apple10pix.png")
DIRECTION = "up"    

def pause():
    paused = True
    message_to_screen("Paused",
                      BLACK,
                      Y_DISPLACE = -100,
                      size = "huge")
    message_to_screen("Press C to continue or Q to quit.",
                      BLACK,
                      Y_DISPLACE = 25)
    pygame.display.update()
    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key in (pygame.K_c, pygame.K_p):
                    paused = False
                elif event.key in(pygame.K_q, pygame.K_ESCAPE):
                    pygame.quit()
                    quit()
        CLOCK.tick(5)

def score(score):
    text = SMALL_FONT.render("Score: " + str(score), True, BLACK)
    gameDisplay.blit(text, [0, 0])

def game_intro():
    intro = True
    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_c:
                    intro = False
                if event.key in (pygame.K_q, pygame.K_ESCAPE):
                    pygame.quit()
                    quit()
        gameDisplay.fill(WHITE)
        message_to_screen("Welcome to",
                          GREEN,
                          Y_DISPLACE = -170,
                          size = "large")
        message_to_screen("Block Worm",
                          GREEN,
                          Y_DISPLACE = -50,
                          size = "huge")
        message_to_screen("The objective of the game is to eat apples.",
                          BLACK,
                          Y_DISPLACE = 36,
                          size = "tiny")
        message_to_screen("The more apples you eat the longer you get.",
                          BLACK,
                          Y_DISPLACE = 68,
                          size = "tiny")
        message_to_screen("If you run into yourself or the edges, you die.",
                          BLACK,
                          Y_DISPLACE = 100,
                          size = "tiny")
        message_to_screen("Press C to play or Q to quit.",
                          GREY,
                          Y_DISPLACE = 210,)
        pygame.display.update()
        CLOCK.tick(FPS)

def text_objects(text, color, size):
    if size == "tiny":
        TEXT_SURFACE = TINY_FONT.render(text, True, color)
    elif size == "small":
        TEXT_SURFACE = SMALL_FONT.render(text, True, color)
    elif size == "medium":
        TEXT_SURFACE = MED_FONT.render(text, True, color)
    elif size == "large":
        TEXT_SURFACE = LARGE_FONT.render(text, True, color)
    elif size == "huge":
        TEXT_SURFACE = HUGE_FONT.render(text, True, color)
    return TEXT_SURFACE, TEXT_SURFACE.get_rect()

def message_to_screen(msg, color, Y_DISPLACE = 0, size = "small"):
    TEXT_SURF, TEXT_RECT = text_objects(msg, color, size)
    TEXT_RECT.center = (SCREEN[0] / 2), (SCREEN[1] / 2) + Y_DISPLACE
    gameDisplay.blit(TEXT_SURF, TEXT_RECT)

class Snake(pygame.sprite.Sprite):
    def __init__(self, image, size, trail, start_size):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.size = size
        self.trail = trail
        self.start_size = start_size
        self.rect = self.image.get_rect()
        if DIRECTION == "right":
            HEAD = pygame.transform.rotate(self.image, 270)
        elif DIRECTION == "left":
            HEAD = pygame.transform.rotate(self.image, 90)
        elif DIRECTION == "down":
            HEAD = pygame.transform.rotate(self.image, 180)
        else:
            HEAD = image
        gameDisplay.blit(HEAD, (self.trail[-1][0], self.trail[-1][1]))
        for XnY in self.trail[:-1]:
            pygame.draw.rect(gameDisplay, GREEN, [XnY[0], XnY[1], self.size, self.size])

class Apple(pygame.sprite.Sprite):
    def __init__(self, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect()
        self.size = self.rect.width
        gameDisplay.blit(self.image, (100, 100))

    def random_location(self):
        self.rect.x = random.randrange(0, (SCREEN[0] - 10), 10)
        self.rect.y = random.randrange(0, (SCREEN[1]- 10), 10)
        gameDisplay.blit(self.image, (self.rect.x, self.rect.y))





def gameLoop():
    global DIRECTION
    DIRECTION = "up"
    gameExit = False
    gameOver = False
    SCORE = 0

    player_snake_trail = [] # Where the snake head has been.
    enemy_snake_trail = [] # If I create an AI snake.
    start_length = 1

    lead_x = (SCREEN[0] / 2)
    lead_y = (SCREEN[1] - (SCREEN[1] / 5))
    move_speed = 10
    move_speed_neg = move_speed * -1
    lead_x_change = 0
    lead_y_change = -move_speed

    while not gameExit:
        if gameOver == True:
            message_to_screen("Game over",
                              RED,
                              Y_DISPLACE = -50,
                              size = "huge")
            message_to_screen("Press C to play again or Q to quit.",
                              BLACK,
                              Y_DISPLACE = 50,
                              size = "small")
            pygame.display.update()
        while gameOver == True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameExit = True
                    gameOver = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        gameOver = False
                        gameExit = True
                    elif event.key == pygame.K_c:
                        gameLoop()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            elif event.type == pygame.KEYDOWN:
                if event.key in (pygame.K_LEFT, pygame.K_a):
                    lead_x_change = move_speed_neg
                    lead_y_change = 0
                    DIRECTION = "left"
                elif event.key in (pygame.K_RIGHT, pygame.K_d):
                    lead_x_change = move_speed
                    lead_y_change = 0
                    DIRECTION = "right"
                elif event.key in (pygame.K_UP, pygame.K_w):
                    lead_y_change = move_speed_neg
                    lead_x_change = 0
                    DIRECTION = "up"
                elif event.key in (pygame.K_DOWN, pygame.K_s):
                    lead_y_change = move_speed
                    lead_x_change = 0
                    DIRECTION = "down"
                elif event.key in (pygame.K_p, pygame.K_ESCAPE):
                    pause()

        # If the snake goes beyond the screen borders the game will end.
        if lead_x >= SCREEN[0] or lead_x < 0 or lead_y >= SCREEN[1] or lead_y <0:
            gameOver = True

        lead_x += lead_x_change
        lead_y += lead_y_change

        gameDisplay.fill(WHITE)

        # Draw the apple on screen
        red_apple = Apple(APPLE_IMG)

        # Draw the snake on screen
        SNAKE_HEAD = []
        SNAKE_HEAD.append(lead_x)
        SNAKE_HEAD.append(lead_y)
        player_snake_trail.append(SNAKE_HEAD)
        # If you hit yourself, game over.
        if SNAKE_HEAD in player_snake_trail[:-1]:
           gameOver = True
        if len(player_snake_trail) > start_length:
            del player_snake_trail[0]

        player_snake = Snake(IMG, 10, player_snake_trail, start_length)
        if pygame.sprite.collide_rect(player_snake, red_apple) == True:
            print("Collided!")

##            start_length += 1
##            SCORE += 1
##            red_apple.random_location()

        # If the snake eats the apple
        # Old code below, needs to be rewritten. Disregard.
##        if APPLE_RECT.collidepoint(lead_x, lead_y) == True:
##            randAppleX, randAppleY = randAppleGen()
##            start_length += 1
##            SCORE += 1

        score(SCORE)

        pygame.display.update()
        CLOCK.tick(FPS)
    pygame.quit()
    quit()

game_intro()
gameLoop()

Tags: toinrectimageselfeventtruesize
1条回答
网友
1楼 · 发布于 2024-05-18 21:41:44

当你在构造器中为苹果和蛇头设置矩形时,它们的x和y坐标为0。你需要设置矩形并在蛇移动时更新它们。我给它们添加了一个集合方法。我还将draw从apple.u位置移到了自己的方法。您的代码应该如下所示:

init()
run()

在运行中:

check_events()
update_snake()
collision_check()
draw_things()
clock.tick(FPS)

这是修改过的代码,试着像上面那样把它分成几个部分

import pygame
import time
import random

pygame.init()

WHITE = (pygame.Color("white"))
BLACK = (  0,   0,  0)
RED   = (245,   0,  0)
TURQ  = (pygame.Color("turquoise"))
GREEN = (  0, 155,  0)
GREY  = ( 90,  90, 90)
SCREEN = (800, 600)
gameDisplay = pygame.display.set_mode(SCREEN)
#Set the window title and picture
pygame.display.set_caption('Block Worm')
ICON = pygame.Surface((10,10)) #pygame.image.load("apple10pix.png")

pygame.display.set_icon(ICON)
CLOCK = pygame.time.Clock()
FPS = 20
FONT = pygame.font.SysFont("arial", 25)
APPLE_SIZE = 10
TINY_FONT = pygame.font.SysFont("candara", 15)
SMALL_FONT = pygame.font.SysFont("candara", 25)
MED_FONT = pygame.font.SysFont("candara", 50)
LARGE_FONT = pygame.font.SysFont("krabbypatty", 75)
HUGE_FONT = pygame.font.SysFont("krabbypatty", 150)
IMG = pygame.Surface((10,10)) #pygame.image.load("snakehead.png")
APPLE_IMG = pygame.Surface((10,10)) #pygame.image.load("apple10pix.png")
DIRECTION = "up"    

def pause():
    paused = True
    message_to_screen("Paused",
                      BLACK,
                      Y_DISPLACE = -100,
                      size = "huge")
    message_to_screen("Press C to continue or Q to quit.",
                      BLACK,
                      Y_DISPLACE = 25)
    pygame.display.update()
    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key in (pygame.K_c, pygame.K_p):
                    paused = False
                elif event.key in(pygame.K_q, pygame.K_ESCAPE):
                    pygame.quit()
                    quit()
        CLOCK.tick(5)

def score(score):
    text = SMALL_FONT.render("Score: " + str(score), True, BLACK)
    gameDisplay.blit(text, [0, 0])

def game_intro():
    intro = True
    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_c:
                    intro = False
                if event.key in (pygame.K_q, pygame.K_ESCAPE):
                    pygame.quit()
                    quit()
        gameDisplay.fill(WHITE)
        message_to_screen("Welcome to",
                          GREEN,
                          Y_DISPLACE = -170,
                          size = "large")
        message_to_screen("Block Worm",
                          GREEN,
                          Y_DISPLACE = -50,
                          size = "huge")
        message_to_screen("The objective of the game is to eat apples.",
                          BLACK,
                          Y_DISPLACE = 36,
                          size = "tiny")
        message_to_screen("The more apples you eat the longer you get.",
                          BLACK,
                          Y_DISPLACE = 68,
                          size = "tiny")
        message_to_screen("If you run into yourself or the edges, you die.",
                          BLACK,
                          Y_DISPLACE = 100,
                          size = "tiny")
        message_to_screen("Press C to play or Q to quit.",
                          GREY,
                          Y_DISPLACE = 210,)
        pygame.display.update()
        CLOCK.tick(FPS)

def text_objects(text, color, size):
    if size == "tiny":
        TEXT_SURFACE = TINY_FONT.render(text, True, color)
    elif size == "small":
        TEXT_SURFACE = SMALL_FONT.render(text, True, color)
    elif size == "medium":
        TEXT_SURFACE = MED_FONT.render(text, True, color)
    elif size == "large":
        TEXT_SURFACE = LARGE_FONT.render(text, True, color)
    elif size == "huge":
        TEXT_SURFACE = HUGE_FONT.render(text, True, color)
    return TEXT_SURFACE, TEXT_SURFACE.get_rect()

def message_to_screen(msg, color, Y_DISPLACE = 0, size = "small"):
    TEXT_SURF, TEXT_RECT = text_objects(msg, color, size)
    TEXT_RECT.center = (SCREEN[0] / 2), (SCREEN[1] / 2) + Y_DISPLACE
    gameDisplay.blit(TEXT_SURF, TEXT_RECT)

class Snake(pygame.sprite.Sprite):
    def __init__(self, image, size, trail, start_size):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.size = size
        self.trail = trail
        self.start_size = start_size
        self.rect = self.image.get_rect()
        if DIRECTION == "right":
            HEAD = pygame.transform.rotate(self.image, 270)
        elif DIRECTION == "left":
            HEAD = pygame.transform.rotate(self.image, 90)
        elif DIRECTION == "down":
            HEAD = pygame.transform.rotate(self.image, 180)
        else:
            HEAD = image
        gameDisplay.blit(HEAD, (self.trail[-1][0], self.trail[-1][1]))
        for XnY in self.trail[:-1]:
            pygame.draw.rect(gameDisplay, GREEN, [XnY[0], XnY[1], self.size, self.size])

    def set_rect(self, rect):
        self.rect = rect

class Apple(pygame.sprite.Sprite):
    def __init__(self, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.random_location()
        self.size = self.rect.width
        gameDisplay.blit(self.image, (100, 100))

    def random_location(self):

        x = random.randrange(0, (SCREEN[0] - 10), 10)
        y = random.randrange(0, (SCREEN[1]- 10), 10)
        self.rect = pygame.Rect(x,y, 10, 10)
        print "apple rect =",
        print self.rect

    def draw(self):
        gameDisplay.blit(self.image, (self.rect.x, self.rect.y))




def gameLoop():
    global DIRECTION
    DIRECTION = "up"
    gameExit = False
    gameOver = False
    SCORE = 0

    player_snake_trail = [] # Where the snake head has been.
    enemy_snake_trail = [] # If I create an AI snake.
    start_length = 1

    lead_x = (SCREEN[0] / 2)
    lead_y = (SCREEN[1] - (SCREEN[1] / 5))
    move_speed = 10
    move_speed_neg = move_speed * -1
    lead_x_change = 0
    lead_y_change = -move_speed


    red_apple = Apple(APPLE_IMG)

    while not gameExit:
        if gameOver == True:
            message_to_screen("Game over",
                              RED,
                              Y_DISPLACE = -50,
                              size = "huge")
            message_to_screen("Press C to play again or Q to quit.",
                              BLACK,
                              Y_DISPLACE = 50,
                              size = "small")
            pygame.display.update()
        while gameOver == True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameExit = True
                    gameOver = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        gameOver = False
                        gameExit = True
                    elif event.key == pygame.K_c:
                        gameLoop()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            elif event.type == pygame.KEYDOWN:
                if event.key in (pygame.K_LEFT, pygame.K_a):
                    lead_x_change = move_speed_neg
                    lead_y_change = 0
                    DIRECTION = "left"
                elif event.key in (pygame.K_RIGHT, pygame.K_d):
                    lead_x_change = move_speed
                    lead_y_change = 0
                    DIRECTION = "right"
                elif event.key in (pygame.K_UP, pygame.K_w):
                    lead_y_change = move_speed_neg
                    lead_x_change = 0
                    DIRECTION = "up"
                elif event.key in (pygame.K_DOWN, pygame.K_s):
                    lead_y_change = move_speed
                    lead_x_change = 0
                    DIRECTION = "down"
                elif event.key in (pygame.K_p, pygame.K_ESCAPE):
                    pause()

        # If the snake goes beyond the screen borders the game will end.
        if lead_x >= SCREEN[0] or lead_x < 0 or lead_y >= SCREEN[1] or lead_y <0:
            gameOver = True

        lead_x += lead_x_change
        lead_y += lead_y_change

        gameDisplay.fill(WHITE)

        # Draw the snake on screen
        SNAKE_HEAD = []
        SNAKE_HEAD.append(lead_x)
        SNAKE_HEAD.append(lead_y)
        player_snake_trail.append(SNAKE_HEAD)

        # draw the apple on the screen
        red_apple.draw()

        # If you hit yourself, game over.
        if SNAKE_HEAD in player_snake_trail[:-1]:
           gameOver = True
        if len(player_snake_trail) > start_length:
            del player_snake_trail[0]

        player_snake = Snake(IMG, 10, player_snake_trail, start_length)
        player_snake.set_rect(pygame.Rect(lead_x, lead_y, 10, 10))

        if pygame.sprite.collide_rect(player_snake, red_apple) == True:
           print("Collided!")

           start_length += 1
           SCORE += 1
           red_apple.random_location()

        # If the snake eats the apple
        # Old code below, needs to be rewritten. Disregard.
##        if APPLE_RECT.collidepoint(lead_x, lead_y) == True:
##            randAppleX, randAppleY = randAppleGen()
##            start_length += 1
##            SCORE += 1

        score(SCORE)

        pygame.display.update()
        CLOCK.tick(FPS)
    pygame.quit()
    quit()

game_intro()
gameLoop()

相关问题 更多 >

    热门问题