Начало разработки курсового проекта
0
code_of_future/part2_OOP/lesson6/snake/__init__.py
Normal file
25
code_of_future/part2_OOP/lesson6/snake/food.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
import pygame as pg
|
||||
|
||||
|
||||
class Food:
|
||||
FOOD = (
|
||||
pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'mouse1.png')),
|
||||
pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'mouse2.png'))
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.x = random.randint(0, 25) * 30
|
||||
self.y = random.randint(0, 19) * 30
|
||||
self.type = random.choice(self.FOOD)
|
||||
|
||||
|
||||
def draw(self, screen):
|
||||
screen.blit(self.type, (self.x, self.y))
|
||||
|
||||
def get_coords(self):
|
||||
return self.x, self.y
|
||||
|
||||
|
163
code_of_future/part2_OOP/lesson6/snake/game.py
Normal file
@@ -0,0 +1,163 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
import pygame as pg
|
||||
import pygame_menu
|
||||
|
||||
from .snake import Snake
|
||||
from .food import Food
|
||||
|
||||
class Game:
|
||||
def __init__(self) -> None:
|
||||
self.screen_widht = 780
|
||||
self.screen_hight = 600
|
||||
self.clock = pg.time.Clock()
|
||||
pg.font.init()
|
||||
self.font = pg.font.SysFont('arial', 72)
|
||||
self.score = 0
|
||||
self.paused = True
|
||||
self.started = False
|
||||
self.title = 'Snakessss'
|
||||
self.done = False # Флаг главного цикла
|
||||
self.need_reset = False
|
||||
self.bg = pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'bg.png'))
|
||||
self.screen = pg.display.set_mode((self.screen_widht, self.screen_hight))
|
||||
self.fps = 60
|
||||
self.set_title()
|
||||
self.menu = None
|
||||
self.snake = Snake()
|
||||
self.foods_array = []
|
||||
self.game_speed = 0
|
||||
|
||||
def game_init(self):
|
||||
pg.init()
|
||||
|
||||
def get_menu(self):
|
||||
self.set_bg()
|
||||
self.menu = pygame_menu.Menu('Snakessss game', 400, 300, theme=pygame_menu.themes.THEME_BLUE)
|
||||
self.menu.add.button('Start new game', self.start_new_game)
|
||||
if self.started:
|
||||
self.menu.add.button('Restore game', self.restore_game)
|
||||
self.menu.add.selector('Speed', [('Slow', 0), ('Medium', 1), ('Fast', 2)], onchange=self.set_speed, onreturn=self.restore_game)
|
||||
self.menu._widgets[-1].set_value(self.game_speed)
|
||||
self.menu.add.button('Exit', pygame_menu.events.EXIT)
|
||||
self.menu.mainloop(self.screen)
|
||||
|
||||
def disable_menu(self):
|
||||
if self.menu is not None:
|
||||
self.menu.disable()
|
||||
|
||||
def set_speed(self, tuple_celected, difficulty):
|
||||
self.game_speed = difficulty
|
||||
self.snake.set_speed(speed=self.game_speed)
|
||||
|
||||
def set_title(self):
|
||||
pg.display.set_caption(self.title)
|
||||
|
||||
def set_bg(self):
|
||||
self.screen.blit(self.bg, (0, 0))
|
||||
|
||||
def start_new_game(self):
|
||||
print(self.game_speed, self.snake.speed)
|
||||
self.started = True
|
||||
self.paused = False
|
||||
self.disable_menu()
|
||||
self.need_reset = True
|
||||
|
||||
def restore_game(self, *args, **kwargs):
|
||||
if self.started:
|
||||
self.disable_menu()
|
||||
self.paused = False
|
||||
else:
|
||||
self.start_new_game()
|
||||
|
||||
|
||||
def save_game(self):
|
||||
pass
|
||||
|
||||
def load_game(self):
|
||||
pass
|
||||
|
||||
def gameover(self):
|
||||
surf = self.font.render('GAME OVER', True, (20, 20, 20))
|
||||
rect = surf.get_rect()
|
||||
score = self.font.render(f'Score: {self.score}', True, (20, 20, 20))
|
||||
rect2 = score.get_rect()
|
||||
rect.midtop = (390, 250)
|
||||
rect2.midtop = (390, 320)
|
||||
self.screen.blit(surf, rect)
|
||||
self.screen.blit(score, rect2)
|
||||
pg.display.flip()
|
||||
time.sleep(3)
|
||||
|
||||
self.get_menu()
|
||||
|
||||
def update_game_window(self):
|
||||
while len(self.foods_array) < 2:
|
||||
food = Food()
|
||||
if food.get_coords() not in self.snake.get_coords():
|
||||
self.foods_array.append(food)
|
||||
|
||||
for f in self.foods_array:
|
||||
if self.snake.get_head_coords() == f.get_coords():
|
||||
self.score += 5 * self.snake.length
|
||||
self.foods_array.remove(f)
|
||||
self.snake.length += 1
|
||||
|
||||
self.set_bg()
|
||||
self.snake.draw(self.screen)
|
||||
for f in self.foods_array:
|
||||
f.draw(self.screen)
|
||||
|
||||
pg.display.update()
|
||||
|
||||
if self.snake.impacted:
|
||||
self.started = False
|
||||
self.gameover()
|
||||
|
||||
|
||||
def mainloop(self):
|
||||
while not self.done:
|
||||
if self.need_reset:
|
||||
self.snake.reset(speed=self.game_speed)
|
||||
self.start_new_game()
|
||||
self.need_reset = False
|
||||
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
self.done = True
|
||||
|
||||
pressed = pg.key.get_pressed()
|
||||
|
||||
if pressed[pg.K_ESCAPE]:
|
||||
self.paused = False if self.paused else True
|
||||
if self.paused:
|
||||
self.get_menu()
|
||||
|
||||
if pressed[pg.K_UP]:
|
||||
if self.snake.direction != 'down':
|
||||
self.snake.direction = 'up'
|
||||
|
||||
if pressed[pg.K_DOWN]:
|
||||
if self.snake.direction != 'up':
|
||||
self.snake.direction = 'down'
|
||||
|
||||
if pressed[pg.K_LEFT]:
|
||||
if self.snake.direction != 'right':
|
||||
self.snake.direction = 'left'
|
||||
|
||||
if pressed[pg.K_RIGHT]:
|
||||
if self.snake.direction != 'left':
|
||||
self.snake.direction = 'right'
|
||||
|
||||
self.update_game_window()
|
||||
|
||||
self.clock.tick(self.fps)
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = Game()
|
||||
game.game_init()
|
||||
game.set_title()
|
||||
game.get_menu()
|
||||
game.mainloop()
|
||||
|
BIN
code_of_future/part2_OOP/lesson6/snake/img/bg.png
Normal file
After Width: | Height: | Size: 1013 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_h.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_ld_ur.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_lu_dr.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_rd_ul.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_ru_dl.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_v.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/mouse1.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/mouse2.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_down.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_left.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_right.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_up.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
106
code_of_future/part2_OOP/lesson6/snake/snake.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import os
|
||||
|
||||
import pygame as pg
|
||||
|
||||
|
||||
class Snake:
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.x = kwargs.get('x', 90)
|
||||
self.y = kwargs.get('y', 300)
|
||||
self.snake_head = {
|
||||
'left': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_left.png')),
|
||||
'right': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_right.png')),
|
||||
'up': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_up.png')),
|
||||
'down': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_down.png')),
|
||||
}
|
||||
self.snake_body = {
|
||||
'h': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_h.png')),
|
||||
'v': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_v.png')),
|
||||
'ru_dl': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_ru_dl.png')),
|
||||
'rd_ul': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_rd_ul.png')),
|
||||
'lu_dr': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_lu_dr.png')),
|
||||
'ld_ur': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_ld_ur.png')),
|
||||
}
|
||||
|
||||
self.direction = 'right'
|
||||
self.direction_prev = 'right'
|
||||
self.length = 2
|
||||
self.speed = 30 # скорость движения змейки чем меньше, тем быстрее
|
||||
self.counter = 0 # Просто счетчик, для регулировки скорости нужен
|
||||
self.body = kwargs.get('body', [('h', 60, 300), ('h', 30, 300)])
|
||||
self.impacted = False
|
||||
|
||||
def set_speed(self, **kwargs):
|
||||
self.speed = (30, 20, 10)[kwargs.get('speed', 30)]
|
||||
|
||||
def reset(self, **kwargs):
|
||||
self.x = 90
|
||||
self.y = 300
|
||||
self.body = [('h', 60, 300), ('h', 30, 300)]
|
||||
self.direction = 'right'
|
||||
self.direction_prev = 'right'
|
||||
self.impacted = False
|
||||
self.length = 2
|
||||
self.set_speed(**kwargs)
|
||||
|
||||
def get_head_coords(self):
|
||||
return self.x, self.y
|
||||
|
||||
def get_coords(self):
|
||||
return [(self.x, self.y)] + [(el[1], el[2]) for el in self.body]
|
||||
|
||||
def draw(self, screen):
|
||||
if len(self.body) > self.length:
|
||||
self.body.pop()
|
||||
|
||||
if self.counter >= self.speed:
|
||||
|
||||
if self.direction == self.direction_prev:
|
||||
if self.direction in ('right', 'left'):
|
||||
self.body.insert(0, ('h', self.x, self.y))
|
||||
else:
|
||||
self.body.insert(0, ('v', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('right', 'up'), ('down', 'left')]:
|
||||
self.body.insert(0, ('ru_dl', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('right', 'down'), ('up', 'left')]:
|
||||
self.body.insert(0, ('rd_ul', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('left', 'up'), ('down', 'right')]:
|
||||
self.body.insert(0, ('lu_dr', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('left', 'down'), ('up', 'right')]:
|
||||
self.body.insert(0, ('ld_ur', self.x, self.y))
|
||||
|
||||
|
||||
match self.direction:
|
||||
case 'left':
|
||||
self.x -= 30
|
||||
if self.x < 0:
|
||||
self.x = 750
|
||||
self.direction_prev = 'left'
|
||||
case 'right':
|
||||
self.x += 30
|
||||
if self.x > 750:
|
||||
self.x = 0
|
||||
self.direction_prev = 'right'
|
||||
case 'up':
|
||||
self.y -= 30
|
||||
if self.y < 0:
|
||||
self.y = 570
|
||||
self.direction_prev = 'up'
|
||||
case 'down':
|
||||
self.y += 30
|
||||
if self.y > 570:
|
||||
self.y = 0
|
||||
self.direction_prev = 'down'
|
||||
|
||||
if (self.x, self.y) in [(x[1], x[2]) for x in self.body]:
|
||||
self.impacted = True
|
||||
|
||||
self.counter = 0
|
||||
|
||||
self.counter += 1
|
||||
|
||||
screen.blit(self.snake_head[self.direction], (self.x, self.y))
|
||||
for el in self.body:
|
||||
screen.blit(self.snake_body[el[0]], (el[1], el[2]))
|
||||
|
||||
|