From f3b15dff6f2b50f7db7d31b0570fe161d5948233 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sun, 10 Apr 2022 16:18:05 +0300 Subject: [PATCH] fixed multiplayer --- .gitignore | 3 +- .../source/assets/sprites/golden_apple.png | Bin 0 -> 297 bytes pygame/snake/source/assets/sprites/poison.png | Bin 0 -> 1165 bytes pygame/snake/source/snake.py | 206 ++++++++++------- pygame/snake/source/snake_test.py | 212 ++++++++++++++++++ 5 files changed, 333 insertions(+), 88 deletions(-) create mode 100644 pygame/snake/source/assets/sprites/golden_apple.png create mode 100644 pygame/snake/source/assets/sprites/poison.png create mode 100644 pygame/snake/source/snake_test.py diff --git a/.gitignore b/.gitignore index 3ef9c395..c927cdba 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ **.log /december/task_081221/files /december/task_081221/*.log -**.pkl \ No newline at end of file +**.pkl +**test.py diff --git a/pygame/snake/source/assets/sprites/golden_apple.png b/pygame/snake/source/assets/sprites/golden_apple.png new file mode 100644 index 0000000000000000000000000000000000000000..902b6e537f7cb1f781071d4421babbc3690b3c22 GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^3qY8I8A$FCoGuTfBm#UwT!HlMMZ&M%g@>qc8i=x( zinIRz|6fv4a$&(GRiGSWNswPKgTu2MX+X|?PZ!6KinzB|t+|*D1za58|0@44Z7r?J zdo4<#Cq!RHWyPBO|Fcv)-*X9ozz1{b7r zfe8fI&PPfI zTR!Ke&mYSMk%7TpKnFw zTQ7O<-!HDhz~I2dz(5)`ONpUhefPz@?`DhVzF*_6z0~D%6AJ@_2LnR`X;iR|?SjX3 zx>5JPU;NV~#Gu0HfJu0Zqf4oM4xGL z7d~8bW$qy0Ydkh&bX|=)p7N4;-v087VSgJg%f{uqFoV>S4g^42Kq(ZJ;k!BL)C`^4 zhP8}YK!Tlgb3r;3Km;&U(HRZ8{}~t+fa2IBfug8VAaw-5fluX?^J)UfY8(F7#-ZgfpbTb$!4Sle None: - self.pos = start_pos + def __init__(self, position, color=RANDOM_COLOR) -> None: + self.pos = position self.direction = (1, 0) self.color = color @@ -34,7 +43,7 @@ class Cube(object): self.direction = direction self.pos = (self.pos[0] + self.direction[0], self.pos[1] + self.direction[1]) - def draw(self, surface, eyes=False) -> None: + def draw(self, surface=WINDOW, eyes=False) -> None: distance = WIDTH // ROWS i, j = self.pos @@ -48,7 +57,7 @@ class Cube(object): pygame.draw.circle(surface, BLACK, circle_middle_2, radius) -class Snake(object): +class Snake: def __init__(self, pos: tuple, color: tuple, player_number: int = 1) -> None: self.color = color @@ -60,42 +69,44 @@ class Snake(object): self.number = player_number def move(self) -> None: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - keys = pygame.key.get_pressed() + keys = pygame.key.get_pressed() + if multiplayer: + num_1, num_2 = 1, 2 + else: + num_1, num_2 = 1, 1 - if multiplayer: - num_1, num_2 = 1, 2 - else: - num_1, num_2 = 1, 1 + if self.number == num_1: + if keys[pygame.K_LEFT] and self.direction != (1, 0): # turn left + self.direction = -1, 0 + self.turns[self.head.pos[:]] = self.direction - if self.number == num_1: - if keys[pygame.K_LEFT] and self.direction != (1, 0): # turn left - self.direction = -1, 0 + if keys[pygame.K_RIGHT] and self.direction != (-1, 0): # turn right + self.direction = 1, 0 + self.turns[self.head.pos[:]] = self.direction - if keys[pygame.K_RIGHT] and self.direction != (-1, 0): # turn right - self.direction = 1, 0 + if keys[pygame.K_UP] and self.direction != (0, 1): # turn up + self.direction = 0, -1 + self.turns[self.head.pos[:]] = self.direction - if keys[pygame.K_UP] and self.direction != (0, 1): # turn up - self.direction = 0, -1 + if keys[pygame.K_DOWN] and self.direction != (0, -1): # turn down + self.direction = 0, 1 + self.turns[self.head.pos[:]] = self.direction - if keys[pygame.K_DOWN] and self.direction != (0, -1): # turn down - self.direction = 0, 1 + if self.number == num_2: + if keys[pygame.K_a] and self.direction != (1, 0): # turn left + self.direction = -1, 0 + self.turns[self.head.pos[:]] = self.direction - if self.number == num_2: - if keys[pygame.K_a] and self.direction != (1, 0): # turn left - self.direction = -1, 0 + if keys[pygame.K_d] and self.direction != (-1, 0): # turn right + self.direction = 1, 0 + self.turns[self.head.pos[:]] = self.direction - if keys[pygame.K_d] and self.direction != (-1, 0): # turn right - self.direction = 1, 0 - - if keys[pygame.K_w] and self.direction != (0, 1): # turn up - self.direction = 0, -1 - - if keys[pygame.K_s] and self.direction != (0, -1): # turn down - self.direction = 0, 1 + if keys[pygame.K_w] and self.direction != (0, 1): # turn up + self.direction = 0, -1 + self.turns[self.head.pos[:]] = self.direction + if keys[pygame.K_s] and self.direction != (0, -1): # turn down + self.direction = 0, 1 self.turns[self.head.pos[:]] = self.direction for index, head in enumerate(self.body): @@ -105,28 +116,35 @@ class Snake(object): head.move((turn[0], turn[1])) if index == len(self.body) - 1: self.turns.pop(head_pos) + else: + if walls: # end game if goes into the wall + if head.direction[0] == -1 and head.pos[0] <= 0: # left to right + end_screen() - else: # move player to other screen size - if head.direction[0] == -1 and head.pos[0] <= 0: # left to right - head.pos = (ROWS - 1, head.pos[1]) + if head.direction[0] == 1 and head.pos[0] >= ROWS - 1: # right to left + end_screen() - elif head.direction[0] == 1 and head.pos[0] >= ROWS - 1: # right to left - head.pos = (0, head.pos[1]) + if head.direction[1] == 1 and head.pos[1] >= COLUMNS - 1: # bottom to top + end_screen() - elif head.direction[1] == 1 and head.pos[1] >= COLUMNS - 1: # bottom to top - head.pos = (head.pos[0], 0) + if head.direction[1] == -1 and head.pos[1] <= 0: # top to bottom + end_screen() - elif head.direction[1] == -1 and head.pos[1] <= 0: # top to bottom - head.pos = (head.pos[0], COLUMNS - 1) + else: # move player to other screen size + if head.direction[0] == -1 and head.pos[0] <= 0: # left to right + head.pos = (ROWS - 1, head.pos[1]) - else: - head.move(head.direction) + elif head.direction[0] == 1 and head.pos[0] >= ROWS - 1: # right to left + head.pos = (0, head.pos[1]) - # def reset(self, pos) -> None: - # self.head = Cube(pos, self.color) - # self.body = [] - # self.turns = {} - # self.direction = randint(-1, 1), randint(-1, 1) + elif head.direction[1] == 1 and head.pos[1] >= COLUMNS - 1: # bottom to top + head.pos = (head.pos[0], 0) + + elif head.direction[1] == -1 and head.pos[1] <= 0: # top to bottom + head.pos = (head.pos[0], COLUMNS - 1) + + else: + head.move(head.direction) def add_cube(self) -> None: tail = self.body[-1] @@ -144,15 +162,29 @@ class Snake(object): def remove_cube(self) -> None: self.body.pop(-1) - def draw(self, surface) -> None: + def draw(self) -> None: for index, head in enumerate(self.body): if index == 0: - head.draw(surface, eyes=True) + head.draw(eyes=True) else: - head.draw(surface) + head.draw() -def draw_grid(surface) -> None: +class Snack: + + def __init__(self, texture) -> None: + self.texture = texture + self.randomize() + + def draw_snack(self) -> None: + snack_rect = pygame.Rect(self.pos[0] * CELL_SIZE, self.pos[1] * CELL_SIZE, CELL_SIZE, CELL_SIZE) + WINDOW.blit(self.texture, snack_rect) + + def randomize(self) -> None: + self.pos = (randrange(ROWS), randrange(COLUMNS)) + + +def draw_grid(surface=WINDOW) -> None: size_between = WIDTH // ROWS x, y = 0, 0 for _ in range(ROWS): @@ -163,25 +195,8 @@ def draw_grid(surface) -> None: pygame.draw.line(surface, WHITE, (0, y), (WIDTH, y)) -def redraw_window(sprites: list) -> None: - WINDOW.fill(BLACK) - draw_grid(WINDOW) - for sprite in sprites: - sprite.draw(WINDOW) - pygame.display.update() - - -def random_snack(items, rows=ROWS, columns=COLUMNS) -> tuple: - for item in items: - positions = item.body - while True: - x = randrange(rows) - y = randrange(columns) - if len(list(filter(lambda z: z.pos == (x, y), positions))) > 0: - continue - else: - break - return x, y +def end_screen() -> None: + quit() def main() -> None: @@ -195,24 +210,41 @@ def main() -> None: snake_two = Snake((randint(0, ROWS - 1), randint(0, COLUMNS - 1)), BLUE, 2) snakes.append(snake_two) - snack = Cube(random_snack(snakes), color=GREEN) - poison = Cube(random_snack(snakes), color=RED) + apple = Snack(apple_texture) + poison = Snack(poison_texture) + while run: clock.tick(FPS) - pygame.time.delay(50) + pygame.time.delay(10) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + quit() + for snake in snakes: snake.move() - if snake.body[0].pos == snack.pos: + + if snake.body[0].pos == apple.pos: snake.add_cube() - snack = Cube(random_snack(snakes), color=GREEN) + apple = Snack(apple_texture) + if snake.body[0].pos == poison.pos: snake.remove_cube() - poison = Cube(random_snack(snakes), color=RED) + poison = Snack(poison_texture) + for i in range(len(snake.body)): if snake.body[i].pos in list(map(lambda z: z.pos, snake.body[i + 1:])): - print(f"Score: {len(snake.body)}") + for snake in snakes: + print(f"{snake.number} snake score: {len(snake.body)}") run = False - redraw_window(list(set(snakes + [snack, poison]))) + + WINDOW.fill(BLACK) + draw_grid() + for snake in snakes: + snake.draw() + apple.draw_snack() + poison.draw_snack() + pygame.display.update() set_font = lambda size: pygame.font.SysFont("roboto", size) # sets font size diff --git a/pygame/snake/source/snake_test.py b/pygame/snake/source/snake_test.py new file mode 100644 index 00000000..341e84ab --- /dev/null +++ b/pygame/snake/source/snake_test.py @@ -0,0 +1,212 @@ +import pygame,sys,random +from pygame.math import Vector2 + +class SNAKE: + def __init__(self): + self.body = [Vector2(5,10),Vector2(4,10),Vector2(3,10)] + self.direction = Vector2(0,0) + self.new_block = False + + self.head_up = pygame.image.load('Graphics/head_up.png').convert_alpha() + self.head_down = pygame.image.load('Graphics/head_down.png').convert_alpha() + self.head_right = pygame.image.load('Graphics/head_right.png').convert_alpha() + self.head_left = pygame.image.load('Graphics/head_left.png').convert_alpha() + + self.tail_up = pygame.image.load('Graphics/tail_up.png').convert_alpha() + self.tail_down = pygame.image.load('Graphics/tail_down.png').convert_alpha() + self.tail_right = pygame.image.load('Graphics/tail_right.png').convert_alpha() + self.tail_left = pygame.image.load('Graphics/tail_left.png').convert_alpha() + + self.body_vertical = pygame.image.load('Graphics/body_vertical.png').convert_alpha() + self.body_horizontal = pygame.image.load('Graphics/body_horizontal.png').convert_alpha() + + self.body_tr = pygame.image.load('Graphics/body_tr.png').convert_alpha() + self.body_tl = pygame.image.load('Graphics/body_tl.png').convert_alpha() + self.body_br = pygame.image.load('Graphics/body_br.png').convert_alpha() + self.body_bl = pygame.image.load('Graphics/body_bl.png').convert_alpha() + self.crunch_sound = pygame.mixer.Sound('Sound/crunch.wav') + + def draw_snake(self): + self.update_head_graphics() + self.update_tail_graphics() + + for index,block in enumerate(self.body): + x_pos = int(block.x * cell_size) + y_pos = int(block.y * cell_size) + block_rect = pygame.Rect(x_pos,y_pos,cell_size,cell_size) + + if index == 0: + screen.blit(self.head,block_rect) + elif index == len(self.body) - 1: + screen.blit(self.tail,block_rect) + else: + previous_block = self.body[index + 1] - block + next_block = self.body[index - 1] - block + if previous_block.x == next_block.x: + screen.blit(self.body_vertical,block_rect) + elif previous_block.y == next_block.y: + screen.blit(self.body_horizontal,block_rect) + else: + if previous_block.x == -1 and next_block.y == -1 or previous_block.y == -1 and next_block.x == -1: + screen.blit(self.body_tl,block_rect) + elif previous_block.x == -1 and next_block.y == 1 or previous_block.y == 1 and next_block.x == -1: + screen.blit(self.body_bl,block_rect) + elif previous_block.x == 1 and next_block.y == -1 or previous_block.y == -1 and next_block.x == 1: + screen.blit(self.body_tr,block_rect) + elif previous_block.x == 1 and next_block.y == 1 or previous_block.y == 1 and next_block.x == 1: + screen.blit(self.body_br,block_rect) + + def update_head_graphics(self): + head_relation = self.body[1] - self.body[0] + if head_relation == Vector2(1,0): self.head = self.head_left + elif head_relation == Vector2(-1,0): self.head = self.head_right + elif head_relation == Vector2(0,1): self.head = self.head_up + elif head_relation == Vector2(0,-1): self.head = self.head_down + + def update_tail_graphics(self): + tail_relation = self.body[-2] - self.body[-1] + if tail_relation == Vector2(1,0): self.tail = self.tail_left + elif tail_relation == Vector2(-1,0): self.tail = self.tail_right + elif tail_relation == Vector2(0,1): self.tail = self.tail_up + elif tail_relation == Vector2(0,-1): self.tail = self.tail_down + + def move_snake(self): + if self.new_block == True: + body_copy = self.body[:] + body_copy.insert(0,body_copy[0] + self.direction) + self.body = body_copy[:] + self.new_block = False + else: + body_copy = self.body[:-1] + body_copy.insert(0,body_copy[0] + self.direction) + self.body = body_copy[:] + + def add_block(self): + self.new_block = True + + def play_crunch_sound(self): + self.crunch_sound.play() + + def reset(self): + self.body = [Vector2(5,10),Vector2(4,10),Vector2(3,10)] + self.direction = Vector2(0,0) + + +class FRUIT: + def __init__(self): + self.randomize() + + def draw_fruit(self): + fruit_rect = pygame.Rect(int(self.pos.x * cell_size),int(self.pos.y * cell_size),cell_size,cell_size) + screen.blit(apple,fruit_rect) + #pygame.draw.rect(screen,(126,166,114),fruit_rect) + + def randomize(self): + self.x = random.randint(0,cell_number - 1) + self.y = random.randint(0,cell_number - 1) + self.pos = Vector2(self.x,self.y) + +class MAIN: + def __init__(self): + self.snake = SNAKE() + self.fruit = FRUIT() + + def update(self): + self.snake.move_snake() + self.check_collision() + self.check_fail() + + def draw_elements(self): + self.draw_grass() + self.fruit.draw_fruit() + self.snake.draw_snake() + self.draw_score() + + def check_collision(self): + if self.fruit.pos == self.snake.body[0]: + self.fruit.randomize() + self.snake.add_block() + self.snake.play_crunch_sound() + + for block in self.snake.body[1:]: + if block == self.fruit.pos: + self.fruit.randomize() + + def check_fail(self): + if not 0 <= self.snake.body[0].x < cell_number or not 0 <= self.snake.body[0].y < cell_number: + self.game_over() + + for block in self.snake.body[1:]: + if block == self.snake.body[0]: + self.game_over() + + def game_over(self): + self.snake.reset() + + def draw_grass(self): + grass_color = (167,209,61) + for row in range(cell_number): + if row % 2 == 0: + for col in range(cell_number): + if col % 2 == 0: + grass_rect = pygame.Rect(col * cell_size,row * cell_size,cell_size,cell_size) + pygame.draw.rect(screen,grass_color,grass_rect) + else: + for col in range(cell_number): + if col % 2 != 0: + grass_rect = pygame.Rect(col * cell_size,row * cell_size,cell_size,cell_size) + pygame.draw.rect(screen,grass_color,grass_rect) + + def draw_score(self): + score_text = str(len(self.snake.body) - 3) + score_surface = game_font.render(score_text,True,(56,74,12)) + score_x = int(cell_size * cell_number - 60) + score_y = int(cell_size * cell_number - 40) + score_rect = score_surface.get_rect(center = (score_x,score_y)) + apple_rect = apple.get_rect(midright = (score_rect.left,score_rect.centery)) + bg_rect = pygame.Rect(apple_rect.left,apple_rect.top,apple_rect.width + score_rect.width + 6,apple_rect.height) + + pygame.draw.rect(screen,(167,209,61),bg_rect) + screen.blit(score_surface,score_rect) + screen.blit(apple,apple_rect) + pygame.draw.rect(screen,(56,74,12),bg_rect,2) + +pygame.mixer.pre_init(44100,-16,2,512) +pygame.init() +cell_size = 40 +cell_number = 20 +screen = pygame.display.set_mode((cell_number * cell_size,cell_number * cell_size)) +clock = pygame.time.Clock() +apple = pygame.image.load('Graphics/apple.png').convert_alpha() +game_font = pygame.font.Font('Font/PoetsenOne-Regular.ttf', 25) + +SCREEN_UPDATE = pygame.USEREVENT +pygame.time.set_timer(SCREEN_UPDATE,150) + +main_game = MAIN() + +while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == SCREEN_UPDATE: + main_game.update() + if event.type == pygame.KEYDOWN: + if event.key == pygame.K_UP: + if main_game.snake.direction.y != 1: + main_game.snake.direction = Vector2(0,-1) + if event.key == pygame.K_RIGHT: + if main_game.snake.direction.x != -1: + main_game.snake.direction = Vector2(1,0) + if event.key == pygame.K_DOWN: + if main_game.snake.direction.y != -1: + main_game.snake.direction = Vector2(0,1) + if event.key == pygame.K_LEFT: + if main_game.snake.direction.x != 1: + main_game.snake.direction = Vector2(-1,0) + + screen.fill((175,215,70)) + main_game.draw_elements() + pygame.display.update() + clock.tick(60) \ No newline at end of file