2017-02-08 3 views
0

Я пытаюсь реализовать цикл, который проверяет, сталкивается ли голова змеи (представленная головой списка snake_parts) с какой-либо частью тела змеи, которые являются прямыми объектами, которые составьте остальную часть списка. Но как только тело змеи расширяется, происходит постоянное столкновение между двумя объектами. Учитывая, как тело змеи реализовано, я не вижу, как они когда-либо пересекаются, поэтому я не уверен, что вызывает столкновения.Проблемы с выполнением столкновения в игре Snake

import pygame 
from pygame.locals import * 
import random 
import sys 


pygame.init() 

FPS = 30 
fpsClock = pygame.time.Clock() 

WIN_WIDTH = 680 #width of window 
WIN_HEIGHT = 500 #height of window 

DISPLAY = (WIN_WIDTH, WIN_HEIGHT) #variable for screen display 
DEPTH = 32 #standard 
FLAGS = 0 #standard 
BLACK = (0, 0, 0) #black 
RED = (255, 0, 0) #red 
GOLD = (255, 215, 0) 
LOL = (14, 18, 194) 

screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) 
pygame.display.set_caption('Snaek')          

snake_parts = [1] 
Score = 0 
speed = 10 
snakex = 125 
snakey = 70 
size = 20 


# --- classes --- 
class Snake(pygame.Rect): 
    def __init__(self, x, y, screen, size, colour): 
     pygame.Rect.__init__(self, x, y, size, 20) 
     self.screen = screen 
     self.colour = colour 
     self.x = x 
     self.y = y 


    def draw(self, screen): 
     pygame.draw.rect(self.screen, self.colour, self) 

    def coordinates(self): 
     return self.x, self.y 

class Food(pygame.Rect): 
    def __init__(self, x, y, screen): 
     pygame.Rect.__init__(self, x, y, 20, 20) 
     self.screen = screen 

    def draw(self, screen): 
     pygame.draw.rect(self.screen, GOLD, self) 

class Barrier(pygame.Rect): 

    def __init__(self, x, y, screen): 
     pygame.Rect.__init__(self, x, y, 40, 20) 
     self.screen = screen 
    def draw(self, screen): 
     pygame.draw.rect(self.screen, LOL, self) 


# --- functions --- 
def get_food_pos(WIN_WIDTH, WIN_HEIGHT): 
    WIN_WIDTH = random.randint(100, WIN_WIDTH-150) 
    WIN_HEIGHT = random.randint(100, WIN_HEIGHT-150) 
    return WIN_WIDTH, WIN_HEIGHT 

eaten = True 
pressed_right = True 
pressed_left = False 
pressed_up = False 
pressed_down = False 
pygame.key.set_repeat(10,10) 

level = [ 
     "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "P           P", 
     "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP", 
] 


while True: 
    screen.fill(BLACK) 

    for event in pygame.event.get(): 
     if event.type == QUIT: 
      pygame.quit() 
      sys.exit() 

     elif event.type == pygame.KEYDOWN:   # check for key presses   
      if event.key == pygame.K_LEFT: 
       if pressed_right: 
        pressed_right = True# left arrow turns left 
       else: 
        pressed_left = True 
        pressed_right = False 
        pressed_up = False 
        pressed_down = False 
      elif event.key == pygame.K_RIGHT: 
       if pressed_left: 
        pressed_left = True# right arrow turns right 
       else: 
        pressed_right = True 
        pressed_left = False 
        pressed_up = False 
        pressed_down = False 
      elif event.key == pygame.K_UP: 
       if pressed_down:# up arrow goes up 
        pressed_down = True 
       else: 
        pressed_up = True 
        pressed_right = False 
        pressed_left = False 
        pressed_down = False 
      elif event.key == pygame.K_DOWN: 
       if pressed_up: 
        pressed_up = False 
       else: 
        pressed_down = True 
        pressed_right = False 
        pressed_up = False 
        pressed_left = False 

    x = snakex 
    y = snakey 




    if pressed_left: 
     snakex -= speed 
    elif pressed_right: 
     snakex += speed 
    elif pressed_up: 
     snakey -= speed 
    elif pressed_down: 
     snakey += speed 

    snake_parts[0] = Snake(snakex, snakey, screen, int(size), RED) 
    snake_parts[0].draw(screen) 



    if eaten: 
     foodx, foody = get_food_pos(WIN_WIDTH, WIN_HEIGHT) 
     eaten = False 

    my_food = Food(foodx, foody, screen) 
    my_food.draw(screen) 

    if snake_parts[0].colliderect(my_food): 
     eaten = True 
     screen.fill(BLACK) 
     a_snake = Snake(snakex, snakey, screen, int(size), RED) 
     snake_parts.append(a_snake) 


    for i in range(1, len(snake_parts)): 
     tempx, tempy = snake_parts[i].coordinates() 
     snake_parts[i] = Snake(x, y, screen, int(size), RED) 
     if snake_parts[0].colliderect(snake_parts[i]): 
      print("Self collision") 
     snake_parts[i].draw(screen) 
     x, y = tempx, tempy 



    platform_x = 0 
    platform_y = 0 

    for row in level: 
     for col in row: 
      if col == "P": 
       col = Barrier(platform_x, platform_y, screen) 
       col.draw(screen) 
       if snake_parts[0].colliderect(col): 
        print("Barrier collision") 

      platform_x += 15 
     platform_y += 20 
     platform_x = 0   



    pygame.display.update() 
    fpsClock.tick(FPS)  
+2

Если я правильно прочитал правила, вы не должны сбрасывать всю программу, но больше * соответствующих * частей, чтобы обратиться за помощью. –

+0

Я запустил вашу программу, и похоже, что у вас есть эта проблема с коллизиями. –

+0

Мы не можем отлаживать всю вашу программу, чтобы найти вашу проблему. Вам нужно знать, с чем вам нужна помощь. Если вы не знаете, что вызывает проблему, вы должны сломать свою программу, пока не найдете разумный небольшой код, вызывающий ошибку. Прочтите [this] (http://meta.stackoverflow.com/a/253788/6486738) и [это] (http://meta.stackoverflow.com/a/284237/6486738) для получения дополнительной информации. –

ответ

0

отладки программ, как это очень трудно, и, как сказал @WillemVanOnsem, мы не можем быстро понять ваш код. Но на основании того, что я видел, я могу дать вам несколько советов, чтобы переписать игру более надежным способом:

  1. Ваши сегменты вашей доски могут жить в двумерном массиве. Ваша змея может быть представлена ​​в виде списка координат в этом двумерном массиве. Вы могли обнаружить столкновения на момент совершения движения, то есть когда вы собираетесь вытащить последний элемент списка змей и добавить следующий элемент в начало списка. Я почти уверен, что я успешно использовал этот метод несколько лет назад, чтобы написать минимальную игру змеи менее чем за 30 строк кода.
  2. Проведите некоторое тестирование единицы измерения. Поместите вашу змею программно в определенную позицию, которую вы знаете, приводит к неожиданному столкновению и пытается понять, что происходит. Если проблема не станет понятной, просто спросите еще раз.
Смежные вопросы