Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
AntynK committed Nov 30, 2024
0 parents commit fe995a4
Show file tree
Hide file tree
Showing 26 changed files with 1,109 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__/
*.zip
save.pickle
venv/
build/
dist/
11 changes: 11 additions & 0 deletions LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Copyright 2024 Andrii Karandashov(AntynK)

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Snake game
Popular game 'snake' written in Python.

## Requirements
Python version 3.9 or later.
Pygame version 2.1.0 or later.

## Run
The game can be run in two ways

### 1. Using the source code
> [!IMPORTANT]
> [Python 3.9](https://www.python.org/downloads/release/python-390/) or later must be installed
1. Open [releases](https://github.com/AntynK/SnakeGame/releases/latest) page.
2. Download the `SourceCode.zip` archive.
3. Unzip the archive.
4. Install the required modules using the command:

#### Windows:
```bash
pip install -r requirements.txt
```
#### Linux and MacOs:
```bash
pip3 install -r requirements.txt
```
5. Run the `main.py` file by double-clicking it or using the command:
#### Windows:
```bash
python main.py
```
#### Linux and MacOs:
```bash
python3 main.py
```

### 2. Using the executable file (Windows only)
> [!NOTE]
> This method is only for Windows. For other operating systems, use Method 1 or an emulator.
> [!IMPORTANT]
> The folder containing the executable must also include an `assets` folder with all images and fonts.
1. Open [releases](https://github.com/AntynK/SnakeGame/releases/latest) page.
2. Download the `Snake game.exe` file and the `assets.zip` archive.
3. Unzip the `assets.zip` archive.
4. Move the `Snake game.exe` file to the unpacked folder.
5. Run the executable file by double-clicking it.

## Building (Windows only)
[Pyinstaller](https://pyinstaller.org/en/stable/index.html) is used for building the game. It can be installed using the following command:

#### Windows
```bash
pip install pyinstaller
```

To build the game, use the following command:
#### Windows
```bash
pyinstaller main.spec
```

After building, a `dist` folder will be created, which contains the executable file.

> [!IMPORTANT]
> The folder containing the executable must also include an `assets` folder with all images and fonts.
68 changes: 68 additions & 0 deletions README_UA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Гра Змійка
Класична гра змійка написана на мові Python з використанням [Pygame](https://www.pygame.org/docs/).

## Вимоги
Версія Python 3.9 або новіша.

Версія pygame 2.1.0 або новіша.

## Запуск
Гру можна запустити 2 способами.

### Спосіб 1: Вихідний код
> [!IMPORTANT]
> У вас має бути встановлений [Python 3.9](https://www.python.org/downloads/release/python-390/) або новіший
1. Відкрийте сторінку [релізів](https://github.com/AntynK/SnakeGame/releases/latest).
2. Завантажте архів `SourceCode.zip`.
3. Розпакуйте його.
4. Інсталюйте залежності для цього відкрийте розпаковану папку і виконайте команду
Windows:
```bash
pip install -r requirements.txt
```
#### Linux та MacOs:
```bash
pip3 install -r requirements.txt
```
5. Запустіть файл `main.py`, двічі натиснувши по ньому або через команду:
#### Windows:
```bash
python main.py
```
#### Linux та MacOs:
```bash
python3 main.py
```

### Спосіб 2: Виконуваний файл (лише Windows)
> [!NOTE]
> Цей спосіб працює лише на Windows, для інших операційних систем довидеться використовувати спосіб 1, або емулятори.
> [!IMPORTANT]
> У папці з виконуваним файлом має бути папка `assets` зі всіма зображеннями та фрифтами.

1. Відкрийте сторінку [релізів](https://github.com/AntynK/SnakeGame/releases/latest).
2. Завантажте файл `Snake game.exe` та архів `assets.zip`.
3. Розпакуйте архів `assets.zip`.
4. Перемістить файл `Snake game.exe` у розпаковану папку.
5. Запустіть його, двічі натиснувши по ньому.

## Збирання (Windows)
Для збирання використовується модуль [Pyinstaller](https://pyinstaller.org/en/stable/index.html), який можна встановити за допомогою команди:

#### Windows
```bash
pip install pyinstaller
```

Збирання програми виконується цією командою:
#### Windows
```bash
pyinstaller main.spec
```
Після завершення процесу збирання у папці `dist` буде знаходитися виконуваний файл.

> [!IMPORTANT]
> У папці з виконуваним файлом має бути папка `assets` зі всіма зображеннями та фрифтами.
Binary file added assets/fonts/PixeloidSansBold.ttf
Binary file not shown.
Binary file added assets/images/apple.ico
Binary file not shown.
Binary file added assets/images/fruits/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/fruits/cherry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/snake_head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/trophy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions game/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from enum import Enum
from pathlib import Path

import pygame

# Game constants
GAME_TITLE = "Snake game"
TILE_SIZE = 16
DISPLAY_WIDTH, DISPLAY_HEIGHT = 480, 480
FPS = 60
SNAKE_SPEED = 500
MAX_FRUIT_COUNT = 2
HORIZONTAL_BAR_HEIGHT = 25

# Colors
MAIN_SNAKE_COLOR = (255, 208, 0)
SECONDARY_SNAKE_COLOR = (189, 155, 4)
WHITE_COLOR = (255, 255, 255)
BLACK_COLOR = (0, 0, 0)
GREEN_COLOR = (0, 255, 0)
DARK_GREEN_COLOR = (0, 170, 0)

# Pathes
ASSETS_FOLDER_PATH = Path("assets")
IMAGES_FOLDER_PATH = Path(ASSETS_FOLDER_PATH, "images")
FRUITS_FOLDER_PATH = Path(IMAGES_FOLDER_PATH, "fruits")
SAVE_FILE_PATH = Path("save.pickle")
FONT_FOLDER_PATH = Path(ASSETS_FOLDER_PATH, "fonts")
FONT_FILE_PATH = Path(FONT_FOLDER_PATH, "PixeloidSansBold.ttf")


class Directions(Enum):
IDLE = pygame.math.Vector2(0, 0)
UP = pygame.math.Vector2(0, -1)
DOWN = pygame.math.Vector2(0, 1)
RIGHT = pygame.math.Vector2(1, 0)
LEFT = pygame.math.Vector2(-1, 0)
58 changes: 58 additions & 0 deletions game/game_objects/fruits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import random
from pathlib import Path

import pygame

from game.constants import TILE_SIZE, FRUITS_FOLDER_PATH


class Fruit(pygame.sprite.Sprite):
VALUE: int
"""This number will be added when snake eats fruit."""
NAME = ""
"""Name of fruit image file."""

def __init__(self, game_area: pygame.rect.Rect) -> None:
"""Base Fruit class.
Arg:
game_area: Area on which fruit can appear.
"""

super().__init__()
self.game_area = game_area
self.image: pygame.surface.Surface = pygame.image.load(
Path(FRUITS_FOLDER_PATH, f"{self.NAME}.png")
).convert_alpha()
self.new_pos()

def new_pos(self) -> None:
"""Change position of fruit."""

self.rect: pygame.rect.Rect = pygame.rect.Rect(
random.randrange(
self.game_area.x + TILE_SIZE, self.game_area.width - TILE_SIZE
),
random.randrange(
self.game_area.y + TILE_SIZE, self.game_area.height - TILE_SIZE
),
TILE_SIZE,
TILE_SIZE,
)

def draw(self, display: pygame.surface.Surface):
display.blit(self.image, self.rect)


class Apple(Fruit):
"""Inherited from Fruit class."""

VALUE = 10
NAME = "apple"


class Cherry(Fruit):
"""Inherited from Fruit class."""

VALUE = 15
NAME = "cherry"
66 changes: 66 additions & 0 deletions game/game_objects/particles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import pygame

from game.ui import Text
from game.constants import WHITE_COLOR


class Particle(pygame.sprite.Sprite):
def __init__(self, game, x: int, y: int, duration: float) -> None:
"""Base particle class.
Args:
game: An instance of main game class.
x,y: Position of particles.
duration: Duration of particles.
"""

super().__init__()
self.particles: pygame.sprite.Group = game.particles
self.particles.add(self)
self.x, self.y = x, y
self.rect: pygame.rect.Rect = pygame.rect.Rect(self.x, self.y, 1, 1)
self.duration = duration

def update(self, delta_time: float):
"""Update particles and delete them when duration time pass."""

self.duration -= 100 * delta_time
if self.duration <= 0:
self.particles.remove(self)


class TextParticle(Particle):
def __init__(
self,
game,
x: int,
y: int,
duration: float,
text: str,
font_size: int = 10,
font_color: tuple[int, int, int] = WHITE_COLOR,
) -> None:
"""TextParticle class.
Args:
game: An instance of main game class.
x, y: Position of button.
text: Text of the button.
font_size: Text font size.
font_color: Text color.
"""

super().__init__(game, x, y, duration)
self.text = Text(x, y, text, font_size, font_color)
self.image: pygame.surface.Surface = self.text.pre_rendered_text

def update(self, delta_time: float):
"""Update particles and fade text.
Extends parent's method.
"""

super().update(delta_time)
self.rect.y -= 5 * delta_time # type: ignore

self.image.set_alpha(self.image.get_alpha() - 5) # type: ignore
Loading

0 comments on commit fe995a4

Please sign in to comment.