82 lines
2.4 KiB
Python
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}')
|