diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/SnakeInPython.iml b/.idea/SnakeInPython.iml deleted file mode 100644 index d0876a7..0000000 --- a/.idea/SnakeInPython.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 23231ce..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 61e2a39..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/font.ttf b/assets/font.ttf similarity index 100% rename from src/font.ttf rename to assets/font.ttf diff --git a/requirements.txt b/requirements.txt index 6302013..b9b6a53 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1 @@ -certifi==2024.2.2 -charset-normalizer==3.3.2 -click==8.1.7 -colorama==0.4.6 -cvlib==0.2.7 -gTTS==2.5.1 -idna==3.7 -imageio==2.34.1 -imutils==0.5.4 -numpy==1.26.4 -opencv-contrib-python==4.9.0.80 -opencv-python-headless==4.9.0.80 -pillow==10.3.0 -progressbar==2.5 -PyAudio==0.2.14 -pygame==2.5.2 -requests==2.31.0 -urllib3==2.2.1 +pygame==2.5.2 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..859f30e --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,42 @@ +""" +Main package + +This package provides a simple implementation of the classic Snake game using the Pygame library. +It consists of three modules: + +1. `__init__.py`: Defines the main function `snake_game()` to run the game. +2. `config_apple.py`: Contains the Apple class, which represents an apple object in the game. +3. `config_snake.py`: Contains the Snake class, which represents the snake entity in the Snake game. +""" + +# Author +__author__ = "Eduardo Benatti" + +# Version +__version__ = "1.1.0" + +# Import +import pygame + +""" Game configuration """ + +# Initialize Pygame +pygame.init() + +# Screen dimensions +SW, SH = 650, 650 + +# Block size for snake and other game elements +BLOCK_SIZE = 50 + +# Font used for the game +FONT = pygame.font.Font(None, BLOCK_SIZE * 2) + +# Create the game screen +screen = pygame.display.set_mode((SW, SH)) + +# Create a clock object to control frame rate +clock = pygame.time.Clock() + +# Set the window caption +pygame.display.set_caption("Snake!") diff --git a/src/apple_config/__init__.py b/src/apple_config/__init__.py new file mode 100644 index 0000000..4412197 --- /dev/null +++ b/src/apple_config/__init__.py @@ -0,0 +1,16 @@ +""" +Configuration module for the Apple class. + +This module provides the Apple class, which represents an +apple object in the game. The apple is an item that the +player can collect for points. +""" + +# Internal import +from .config_apple import Apple + +# Author +__author__ = "Eduardo Benatti " + +# Version +__version__ = "1.1.0" diff --git a/src/apple_config/config_apple.py b/src/apple_config/config_apple.py new file mode 100644 index 0000000..06837ee --- /dev/null +++ b/src/apple_config/config_apple.py @@ -0,0 +1,50 @@ +""" +This module provides the Apple class, which represents an +apple object in the game. The apple is an item that the +player can collect for points. + +Author: Eduardo Benatti +""" + +import random +from src import (BLOCK_SIZE, SH, SW, pygame) + +class Apple: + """ + A class to represent an apple in the game. + + Attributes: + - rect (pygame.Rect): A rectangle representing the apple's position and size on the screen. + + Methods: + - __init__(): Initializes the apple attributes and randomly places it on the screen. + - randomize(): Randomly places the apple on the screen. + - draw(screen): Draws the apple on the given screen. + """ + + def __init__(self): + """ + Initialize an Apple object. + + Sets the initial position of the apple to (0, 0) and then randomizes its position. + """ + self.rect = pygame.Rect(0, 0, BLOCK_SIZE, BLOCK_SIZE) + self.randomize() + + def randomize(self) -> None: + """ + Randomize the position of the apple. + + Randomly sets the x and y coordinates of the apple within the boundaries of the screen. + """ + self.rect.x = random.randint(0, SW - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE + self.rect.y = random.randint(0, SH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE + + def draw(self, screen) -> None: + """ + Draw the apple on the screen. + + Args: + - screen: The surface on which the apple will be drawn. + """ + pygame.draw.rect(screen, "red", self.rect) diff --git a/src/snake.py b/src/snake.py deleted file mode 100644 index 7d8d837..0000000 --- a/src/snake.py +++ /dev/null @@ -1,125 +0,0 @@ -import pygame -import sys -import random - -pygame.init() - -SW, SH = 650, 650 - -BLOCK_SIZE = 50 -FONT = pygame.font.Font(None, BLOCK_SIZE * 2) - -screen = pygame.display.set_mode((SW, SH)) -pygame.display.set_caption("Snake!") -clock = pygame.time.Clock() - -class Snake: - def __init__(self): - # Initialize snake attributes - self.x, self.y = BLOCK_SIZE, BLOCK_SIZE - self.xdir = 1 - self.ydir = 0 - self.head = pygame.Rect(self.x, self.y, BLOCK_SIZE, BLOCK_SIZE) - self.body = [pygame.Rect(self.x - BLOCK_SIZE, self.y, BLOCK_SIZE, BLOCK_SIZE)] - self.dead = False - - def update(self): - global apple - - # Check for collisions with snake body or walls - for square in self.body: - if self.head.colliderect(square): - self.dead = True - if not (0 <= self.head.x < SW and 0 <= self.head.y < SH): - self.dead = True - - # Handle snake death - if self.dead: - self.reset() - apple = Apple() - - # Update snake's body - self.body.insert(0, self.head.copy()) - if self.head.colliderect(apple.rect): - apple.randomize() - else: - self.body.pop() - - # Move snake's head - self.head.x += self.xdir * BLOCK_SIZE - self.head.y += self.ydir * BLOCK_SIZE - - def reset(self): - # Reset snake attributes - self.x, self.y = BLOCK_SIZE, BLOCK_SIZE - self.head = pygame.Rect(self.x, self.y, BLOCK_SIZE, BLOCK_SIZE) - self.body = [pygame.Rect(self.x - BLOCK_SIZE, self.y, BLOCK_SIZE, BLOCK_SIZE)] - self.xdir = 1 - self.ydir = 0 - self.dead = False - - def draw(self, screen): - # Draw snake on the screen - pygame.draw.rect(screen, "green", self.head) - for square in self.body: - pygame.draw.rect(screen, "green", square) - -class Apple: - def __init__(self): - # Initialize apple attributes - self.rect = pygame.Rect(0, 0, BLOCK_SIZE, BLOCK_SIZE) - self.randomize() - - def randomize(self): - # Randomize apple position - self.rect.x = random.randint(0, SW - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE - self.rect.y = random.randint(0, SH - BLOCK_SIZE) // BLOCK_SIZE * BLOCK_SIZE - - def draw(self, screen): - # Draw apple on the screen - pygame.draw.rect(screen, "red", self.rect) - -snake = Snake() -apple = Apple() - -score = 0 - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - sys.exit() - if event.type == pygame.KEYDOWN: - # Handle key presses to change snake direction - if event.key == pygame.K_DOWN and snake.ydir != -1: - snake.ydir = 1 - snake.xdir = 0 - elif event.key == pygame.K_UP and snake.ydir != 1: - snake.ydir = -1 - snake.xdir = 0 - elif event.key == pygame.K_RIGHT and snake.xdir != -1: - snake.ydir = 0 - snake.xdir = 1 - elif event.key == pygame.K_LEFT and snake.xdir != 1: - snake.ydir = 0 - snake.xdir = -1 - - # Update snake and apple - snake.update() - - # Draw game elements on the screen - screen.fill('black') - snake.draw(screen) - apple.draw(screen) - - # Check for apple collision and update score - if snake.head.colliderect(apple.rect): - score += 1 - - # Display score on the screen - score_text = FONT.render(f"Score: {score}", True, "white") - screen.blit(score_text, (SW // 2 - score_text.get_width() // 2, SH // 20)) - - # Update display and control game speed - pygame.display.update() - clock.tick(10) diff --git a/src/snake_config/__init__.py b/src/snake_config/__init__.py new file mode 100644 index 0000000..23ca05c --- /dev/null +++ b/src/snake_config/__init__.py @@ -0,0 +1,16 @@ +""" +Configuration module for the Snake class. + +This module provides the Snake class, which represents the snake +entity in the Snake game. The Snake class handles the snake's +movement, collision detection, and drawing on the screen. +""" + +# Internal import +from .snake_config import Snake + +# Author +__author__ = "Eduardo Benatti " + +# Version +__version__ = "1.1.0" diff --git a/src/snake_config/snake_config.py b/src/snake_config/snake_config.py new file mode 100644 index 0000000..bbf7aa4 --- /dev/null +++ b/src/snake_config/snake_config.py @@ -0,0 +1,108 @@ +""" +Module containing the Snake class for the Snake game. + +This module provides the Snake class, which represents the +snake entity in the Snake game. +The Snake class handles the snake's movement, collision +detection, and drawing on the screen. + +Author: Eduardo Benatti +""" + +# Import statements and code for the Snake class go here + + +import apple_config # Import the apple_config module +from src import (BLOCK_SIZE, SH, SW, pygame) # Import constants and libraries from the src module + + +class Snake: + """ + Class to represent the snake in the Snake game. + + Attributes: + x (int): x position of the snake's head. + y (int): y position of the snake's head. + xdir (int): Direction of the snake on the x-axis (-1 for left, 1 for right). + ydir (int): Direction of the snake on the y-axis (-1 for up, 1 for down). + head (pygame.Rect): Rectangle representing the snake's head. + body (list): List of rectangles representing the snake's body. + dead (bool): Indicates whether the snake is dead (True) or alive (False). + """ + + def __init__(self): + """ + Initializes the snake's attributes. + + Initializes the snake's position, direction, head, and body. + """ + self.x, self.y = BLOCK_SIZE, BLOCK_SIZE + self.xdir = 1 + self.ydir = 0 + self.head = pygame.Rect(self.x, self.y, BLOCK_SIZE, BLOCK_SIZE) + self.body = [pygame.Rect(self.x - BLOCK_SIZE, self.y, BLOCK_SIZE, BLOCK_SIZE)] + self.dead = False + + def update(self, apple: apple_config) -> None: + """ + Updates the snake's position and checks for collisions. + + Args: + apple (apple_config): Apple object to check for collisions. + + Returns: + None + """ + # Check for collisions with the snake's body or walls + for square in self.body: + if self.head.colliderect(square): + self.dead = True + if not (0 <= self.head.x < SW and 0 <= self.head.y < SH): + self.dead = True + + # Handle snake death + if self.dead: + self.reset() + + # Update the snake's body + self.body.insert(0, self.head.copy()) + if self.head.colliderect(apple.rect): + apple.randomize() + else: + self.body.pop() + + # Move the snake's head + self.head.x += self.xdir * BLOCK_SIZE + self.head.y += self.ydir * BLOCK_SIZE + + def reset(self) -> None: + """ + Resets the snake. + + Reinitializes the snake's attributes to restart the game. + + Returns: + None + """ + self.x, self.y = BLOCK_SIZE, BLOCK_SIZE + self.head = pygame.Rect(self.x, self.y, BLOCK_SIZE, BLOCK_SIZE) + self.body = [pygame.Rect(self.x - BLOCK_SIZE, self.y, BLOCK_SIZE, BLOCK_SIZE)] + self.xdir = 1 + self.ydir = 0 + self.dead = False + + def draw(self, screen) -> None: + """ + Draws the snake on the screen. + + Args: + screen: Screen where the snake will be drawn. + + Returns: + None + """ + # Draw the snake's head + pygame.draw.rect(screen, "green", self.head) + # Draw the snake's body + for square in self.body: + pygame.draw.rect(screen, "green", square) diff --git a/src/snake_game.py b/src/snake_game.py new file mode 100644 index 0000000..a499e32 --- /dev/null +++ b/src/snake_game.py @@ -0,0 +1,72 @@ +""" +This module provides a simple implementation of the classic +Snake game using the Pygame library. +It defines the main function `snake_game()` to run the game. + +Author: Eduardo Benatti +""" + +import sys, os + +sys.path.append(os.getcwd()) + +from src import * +import apple_config +import snake_config + +def snake_game() -> None: + """ + Main function to run the Snake game. + + Initializes the snake and apple objects, and enters the game loop. + Handles user input to change the snake's direction. + Updates the game state, draws game elements on the screen, and controls game speed. + """ + snake_obj = snake_config.Snake() + apple_obj = apple_config.Apple() + + score = 0 + + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.KEYDOWN: + # Handle key presses to change snake direction + if event.key == pygame.K_DOWN and snake_obj.ydir != -1: + snake_obj.ydir = 1 + snake_obj.xdir = 0 + elif event.key == pygame.K_UP and snake_obj.ydir != 1: + snake_obj.ydir = -1 + snake_obj.xdir = 0 + elif event.key == pygame.K_RIGHT and snake_obj.xdir != -1: + snake_obj.ydir = 0 + snake_obj.xdir = 1 + elif event.key == pygame.K_LEFT and snake_obj.xdir != 1: + snake_obj.ydir = 0 + snake_obj.xdir = -1 + + # Update snake and apple + snake_obj.update(apple_obj) + + # Draw game elements on the screen + screen.fill('black') + snake_obj.draw(screen) + apple_obj.draw(screen) + + # Check for apple collision and update score + if snake_obj.head.colliderect(apple_obj.rect): + score += 1 + + # Display score on the screen + score_text = FONT.render(f"Score: {score}", True, "white") + screen.blit(score_text, (SW // 2 - score_text.get_width() // 2, SH // 20)) + + # Update display and control game speed + pygame.display.update() + clock.tick(10) + + +if __name__ == "__main__": + snake_game()