pygame-snake/objects.py

82 lines
2.4 KiB
Python

import logging
import pygame
from config import INITIAL_SNAKE_SIZE, RESOLUTION, TILE_SIZE, SNAKE_COLOR, BACKGROUND_COLOR, APPLE_COLOR
from utils import make_slot, Direction, random_slot
logger = logging.getLogger(__name__)
class Snake:
def __init__(self, ):
self.slots = [make_slot(21, 16)] * INITIAL_SNAKE_SIZE
self._direction = None # type: Direction
self.dead = False
def add_slot(self, left: int, top: int):
self.slots.append(make_slot(left, top))
def move(self, screen: pygame.Surface, apple: 'Apple'):
if self.direction is None:
return []
new_head = self.slots[0].move(*self.direction.value)
if new_head.collidelist(self.slots[1:]) > -1:
self.dead = True
return []
if new_head.right > RESOLUTION[0]:
new_head = pygame.Rect(0, new_head.top, TILE_SIZE, TILE_SIZE)
elif new_head.left < 0:
new_head = pygame.Rect(RESOLUTION[0] - TILE_SIZE, new_head.top, TILE_SIZE, TILE_SIZE)
if new_head.bottom > RESOLUTION[1]:
new_head = pygame.Rect(new_head.left, 0, TILE_SIZE, TILE_SIZE)
elif new_head.top < 0:
new_head = pygame.Rect(new_head.left, RESOLUTION[1] - TILE_SIZE, TILE_SIZE, TILE_SIZE)
self.slots.insert(0, new_head)
screen.fill(SNAKE_COLOR, new_head)
if not new_head.colliderect(apple.rect):
old_tail = self.slots.pop()
screen.fill(BACKGROUND_COLOR, old_tail)
return [old_tail, new_head]
return [new_head]
@property
def head(self) -> pygame.Rect:
return self.slots[0]
@head.setter
def head(self, value: pygame.Rect):
self.slots.pop(0)
self.slots.insert(0, value)
@property
def direction(self) -> Direction:
return self._direction
@direction.setter
def direction(self, value: Direction):
if not value.is_opposed_to(self.direction):
self._direction = value
else:
logger.debug('Move prohibited : tried to change to an opposed direction')
class Apple:
def __init__(self):
self.rect = random_slot()
self.score = 10
def display(self, screen: pygame.Surface) -> pygame.Rect:
screen.fill(APPLE_COLOR, self.rect)
return self.rect
def renew(self):
self.rect = random_slot()
logger.debug(f'Apple generated at {self.rect.left / TILE_SIZE} {self.rect.top / TILE_SIZE}')