Untitled
unknown
python
2 years ago
9.9 kB
12
Indexable
import pygame
import sys
import random
import time
class Game():
def __init__(self):
# задаем размеры экрана
self.screen_width = 720
self.screen_height = 460
# необходимые цвета
self.red = pygame.Color(255, 0, 0)
self.green = pygame.Color(0, 255, 0)
self.black = pygame.Color(0, 0, 0)
self.white = pygame.Color(255, 255, 255)
self.brown = pygame.Color(165, 42, 42)
# Frame per second controller
# будет задавать количество кадров в секунду
self.fps_controller = pygame.time.Clock()
# переменная для оторбражения результата
# (сколько еды съели)
self.score = 0
def init_and_check_for_errors(self):
"""Начальная функция для инициализации и
проверки как запустится pygame"""
check_errors = pygame.init()
if check_errors[1] > 0:
sys.exit()
else:
print('Ok')
def set_surface_and_title(self):
"""Задаем surface(поверхность поверх которой будет все рисоваться)
и устанавливаем загаловок окна"""
self.play_surface = pygame.display.set_mode((
self.screen_width, self.screen_height))
pygame.display.set_caption('Snake Game')
def event_loop(self, change_to):
"""Функция для отслеживания нажатий клавиш игроком"""
# запускаем цикл по ивентам
for event in pygame.event.get():
# если нажали клавишу
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT or event.key == ord('d'):
change_to = "RIGHT"
elif event.key == pygame.K_LEFT or event.key == ord('a'):
change_to = "LEFT"
elif event.key == pygame.K_UP or event.key == ord('w'):
change_to = "UP"
elif event.key == pygame.K_DOWN or event.key == ord('s'):
change_to = "DOWN"
# нажали escape
elif event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
return change_to
def refresh_screen(self):
"""обновляем экран и задаем фпс"""
pygame.display.flip()
game.fps_controller.tick(23)
def show_score(self, choice=1):
"""Отображение результата"""
s_font = pygame.font.SysFont('monaco', 24)
s_surf = s_font.render(
'Score: {0}'.format(self.score), True, self.black)
s_rect = s_surf.get_rect()
# дефолтный случай отображаем результат слева сверху
if choice == 1:
s_rect.midtop = (80, 10)
# при game_overe отображаем результат по центру
# под надписью game over
else:
s_rect.midtop = (360, 120)
# рисуем прямоугольник поверх surface
self.play_surface.blit(s_surf, s_rect)
def game_over(self):
"""Функция для вывода надписи Game Over и результатов
в случае завершения игры и выход из игры"""
go_font = pygame.font.SysFont('monaco', 72)
go_surf = go_font.render('Game over', True, self.red)
go_rect = go_surf.get_rect()
go_rect.midtop = (360, 15)
self.play_surface.blit(go_surf, go_rect)
self.show_score(0)
pygame.display.flip()
time.sleep(3)
pygame.quit()
sys.exit()
class Snake():
def __init__(self, snake_color):
# важные переменные - позиция головы змеи и его тела
self.snake_head_pos = [100, 50] # [x, y]
# начальное тело змеи состоит из трех сегментов
# голова змеи - первый элемент, хвост - последний
self.snake_body = [[100, 50], [90, 50], [80, 50]]
self.snake_color = snake_color
# направление движение змеи, изначально
# зададимся вправо
self.direction = "RIGHT"
# куда будет меняться напрвление движения змеи
# при нажатии соответствующих клавиш
self.change_to = self.direction
def validate_direction_and_change(self):
"""Изменияем направление движения змеи только в том случае,
если оно не прямо противоположно текущему"""
if any((self.change_to == "RIGHT" and not self.direction == "LEFT",
self.change_to == "LEFT" and not self.direction == "RIGHT",
self.change_to == "UP" and not self.direction == "DOWN",
self.change_to == "DOWN" and not self.direction == "UP")):
self.direction = self.change_to
def change_head_position(self):
"""Изменияем положение головы змеи"""
if self.direction == "RIGHT":
self.snake_head_pos[0] += 10
elif self.direction == "LEFT":
self.snake_head_pos[0] -= 10
elif self.direction == "UP":
self.snake_head_pos[1] -= 10
elif self.direction == "DOWN":
self.snake_head_pos[1] += 10
def snake_body_mechanism(
self, score, food_pos, screen_width, screen_height):
# если вставлять просто snake_head_pos,
# то на всех трех позициях в snake_body
# окажется один и тот же список с одинаковыми координатами
# и мы будем управлять змеей из одного квадрата
self.snake_body.insert(0, list(self.snake_head_pos))
# если съели еду
if (self.snake_head_pos[0] == food_pos[0] and
self.snake_head_pos[1] == food_pos[1]):
# если съели еду то задаем новое положение еды случайным
# образом и увеличивем score на один
food_pos = [random.randrange(1, int(screen_width/10))*10,
random.randrange(1, int(screen_height/10))*10]
score += 1
else:
# если не нашли еду, то убираем последний сегмент,
# если этого не сделать, то змея будет постоянно расти
self.snake_body.pop()
return score, food_pos
def draw_snake(self, play_surface, surface_color):
"""Отображаем все сегменты змеи"""
play_surface.fill(surface_color)
for pos in self.snake_body:
# pygame.Rect(x,y, sizex, sizey)
pygame.draw.rect(
play_surface, self.snake_color, pygame.Rect(
pos[0], pos[1], 10, 10))
def check_for_boundaries(self, game_over, screen_width, screen_height):
"""Проверка, что столкунлись с концами экрана или сами с собой
(змея закольцевалась)"""
if any((
self.snake_head_pos[0] > screen_width-10
or self.snake_head_pos[0] < 0,
self.snake_head_pos[1] > screen_height-10
or self.snake_head_pos[1] < 0
)):
game_over()
for block in self.snake_body[1:]:
# проверка на то, что первый элемент(голова) врезался в
# любой другой элемент змеи (закольцевались)
if (block[0] == self.snake_head_pos[0] and
block[1] == self.snake_head_pos[1]):
game_over()
class Food():
def __init__(self, food_color, screen_width, screen_height):
"""Инит еды"""
self.food_color = food_color
self.food_size_x = 10
self.food_size_y = 10
self.food_pos = [random.randrange(1, int(screen_width/10))*10,
random.randrange(1, int(screen_height/10))*10]
def draw_food(self, play_surface):
"""Отображение еды"""
pygame.draw.rect(
play_surface, self.food_color, pygame.Rect(
self.food_pos[0], self.food_pos[1],
self.food_size_x, self.food_size_y))
game = Game()
snake = Snake(game.green)
food = Food(game.brown, game.screen_width, game.screen_height)
game.init_and_check_for_errors()
game.set_surface_and_title()
while True:
snake.change_to = game.event_loop(snake.change_to)
snake.validate_direction_and_change()
snake.change_head_position()
game.score, food.food_pos = snake.snake_body_mechanism(
game.score, food.food_pos, game.screen_width, game.screen_height)
snake.draw_snake(game.play_surface, game.white)
food.draw_food(game.play_surface)
snake.check_for_boundaries(
game.game_over, game.screen_width, game.screen_height)
game.show_score()
game.refresh_screen()Editor is loading...
Leave a Comment