user19022072
user19022072

Reputation:

Snake with pygame method - pixel overlap problem

I started playing a little with pygame and so far I'm not doing badly. I encountered a problem and managed to solve it. The solution is possible. It is not 100% correct. I want to implement an eat method when the head of the subject meets the food. It is probably a relatively simple method when the rest of the value of X and Y are equal to the head of the snake being eaten. For some reason I was not able to fully understand the overlap of pixels and I am not really correct in the method.

The problem at the moment is that there is no overlap between the pixels and "eating is not done".

BACKGROUND = pygame.image.load("background.jpg")
WIDTH, HEIGHT = BACKGROUND.get_width(), BACKGROUND.get_height()
pygame.font.init()
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
def checkForEat(self):
        head = self.body[-1]
        x = self.food.getPos()[0]
        y= self.food.getPos()[1]
        # if abs(head[0] - x ) < 9 and abs(head[1] - y ) < 9: -- This is my temporary solution
        if head[0] == x  and head[1] == y:
            self.food = Food()
            self.eat()

I try not to add too much unnecessary code.

class Food:
    def __init__(self):
        self.color = (5, 5, 255)
        self.pos = (random.randint(10,WIDTH-50),random.randint(10,HEIGHT-50))

    def draw(self,win):
        pygame.draw.circle(win,self.color, self.pos, 5)

    def getPos(self):
        return self.pos



class Snake:

    START_POS = (85, 85)
    def __init__(self):
        self.food = Food()
        self.block_size = 11
        self.x , self.y = self.START_POS
        self.body = self.create_body()

    def create_body(self):
        body = []
        for i in range(self.length):
            body.append((85,85+i*self.block_size))

        return body

def draw(self,win):
    WIN.blit(BACKGROUND, (0, 0))
    self.food.draw(win)
    for i in range(self.length):
        pygame.draw.circle(win, (255, 0, 0), self.body[i], 5)



I'm not adding the rest of the program.
Just saying that apart from the problem I wrote above everything works fine.

Upvotes: 0

Views: 107

Answers (1)

Rabbid76
Rabbid76

Reputation: 210908

Use pygame.Rect/pygame.Rect.colliderect to check if the bounding rectangle of the food overlaps with the head of the snake:

class Food:
    def __init__(self):
        self.color = (5, 5, 255)
        self.pos = (random.randint(10,WIDTH-50),random.randint(10,HEIGHT-50))

    def draw(self,win):
        pygame.draw.circle(win,self.color, self.pos, 5)

    def getPos(self):
        return self.pos

    def getRect(self):
        return pygame.Rect(self.pos[0]-5, self.pos[1]-5, 10, 10)
class Snake:

    START_POS = (85, 85)
    def __init__(self):
        self.food = Food()
        self.block_size = 11
        self.x , self.y = self.START_POS
        self.body = self.create_body()

    # [...]

    def checkForEat(self):
        head = self.body[-1]
        head_rect = pygame.Rect(head[0]-5, head[1]-5, self.block_size, self.block_size)
    
        food_rect = self.food.getRect()
        
        if food_rect.colliderect(head_rect):
            self.food = Food()
            self.eat()

Also see How do I detect collision in pygame?.


Alternatively you can compute the Euclidean distance between the circle center of the circles and compare the distance to the sum of the radii:

class Snake:
    # [...]

    def checkForEat(self):
        dx = self.food.getPos()[0] - self.body[-1][0]
        dy = self.food.getPos()[1] - self.body[-1][1]
        dist_center = math.hypot(dx, dy)
        if dist_center <= 20:
            self.food = Food()
            self.eat()

Upvotes: 0

Related Questions