Filmania Project (Combined)
Filmania Project (Combined)
BONAFIDE CERTIFICATE
1|Page
First of all, we would like to thank our Computer
Science Teacher, Mrs.Dhanalakshmi, who was a
constant source of inspiration. She encouraged us to
think creatively and motivated us to work on this
assignment without giving it a second thought. She
expressed full support and provided us with the
different teaching aids that were required to complete
this assignment. She believed in us even when we could
not believe that we could do it. We are also thankful to
every member of this group. It was each and every
individual’s contribution that made this assignment a
success. We were always there to lift each other up,
and that was what helped us stay together till the end.
We thank our parents for always trusting in us and
teaching us to believe in our abilities and strengths and
never give up until the goal is achieved. We are
thankful to all our friends who extended their moral
support.
2|Page
INDEX
3|Page
INTRODUCTION
4|Page
SYSTEM REQUIREMENTS
TESTING TECHNOLOGY
5|Page
MODULES AND
FUNCTIONS USED
Modules used:
Pygame
Random
Math
Csv
Mysql.connector.pooling
Mysql.connector
Threading
Sys
Re
Textwrap
Classes used:
1. FlameEffect
Used to create a dynamic flame effect that
follows the player's cursor. It initializes the flame
at the center of the screen and updates its
position based on the cursor's coordinates (x, y),
then draws the flame effect onto the game
screen to add visual appeal and interactivity.
6|Page
2. FlameParticle
Used to create individual flame particles for a fire
effect. Each particle has properties like position,
radius, and burn rate, which control its size and
movement as it "burns." The class draws circles
with varying levels of opacity and color (from
bright orange to gold) to simulate a glowing,
flickering flame, and it gradually shrinks until it
fades out, enhancing the realism of the flame
effect.
3. Flame
Used to manage a collection of FlameParticle
objects to create a full flame effect. It initializes
particles at a specified position and updates their
positions to follow the flame’s movement. When
particles fade out, new ones are generated to
maintain a continuous flame, creating a dynamic
and realistic fire effect on the screen.
4. MatrixColumn
Used to simulate a column of falling characters,
reminiscent of the "Matrix" effect. It initializes with
random characters and colors, applying wave-
like motion and pulsating speed to create
dynamic movement. As the column moves down
the screen, it randomly changes characters and
shifts colors, maintaining a visually engaging
appearance. When the column reaches the
bottom of the screen, it resets to create a
continuous flow of characters.
7|Page
Functions Used:
1. load_movies_from_file(filename)
Used to read a specified file to load movie quotes
organized by difficulty levels: easy, medium, and
hard. It initializes a dictionary to store the quotes,
identifies the current difficulty level based on the
section headers in the file, and populates the
dictionary with movie titles and their
corresponding quotes. The function returns the
structured dictionary of movies and quotes for
later use in the application.
2. get_db_connection()
Used to retrieve a database connection from a
connection pool. This allows for efficient
management of database connections by
reusing existing ones instead of creating new
connections each time, improving performance
and resource utilization in database-driven
applications.
3. preload_questions(num_questions=10)
Used to fetch a specified number of random
questions from a database and stores them in a
global cache. It establishes a database
connection, executes a query to retrieve the
questions and their correct answers, and then
closes the connection. This function helps in
efficiently loading questions for use in a quiz or
game, minimizing database access during
gameplay.
8|Page
4. load_next_question()
Used to retrieve the next question from a
preloaded cache. If the cache is empty, it first calls
preload_questions to load more questions from
the database. The function then pops a question
from the cache and assigns it to the global
variable next_question, ensuring that a new
question is available for the quiz or game. This
mechanism allows for a seamless flow of
questions during gameplay.
5. get_random_quote_from_db()
Used to retrieve a random quote and its
associated correct answer from the current
question stored in the next_question variable. If
next_question is None, it calls
load_next_question to load a new question.
Additionally, it starts a new thread to preload the
next question, ensuring that future calls have a
question ready without interrupting the current
flow. This function helps maintain a smooth user
experience by providing immediate access to
questions while preparing the next one in the
background.
6. draw_glowing_circle(screen, color,
position, radius, glow_radius)
The draw_glowing_circle function creates a
glowing circle effect on the volume screen. It
draws a series of circles with decreasing opacity
(alpha) based on their distance from the center,
creating a smooth glow around a given color at a
9|Page
specified position and radius. The glow_radius
parameter determines how far the glow extends.
This function enhances visual aesthetics by
simulating a glowing effect, often used for
highlighting objects or adding an ambient light
effect in a game or graphical application.
7. draw_slider_handle(screen,position)
The draw_slider_handle function is responsible
for rendering a slider handle on the volume
screen. It first draws a shadow beneath the
handle to give a sense of depth, using a semi-
transparent black color. Then, it calls
draw_glowing_circle to create a glowing effect
around the handle, using a predefined color and
radius for the glow. Finally, it draws the actual
handle itself using the specified handle_color and
radius. This function enhances the visual
appearance of the slider, making it more
attractive and interactive in a graphical user
interface or game.
8. update_volume(delta)
The update_volume function adjusts the audio
volume in the application based on a specified
change (delta). It updates the global volume
variable by adding delta, ensuring that the volume
remains within defined limits (between
VOLUME_MIN and VOLUME_MAX). The function
also calculates the new position for the slider
handle (target_handle_x) based on the updated
volume. Finally, it sets the new volume for both
the background music and any female instruction
10 | P a g e
audio, allowing for real-time audio adjustments in
the user interface.
9. create_stars(num_columns)
The create_stars function generates a specified
number of columns for a visual effect, likely
resembling falling characters or stars in a matrix-
like display. It takes num_columns as an
argument to determine how many columns to
create. The function initializes a global variable
matrix_columns and uses a font for rendering
characters. It calculates the spacing between
each column based on the screen width and
creates a list of MatrixColumn instances,
positioning each column according to its index.
This setup is essential for creating a dynamic
visual effect on the screen.
10. update_stars()
The update_stars function updates the positions
of all the star-like columns on the screen. It
retrieves the current time in milliseconds using
pygame.time.get_ticks(), which is used to create a
time-based effect. The function iterates through
each MatrixColumn in the matrix_columns list and
calls the move method on each column, allowing
them to animate and create a dynamic visual
effect. This function is crucial for continuously
refreshing the display of falling characters or
stars in the animation.
11 | P a g e
11. draw_stars(screen)
The draw_stars function renders the star-like
characters on the screen by iterating through
each MatrixColumn in the matrix_columns list. For
each column, it loops through the characters and
their corresponding colors. It calculates the
vertical position (y) for each character based on
the column's current y position and the font size
(14). If the character is within the screen's height, it
creates a surface for the character using the
specified font and color, then blits (draws) it onto
the screen at the calculated position. This
function is essential for visually displaying the
animated falling effect of characters in the
project.
12 | P a g e
13. display_instructions(screen)
The display_instructions function manages the
presentation of instructions to the player in a
graphical window. It begins by filling the screen
with a black background and playing a specific
audio track (female_instruction). The background
music is paused during this display, and a flame
effect is initialized to enhance the visual
experience.
14. sound_volume(screen)
The sound_volume function manages the
volume control interface in a Pygame application.
It allows users to adjust the audio volume using
both mouse movements and arrow key presses.
The function runs in a loop until the user decides
to continue, handling events such as mouse
motion (for dragging the volume slider) and key
presses (for incrementing or decrementing the
volume with the left and right arrow keys).
15. display_currency()
The display_currency function retrieves the
player's in-game currency and item counts from
a database, ensuring that certain quantities (skips,
clocks, and golden clocks) do not exceed
specified limits. It fetches the current amounts of
coins, gems, skips, clocks, and golden clocks,
updates the database if limits are breached, and
then visually displays this information on the
screen using Pygame's drawing functions.
Finally, it returns the counts of coins and gems for
further use in the game.
13 | P a g e
16. store(screen)
The store function presents the in-game store
interface where players can purchase various
items using their in-game currency. It initializes the
store display, including background graphics and
item buttons for purchasing skips, clocks, gems,
golden clocks, and a special level upgrade. The
function checks the player's currency and item
limits before allowing purchases, providing
feedback messages based on the transaction
outcome. Players can interact with the store by
clicking buttons or pressing the Enter key to
return to the previous screen. It updates the
display to reflect the current state of the player's
inventory and any purchase confirmations or
error messages.
17. display_start_menu(screen)
The display_start_menu function creates the
start menu for the game, featuring a visually
dynamic background with a blinking "Are you
ready?" message that changes color to grab the
player's attention. It initializes a flame effect that
responds to the mouse position, enhancing the
visual appeal. The menu allows players to start
the game by pressing the Enter key, which also
triggers background music to play from a specific
starting position in the audio file. The menu
remains active until the player decides to start the
game or quits the application, providing a clear
indication of how to proceed with a "Press Enter
to start" message after the blinking phase.
14 | P a g e
18. get_username(screen)
The get_username function manages user input
for a login or registration interface in a game. It
allows users to enter their username and
password, providing a series of prompts and
validations throughout the process. The interface
features a textbox for username input, which
leads to password entry if the username is
recognized or prompts for password creation if
it's new. Users can toggle the visibility of their
password via a checkbox and have the option to
reset their password if needed. The function
includes error messaging for invalid inputs,
guiding the user through the registration or login
flow while utilizing a visually appealing
background and flame effect. It returns the
username once the process is successfully
completed.
15 | P a g e
password change or False if the process is
aborted.
20. is_password_valid(password)
The is_password_valid function checks the
strength of a given password against several
criteria to ensure it meets security standards. It
verifies that the password is at least 8
characters long, contains at least one letter,
includes at least one numeric digit, and has at
least one special character (symbol). If the
password fails to meet any of these
requirements, the function returns False along
with a specific error message indicating which
condition was not satisfied. If the password
passes all checks, it returns True and a
confirmation message stating that the password
is valid.
16 | P a g e
22. confirm_username(screen, username,
existing_usernames)
The confirm_username function checks if a
specified username already exists in a list of
existing usernames. If the username does not
exist, it returns True (indicating that the username
is available) without further confirmation. If the
username does exist, it displays a confirmation
dialog on the screen, asking the user whether
they want to proceed with that username. The
user can choose to confirm ("Yes") or decline
("No"), and the function returns the appropriate
response based on the user's choice. The
function also incorporates visual elements, such
as drawing background images, stars, messages,
and buttons, while handling user input and mouse
interactions for a dynamic user experience.
23. display_difficulty(screen)
The display_difficulty function presents a user
interface for selecting the difficulty level of a
game. It creates three buttons for "Easy,"
"Medium," and "Hard" difficulty levels and waits for
the user to click one of them. When a button is
clicked, it plays a sound and sets the difficulty
variable to the corresponding level, then exits the
loop. Throughout the process, the function
continuously updates the screen by drawing the
background, animated stars, and the buttons,
while also handling user events such as quitting
the game. Finally, it returns the selected difficulty
level as a string.
17 | P a g e
24. ask_for_music(screen)
The ask_for_music function displays a prompt on
the screen asking the user if they want to enable
music for the game. It features two buttons
labeled "Yes" and "No." The function continuously
listens for user interactions, specifically mouse
clicks on the buttons. If the user clicks "Yes," it
plays a sound and returns True, indicating the
user wants music. If "No" is clicked, it plays a
sound and returns False, indicating the user does
not want music. The function also handles quitting
the game, updates the screen with a background
and animated stars, and visually highlights the
buttons based on mouse hover events.
25. choose_music_playlist(screen)
The choose_music_playlist function allows the
user to select a music playlist for the game by
presenting three options: "Sunny Days," "Rainy
Nights," and "Adrenaline Rush." It listens for mouse
click events, and when the user clicks on one of
the buttons, it plays the corresponding music
track in a loop while also playing a click sound.
The function continuously updates the screen
with a background, animated stars, and displays
the playlist options. Additionally, it provides visual
feedback by highlighting the buttons when the
mouse hovers over them. The function concludes
when the user selects a playlist.
27. display_survival_mode(screen)
The display_survival_mode function presents
the user with a screen featuring a "Survival
Mode" button. It enters a loop that waits for user
interactions until the button is clicked. If the user
clicks the button, a sound effect plays, and the
loop ends, indicating that the player has selected
Survival Mode. Throughout the loop, the function
continuously updates the screen by drawing a
background, animated stars, and the button, while
also handling mouse events for hover effects to
enhance interactivity. The function ultimately
returns True, signifying that the selection was
successful.
19 | P a g e
28. load_leaderboard(mode)
The load_leaderboard function retrieves the
leaderboard data for a specified game mode from
a CSV file. It constructs the filename based on the
provided mode and attempts to open the
corresponding file. If the file exists, it reads the
data using a CSV dictionary reader, converting
each entry's username to lowercase and its
score to an integer. Additionally, it checks for an
'average_time' field, converting it to a float or
setting it to None if the value is 'N/A'. The function
returns the processed leaderboard as a list of
dictionaries. If the file is not found, it returns an
empty list.
20 | P a g e
30. display_leaderboard(screen,
leaderboard, mode)
The display_leaderboard function is responsible
for rendering the leaderboard on the screen
during the game. It enters a loop to handle events,
allowing the player to quit or continue by pressing
the Enter key. Within the loop, it draws the
background, stars, and a flame effect while
dynamically adjusting the layout of the
leaderboard based on the screen's dimensions.
The function calculates the required widths for
the username, score, and average time columns,
ensuring they fit within the available space. It then
displays the leaderboard entries, truncating
usernames that are too long and formatting
scores and average times accordingly. Finally, it
prompts the user to press Enter to continue,
updating the display with each frame until the user
decides to proceed.
21 | P a g e
and, for survival mode, by average time as well.
Finally, the updated leaderboard is saved back to
the file, and a message is printed to confirm the
changes.
33. generate_hint(movie)
The generate_hint function creates a hint for a
given movie title by randomly revealing three
letters from the title while obscuring the rest with
22 | P a g e
underscores. It first removes spaces and
converts the movie title to uppercase for
uniformity. If the movie title has three or fewer
letters, the function returns the entire title. For
longer titles, it randomly selects three letters
from the title and constructs a hint where non-
selected letters are replaced with underscores.
The resulting hint is then formatted with spaces
between letters for improved readability and
returned as a string.
34.play_creative_mode(screen,username
, used_movies)
The play_creative_mode function manages the
gameplay for a movie-quote guessing game in
creative mode. It initializes game variables,
including score, hint count, and time limits, while
continuously fetching random movie quotes from
a database. The player interacts with the game by
entering their guesses, using hints, and managing
time constraints. The function includes logic for
rendering the game screen, displaying quotes,
score, hints, and remaining time, and it updates the
game state based on user inputs. If the player
guesses incorrectly or the time runs out, the
game ends, displaying the score and updating the
leaderboard before offering options for the next
steps.
35. special_level()
The special_level function implements a card-
matching game where players match quotes with
their corresponding movies. It initializes game
23 | P a g e
parameters, including score, attempts, and a
countdown timer set for 2 minutes. The function
retrieves random quotes and their matching
movies from a database, creates and shuffles
cards, and manages player interactions through
mouse clicks to reveal cards. When two cards
are selected, it checks for a match, updating the
score and the number of gems obtained. The
function handles the game state, including
displaying the game board, managing time, and
ending the game either when all pairs are found or
time runs out. After the game ends, it presents the
final score, congratulating the player or indicating
game over.
36. display_game_mode(screen)
The display_game_mode function presents a
menu screen where players can select between
different game modes: Survival, Creative, or
access instructions, a store, or a special level. It
initializes buttons for each option and checks for
user interactions, playing a sound on button
clicks. The function retrieves the status of the
special level from the database to determine if it
should be accessible. It updates the screen with a
background, animated stars, and button states,
applying visual effects like color changes on
hover. The function loops until the player selects
a mode or option, then returns the chosen game
mode to the calling function.
24 | P a g e
37.display_score_and_time(screen,score,
average_time, num_questions)
The display_score_and_time function shows a
game-over screen for seven seconds, displaying
the player's final score and the average time per
question answered. It runs a loop that listens for
quit events and updates the screen with a
background, animated stars, and the score text. If
the player answered any questions, it calculates
and displays the average time per question;
otherwise, it indicates that no questions were
answered. The function also incorporates a flame
effect that responds to mouse position, enhancing
the visual experience before exiting after the
designated time.
38.display_end_options(screen,
leaderboard,mode,score,num_questions=
0)
The display_end_options function presents the
player with options after completing a game,
including the ability to play again, view the
leaderboard, or quit. The function initializes a
graphical interface with buttons for each option,
and it handles user input by listening for mouse
clicks. If the player selects "Play Again," it plays a
sound and returns a corresponding string; if
"Leaderboard" is chosen, it calls the function to
display the leaderboard. The "Quit" option exits the
game. Throughout the loop, it continuously
updates the display with the background,
animated stars, and button hover effects,
enhancing the visual experience.
25 | P a g e
39. ask_to_continue_as_same_user
(screen, username)
The ask_to_continue_as_same_user function
prompts the user to decide whether to continue
with the same username or choose a new one. It
displays a message asking if the user wants to
continue, along with the current username
centered on the screen. The function features
two buttons—"Yes" and "No"—that the user can
click. If the "Yes" button is clicked, the function
returns the username in lowercase, allowing the
user to continue. If "No" is selected, it calls another
function to retrieve a new username. Throughout
the loop, the function updates the display with
background visuals, animated stars, and button
hover effects to enhance the user interface
experience.
40. countdown(screen)
The countdown function displays a countdown
from 3 to 1 on the screen, accompanied by a
countdown sound effect. For each number, it
creates a visual effect where the number fades
in and out over a period of one second, with a half-
second fade-out after displaying each number.
During the countdown, the background and
animated stars are redrawn, and mouse events
are processed, allowing the user to adjust sound
settings through a speaker button. The function
ensures that the countdown numbers are
centered on the screen and handles quitting the
game if the window is closed. The overall effect
26 | P a g e
creates a dynamic and engaging countdown
experience before starting a game or a new level.
41. main()
The main function initializes the Pygame
environment for the game "FILMANIA," setting up
the screen and creating visual effects like stars.
It manages the user interface flow, starting with
the display of the start menu and prompting the
user to enter their username. It checks if the
username already exists in the database; if not, it
adds the new user. The game then enters a loop
where it allows the player to select between
"survival" and "creative" game modes. For each
mode, it manages the flow of gameplay, including
difficulty selection, a countdown, playing the
game, updating the leaderboard, and displaying
the score. Players are given options to play again
or quit, with appropriate sound effects and user
prompts to enhance the experience. The loop
continues until the player decides to quit the
game.
27 | P a g e
SOURCE CODE
import pygame
import random
import math
import csv
from mysql.connector.pooling import MySQLConnectionPool
import mysql.connector as sql
import threading
from sys import exit
import re
import textwrap
class FlameEffect:
def __init__(self, screen_width, screen_height):
self.SCREEN_WIDTH = screen_width
self.SCREEN_HEIGHT = screen_height
self.flame = Flame(screen_width // 2, screen_height // 2)
class FlameParticle:
alpha_layer_qty = 2
alpha_glow_difference_constant = 2
def update(self):
self.y -= 7 - self.r
self.x += random.randint(-self.r, self.r)
self.original_r -= self.burn_rate
self.r = int(self.original_r)
if self.r <= 0:
self.r = 1
28 | P a g e
for i in range(self.alpha_layers, -1, -1):
alpha = 255 - i * (255 // self.alpha_layers - 5)
if alpha <= 0:
alpha = 0
radius = self.r * i * i * self.alpha_glow
if self.r == 4 or self.r == 3:
r, g, b = (255, 69, 0)
elif self.r == 2:
r, g, b = (255, 140, 0)
else:
r, g, b = (255, 215, 0)
color = (r, g, b, alpha)
pygame.draw.circle(self.surf, color, (self.surf.get_width() //
2, self.surf.get_height() // 2), radius)
screen.blit(self.surf, self.surf.get_rect(center=(self.x, self.y)))
class Flame:
def __init__(self, x, y):
self.x = x
self.y = y
self.flame_intensity = 2
self.flame_particles = []
for i in range(self.flame_intensity * 25):
self.flame_particles.append(FlameParticle(self.x +
random.randint(-5, 5), self.y, random.randint(1, 5)))
def load_movies_from_file(filename):
movies = {"easy": {}, "medium": {}, "hard": {}}
current_difficulty = None
return movies
db = sql.connect(host='localhost', user='root',
password='hughjackman@wolverine', database='filmania')
cur = db.cursor()
db_config = {
'host': 'localhost',
29 | P a g e
'database': 'filmania',
'user': 'root',
'password': 'hughjackman@wolverine'
}
def get_db_connection():
return pool.get_connection()
question_cache = []
next_question = None
def preload_questions(num_questions=10):
global question_cache
connection = get_db_connection()
cursor = connection.cursor(dictionary=True)
query = "SELECT quote, correct_answer FROM questions ORDER BY RAND()
LIMIT %s"
cursor.execute(query, (num_questions,))
question_cache = cursor.fetchall()
cursor.close()
connection.close()
def load_next_question():
global next_question
if not question_cache:
preload_questions()
next_question = question_cache.pop()
def get_random_quote_from_db():
global next_question
if next_question is None:
load_next_question()
current_question = next_question
threading.Thread(target=load_next_question).start()
return current_question['quote'], current_question['correct_answer']
# Initialize pygame
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load('flicker.mp3')
pygame.mixer.music.play()
# Screen dimensions
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height),
pygame.SRCALPHA)
pygame.display.set_caption("FILMANIA")
30 | P a g e
# Colors
white = (255, 255, 255)
black = (0, 0, 0)
gray = (200, 200, 200)
red = (255, 0, 0)
# Font
font = pygame.font.Font('sketch.ttf', 40)
font1 = pygame.font.Font('sketch.ttf', 45)
# Volume Slider
WIDTH, HEIGHT = 640, 480
SLIDER_WIDTH = 300
SLIDER_HEIGHT = 8
SLIDER_HANDLE_RADIUS = 15
VOLUME_MIN = 0.0
VOLUME_MAX = 1.0
slider_start_x = 250 # X position of the slider start
slider_y = 300 # Y position of the slider center
slider_end_x = slider_start_x + SLIDER_WIDTH
volume = 1.0
slider_handle_x = slider_start_x + SLIDER_WIDTH * volume
volume_text_x = 360 # X position of the volume text
volume_text_y = 320 # Y position of the volume text
bg_color = (30, 30, 30) # Dark background
slider_bg_color = (50, 50, 50) # Dark slider background
slider_active_color = (0, 128, 255) # Active slider bar color
handle_color = (255, 255, 255) # White handle with glow
handle_glow_color = (0, 128, 255) # Light blue for the glowing effect
shadow_color = (0, 0, 0, 100) # Semi-transparent black for shadow
text_color = (255, 255, 255) # White for the text
target_handle_x = slider_handle_x
handle_animation_speed = 0.1
# Arrow key press flags
right_arrow_held = False
left_arrow_held = False
hold_interval = 100
# Timer variables for 100-millisecond delay between volume changes
right_arrow_last_press = 0
left_arrow_last_press = 0
# Function to draw a circle with glow effect
def draw_glowing_circle(screen, color, position, radius, glow_radius):
for i in range(glow_radius):
alpha = max(0, 255 - int(255 * (i / glow_radius))) # Alpha
decreases with distance
glow_color = (*color[:3], alpha) # Create the glowing color
pygame.draw.circle(screen, glow_color, position, radius + i)
31 | P a g e
# Draw shadow
pygame.draw.circle(screen, (0, 0, 0, 128), position,
SLIDER_HANDLE_RADIUS + 5)
# Draw the handle
draw_glowing_circle(screen, handle_glow_color, position,
SLIDER_HANDLE_RADIUS, 10)
pygame.draw.circle(screen, handle_color, position,
SLIDER_HANDLE_RADIUS)
# Heart image
red_heart = pygame.image.load('heart.png')
grey_heart = pygame.image.load('lost heart.png')
wid = int(red_heart.get_width()*0.2)
hei = int(red_heart.get_height()*0.2)
red_heart = pygame.transform.scale(red_heart, (wid, hei))
grey_heart = pygame.transform.scale(grey_heart, (wid, hei))
# Clock image
pause_button = pygame.image.load('clock.png')
pause_button_off = pygame.image.load('dead_clock.png')
wid = int(pause_button.get_width()*0.15)
hei = int(pause_button.get_height()*0.15)
pause_button = pygame.transform.scale(pause_button, (wid, hei))
pause_button_off = pygame.transform.scale(pause_button_off, (wid, hei))
#Hint image
hint_button = pygame.image.load('hint_on.png')
hint_button_off = pygame.image.load('hint_off.png')
wid = int(hint_button.get_width()*0.13)
hei = int(hint_button.get_height()*0.13)
hint_button = pygame.transform.scale(hint_button, (wid, hei))
hint_button_off = pygame.transform.scale(hint_button_off, (wid, hei))
32 | P a g e
# skip image
skip_button = pygame.image.load('skip.png')
skip_button_off = pygame.image.load('empty skip.png')
wid = int(skip_button.get_width()*0.15)
hei = int(skip_button.get_height()*0.15)
wid_store = int(skip_button.get_width()*0.17)
hei_store = int(skip_button.get_height()*0.17)
skip_button = pygame.transform.scale(skip_button, (wid, hei))
skip_store = pygame.transform.scale(skip_button, (wid_store, hei_store))
skip_button_off = pygame.transform.scale(skip_button_off, (wid, hei))
# Speaker image
speaker_button = pygame.image.load('speaker.png')
wid = int(speaker_button.get_width()*0.04)
hei = int(speaker_button.get_height()*0.04)
speaker_button = pygame.transform.scale(speaker_button, (wid, hei))
# Currency images
coin_button = pygame.image.load('coin.png')
gem_button = pygame.image.load('gem.png')
c_wid = int(coin_button.get_width()*0.25)
g_wid = int(gem_button.get_width()*0.22)
c_hei = int(coin_button.get_height()*0.25)
g_hei = int(gem_button.get_height()*0.22)
coin_button = pygame.transform.scale(coin_button, (c_wid, c_hei))
gem_button = pygame.transform.scale(gem_button, (g_wid, g_hei))
# buy image
buy_button = pygame.image.load('buy now.png')
buy_button_off = pygame.image.load('buy now_off.png')
wid = int(buy_button.get_width()*0.2)
hei = int(buy_button.get_height()*0.2)
buy_button = pygame.transform.scale(buy_button, (wid, hei))
buy_button_off = pygame.transform.scale(buy_button_off, (wid, hei))
# Screen dimensions (make sure these are defined in your main script)
screen_width = 800
screen_height = 600
# Number of stars
NUM_STARS = 200
class MatrixColumn:
def __init__(self, x, font):
self.x = x
self.font = font
self.chars = []
self.base_speed = random.uniform(1, 3)
self.speed = self.base_speed
self.length = random.randint(5, 30)
self.wave_offset = random.uniform(0, 2 * math.pi)
self.color_shift = 0
self.reset()
def reset(self):
self.y = random.randint(-300, -50)
self.chars = [self.random_char() for _ in range(self.length)]
self.colors = [(0, random.randint(50, 255), 0) for _ in
33 | P a g e
range(self.length)]
self.colors[0] = (180, 255, 180) # Brighter green for the first
character
def random_char(self):
return
random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567
89@#$%^&*()_+-=[]{}|;:,.<>?")
# Pulsating speed
self.speed = self.base_speed + math.sin(time * 0.005) * 0.5
self.y += self.speed
if self.y > screen_height:
self.reset()
# Color shifting
self.color_shift = (self.color_shift + 0.02) % (2 * math.pi)
def create_stars(num_columns):
global matrix_columns
font = pygame.font.Font(None, 14)
spacing = screen_width // num_columns
matrix_columns = [MatrixColumn(i * spacing, font) for i in
range(num_columns)]
def update_stars():
current_time = pygame.time.get_ticks()
for column in matrix_columns:
column.move(current_time)
def draw_stars(screen):
for column in matrix_columns:
for i, (char, color) in enumerate(zip(column.chars,
column.colors)):
y = column.y + i * 14 # 14 is the font size
if 0 <= y < screen_height:
char_surface = column.font.render(char, True, color)
screen.blit(char_surface, (int(column.x), int(y)))
34 | P a g e
# Function to display text
def draw_text(surface, text, color, rect, font, aa=False, bkg=None):
rect = pygame.Rect(rect)
y = rect.top
line_spacing = -2
while text:
i = 1
if y + font_height > rect.bottom:
break
# If we've wrapped the text, then adjust back to the last word
if i < len(text):
i = text.rfind(" ", 0, i) + 1
text = text[i:]
return text
def display_instructions(screen):
screen.fill((0, 0, 0))
done = False
female_instruction.play()
start_time = pygame.time.get_ticks()
meendum.set_volume(0) # Pause the audio track meendum
pygame.mixer.music.pause() # Pause the background music
flame_effect = FlameEffect(screen_width, screen_height)
# speaker button
speaker_button_rect = speaker_button.get_rect(center=(750, 550))
35 | P a g e
if speaker_button_rect.collidepoint(event.pos):
mouse_click_sound.play()
sound_volume(screen)
pygame.display.flip()
def sound_volume(screen):
global right_arrow_held
global left_arrow_held
global slider_handle_x
global target_handle_x
global volume
global left_arrow_last_press
global right_arrow_last_press
flame_effect = FlameEffect(screen_width, screen_height)
done = False
while not done:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]: # If the left mouse button is pressed
mouse_x, mouse_y = event.pos
if slider_start_x <= mouse_x <= slider_end_x and
(slider_y - SLIDER_HEIGHT / 2) <= mouse_y <= (
slider_y + SLIDER_HEIGHT / 2):
target_handle_x = mouse_x
volume = (target_handle_x - slider_start_x) /
(SLIDER_WIDTH)
volume = max(VOLUME_MIN, min(volume, VOLUME_MAX))
# Clamp the volume to the valid range
pygame.mixer.music.set_volume(volume)
# Check for arrow key presses
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT: # Right arrow key pressed
right_arrow_held = True # Set the flag to True
elif event.key == pygame.K_LEFT: # Left arrow key pressed
left_arrow_held = True # Set the flag to True
elif event.key == pygame.K_RETURN:
click_sound.play()
female_instruction.stop()
pygame.mixer.music.unpause() # Unpause the background
36 | P a g e
music
done = True
# Draw bg
screen.blit(background_image, (0, 0))
draw_stars(screen)
update_stars()
mouse_x, mouse_y = pygame.mouse.get_pos()
flame_effect.update(mouse_x, mouse_y)
flame_effect.draw(screen)
37 | P a g e
screen.blit(volume_text, (volume_text_x, volume_text_y)) #
Positioning the text using custom variables
def display_currency():
#limit
cur.execute(f'select * from store where username = "{username}"')
data = cur.fetchall()[0]
Skips, clock, gold_clock = data[3], data[4], data[5]
if Skips > 7:
cur.execute(f'update store set skips = 7 where username =
"{username}"')
db.commit()
if clock > 5:
cur.execute(f'update store set clocks = 5 where username =
"{username}"')
db.commit()
if gold_clock > 2:
cur.execute(f'update store set golden_clocks = 2 where username =
"{username}"')
db.commit()
global coins, gems
coins = cur.execute(f'''select coins from store where username =
"{username}"''')
coins = cur.fetchall()[0][0]
gems = cur.execute(f'''select gems from store where username =
"{username}"''')
gems = cur.fetchall()[0][0]
skips = cur.execute(f'''select skips from store where username =
"{username}"''')
skips = cur.fetchall()[0][0]
clocks = cur.execute(f'''select clocks from store where username =
"{username}"''')
clocks = cur.fetchall()[0][0]
golden_clocks = cur.execute(f'''select golden_clocks from store where
username = "{username}"''')
golden_clocks = cur.fetchall()[0][0]
screen.blit(coin_button, (30, 30))
draw_text(screen, f"{coins}", (255, 215, 0), pygame.Rect(100, 40, 200,
50), font)
screen.blit(gem_button, (180, 32))
draw_text(screen, f"{gems}", (15, 82, 186), pygame.Rect(255, 40, 200,
50), font)
screen.blit(skip_button, (330, 25))
draw_text(screen, f"{skips}", (54, 1, 63), pygame.Rect(410, 40, 200,
50), font)
screen.blit(pause_button, (470, 28))
draw_text(screen, f"{clocks}", (255, 0, 0), pygame.Rect(550, 40, 200,
50), font)
screen.blit(add_time_button, (600, 30))
draw_text(screen, f"{golden_clocks}", (255, 0, 0), pygame.Rect(690, 40,
200, 50), font)
return coins, gems
def store(screen):
global Skips, clock, gold_clock
screen.fill((0, 0, 0))
flame_effect = FlameEffect(screen_width, screen_height)
done = False
38 | P a g e
# Buy button
buy_button_rect1 = buy_button.get_rect(center=(220, 200))
buy_button_rect2 = buy_button.get_rect(center=(220, 350))
buy_button_rect3 = buy_button.get_rect(center=(220, 500))
buy_button_rect4 = buy_button.get_rect(center=(620, 200))
buy_button_rect5 = buy_button.get_rect(center=(620, 350))
message = ""
message_end_time = 0
message_end_time1 = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
if buy_button_rect1.collidepoint(event.pos):
if Skips < 7:
mouse_click_sound.play()
if coins >= 5:
cur.execute(f'update store set coins = coins -
5 WHERE username = "{username}"')
cur.execute(f'update store set skips = skips +
1 WHERE username = "{username}"')
db.commit()
message = "Purchased successfully!!!"
message_end_time1 = pygame.time.get_ticks() +
2000
else:
message = "You don't have enough coins"
message_end_time = pygame.time.get_ticks() +
2000
else:
message = "You have reached your limit!!!"
message_end_time = pygame.time.get_ticks() + 2000
if buy_button_rect2.collidepoint(event.pos):
if clock < 5:
mouse_click_sound.play()
if coins >= 10:
cur.execute(f'update store set coins = coins -
10 where username = "{username}" ')
cur.execute(f'update store set clocks = clocks
+ 1 where username = "{username}" ')
39 | P a g e
db.commit()
message = "Purchased successfully!!!"
message_end_time1 = pygame.time.get_ticks() +
2000
else:
message = "You don't have enough coins"
message_end_time = pygame.time.get_ticks() +
2000
else:
message = "You have reached your limit!!!"
message_end_time = pygame.time.get_ticks() + 2000
if buy_button_rect3.collidepoint(event.pos):
mouse_click_sound.play()
if coins >= 20:
cur.execute(f'update store set coins = coins - 20
where username = "{username}" ')
cur.execute(f'update store set gems = gems + 1
where username = "{username}" ')
db.commit()
message = "Purchased successfully!!!"
message_end_time1 = pygame.time.get_ticks() + 2000
else:
message = "You don't have enough coins"
message_end_time = pygame.time.get_ticks() + 2000
if buy_button_rect4.collidepoint(event.pos):
if gold_clock < 2:
mouse_click_sound.play()
if gems >= 10:
cur.execute(f'update store set gems = gems - 10
where username = "{username}" ')
cur.execute(
f'update store set golden_clocks =
golden_clocks + 1 where username = "{username}" ')
db.commit()
message = "Purchased successfully!!!"
message_end_time1 = pygame.time.get_ticks() +
2000
else:
message = "You don't have enough gems"
message_end_time = pygame.time.get_ticks() +
2000
else:
message = "You have reached your limit!!!"
message_end_time = pygame.time.get_ticks() + 2000
if buy_button_rect5.collidepoint(event.pos):
if spl_level == "False":
mouse_click_sound.play()
if gems >= 50:
cur.execute(f'update store set gems = gems - 50
where username = "{username}" ')
cur.execute(f'update store set special_level =
"True" where username = "{username}" ')
db.commit()
message = "Purchased successfully!!!"
message_end_time1 = pygame.time.get_ticks() +
2000
else:
message = "You don't have enough gems"
message_end_time = pygame.time.get_ticks() +
2000
else:
40 | P a g e
message = "You have reached your limit!!!"
message_end_time = pygame.time.get_ticks() + 2000
41 | P a g e
screen.blit(buy_button_off, buy_button_rect5.topleft)
pygame.display.flip()
42 | P a g e
update_stars()
pygame.display.flip()
return score
# Function to get the username
def get_username(screen):
input_box = pygame.Rect(200, 300, 400, 50)
color_inactive = pygame.Color('lightskyblue3')
color_active = pygame.Color('dodgerblue2')
color = color_inactive
active = False
text = ''
password = ''
done = False
flame_effect = FlameEffect(screen_width, screen_height)
message = ""
message_end_time = 0
state = "username"
43 | P a g e
mouse_click_sound.play()
else:
active = False
color = color_active if active else color_inactive
44 | P a g e
is_valid, validation_message =
is_password_valid(password)
if is_valid:
cur.execute("UPDATE store SET password
= %s WHERE username = %s",
(password, text.lower()))
db.commit()
message = "Password changed. Please
enter your new password."
state = "enter_password"
password = ''
else:
message = validation_message
password = ''
else:
message = "Please enter a new password!"
message_end_time = pygame.time.get_ticks() +
2000
elif event.key == pygame.K_BACKSPACE:
if state == "username":
text = text[:-1]
else:
password = password[:-1]
else:
if state == "username":
text += event.unicode
else:
password += event.unicode
if state == "username":
draw_text(screen, "Enter your username:", (255, 255, 0),
pygame.Rect(200, 230, 400, 50), font)
txt_surface = font.render(text, True, color)
else:
draw_text(screen, message, (255, 255, 0), pygame.Rect(200, 230,
400, 50), font)
if show_password:
txt_surface = font.render(password, True, color)
else:
txt_surface = font.render('*' * len(password), True, color)
if state == "username":
draw_text(screen, "Tip: Keep it short and snappy! ", (255, 0,
255), pygame.Rect(200, 370, 400, 50), font)
else:
# Draw checkbox
pygame.draw.rect(screen, (255, 255, 255), checkbox_rect, 2)
if show_password:
pygame.draw.line(screen, (255, 255, 255),
45 | P a g e
checkbox_rect.topleft, checkbox_rect.bottomright, 2)
pygame.draw.line(screen, (255, 255, 255),
checkbox_rect.topright, checkbox_rect.bottomleft, 2)
draw_text(screen, "Show Password", (255, 255, 255),
pygame.Rect(230, 370, 200, 50), font)
if state == "enter_password":
pygame.draw.rect(screen, (0, 31, 63), forgot_password_button)
forgot_password_button_text = font.render("Forgot Password",
True, (46, 204, 64))
forgot_password_button_text_rect =
forgot_password_button_text.get_rect(
center=forgot_password_button.center)
screen.blit(forgot_password_button_text,
forgot_password_button_text_rect)
pygame.display.flip()
return text.lower()
46 | P a g e
message = validation_message
new_password = ''
else:
message = "Please enter a new password!"
message_end_time = pygame.time.get_ticks() + 2000
elif event.key == pygame.K_BACKSPACE:
new_password = new_password[:-1]
else:
new_password += event.unicode
pygame.display.flip()
return False
def is_password_valid(password):
if len(password) < 8:
return False, "Password must be at least 8 characters long"
if not re.search(r"[A-Za-z]", password):
return False, "Password must contain at least one letter"
if not re.search(r"\d", password):
return False, "Password must contain at least one number"
if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
return False, "Password must contain at least one symbol"
return True, "Password is valid"
if not username_exists:
47 | P a g e
return True, False # Username doesn't exist, no need to confirm
# Draw messages
draw_text(screen, message1, (255,255,0), pygame.Rect(100, 180, 600,
50), font)
draw_text(screen, message2, (255,0,0), pygame.Rect(100, 230, 600,
50), font)
draw_text(screen, message3, (255, 0, 255), pygame.Rect(100, 280,
600, 50), font)
# Draw buttons
pygame.draw.rect(screen, (0, 31, 63), yes_button)
pygame.draw.rect(screen, (0, 31, 63), no_button)
yes_text_rect = yes_text.get_rect(center=yes_button.center)
no_text_rect = no_text.get_rect(center=no_button.center)
screen.blit(yes_text, yes_text_rect)
screen.blit(no_text, no_text_rect)
48 | P a g e
pygame.display.flip()
pygame.display.flip()
return difficulty
49 | P a g e
if event.type == pygame.MOUSEBUTTONDOWN:
if yes_button.collidepoint(event.pos):
mouse_click_sound.play()
return True
elif no_button.collidepoint(event.pos):
mouse_click_sound.play()
return False
# Draw message
draw_text(screen, "READY TO GROOVE?", (255,0,255), pygame.Rect(250,
200, 300, 50), font)
# Draw buttons
pygame.draw.rect(screen, (0, 31, 63), yes_button)
pygame.draw.rect(screen, (0, 31, 63), no_button)
yes_text_rect = yes_text.get_rect(center=yes_button.center)
no_text_rect = no_text.get_rect(center=no_button.center)
screen.blit(yes_text, yes_text_rect)
screen.blit(no_text, no_text_rect)
pygame.display.flip()
50 | P a g e
if sunny_days_button.collidepoint(event.pos):
mouse_click_sound.play()
pygame.mixer.music.load('sunny_days.mp3')
pygame.mixer.music.play(-1)
done = True
elif rainy_nights_button.collidepoint(event.pos):
mouse_click_sound.play()
pygame.mixer.music.load('rainy_nights.mp3')
pygame.mixer.music.play(-1)
done = True
elif adrenaline_rush_button.collidepoint(event.pos):
mouse_click_sound.play()
pygame.mixer.music.load('adrenaline_rush.mp3')
pygame.mixer.music.play(-1)
done = True
# Draw message
draw_text(screen, "PICK YOUR VIBE!", (255,255,0), pygame.Rect(300,
200, 200, 50), font)
# Draw buttons
pygame.draw.rect(screen, (0, 31, 63), sunny_days_button)
pygame.draw.rect(screen, (0, 31, 63), rainy_nights_button)
pygame.draw.rect(screen, (0, 31, 63), adrenaline_rush_button)
sunny_days_text_rect =
sunny_days_text.get_rect(center=sunny_days_button.center)
rainy_nights_text_rect =
rainy_nights_text.get_rect(center=rainy_nights_button.center)
adrenaline_rush_text_rect =
adrenaline_rush_text.get_rect(center=adrenaline_rush_button.center)
screen.blit(sunny_days_text, sunny_days_text_rect)
screen.blit(rainy_nights_text, rainy_nights_text_rect)
screen.blit(adrenaline_rush_text, adrenaline_rush_text_rect)
51 | P a g e
pygame.draw.rect(screen, (46, 204, 64), adrenaline_rush_button)
adrenaline_rush_text = font.render("Adrenaline Rush", True, (0,
31, 63))
screen.blit(adrenaline_rush_text, adrenaline_rush_text_rect)
pygame.display.flip()
52 | P a g e
# Draw the input box and text
txt_surface = font.render(text, True, color)
width = max(400, txt_surface.get_width()+10)
input_box.w = width
screen.blit(txt_surface, (input_box.x+5, input_box.y+5))
pygame.draw.rect(screen, color, input_box, 2)
pygame.display.flip()
pygame.time.wait(2000)
53 | P a g e
# Animation: button hover
if survival_button.collidepoint(pygame.mouse.get_pos()):
pygame.draw.rect(screen, (46, 204, 64), survival_button)
draw_text(screen, "Survival Mode", (0, 31, 63),
survival_button, pygame.font.Font('sketch.ttf', 40), True)
pygame.display.flip()
return True
54 | P a g e
# Calculate the maximum width needed for usernames
max_username_width = max([font.size(entry['username'])[0] for entry
in leaderboard[:5]])
available_width = screen_width - 200 # Total available width minus
margins
y = 120
for i, entry in enumerate(leaderboard[:5]):
# Rank
draw_text(screen, f"{i+1}.", white, pygame.Rect(rank_x, y,
rank_width, 50), font, True)
# Score
draw_text(screen, f"{entry['score']}", (0, 255, 0),
pygame.Rect(score_x, y, score_width, 50), font, True)
pygame.display.flip()
55 | P a g e
# Convert username to lowercase for case-insensitive comparison
username = username.lower()
save_leaderboard(leaderboard, mode)
print(f"Leaderboard updated: {leaderboard}")
56 | P a g e
heart3 = red_heart
heart = [1, 2, 3]
skip = []
TIME = []
gold_clock = []
hint_count = []
display_hint = False
#load hints
cur.execute(f'select hints from store where username = "{username}" ')
for i in range(cur.fetchall()[0][0]):
hint_count.append(i+1)
correct_answer = 0
#Pause
pause_button_rect = pause_button.get_rect(center=(450,475))
paused = False
pause_duration = 10
watch_mech = pygame.mixer.Sound('watch mechanic.mp3')
pause_button_disabled = False
timer_visible = True
blink_interval = 500
last_blink_time = 0
timer_paused_time = 0
sound_playing = False
sound_finished_time = 0
# Hint
hint_button_rect = hint_button.get_rect(center=(723, 130))
# Skip
skip_button_rect = skip_button.get_rect(center=(300, 475))
# Golden Clock
golden_clock_rect = add_time_button.get_rect(center=(600, 475))
# Speaker button
speaker_button_rect = speaker_button.get_rect(center=(750, 550))
57 | P a g e
while True:
available_movies = list(set(movies[difficulty].keys()) -
used_movies)
if not available_movies: # If all movies have been used
break # You can handle this case as needed (e.g., reset
used_movies or end the game)
movie = random.choice(available_movies)
used_movies.add(movie) # Add the selected movie to the set
quote = random.choice(movies[difficulty][movie])
hint = None
if pause_button_rect.collidepoint(event.pos):
if len(TIME) != 0:
# watch mechanic
if not sound_playing:
pygame.mixer.music.pause()
watch_mech.play()
sound_playing = True
sound_finished_time =
pygame.time.get_ticks() + int(watch_mech.get_length() * 1000)
TIME.pop()
cur.execute(f'update store set clocks = clocks
- 1 where username = "{username}"')
db.commit()
mouse_click_sound.play()
paused = True
pause_button_disabled = True
pause_start_time = pygame.time.get_ticks()
58 | P a g e
if golden_clock_rect.collidepoint(event.pos):
if len(gold_clock) != 0:
mouse_click_sound.play()
time_limit = time_limit - int(elapsed_time) +
120
gold_clock.pop()
cur.execute(f'update store set golden_clocks =
golden_clocks - 1 where username = "{username}"')
db.commit()
if hint_button_rect.collidepoint(event.pos):
if len(hint_count) != 0:
mouse_click_sound.play()
hint_count.pop()
cur.execute(f'update store set hints = hints -
1 where username = "{username}"')
db.commit()
display_hint = True
hint = generate_hint(movie)
elif speaker_button_rect.collidepoint(event.pos):
mouse_click_sound.play()
sound_volume(screen)
if event.type == pygame.KEYDOWN:
if active:
if event.key == pygame.K_RETURN:
click_sound.play() # Play sound effect
if text.strip() == '':
# Set the end time for the message display
message_end_time = pygame.time.get_ticks()
+ 1500 # Display for 1.5 seconds
else:
if text.lower() == movie.lower():
correct_answer += 1
if 3 < correct_answer <= 5:
score += 2
bonus_active = True
blink_start_time =
pygame.time.get_ticks()
elif 5 < correct_answer <= 10:
score += 3
elif correct_answer > 10:
score += 5
else:
score += 1
question_done = True
if display_hint:
display_hint = False
total_time += pygame.time.get_ticks() -
question_start_time
num_questions += 1
if text.lower() != movie.lower():
correct_answer = 0
s = len(heart)
if s == 3:
heart3 = grey_heart
heart.pop()
elif s == 2:
heart2 = grey_heart
heart.pop()
elif s == 1:
59 | P a g e
heart1 = grey_heart
heart.pop()
if len(heart) == 0:
done = True
# golden clock
if len(gold_clock) != 0:
screen.blit(add_time_button, golden_clock_rect.topleft)
draw_text(screen, f"{len(gold_clock)}", red,
pygame.Rect(600, 500, 700, 200), font)
else:
screen.blit(add_time_button_off, golden_clock_rect.topleft)
#Pause button
if len(TIME) != 0:
screen.blit(pause_button, pause_button_rect.topleft)
draw_text(screen, f"{len(TIME)}", red, pygame.Rect(450,
60 | P a g e
500, 700, 200), font)
else:
screen.blit(pause_button_off, pause_button_rect.topleft)
#hint button
if len(hint_count) != 0:
screen.blit(hint_button, hint_button_rect.topleft)
draw_text(screen, f"{len(hint_count)}", red,
pygame.Rect(750, 110, 700, 200), font)
else:
screen.blit(hint_button_off, hint_button_rect.topleft)
if display_hint:
draw_text(screen, f"Hint: {hint}", (0, 255, 0),
pygame.Rect(200, 500, 400, 50), font)
# Blinking Bonus!!!
if bonus_active:
current_time = pygame.time.get_ticks()
if (current_time - blink_start_time) // blink_duration % 2
== 0:
draw_text(screen, "BONUS BONANZA!!!", (255, 255, 0),
pygame.Rect(190, 50, 700, 200), font)
if correct_answer <= 3:
bonus_active = False
if not paused:
elapsed_time = (pygame.time.get_ticks() - start_time -
timer_paused_time) / 1000
if elapsed_time < time_limit:
draw_text(screen, f"Time: {time_limit -
int(elapsed_time)}", red, pygame.Rect(50, 16, 200, 50), pygame.font.Font
('sketch.ttf', 38))
else:
draw_text(screen, "Time's up!", red, pygame.Rect(50,
16, 200, 50), pygame.font.Font('sketch.ttf', 38))
question_done = True
done = True
else:
if int((pygame.time.get_ticks()/500) % 2):
draw_text(screen, f"Time: {time_limit -
int(elapsed_time)}", red, pygame.Rect(50, 16, 200, 50), pygame.font.Font
('sketch.ttf', 38))
if paused:
elapsed_pause_time = (pygame.time.get_ticks() -
pause_start_time) / 1000
if elapsed_pause_time >= pause_duration:
paused = False
timer_paused_time += pygame.time.get_ticks() -
pause_start_time
61 | P a g e
# Check if we need to display the message
current_time = pygame.time.get_ticks()
if current_time < message_end_time:
draw_text(screen, "Please enter a movie name!", (255, 0,
0), pygame.Rect(200, 400, 400, 50), font)
pygame.display.flip()
clock.tick(60)
if done:
break
else:
average_time = None
def generate_hint(movie):
movie_letters = list(movie.replace(" ", "").upper()) # Remove spaces
and convert to uppercase
if len(movie_letters) <= 3:
return "".join(movie_letters) # If movie name is 3 letters or
less, reveal all
hint_letters = random.sample(movie_letters, 3) # Choose 3 random
letters
hint = ["_" if letter not in hint_letters else letter for letter in
movie.upper()]
return " ".join(hint) # Join with spaces for better readability
countdown(screen)
# Speaker button
62 | P a g e
speaker_button_rect = speaker_button.get_rect(center=(750, 550))
quote = result['quote']
movie = result['correct_answer']
question_done = False
question_start_time = pygame.time.get_ticks() # Start time for the
question
63 | P a g e
if active:
if event.key == pygame.K_RETURN:
click_sound.play()
if text.strip() == '':
enter_movie_message_end_time =
pygame.time.get_ticks() + 1500 # Display for 1.5 seconds
else:
if text.lower() == movie.lower():
score += 1
else:
game_over = True # End the game on
wrong answer
question_done = True
text = ''
active = False
color = color_inactive
elif event.key == pygame.K_BACKSPACE:
text = text[:-1]
else:
text += event.unicode
# Draw score
draw_text(screen, f"Score: {score}", (0, 255, 0),
pygame.Rect(50, 50, 200, 50), font)
64 | P a g e
# Display hint if active
current_time = pygame.time.get_ticks()
if current_time < hint_message_end_time:
draw_text(screen, f"Hint: {hint}", (0, 255, 0),
pygame.Rect(200, 450, 400, 50), font)
pygame.display.flip()
clock.tick(60)
# Update leaderboard
update_leaderboard(username, score, None, "creative")
65 | P a g e
game_over = False
gems_obtained = 0
pairs_found = 0
attempts = 0
# Colors
CARD_BACK = (0, 31, 63) # Dark blue
CARD_FRONT = (46, 204, 64) # Green
TEXT_COLOR = (0, 0, 0) # Black text
SELECTED_COLOR = (225,225,0)
countdown(screen)
flame_effect = FlameEffect(screen_width, screen_height)
# Shuffle cards
random.shuffle(cards)
66 | P a g e
y = start_y + row * (CARD_HEIGHT + CARD_SPACING)
card_positions.append(pygame.Rect(x, y, CARD_WIDTH,
CARD_HEIGHT))
if current_line:
lines.append(' '.join(current_line))
return lines
selected_cards = []
reveal_time = None
game_start_time = pygame.time.get_ticks()
time_limit = 120 # 2 minutes time limit
if remaining_time == 0:
game_over = True
if len(selected_cards) == 2:
attempts += 1
67 | P a g e
if (cards[selected_cards[0]]['match'] ==
cards[selected_cards[1]]['content'] or
cards[selected_cards[1]]['match'] ==
cards[selected_cards[0]]['content']):
pairs_found += 1
cards[selected_cards[0]]['matched'] = True
cards[selected_cards[1]]['matched'] = True
score += 100
gems_obtained += 1
cur.execute(f'update store set gems = gems
+ 1 where username = "{username}"')
db.commit()
reveal_time = current_time + 1000
# Draw everything
screen.blit(background_image, (0, 0))
draw_stars(screen)
update_stars()
mouse_x, mouse_y = pygame.mouse.get_pos()
flame_effect.update(mouse_x, mouse_y)
flame_effect.draw(screen)
# Draw cards
for i, (card, rect) in enumerate(zip(cards, card_positions)):
if card['matched']:
pygame.draw.rect(screen, CARD_FRONT, rect)
elif card['revealed']:
pygame.draw.rect(screen, SELECTED_COLOR, rect)
else:
pygame.draw.rect(screen, CARD_BACK, rect)
if card['revealed'] or card['matched']:
content = card['content']
# Wrap text
lines = wrap_text(content, card_font, rect.width)
68 | P a g e
text_rect = text_surface.get_rect()
text_rect.centerx = rect.centerx
text_rect.y = start_y
screen.blit(text_surface, text_rect)
start_y += card_font.get_linesize()
# Draw HUD
draw_text(screen, f"Score: {score}", (0, 255, 0), pygame.Rect(50,
50, 200, 50), font)
draw_text(screen, f"Gems: {gems_obtained}", (0, 255, 0),
pygame.Rect(50, 100, 200, 50), font)
draw_text(screen, f"Pairs Found: {pairs_found}/6", (255, 255, 255),
pygame.Rect(50, 150, 200, 50), font)
draw_text(screen, f"Attempts: {attempts}", (255, 255, 255),
pygame.Rect(600, 50, 200, 50), font)
draw_text(screen, f"Time: {remaining_time}s", (255, 0, 0),
pygame.Rect(600, 100, 200, 50), font)
if pairs_found == 6:
game_over = True
pygame.display.flip()
clock.tick(60)
if pairs_found == 6:
bonus = max(0, 1000 - (attempts * 50)) # Bonus points based on
attempts
final_score = score + bonus
draw_text(screen , f"Congratulations! You won with a score of
{final_score}!", (0, 255, 0), pygame.Rect(100, 200, 600, 200), font)
else:
draw_text(screen, f"Game Over! Your final score is {score}.",
(255, 0, 0), pygame.Rect(100, 200, 600, 200), font)
pygame.display.flip()
# Function to display game mode options
def display_game_mode(screen):
survival_button = pygame.Rect(200, 250, 200, 50)
creative_button = pygame.Rect(450, 250, 200, 50)
instructions_button = pygame.Rect(200, 350, 200, 50)
store_button = pygame.Rect(450, 350, 200, 50)
spl_level_button = pygame.Rect(300, 450, 200, 50)
spl_level_off_button = pygame.Rect(300, 450, 200, 50)
speaker_button_rect = speaker_button.get_rect(center=(750, 550))
locked_rect = lock_button.get_rect(center=(100, 500))
unlocked_rect = unlock_button.get_rect(center=(100, 500))
done = False
69 | P a g e
game_mode = None
flame_effect = FlameEffect(screen_width, screen_height)
70 | P a g e
instructions_text.get_rect(center=instructions_button.center)
store_text = font.render("STORE", True, (46, 204, 64))
store_text_rect = store_text.get_rect(center=store_button.center)
if spl_level == "True":
spl_level_text = font.render("SPL LEVEL", True, (46, 204, 64))
spl_level_text_rect =
store_text.get_rect(center=spl_level_button.center)
else:
spl_level_off_text = font.render("SPL LEVEL", True, (90, 90,
90))
spl_level_off_text_rect =
store_text.get_rect(center=spl_level_button.center)
display_currency()
pygame.display.flip()
return game_mode
# Function to display score and time
def display_score_and_time(screen, score, average_time, num_questions):
start_time = pygame.time.get_ticks()
flame_effect = FlameEffect(screen_width, screen_height)
while pygame.time.get_ticks() - start_time < 7000: # Display for 7
seconds
for event in pygame.event.get():
71 | P a g e
if event.type == pygame.QUIT:
pygame.quit()
exit()
pygame.display.flip()
# Control the frame rate
72 | P a g e
flame_effect.draw(screen)
# Draw buttons
pygame.draw.rect(screen, (0, 31, 63), play_again_button)
pygame.draw.rect(screen, (0, 31, 63), leaderboard_button)
pygame.draw.rect(screen, (0, 31, 63), quit_button)
play_again_text_rect =
play_again_text.get_rect(center=play_again_button.center)
leaderboard_text_rect =
leaderboard_text.get_rect(center=leaderboard_button.center)
quit_text_rect = quit_text.get_rect(center=quit_button.center)
screen.blit(play_again_text, play_again_text_rect)
screen.blit(leaderboard_text, leaderboard_text_rect)
screen.blit(quit_text, quit_text_rect)
73 | P a g e
update_stars()
mouse_x, mouse_y = pygame.mouse.get_pos()
flame_effect.update(mouse_x, mouse_y)
flame_effect.draw(screen)
# Draw message
draw_text(screen, "DO YOU WANT TO CONTINUE AS", (255,255,0),
pygame.Rect(190, 200, 500, 50), font)
# Draw buttons
pygame.draw.rect(screen, (0, 31, 63), yes_button)
pygame.draw.rect(screen, (0, 31, 63), no_button)
yes_text_rect = yes_text.get_rect(center=yes_button.center)
no_text_rect = no_text.get_rect(center=no_button.center)
screen.blit(yes_text, yes_text_rect)
screen.blit(no_text, no_text_rect)
pygame.display.flip()
def countdown(screen):
countdown_sound = pygame.mixer.Sound('count.mp3')
font = pygame.font.Font('sketch.ttf', 100)
countdown_sound.play()
flame_effect = FlameEffect(screen_width, screen_height)
#Speaker Button
speaker_button_rect = speaker_button.get_rect(center=(750, 550))
start_time = pygame.time.get_ticks()
74 | P a g e
screen.blit(background_image, (0, 0))
draw_stars(screen)
update_stars()
mouse_x, mouse_y = pygame.mouse.get_pos()
flame_effect.update(mouse_x, mouse_y)
flame_effect.draw(screen)
screen.blit(speaker_button, speaker_button_rect.topleft)
pygame.display.flip()
# Fade out
start_time = pygame.time.get_ticks()
while pygame.time.get_ticks() - start_time < 500:
alpha = max(0, 255 - (pygame.time.get_ticks() - start_time) *
255 // 500)
screen.blit(speaker_button, speaker_button_rect.topleft)
pygame.display.flip()
# Main function
def main():
global username
screen = pygame.display.set_mode((screen_width, screen_height))
75 | P a g e
pygame.display.set_caption("FILMANIA")
# Create stars
create_stars(200)
# Initialize flame effect
flame_effect = FlameEffect(screen_width, screen_height)
display_start_menu(screen)
# Get username after start menu
username = get_username(screen)
print("Username:", username)
if not user_exists:
cur.execute(f'''insert into store values("{username}", 0, 0, 0, 0,
0, "False", "", 0)''')
db.commit()
music_playing = False
music = ""
playlist = ""
while True:
if not pygame.display.get_init():
break
game_mode = display_game_mode(screen)
if game_mode == "survival":
if music == "":
music = ask_for_music(screen)
if music:
choose_music_playlist(screen)
difficulty = display_difficulty(screen)
if difficulty:
countdown(screen)
score, average_time, num_questions =
play_survival_mode(screen, difficulty, username, used_movies)
# Update leaderboard
update_leaderboard(username, score, average_time,
"survival")
# Display score and time
display_score_and_time(screen, score, average_time,
num_questions)
# Display end options and handle user choice
choice = display_end_options(screen,
load_leaderboard("survival"), "survival", score, num_questions)
if choice == "play_again":
meendum.play() # Play the meendum sound
used_movies.clear() # Clear the set to allow all
movies to be available again
username = ask_to_continue_as_same_user(screen,
username)
continue
76 | P a g e
elif choice == "quit":
pygame.quit()
return
elif game_mode == "creative":
if music == "":
music = ask_for_music(screen)
if music:
choose_music_playlist(screen)
while True: # This loop allows for multiple games in creative
mode
choice = play_creative_mode(screen, username, used_movies)
if choice == "play_again":
meendum.play() # Play the meendum sound
used_movies.clear() # Clear the set to allow all
movies to be available again
username = ask_to_continue_as_same_user(screen,
username)
threading.Thread(target=load_next_question).start()
break # Break out of the creative mode loop to return
to game mode selection
elif choice == "quit":
pygame.quit()
return
break # Exit the loop if the player doesn't choose to play
again
if __name__ == "__main__":
main()
77 | P a g e
FLOWCHART
78 | P a g e
OUTPUT SCREENS
79 | P a g e
80 | P a g e
81 | P a g e
82 | P a g e
83 | P a g e
84 | P a g e
85 | P a g e
86 | P a g e
87 | P a g e
88 | P a g e
REQUIRED IMAGES
89 | P a g e
CONCLUSIONS
90 | P a g e
https://www.youtube.com/
https://www.google.com/
https://copilot.microsoft.com/
https://ncert.nic.in/
https://www.quora.com/
https://www.wikipedia.org/
91 | P a g e