diff --git a/Games/Whiskers_Toy_Quest/README.md b/Games/Whiskers_Toy_Quest/README.md new file mode 100644 index 000000000..e72771aa7 --- /dev/null +++ b/Games/Whiskers_Toy_Quest/README.md @@ -0,0 +1,60 @@ +# **Whiskers Toy Quest** + +--- + +
+ +## **Description 📃** +Whiskers Toy Quest is an interactive text-based adventure game where players help Whiskers, a curious and playful cat, overcome exciting challenges to retrieve his favorite toys. Designed for children, the game fosters reading skills and enhances decision-making abilities by requiring players to carefully read and type their responses. Featuring diverse game states, branching storylines, and multiple outcomes, Whiskers Toy Quest provides an engaging, educational, and fun experience for kids of all ages. + +## **Functionalities 🎮** +- Interactive story progression +- Multiple game states and choices +- Engaging GUI with customtkinter +
+ +## **How to Play? 🎩** +- Launch the game +- Follow the on-screen instructions to make choices +- Help Whiskers find his toys by making the right decisions + +## **Installation and Running the Game 🚀** +### Prerequisites +- **Python 3.7 or later** +- **pip** (Python package installer) +- **customtkinter** library + +### Steps + +1. Clone the repository: + ```bash + git clone https://github.com/wenstef/GameZone.git + ``` +2. Install the required Python libraries using `pip`: + ```bash + pip install customtkinter + ``` +3. Start the game by running the main script: + ```bash + python main.py + ``` + or + ```bash + python3 main.py + ``` + +**The game window should open, and you can start playing!** + +
+ +## **Screenshots 📸** + +
+ +![image](assets/Whiskers_Toy_Quest.png) +![image](assets/Whiskers_Toy_Quest_2.png) +![image](assets/Whiskers_Toy_Quest_3.png) + + +
+ diff --git a/Games/Whiskers_Toy_Quest/__init__.py b/Games/Whiskers_Toy_Quest/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest.png b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest.png new file mode 100644 index 000000000..9ce81e810 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest.png differ diff --git a/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_2.png b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_2.png new file mode 100644 index 000000000..75010e172 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_2.png differ diff --git a/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_3.png b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_3.png new file mode 100644 index 000000000..4dc4158c7 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/Whiskers_Toy_Quest_3.png differ diff --git a/Games/Whiskers_Toy_Quest/assets/__init__.py b/Games/Whiskers_Toy_Quest/assets/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Games/Whiskers_Toy_Quest/assets/bedroom.jpg b/Games/Whiskers_Toy_Quest/assets/bedroom.jpg new file mode 100644 index 000000000..eca636151 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/bedroom.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/eating.jpg b/Games/Whiskers_Toy_Quest/assets/eating.jpg new file mode 100644 index 000000000..cf00b8ae4 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/eating.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/ending.jpg b/Games/Whiskers_Toy_Quest/assets/ending.jpg new file mode 100644 index 000000000..243be12e1 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/ending.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/find_toy.jpg b/Games/Whiskers_Toy_Quest/assets/find_toy.jpg new file mode 100644 index 000000000..caf6756c1 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/find_toy.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/hallway.jpg b/Games/Whiskers_Toy_Quest/assets/hallway.jpg new file mode 100644 index 000000000..0110e3a4f Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/hallway.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/living_room.jpg b/Games/Whiskers_Toy_Quest/assets/living_room.jpg new file mode 100644 index 000000000..3fa2e6b02 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/living_room.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/outside.jpg b/Games/Whiskers_Toy_Quest/assets/outside.jpg new file mode 100644 index 000000000..a3dc62927 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/outside.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/shiny_object.jpg b/Games/Whiskers_Toy_Quest/assets/shiny_object.jpg new file mode 100644 index 000000000..4f451b613 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/shiny_object.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/sitting_on_couch.jpg b/Games/Whiskers_Toy_Quest/assets/sitting_on_couch.jpg new file mode 100644 index 000000000..cc62f55b5 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/sitting_on_couch.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/tree.jpg b/Games/Whiskers_Toy_Quest/assets/tree.jpg new file mode 100644 index 000000000..d0d2796cb Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/tree.jpg differ diff --git a/Games/Whiskers_Toy_Quest/assets/whiskers.jpg b/Games/Whiskers_Toy_Quest/assets/whiskers.jpg new file mode 100644 index 000000000..4ea381a79 Binary files /dev/null and b/Games/Whiskers_Toy_Quest/assets/whiskers.jpg differ diff --git a/Games/Whiskers_Toy_Quest/game.py b/Games/Whiskers_Toy_Quest/game.py new file mode 100644 index 000000000..23c00822e --- /dev/null +++ b/Games/Whiskers_Toy_Quest/game.py @@ -0,0 +1,114 @@ +import customtkinter as ctk +import os +from tkinter import Image +from PIL import Image, ImageTk + +class GameGUI: + def __init__(self, master, game_state, whiskers_choices): + self.master = master + self.master.title("Whiskers Toy Quest") + self.master.geometry("800x600") + + # Save game state and choices + self.game_state = game_state + self.whiskers_choices = whiskers_choices + + # Configure grid layout + self.master.grid_rowconfigure(0, weight=1) + self.master.grid_rowconfigure(1, weight=1) + self.master.grid_columnconfigure(0, weight=1) + self.master.grid_columnconfigure(1, weight=1) + + # Title label + self.title_label = ctk.CTkLabel(self.master, text="Whiskers Toy Quest", + font=ctk.CTkFont(size=24, weight="bold")) + self.title_label.grid(row=0, column=0, columnspan=2, pady=10) + + # Left frame for button and image + self.left_frame = ctk.CTkFrame(self.master) + self.left_frame.grid(row=1, column=0, sticky="nsew", padx=20, pady=20) + + # Story label + self.story_label = ctk.CTkLabel(self.left_frame, text="", wraplength=300, justify="left", + font=ctk.CTkFont(size=14)) + self.story_label.pack() + + self.image_label = ctk.CTkLabel(self.left_frame, text="", width=400, height=300) + self.image_label.pack(pady=20, padx=20) + + # Right frame for story and input + self.right_frame = ctk.CTkScrollableFrame(self.master, width=400, height=500) + self.right_frame.grid(row=1, column=1, sticky="nsew", padx=20, pady=20) + + # Question label + self.question_label = ctk.CTkLabel(self.right_frame, text="", wraplength=300, font=ctk.CTkFont(size=14)) + self.question_label.pack() + + # Input field + self.user_input = ctk.CTkEntry(self.right_frame, placeholder_text="Type your choice here", width=350) + self.user_input.pack(pady=20) + self.user_input.bind("", self.handle_input) + self.user_input.configure(state="disabled") + + # Start the game + self.start_game() + + def get_asset_path(self, filename): + """Get the full path to the asset file.""" + return os.path.join("assets", filename) + + def start_game(self): + """Start the game by displaying the intro story.""" + self.update_stage_description() + self.user_input.configure(state="normal") + + def display_next_char(self, text, callback): + """Display the next character in a given text.""" + if hasattr(self, '_current_text'): # Ensure continuation between calls + current_text = self._current_text + else: + current_text = "" + + if len(current_text) < len(text): # If there are more characters to display + next_char = text[len(current_text)] # Get the next character + self._current_text = current_text + next_char # Append the next character + self.story_label.configure(text=self._current_text) # Update the label + self.master.after(50, lambda: self.display_next_char(text, callback)) # Call the function again + else: + delattr(self, '_current_text') # Remove the attribute + callback() # Call the callback function + + def update_stage_description(self): + """Update the stage description and question.""" + stage_info = self.game_state.get_current_stage_info() + if stage_info: + self.display_next_char(stage_info['scene_desc'], self.enable_input) + self.update_image(stage_info['image']) + self.question_label.configure(text=stage_info['question']) + + def handle_input(self, event): + """Handle the user input.""" + user_input = self.user_input.get().strip() + if user_input: + self.user_input.delete(0, "end") # Clear the input field + if self.game_state.transition_to_next_state(user_input): # Transition to the next state + self.update_stage_description() # Update the stage description + else: + self.story_label.configure(text="Invalid choice. Try again.") # Display an error message + + def enable_input(self): + """Enable the user input field.""" + self.user_input.configure(state="normal") + + def update_image(self, image_path): + """Loads and updates the image in the GUI.""" + img_path = self.get_asset_path(image_path) + try: + img = Image.open(img_path) + img_resized = ctk.CTkImage(img, size=(350, 350)) + self.image_label.configure(image=img_resized, text="") + self.image_label.image = img_resized + except FileNotFoundError: + print(f"Error: Image file not found: {img_path}") + self.image_label.configure(image='', text="Image not found") + self.image_label.image = None \ No newline at end of file diff --git a/Games/Whiskers_Toy_Quest/game_state.py b/Games/Whiskers_Toy_Quest/game_state.py new file mode 100644 index 000000000..2c3e72ab3 --- /dev/null +++ b/Games/Whiskers_Toy_Quest/game_state.py @@ -0,0 +1,17 @@ +class WhiskersGameState: + def __init__(self, whiskers_choices): + self.whiskers_choices = whiskers_choices + self.current_state = 'intro' + + def get_current_stage_info(self): + """Retrieve the current stage's information.""" + return self.whiskers_choices.get_stage_info(self.current_state) + + def transition_to_next_state(self, choice): + """Move to the next state based on the user's choice.""" + current_info = self.whiskers_choices.get_stage_info(self.current_state) + next_states = current_info.get('next_state', {}) + if choice in next_states: + self.current_state = next_states[choice] + return True + return False \ No newline at end of file diff --git a/Games/Whiskers_Toy_Quest/main.py b/Games/Whiskers_Toy_Quest/main.py new file mode 100644 index 000000000..0c91ce923 --- /dev/null +++ b/Games/Whiskers_Toy_Quest/main.py @@ -0,0 +1,16 @@ +import customtkinter as ctk + +from game import GameGUI +from game_state import WhiskersGameState +from whiskers_choices import WhiskersChoices + +if __name__ == "__main__": + root = ctk.CTk() + root.title("Whiskers Toy Quest") + root.geometry("800x600") + + whiskers_choices = WhiskersChoices() # Create an instance of WhiskersChoices + game_state = WhiskersGameState(whiskers_choices) # Create an instance of WhiskersGameState + gui = GameGUI(root, game_state, whiskers_choices) # Create an instance of GameGUI + + root.mainloop() # Start the main event loop \ No newline at end of file diff --git a/Games/Whiskers_Toy_Quest/whiskers_choices.py b/Games/Whiskers_Toy_Quest/whiskers_choices.py new file mode 100644 index 000000000..d21f34ec0 --- /dev/null +++ b/Games/Whiskers_Toy_Quest/whiskers_choices.py @@ -0,0 +1,128 @@ +class WhiskersChoices: + def __init__(self): + self.choices = { # Dictionary of game choices + "intro": { + "image": "living_room.jpg", + "scene_desc": "Whiskers lost his favorite toy and needs your help to find it! Are you ready to embark on a fun adventure?", + "question": "Type 'start' to begin the quest.", + "next_state": {"start": "bedroom"}, + }, + "bedroom": { + "image": "bedroom.jpg", + "scene_desc": "Whiskers just had a nap and dreamed about his lost toy. He woke up and found himself in the bedroom. He decides to look for his toy.", + "question": "You are in Whiskers' bedroom. What would you like to do? Type 'look under the bed' or 'leave the bedroom' and press Enter.", + "next_state": { + "look under the bed": "under_bed", + "leave the bedroom": "hallway" + }, + }, + "under_bed": { + "image": "bedroom.jpg", + "scene_desc": "You found a hidden stash of toys under the bed! But none of them are Whiskers' favorite toy.", + "question": "What would you like to do next? Type 'take toy' or 'leave the bedroom' and press Enter.", + "next_state": {"take toy": "play_with_toy_ending", "leave the bedroom": "hallway"}, + }, + "hallway": { + "image": "hallway.jpg", + "scene_desc": "You are in the hallway. There are several rooms you can explore. But you can also leave the house and go outside.", + "question": "Where would you like to go? Type 'kitchen', 'living room', or 'leave the house and go outside' and press Enter.", + "next_state": {"kitchen": "kitchen", "living room": "living_room", "leave the house and go outside": + "outside"}, + }, + "kitchen": { + "image": "eating.jpg", + "scene_desc": "You are in the kitchen. It smells like food!", + "question": "What would you like to do? Type 'eat' or 'leave the kitchen' and press Enter.", + "next_state": {"eat": "eating", "leave the kitchen": "hallway"}, + }, + "living_room": { + "image": "living_room.jpg", + "scene_desc": "You are in the living room. It's cozy and quiet.", + "question": "What would you like to do? Type 'sit on couch' or 'leave the living room' and press Enter.", + "next_state": {"sit on couch": "sitting_on_couch", "leave the living room": "hallway"}, + }, + "outside": { + "image": "outside.jpg", + "scene_desc": "You are outside the house. The sun is shining, and the birds are chirping. You can explore the garden. Look near the tree or by the pond.", + "question": "What would you like to do? Type 'look near the tree' or 'look by the pond'.", + "next_state": {"look near the tree": "tree", "look by the pond": "pond"}, + }, + "eating": { + "image": "eating.jpg", + "scene_desc": "You are eating food in the kitchen. Yum! But you're so distracted by the food that you forget about the toy. You can continue eating or start over.", + "question": "What would you like to do next? Type 'continue eating' or 'leave the kitchen' and press Enter.", + "next_state": {"continue eating": "eating_ending", "leave the kitchen": "hallway"}, + }, + "tree": { + "image": "tree.jpg", + "scene_desc": "You look near the tree and find a buried pile of leaves. Underneath, there's a strange hole that looks like it might hold something interesting.", + "question": "What would you like to do? Type 'dig' to explore the hole or 'go back' to return outside.", + "next_state": {"dig": "find_toy", "go back": "outside"}, + }, + "pond": { + "image": "shiny_object.jpg", + "scene_desc": "You look by the pond and see some ripples in the water. It seems like something shiny is reflecting sunlight near the edge.", + "question": "What would you like to do? Type 'check shiny object' or 'go back' to return outside.", + "next_state": {"check shiny object": "shiny_object", "go back": "outside"}, + }, + "find_toy": { + "image": "find_toy.jpg", + "scene_desc": "You dig into the hole near the tree and find Whiskers' favorite toy! He purrs happily, his adventure complete.", + "question": "Congratulations! You've found the toy. Would you like to start a new adventure? Type 'yes' or 'no'.", + "next_state": {"yes": "intro", "no": "ending"}, + }, + "shiny_object": { + "image": "shiny_object.jpg", + "scene_desc": "The shiny object turns out to be a small bell. It's not the toy, but it seems important.", + "question": "What would you like to do? Type 'take bell' or 'go back'.", + "next_state": {"take bell": "bell_clue", "go back": "outside"}, + }, + "bell_clue": { + "image": "whiskers.jpg", + "scene_desc": "The bell jingles as you hold it. It reminds Whiskers of something. He runs toward the tree, meowing excitedly.", + "question": "Follow Whiskers? Type 'yes' or 'no'.", + "next_state": {"yes": "find_toy", "no": "outside"}, + }, + "sitting_on_couch": { + "image": "sitting_on_couch.jpg", + "scene_desc": "You sit on the couch, but Whiskers starts to feel sleepy and distracted.", + "question": "Would you like to keep looking for the toy or take a nap? Type 'keep looking' or 'nap'.", + "next_state": {"keep looking": "hallway", "nap": "nap_ending"}, + }, + "play_with_toy_ending": { + "image": "whiskers.jpg", + "scene_desc": "Whiskers plays with another toy, it's not his favorite. Maybe next time he'll " + "find it.", + "question": "The adventure ends here. Would you like to start over? Type 'yes' or 'no'.", + "next_state": {"yes": "intro", "no": "ending"}, + }, + "nap_ending": { + "image": "whiskers.jpg", + "scene_desc": "Whiskers falls asleep on the couch, dreaming again about his toy. Maybe next time he'll find it.", + "question": "The adventure ends here. Would you like to start over? Type 'yes' or 'no'.", + "next_state": {"yes": "intro", "no": "ending"}, + }, + "eating_ending": { + "image": "eating.jpg", + "scene_desc": "You decide to keep eating and forget all about the toy. Maybe you'll look for it another time.", + "question": "Would you like to start the adventure again? Type 'yes' or 'no'.", + "next_state": {"yes": "intro", "no": "ending"}, + }, + "start_over": { + "image": "whiskers.jpg", + "scene_desc": "You decide to start the adventure over from the beginning.", + "question": "Type 'start' to begin again.", + "next_state": {"start": "intro"}, + }, + "ending": { + "image": "ending.jpg", + "scene_desc": "Thank you for helping Whiskers in his adventure! See you next time!", + "question": "", + "next_state": {}, + }, + } + + + def get_stage_info(self, state): + """Returns the information for the given state.""" + return self.choices.get(state, {}) diff --git a/README.md b/README.md index 7c75d9bc0..962036393 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ This repository also provides one such platforms where contributers come over an | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | --- | -| [Master Typing](https://github.com/kunjgit/GameZone/tree/main/Games/Master_Typing) | [Treasure Hunt](https://github.com/Antiquely3059/GameZone/tree/main/Games/Treasure%20Hunt) | [Virtual Pet](https://github.com/Antiquely3059/GameZone/tree/main/Games/Virtual_Pet) | [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | [Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | [Madlibs](https://github.com/AaryanManghnani/GameZone/tree/main/Games/Madlibs) | +| [Whiskers_Toy_Quest](https://github.com/kunjgit/GameZone/tree/main/Games/Whiskers_Toy_Quest) | [Master Typing](https://github.com/kunjgit/GameZone/tree/main/Games/Master_Typing) | [Treasure Hunt](https://github.com/Antiquely3059/GameZone/tree/main/Games/Treasure%20Hunt) | [Virtual Pet](https://github.com/Antiquely3059/GameZone/tree/main/Games/Virtual_Pet) | [MazeRunner](https://github.com/kunjgit/GameZone/tree/main/Games/MazeRunner) | [Ping_Pong_Singleplayer](https://github.com/kunjgit/GameZone/tree/main/Games/Ping_Pong_Singleplayer) | [Madlibs](https://github.com/AaryanManghnani/GameZone/tree/main/Games/Madlibs) | | [Bulls_And_Cows_New](https://github.com/kunjgit/GameZone/tree/main/Games/Bulls_And_Cows_New) | [Find The Number](https://github.com/kunjgit/GameZone/tree/main/Games/Find_the_Number) | [Guess_That_Pokemon](https://github.com/kunjgit/GameZone/tree/main/Games/Guess_That_Pokemon) diff --git a/assets/images/Whiskers_Toy_Quest.png b/assets/images/Whiskers_Toy_Quest.png new file mode 100644 index 000000000..9ce81e810 Binary files /dev/null and b/assets/images/Whiskers_Toy_Quest.png differ