我正在进行Snake游戏,我正试图探测蛇头和尾巴之间的碰撞。
class Snake():
def __init__(self, screen, startx, starty, width, height, color):
self.screen = screen
self.startx = startx
self.starty = starty
self.width = width
self.height = height
self.color = color
self.amount_tiles = 5
self.tile = 0
self.position = []
self.rect = pygame.Rect(startx, starty, width, height) #rectangle 1: Head of the Snake
pygame.draw.rect(screen, color, self.rect)
-
def existing_tiles(self):
self.count = self.tile
while self.count > 0:
self.current_pos = self.position
x = self.current_pos[self.count - 1]
self.rect_new = pygame.Rect(x[0], x[1], self.width, self.height) #rectangle 2:Tail of the Snake
pygame.draw.rect(self.screen, GREEN, self.rect_new)
self.count = self.count - 1
我尝试使用pygame.Rect.colliderect(rect1,rect2),就像我之前使用Snake Head和Food矩形一样,但它似乎不起作用。
Console output: AttributeError: 'Snake' object has no attribute 'rect_new'
以下是完整的代码:
import pygame
import random
RED = (255,0,0)
WHITE = (255,255,255)
GREEN = (0,255,0)
BLUE = (0,128,255)
#------------------------------FUNCTIONS--------------------------------#
def main():
pygame.init()
display_width=460
display_height=460
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Snake')
clock = pygame.time.Clock()
FPS = 10
schlange = Snake(gameDisplay, 220, 220, 20, 20, BLUE)
essen = Food(gameDisplay)
speed = (0,0)
while True:
#event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
speed = (0, -20)
if event.key == pygame.K_DOWN:
speed = (0, 20)
if event.key == pygame.K_LEFT:
speed = (-20, 0)
if event.key == pygame.K_RIGHT:
speed = (20, 0)
if pygame.Rect.colliderect(schlange.rect, essen.rect) == True:
essen = Food(gameDisplay)
schlange.eat()
if pygame.Rect.colliderect(schlange.rect, schlange.rect_new) == True:
print('rip')
pygame.quit()
quit()
schlange.move(speed[0], speed[1])
essen.spawn()
clock.tick(FPS)
pygame.display.update()
#------------------------------CLASSES---------------------------------#
class Snake():
def __init__(self, screen, startx, starty, width, height, color):
self.screen = screen
self.startx = startx
self.starty = starty
self.width = width
self.height = height
self.color = color
self.amount_tiles = 5
self.tile = 0
self.position = []
self.rect = pygame.Rect(startx, starty, width, height)
pygame.draw.rect(screen, color, self.rect)
def move(self, x_change, y_change):
self.screen.fill(WHITE)
self.x_change = x_change
self.y_change = y_change
self.position.insert(0, (self.startx, self.starty))
self.pos = self.position[self.tile]
'''self.add_tile()'''
self.existing_tiles()
self.startx += x_change
self.starty += y_change
self.rect = pygame.Rect(self.startx, self.starty, self.width, self.height)
pygame.draw.rect(self.screen, self.color, self.rect)
def existing_tiles(self):
self.count = self.tile
while self.count > 0:
self.current_pos = self.position
x = self.current_pos[self.count - 1]
self.rect_new = pygame.Rect(x[0], x[1], self.width, self.height)
pygame.draw.rect(self.screen, GREEN, self.rect_new)
self.count = self.count - 1
'''def add_tile(self):
x = self.pos[0]
y = self.pos[1]
pygame.draw.rect(self.screen, GREEN, (x, y, self.width, self.height))'''
def eat(self):
self.amount_tiles += 1
self.tile += 1
class Food():
def __init__(self, screen):
self.screen = screen
self.width = 20
self.height = 20
self.spawnx = random.randrange(0, 460, 20)
self.spawny = random.randrange(0, 460, 20)
self.rect = pygame.Rect(self.spawnx, self.spawny, self.width, self.height)
def spawn(self):
pygame.draw.rect(self.screen, RED, self.rect)
if __name__ == '__main__':
main()
提前致谢!
答案 0 :(得分:0)
在下面尝试编辑后的游戏版本。我做了两处修改,并在代码中写了几个笔记。
import pygame
import random
RED = (255,0,0)
WHITE = (255,255,255)
GREEN = (0,255,0)
BLUE = (0,128,255)
#------------------------------FUNCTIONS--------------------------------#
def main():
pygame.init()
display_width=460
display_height=460
gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Snake')
clock = pygame.time.Clock()
FPS = 10
schlange = Snake(gameDisplay, 220, 220, 20, 20, BLUE)
essen = Food(gameDisplay)
speed = (0,0)
while True:
#event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
speed = (0, -20)
if event.key == pygame.K_DOWN:
speed = (0, 20)
if event.key == pygame.K_LEFT:
speed = (-20, 0)
if event.key == pygame.K_RIGHT:
speed = (20, 0)
if pygame.Rect.colliderect(schlange.rect, essen.rect) == True:
essen = Food(gameDisplay)
schlange.eat()
""" ADDED """
""" I realized that you're storing the tail pieces in self.position.
Iterating through this list and checking for collisions seems to do the trick.
Skip check when there's only one element in schlange.position to avoid a collision as soon as the game starts.
Now you probably just need to prevent the snake from going straight back
into itself (180 degree turn) since that would trigger a collision that you might not want """
if len(schlange.position) > 1:
for coords in schlange.position:
if pygame.Rect.colliderect(schlange.rect, pygame.Rect(coords[0], coords[1], schlange.width, schlange.height)) == True:
print('rip')
pygame.quit()
quit()
""" /ADDED """
schlange.move(speed[0], speed[1])
essen.spawn()
clock.tick(FPS)
pygame.display.update()
#------------------------------CLASSES---------------------------------#
class Snake():
def __init__(self, screen, startx, starty, width, height, color):
self.screen = screen
self.startx = startx
self.starty = starty
self.width = width
self.height = height
self.color = color
self.amount_tiles = 5
self.tile = 0
self.position = []
self.rect = pygame.Rect(startx, starty, width, height)
pygame.draw.rect(screen, color, self.rect)
def move(self, x_change, y_change):
self.screen.fill(WHITE)
self.x_change = x_change
self.y_change = y_change
self.position.insert(0, (self.startx, self.starty))
self.pos = self.position[self.tile]
'''self.add_tile()'''
self.existing_tiles()
self.startx += x_change
self.starty += y_change
self.rect = pygame.Rect(self.startx, self.starty, self.width, self.height)
pygame.draw.rect(self.screen, self.color, self.rect)
""" ADDED """
""" You kept adding to self.position but never deleted any elements.
That's unnecessary and would eventually cause a MemoryError """
if len(self.position) > self.tile+1:
del self.position[-1]
""" /ADDED """
def existing_tiles(self):
self.count = self.tile
while self.count > 0:
self.current_pos = self.position
x = self.current_pos[self.count - 1]
self.rect_new = pygame.Rect(x[0], x[1], self.width, self.height)
pygame.draw.rect(self.screen, GREEN, self.rect_new)
self.count = self.count - 1
'''def add_tile(self):
x = self.pos[0]
y = self.pos[1]
pygame.draw.rect(self.screen, GREEN, (x, y, self.width, self.height))'''
def eat(self):
self.amount_tiles += 1
self.tile += 1
class Food():
def __init__(self, screen):
self.screen = screen
self.width = 20
self.height = 20
self.spawnx = random.randrange(0, 460, 20)
self.spawny = random.randrange(0, 460, 20)
self.rect = pygame.Rect(self.spawnx, self.spawny, self.width, self.height)
def spawn(self):
pygame.draw.rect(self.screen, RED, self.rect)
if __name__ == '__main__':
main()