pygame-dvd/dvd_bounce/surfaces/dvd_screen.py

149 lines
5.5 KiB
Python

import pygame
import os
import random
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LOGO_SCALING = 0.1
class DVDLogo(pygame.sprite.Sprite):
"""
A Pygame sprite representing a DVD logo that moves around the screen.
Attributes:
base_image (pygame.Surface): The original image of the DVD logo.
x_speed (int): Current speed in the X axis.
y_speed (int): Current speed in the Y axis.
max_x (int): Maximum X position on the screen.
max_y (int): Maximum Y position on the screen.
"""
def __init__(self, window_size: tuple):
"""
Initialize DVDLogo sprite with given window size.
Args:
window_size (tuple): Size of the game window (width, height).
"""
super().__init__()
# Load and scale original logo image
self.base_image = pygame.image.load(SCRIPT_DIR + '/resources/dvd.png')
self.base_image.convert_alpha()
self.base_image = pygame.transform.scale(self.base_image, (self.base_image.get_width() * LOGO_SCALING,
self.base_image.get_height() * LOGO_SCALING))
# Copy the base image and store it in a separate instance variable; this is the image that will be drawn.
self.image = self.base_image.copy()
# Generate random color and apply it to the sprite.
self.random_color()
# Initialize rectangle (position, size) and speed attributes.
self.rect = self.image.get_rect()
self.x_speed = 4
self.y_speed = 4
# Calculate maximum X and Y positions on the screen for boundary checking.
self.max_x = window_size[0] - self.rect.width
self.max_y = window_size[1] - self.rect.height
def random_color(self):
"""
Generate a new, random color and apply it to the sprite.
"""
# Create a surface with alpha channel for generating transparent colors.
color_surface = pygame.Surface(self.image.get_size(), pygame.SRCALPHA)
# Generate random RGB values and fill the color surface accordingly.
new_color = (random.randint(32, 255),
random.randint(32, 255),
random.randint(32, 255))
color_surface.fill(new_color)
# Replace the drawn image with a copy of the base image and apply the randomly generated color.
self.image = self.base_image.copy()
self.image.blit(color_surface, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)
def update(self):
"""
Update DVDLogo sprite's position and speed based on its current state.
This method is called each frame during game execution to move the logo around
the screen and to handle collision/color changes.
"""
# Move the logo in the X and Y axis according to its current speed in those directions.
self.rect.x += self.x_speed
self.rect.y += self.y_speed
# Check for collisions with edges of the screen, change direction if necessary,
# and generate a new random color when hitting an edge.
if self.rect.x < 0 or self.rect.x > self.max_x:
self.x_speed *= -1
self.random_color()
if self.rect.y < 0 or self.rect.y > self.max_y:
self.y_speed *= -1
self.random_color()
# Ensure the logo stays within screen boundaries by clamping its position.
self.rect.x = max(0, min(self.rect.x, self.max_x))
self.rect.y = max(0, min(self.rect.y, self.max_y))
class Surface(pygame.Surface):
"""
A custom Pygame surface class for managing game logic and events.
Attributes:
running (bool): Flag indicating whether the surface is still running.
quit (bool): Flag signaling that the program should end rather than moving to a new surface.
next_surface (str): Name of the next surface to display after current one stops.
all_sprites (pygame.sprite.Group): A group containing sprites for easy sprite management.
"""
def __init__(self, window_size: tuple):
"""
Initialize Surface class with given window size.
Args:
window_size (tuple): Size of the game window (width, height).
"""
# Create a Pygame surface with alpha channel for generating transparent colors.
super().__init__(window_size, pygame.SRCALPHA)
# Initialize flags and attributes for managing game state.
self.running = True
self.quit = False
self.next_surface = ''
pygame.mouse.set_visible(False)
# Create a DVDLogo sprite instance and add it to the sprite group.
dvd_logo = DVDLogo(window_size)
self.all_sprites = pygame.sprite.Group(dvd_logo)
def update(self):
"""
Update game state by handling events, updating sprites, and redrawing surfaces.
This method is called every frame during game execution.
"""
# Fill the surface with a black background color
self.fill(pygame.colordict.THECOLORS.get('black'))
# Handle events such as mouse button clicks or key presses.
for event in pygame.event.get():
match event.type:
case pygame.MOUSEBUTTONDOWN:
# Stop the game when a user clicks anywhere on the screen.
self.running = False
self.quit = True
# Update positions and speeds of all sprites (in this case, just one logo sprite).
self.all_sprites.update()
# Draw all sprites onto this surface.
self.all_sprites.draw(self)