问题描述
我正在用 python 制作一个蛇游戏,我已经快完成了,但我正在努力解决一个问题。在碰撞方法的主类中,我写了一些代码来检测蛇与屏幕边框的碰撞,如果语句为真,蛇将返回其原始状态。但是,当我运行程序时,碰撞检测只工作一次。之后,蛇可以简单地离开屏幕。提前致谢。
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)
white = (255,255,255)
blue = (255,0)
green = (0,255)
# Grid
def draw_grid():
# Vertical lines
for x in range(0,screen_height,cellSize):
pygame.draw.line(screen,white,(x,0),screen_height))
# Horizontal lines
for y in range(0,screen_width,(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,[5 * cellSize,40]]
self.body = [[3 * 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.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()
解决方法
当您执行 self.snake.body = self.snake.initBody
时,您不是在复制 initBody
,而是将 body
定义为与 {{1} 相同的对象 },所以当你修改一个的时候,另一个也被修改了......这是在玩的时候发生的。
所以在第一次碰撞之后,initBody
与 initBody
同时被修改(因为它们已经成为相同的东西),所以当另一个碰撞发生时,第 body
行什么都不做。
您需要将其替换为 self.snake.body = self.snake.initBody
,以便原始 self.snake.body = self.snake.initBody.copy()
保持不变。
最好在循环中编写这样的代码。
if playerx = 0:
playerx = 0
if playerx = 600:
playerx = 600:
对 y 轴也使用相同的方法。