#python #pygame
#python #pygame
Вопрос:
Я создаю игру snake на python, и я почти закончил, но я изо всех сил пытаюсь решить проблему. В основном классе в методе collision я написал некоторый код для обнаружения столкновения snake с границами экрана, и если утверждение верно, snake вернется в исходное состояние. Однако, когда я запускаю программу, обнаружение столкновений срабатывает только один раз. После этого змея может просто исчезнуть с экрана. Заранее спасибо.
import pygame
import random
pygame.init()
clock = pygame.time.Clock()
# Screen setup
screen_width = 600
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Snake")
cellSize = 20
# Colors
black = (0, 0, 0)
white = (255, 255, 255)
blue = (255, 0, 0)
green = (0, 0, 255)
# Grid
def draw_grid():
# Vertical lines
for x in range(0, screen_height, cellSize):
pygame.draw.line(screen, white, (x, 0), (x, screen_height))
# Horizontal lines
for y in range(0, screen_width, cellSize):
pygame.draw.line(screen, white, (0, y), (screen_width, y))
# Maze
class MAZE:
def __init__(self):
self.rect_width = 20
self.rect_height = 20
self.rects = []
def draw_rects(self):
# Drawing Maze
pass
# Snake
class SNAKE(MAZE):
def __init__(self):
super().__init__()
self.width = 20
self.height = 20
self.speed = 20
self.initBody = [[3 * cellSize, 40], [4 * cellSize, 40], [5 * cellSize, 40]]
self.body = [[3 * cellSize, 40], [4 * cellSize, 40], [5 * cellSize, 40]]
self.rects = []
self.move = [0, 0]
self.grow = False
def draw_snake(self):
# Drawing snake body
for cor in self.body:
snake_rect = pygame.Rect(cor[0], cor[1], self.width, self.height)
self.rects.append(snake_rect)
pygame.draw.rect(screen, blue, snake_rect)
def move_snake(self):
# Key bindings
key = pygame.key.get_pressed()
if key[pygame.K_UP]:
self.move = [0, -1]
if key[pygame.K_DOWN]:
self.move = [0, 1]
if key[pygame.K_LEFT]:
self.move = [-1, 0]
if key[pygame.K_RIGHT]:
self.move = [1, 0]
if self.move[0] != 0 or self.move[1] != 0:
# Adding rects to the end of snake body
new_rect = self.body[-1][:]
new_rect[0] = self.move[0] * cellSize
new_rect[1] = self.move[1] * cellSize
self.body.append(new_rect)
# Removing rects from tail
if self.grow == False:
self.body.pop(0)
self.grow = False
# Food
class FOOD_1:
def __init__(self):
self.width = 20
self.height = 20
self.x = 4 * cellSize
self.y = 4 * cellSize
self.food_rect = pygame.Rect(self.x, self.y, self.width, self.height)
def draw_food_1(self):
pygame.draw.rect(screen, green, self.food_rect)
maze = MAZE()
snake = SNAKE()
food_1 = FOOD_1()
class MAIN():
def __init__(self):
self.maze = MAZE()
self.snake = SNAKE()
self.food_1 = FOOD_1()
def draw(self):
self.maze.draw_rects()
self.snake.draw_snake()
self.food_1.draw_food_1()
def move(self):
self.snake.move_snake()
def collision(self):
# Snake and food collision
for rect in self.snake.rects:
if rect.colliderect(self.food_1.food_rect):
self.food_1.x = random.randint(0, 29) * cellSize
self.food_1.y = random.randint(0, 29) * cellSize
self.food_1.food_rect.topleft = (self.food_1.x, self.food_1.y)
self.snake.grow = True
# Border collisions
if self.snake.body[-1][0] <= 0:
self.snake.body = self.snake.initBody
elif self.snake.body[-1][0] >= 600:
self.snake.body = self.snake.initBody
elif self.snake.body[-1][1] <= 0:
self.snake.body = self.snake.initBody
elif self.snake.body[-1][1] >= 600:
self.snake.body = self.snake.initBody
main = MAIN()
# Main loop
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Drawing on screen
screen.fill(black)
main.draw()
draw_grid()
# Movement and Collisions
main.move()
main.collision()
pygame.display.flip()
clock.tick(10)
pygame.quit()
Ответ №1:
Когда вы это делаете self.snake.body = self.snake.initBody
, вы не создаете копию initBody
, вы определяете body
как тот же объект, initBody
что и , поэтому, когда вы изменяете один, другой тоже изменяется … что происходит во время игры.
Таким образом, после первого столкновения initBody
они изменяются одновременно body
(поскольку они стали одним и тем же), поэтому, когда происходит еще одно столкновение, линия self.snake.body = self.snake.initBody
ничего не делает.
Вам нужно заменить его на self.snake.body = self.snake.initBody.copy()
такой, чтобы оригинал initBody
остался нетронутым.
Комментарии:
1. Кроме того, общее замечание: всякий раз, когда вы копируете и вставляете фрагмент кода несколько раз, вы должны спросить себя: «Разве я не должен создавать метод / функцию для этого?». Иногда ответ может быть отрицательным, но поскольку вы собираетесь исправить 4 идентичные строки кода, вы, вероятно, понимаете, почему было бы неплохо определить
reset_body(self)
метод 😉
Ответ №2:
Лучше бы вы создали такой код в своем цикле.
if playerx = 0:
playerx = 0
if playerx = 600:
playerx = 600:
Используйте тот же метод и для оси y.