first commit
BIN
Audio/crunch.wav
Normal file
BIN
Texture/Snake.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Texture/bendD.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
Texture/bendL.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
Texture/bendR.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
Texture/bendU.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
Texture/body.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
Texture/bodyH.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
Texture/cherry.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
Texture/cherry2.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
Texture/head.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Texture/headD.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Texture/headL.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Texture/headR.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
Texture/snake.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
Texture/tailD.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
Texture/tailL.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
Texture/tailR.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
Texture/tailU.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
1
highscore.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
0
|
291
main.py
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
import pygame
|
||||||
|
import sys
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
from pygame.math import Vector2
|
||||||
|
|
||||||
|
# TODO: Implement menu for Retry and Quit
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# Textures
|
||||||
|
self.head_up = pygame.image.load(
|
||||||
|
'Texture/head.png').convert_alpha()
|
||||||
|
self.head_down = pygame.image.load(
|
||||||
|
'Texture/headD.png').convert_alpha()
|
||||||
|
self.head_left = pygame.image.load(
|
||||||
|
'Texture/headL.png').convert_alpha()
|
||||||
|
self.head_right = pygame.image.load(
|
||||||
|
'Texture/headR.png').convert_alpha()
|
||||||
|
|
||||||
|
self.tail_up = pygame.image.load(
|
||||||
|
'Texture/tailU.png').convert_alpha()
|
||||||
|
self.tail_down = pygame.image.load(
|
||||||
|
'Texture/tailD.png').convert_alpha()
|
||||||
|
self.tail_left = pygame.image.load(
|
||||||
|
'Texture/tailL.png').convert_alpha()
|
||||||
|
self.tail_right = pygame.image.load(
|
||||||
|
'Texture/tailR.png').convert_alpha()
|
||||||
|
|
||||||
|
self.bend_right = pygame.image.load(
|
||||||
|
'Texture/bendR.png').convert_alpha() # right
|
||||||
|
self.bend_left = pygame.image.load(
|
||||||
|
'Texture/bendL.png').convert_alpha() # right
|
||||||
|
self.bend_up = pygame.image.load(
|
||||||
|
'Texture/bendU.png').convert_alpha() # dont show up
|
||||||
|
self.bend_down = pygame.image.load(
|
||||||
|
'Texture/bendD.png').convert_alpha() # right
|
||||||
|
|
||||||
|
self.body_vertical = pygame.image.load(
|
||||||
|
'Texture/body.png').convert_alpha()
|
||||||
|
self.body_horizontal = pygame.image.load(
|
||||||
|
'Texture/bodyH.png').convert_alpha()
|
||||||
|
|
||||||
|
self.crunch_sound = pygame.mixer.Sound(
|
||||||
|
'Audio/crunch.wav')
|
||||||
|
|
||||||
|
def draw_snake(self):
|
||||||
|
self.update_head_graphics()
|
||||||
|
self.update_tail_graphics()
|
||||||
|
|
||||||
|
for index, block in enumerate(self.body):
|
||||||
|
# 1. Rect for the position
|
||||||
|
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)
|
||||||
|
# Head lokks in what position
|
||||||
|
if index == 0:
|
||||||
|
display.blit(self.head, block_rect)
|
||||||
|
elif index == len(self.body) - 1:
|
||||||
|
display.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:
|
||||||
|
display.blit(self.body_vertical, block_rect)
|
||||||
|
elif previous_block.y == next_block.y:
|
||||||
|
display.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:
|
||||||
|
display.blit(self.bend_right, block_rect)
|
||||||
|
if previous_block.x == -1 and next_block.y == 1 or previous_block.y == 1 and next_block.x == -1:
|
||||||
|
display.blit(self.bend_left, block_rect)
|
||||||
|
if previous_block.x == -1 and next_block.y == -1 or previous_block.y == -1 and next_block.x == -1:
|
||||||
|
display.blit(self.bend_up, block_rect)
|
||||||
|
if previous_block.x == 1 and next_block.y == 1 or previous_block.y == 1 and next_block.x == 1:
|
||||||
|
display.blit(self.bend_down, 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
|
||||||
|
|
||||||
|
# for block in self.body:
|
||||||
|
# # create rectangle and draw it
|
||||||
|
# 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)
|
||||||
|
# pygame.draw.rect(display, (137, 255, 130), block_rect)
|
||||||
|
|
||||||
|
def update_tail_graphics(self):
|
||||||
|
tail_relation = self.body[-2] - self.body[-1]
|
||||||
|
if tail_relation == Vector2(1, 0):
|
||||||
|
self.tail = self.tail_right
|
||||||
|
elif tail_relation == Vector2(-1, 0):
|
||||||
|
self.tail = self.tail_left
|
||||||
|
elif tail_relation == Vector2(0, 1):
|
||||||
|
self.tail = self.tail_down
|
||||||
|
elif tail_relation == Vector2(0, -1):
|
||||||
|
self.tail = self.tail_up
|
||||||
|
|
||||||
|
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):
|
||||||
|
# draw a rectangle
|
||||||
|
fruit_rect = pygame.Rect(
|
||||||
|
int(self.pos.x) * cell_size, int(self.pos.y)*cell_size, cell_size, cell_size)
|
||||||
|
# pygame.draw.rect(display, (255, 7, 7), fruit_rect) draw rectangle
|
||||||
|
display.blit(cherry, fruit_rect) # Draws Grpahics
|
||||||
|
|
||||||
|
def randomize(self):
|
||||||
|
self.x = random.randint(0, cell_number-1)
|
||||||
|
self.y = random.randint(0, cell_number-1)
|
||||||
|
# Create a Vector with 2 Options
|
||||||
|
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.collision()
|
||||||
|
self.check_fail()
|
||||||
|
|
||||||
|
def draw_elements(self):
|
||||||
|
self.draw_grass()
|
||||||
|
self.fruit.draw_fruit()
|
||||||
|
self.snake.draw_snake()
|
||||||
|
self.draw_score()
|
||||||
|
|
||||||
|
def collision(self):
|
||||||
|
if self.fruit.pos == self.snake.body[0]:
|
||||||
|
# New Fruit
|
||||||
|
# Make Snake longer
|
||||||
|
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):
|
||||||
|
# Is snake outsie of the screen?
|
||||||
|
# Check if snake hit himself
|
||||||
|
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 draw_grass(self):
|
||||||
|
grass_color = (97, 180, 8)
|
||||||
|
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(display, 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(display, grass_color, grass_rect)
|
||||||
|
|
||||||
|
def draw_score(self):
|
||||||
|
with open('highscore.txt', mode='r+', encoding='UTF-8', errors='strict')as file:
|
||||||
|
global score_text
|
||||||
|
score_text = str(len(self.snake.body) - 3)
|
||||||
|
score_surface = game_font.render(score_text, True, (54, 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))
|
||||||
|
cherry_rect = cherry.get_rect(
|
||||||
|
midright=(score_rect.left, score_rect.centery))
|
||||||
|
bg_rect = pygame.Rect(cherry_rect.left-6, cherry_rect.top-6,
|
||||||
|
cherry_rect.width + 6 + score_rect.width + 6, cherry_rect.height+12)
|
||||||
|
|
||||||
|
pygame.draw.rect(display, (167, 209, 61), bg_rect)
|
||||||
|
display.blit(score_surface, score_rect)
|
||||||
|
display.blit(cherry, cherry_rect)
|
||||||
|
pygame.draw.rect(display, (54, 74, 12), bg_rect, 2)
|
||||||
|
# Highscore
|
||||||
|
hscore_text = "highscore: " + str(file.readlines()).strip("'[]'")
|
||||||
|
hscore_surface = game_font.render(hscore_text, True, (34, 54, 12))
|
||||||
|
hscore_x = int(cell_size * cell_number-cell_number*cell_size + 40)
|
||||||
|
hscore_y = int(cell_number*cell_size-cell_number*cell_size + 60)
|
||||||
|
hscore_rect = hscore_surface.get_rect(
|
||||||
|
center=(hscore_x + 75, hscore_y))
|
||||||
|
h_rect = pygame.Rect(hscore_rect.left-6, hscore_rect.top-6,
|
||||||
|
hscore_rect.width + 12, hscore_rect.height+12)
|
||||||
|
pygame.draw.rect(display, (0, 0, 0), h_rect, 2)
|
||||||
|
display.blit(hscore_surface, hscore_rect)
|
||||||
|
|
||||||
|
def game_over(self):
|
||||||
|
save()
|
||||||
|
self.snake.reset()
|
||||||
|
|
||||||
|
|
||||||
|
def save():
|
||||||
|
with open('highscore.txt', mode='r') as file:
|
||||||
|
data = file.read()
|
||||||
|
if int(score_text) >= int(data):
|
||||||
|
with open('highscore.txt', mode='r+')as file:
|
||||||
|
file.write(score_text)
|
||||||
|
|
||||||
|
|
||||||
|
pygame.mixer.pre_init(44100, -16, 2, 512)
|
||||||
|
pygame.init()
|
||||||
|
cell_size = 40
|
||||||
|
cell_number = 20
|
||||||
|
pygame.display.set_caption('Pythonistas Snake')
|
||||||
|
display = pygame.display.set_mode(
|
||||||
|
(cell_number * cell_size, cell_number * cell_size))
|
||||||
|
clock = pygame.time.Clock() # Set the speed of the Game
|
||||||
|
cherry = pygame.image.load(
|
||||||
|
'Texture/cherry2.png').convert_alpha()
|
||||||
|
game_font = pygame.font.Font(
|
||||||
|
'/home/sandwich/Müll/Code/Python/Assets/Fonts/PinkChicken-Regular.ttf', 31)
|
||||||
|
|
||||||
|
DISPLAY_UPDATE = pygame.USEREVENT
|
||||||
|
pygame.time.set_timer(DISPLAY_UPDATE, 150)
|
||||||
|
|
||||||
|
main_game = MAIN()
|
||||||
|
|
||||||
|
# In this Loop are all our elements / Main loop
|
||||||
|
while True:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if event.type == DISPLAY_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_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)
|
||||||
|
if event.key == pygame.K_RIGHT:
|
||||||
|
if main_game.snake.direction.x != -1:
|
||||||
|
main_game.snake.direction = Vector2(1, 0)
|
||||||
|
display.fill((98, 184, 8))
|
||||||
|
main_game.draw_elements()
|
||||||
|
pygame.display.update()
|
||||||
|
clock.tick(240)
|