معرفی
Cosmic Egg Catcher یک بازی جذاب و رنگارنگ است که در آن بازیکن باید
تخممرغهای کیهانی در حال سقوط را با استفاده از یک جمعکننده کنترل شده
توسط کلیدهای کیبورد، جمعآوری کند. این پروژه از کتابخانه
tkinter برای ایجاد رابط گرافیکی استفاده میکند و دارای
ویژگیهای پیشرفتهای مانند سیستم کامبو، افکتهای ذرهای، انیمیشنهای پویا
و تمهای رنگی متنوع است.
نصب و پیشنیازها
برای اجرای این پروژه نیاز به پایتون نسخه 3.6 یا بالاتر دارید. کتابخانههای مورد نیاز به صورت پیشفرض در پایتون موجود هستند:
tkinter- برای رابط گرافیکیitertools- برای چرخه رنگهاrandom- برای ایجاد اعداد تصادفیmath- برای محاسبات ریاضیtime- برای مدیریت زمان
معماری پروژه
کلاس اصلی بازی CosmicEggCatcher شامل بخشهای زیر است:
- مدیریت پنجره و کانواس
- سیستم تمهای رنگی پویا
- مدیریت وضعیت بازی (امتیاز، جانها، کامبو)
- سیستم فیزیک و تشخیص برخورد
- انیمیشنها و افکتهای بصری
- کنترلهای بازیکن
کدنویسی پروژه
کد کامل پروژه
from itertools import cycle
from random import randrange, choice, uniform
import tkinter as tk
from tkinter import messagebox
import math
import time
class CosmicEggCatcher:
def __init__(self):
# Game setup variables
self.canvas_width = 900
self.canvas_height = 600
# Enhanced Color themes with gradients
self.themes = {
"Aurora Sky": {
"sky": "#667eea",
"ground": "#2E8B57",
"sun": "#FFD700",
"text": "#FFFFFF",
"catcher": "#FF6B6B",
"cloud": "#FFFFFF",
"particle": ["#FF6B6B", "#4ECDC4", "#45B7D1"]
},
"Sunset Dream": {
"sky": "#ff7e5f",
"ground": "#8B4513",
"sun": "#FF4500",
"text": "#FFFFFF",
"catcher": "#FF8C00",
"cloud": "#FFA07A",
"particle": ["#FF8C00", "#FF6347", "#FFD700"]
},
"Midnight Magic": {
"sky": "#0f0c29",
"ground": "#34495E",
"sun": "#F1C40F",
"text": "#ECF0F1",
"catcher": "#9B59B6",
"cloud": "#BDC3C7",
"particle": ["#9B59B6", "#3498DB", "#1ABC9C"]
},
"Forest Whisper": {
"sky": "#74b9ff",
"ground": "#00b894",
"sun": "#FFEAA7",
"text": "#2D3436",
"catcher": "#00b894",
"cloud": "#DFE6E9",
"particle": ["#00b894", "#55EFC4", "#81ECEC"]
}
}
self.current_theme = "Aurora Sky"
# Enhanced egg colors
self.egg_colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
self.color_cycle = cycle(self.egg_colors)
# Game design variables
self.egg_width = 50
self.egg_height = 60
self.egg_score = 10
self.egg_speed = 500
self.egg_interval = 3500
self.difficulty_factor = 0.95
# Catcher setup
self.catcher_width = 120
self.catcher_height = 80
# Game state
self.score = 0
self.lives_remaining = 3
self.eggs = []
self.particles = []
self.combo = 0
self.last_catch_time = 0
# Animation variables
self.catcher_glow = 0
self.sun_pulse = 0
self.cloud_offset = 0
self.setup_gui()
self.setup_game()
def setup_gui(self):
# Initialize the main window
self.win = tk.Tk()
self.win.title("✨ Cosmic Egg Catcher ✨")
self.win.configure(bg='#0f0c29')
self.win.resizable(False, False)
# Center the window
screen_width = self.win.winfo_screenwidth()
screen_height = self.win.winfo_screenheight()
x = (screen_width - self.canvas_width) // 2
y = (screen_height - self.canvas_height) // 2 - 50
self.win.geometry(f"{self.canvas_width}x{self.canvas_height}+{x}+{y}")
# Create canvas with current theme
theme = self.themes[self.current_theme]
self.c = tk.Canvas(self.win, width=self.canvas_width, height=self.canvas_height,
background=theme["sky"], highlightthickness=0)
self.c.pack()
# Enhanced control panel
self.setup_control_panel()
def draw_background(self):
theme = self.themes[self.current_theme]
# Clear only background elements, keep game objects
self.c.delete("bg")
# Ground
self.c.create_rectangle(-5, self.canvas_height - 100, self.canvas_width + 5,
self.canvas_height + 5, fill=theme["ground"], width=0, tags="bg")
# Sun with simple animation
sun_size = 40 + math.sin(self.sun_pulse) * 5
self.c.create_oval(50 - sun_size, 50 - sun_size, 50 + sun_size, 50 + sun_size,
fill=theme["sun"], outline="", tags="bg")
# Clouds
self.draw_animated_clouds(theme["cloud"])
# Add grass details
for i in range(0, self.canvas_width, 15):
height = randrange(5, 12)
self.c.create_rectangle(i, self.canvas_height - 100, i + 8,
self.canvas_height - 100 - height,
fill="#228B22", outline="", tags="bg")
def draw_animated_clouds(self, color):
cloud_positions = [
(150 + self.cloud_offset, 80),
(400 + self.cloud_offset * 0.7, 120),
(650 + self.cloud_offset * 0.5, 70)
]
for x, y in cloud_positions:
self.draw_cloud(x % (self.canvas_width + 200) - 100, y, color)
def draw_cloud(self, x, y, color):
# Simple cloud with multiple circles
circles = [
(x, y, 20), (x + 15, y - 8, 16), (x + 30, y, 20),
(x + 12, y + 8, 14), (x + 25, y + 4, 16)
]
for cx, cy, radius in circles:
self.c.create_oval(cx - radius, cy - radius, cx + radius, cy + radius,
fill=color, outline="", tags="bg")
def setup_control_panel(self):
control_frame = tk.Frame(self.win, bg='#0f0c29', bd=0)
control_frame.pack(pady=10)
# Theme selector
tk.Label(control_frame, text="🎨 Theme:", fg='white', bg='#0f0c29',
font=('Arial', 11, 'bold')).pack(side=tk.LEFT, padx=5)
self.theme_var = tk.StringVar(value=self.current_theme)
theme_menu = tk.OptionMenu(control_frame, self.theme_var, *self.themes.keys(), command=self.change_theme)
theme_menu.config(bg='#667eea', fg='white', font=('Arial', 10, 'bold'),
relief='flat', bd=0, padx=10, pady=5)
theme_menu.pack(side=tk.LEFT, padx=5)
# Restart button
restart_btn = tk.Button(control_frame, text="🔄 Restart", command=self.reset_game,
bg='#FF6B6B', fg='white', font=('Arial', 11, 'bold'),
relief='flat', bd=0, padx=15, pady=6)
restart_btn.pack(side=tk.LEFT, padx=10)
# Combo display
self.combo_label = tk.Label(control_frame, text="Combo: 0x", fg='#FFD700', bg='#0f0c29',
font=('Arial', 11, 'bold'))
self.combo_label.pack(side=tk.LEFT, padx=10)
def change_theme(self, theme_name):
self.current_theme = theme_name
theme = self.themes[theme_name]
self.c.config(bg=theme["sky"])
self.draw_background()
if hasattr(self, 'catcher'):
self.c.itemconfig(self.catcher, outline=theme["catcher"])
if hasattr(self, 'score_text'):
self.c.itemconfig(self.score_text, fill=theme["text"])
self.c.itemconfig(self.lives_text, fill=theme["text"])
def setup_game(self):
theme = self.themes[self.current_theme]
# Draw background first
self.draw_background()
# Create catcher
catcher_start_x = self.canvas_width / 2 - self.catcher_width / 2
catcher_start_y = self.canvas_height - self.catcher_height - 80
catcher_start_x2 = catcher_start_x + self.catcher_width
catcher_start_y2 = catcher_start_y + self.catcher_height
self.catcher = self.c.create_arc(catcher_start_x, catcher_start_y,
catcher_start_x2, catcher_start_y2,
start=200, extent=140, style='arc',
outline=theme["catcher"], width=6, tags="game")
# Score and lives display
self.score_text = self.c.create_text(20, 20, anchor='nw',
font=('Arial', 18, 'bold'),
fill=theme["text"],
text='🌟 Score: 0', tags="game")
self.lives_text = self.c.create_text(self.canvas_width - 20, 20, anchor='ne',
font=('Arial', 18, 'bold'),
fill=theme["text"],
text='💖 Lives: 3', tags="game")
# Game title
self.c.create_text(self.canvas_width // 2, 30, anchor='n',
font=('Arial', 20, 'bold'),
fill=theme["text"],
text='✨ COSMIC EGG CATCHER ✨', tags="game")
# Instructions
self.c.create_text(self.canvas_width // 2, self.canvas_height - 30, anchor='n',
font=('Arial', 12),
fill=theme["text"],
text='Use ← → or A D keys to move • Catch the falling eggs!', tags="game")
# Bind controls
self.win.bind('<Left>', self.move_left)
self.win.bind('<Right>', self.move_right)
self.win.bind('<a>', self.move_left)
self.win.bind('<d>', self.move_right)
self.c.focus_set()
# Start game loops
self.start_game_loops()
def start_game_loops(self):
self.win.after(1000, self.create_eggs)
self.win.after(1000, self.move_eggs)
self.win.after(1000, self.catch_check)
self.win.after(50, self.update_particles)
self.win.after(50, self.update_animations)
def create_eggs(self):
if self.lives_remaining > 0: # Only create eggs if game is active
x = randrange(20, self.canvas_width - self.egg_width - 20)
y = 60
# Create egg with simple design
egg_color = next(self.color_cycle)
new_egg = self.c.create_oval(x, y, x + self.egg_width, y + self.egg_height,
fill=egg_color, width=0, tags="egg")
# Add simple shine
shine = self.c.create_oval(x + 10, y + 10, x + 20, y + 20, fill='white', width=0, tags="egg")
self.eggs.append({"egg": new_egg, "shine": shine})
self.win.after(self.egg_interval, self.create_eggs)
def move_eggs(self):
if self.lives_remaining > 0: # Only move eggs if game is active
for egg_data in self.eggs[:]:
egg = egg_data["egg"]
shine = egg_data["shine"]
self.c.move(egg, 0, 8)
self.c.move(shine, 0, 8)
egg_coords = self.c.coords(egg)
if egg_coords and egg_coords[3] > self.canvas_height:
self.egg_dropped(egg_data)
self.win.after(self.egg_speed, self.move_eggs)
def egg_dropped(self, egg_data):
if egg_data in self.eggs: # Check if egg still exists
self.eggs.remove(egg_data)
self.c.delete(egg_data["egg"])
self.c.delete(egg_data["shine"])
self.lose_a_life()
self.combo = 0
self.combo_label.config(text=f"Combo: {self.combo}x")
def lose_a_life(self):
self.lives_remaining -= 1
self.c.itemconfig(self.lives_text, text=f'💖 Lives: {self.lives_remaining}')
if self.lives_remaining <= 0:
self.win.after(500, self.game_over)
else:
# Visual feedback
original_bg = self.themes[self.current_theme]["sky"]
self.c.config(bg='#FF6B6B')
self.win.after(100, lambda: self.c.config(bg=original_bg))
def game_over(self):
# Create explosion effect for remaining eggs
for egg_data in self.eggs[:]:
self.create_explosion(egg_data)
self.eggs.remove(egg_data)
# Show game over dialog
self.show_game_over_dialog()
def show_game_over_dialog(self):
response = messagebox.askyesno(
'🎮 GAME OVER! ✨',
f'🌟 Final Score: {self.score}\n🔥 Max Combo: {self.combo}x\n\nDo you want to play again?'
)
if response:
self.reset_game()
else:
self.win.quit()
def create_explosion(self, egg_data, particle_count=6):
egg_coords = self.c.coords(egg_data["egg"])
if not egg_coords:
return
egg_x, egg_y, egg_x2, egg_y2 = egg_coords
center_x = (egg_x + egg_x2) / 2
center_y = (egg_y + egg_y2) / 2
theme = self.themes[self.current_theme]
for _ in range(particle_count):
angle = randrange(0, 360)
speed = uniform(2, 6)
size = randrange(3, 6)
color = choice(theme["particle"])
life = randrange(20, 30)
particle = {
"x": center_x, "y": center_y,
"dx": math.cos(math.radians(angle)) * speed,
"dy": math.sin(math.radians(angle)) * speed,
"size": size,
"color": color,
"life": life,
"max_life": life
}
self.particles.append(particle)
# Remove egg
self.c.delete(egg_data["egg"])
self.c.delete(egg_data["shine"])
def update_particles(self):
particles_to_remove = []
for particle in self.particles:
particle["x"] += particle["dx"]
particle["y"] += particle["dy"]
particle["life"] -= 1
if particle["life"] <= 0:
particles_to_remove.append(particle)
continue
# Draw particle
x, y = particle["x"], particle["y"]
size = particle["size"]
self.c.create_oval(x, y, x + size, y + size,
fill=particle["color"], outline="", tags="particle")
# Remove dead particles
for particle in particles_to_remove:
self.particles.remove(particle)
self.c.delete("particle")
self.win.after(30, self.update_particles)
def update_animations(self):
# Update sun pulse
self.sun_pulse += 0.1
# Update cloud movement
self.cloud_offset += 0.5
if self.cloud_offset > self.canvas_width + 200:
self.cloud_offset = 0
# Redraw background for animations
self.draw_background()
# Bring game objects to front
self.c.tag_raise("game")
self.c.tag_raise("egg")
self.c.tag_raise("particle")
self.win.after(50, self.update_animations)
def catch_check(self):
if self.lives_remaining > 0: # Only check catches if game is active
catcher_coords = self.c.coords(self.catcher)
if not catcher_coords:
self.win.after(50, self.catch_check)
return
catcher_x, catcher_y, catcher_x2, catcher_y2 = catcher_coords
current_time = time.time()
for egg_data in self.eggs[:]:
egg = egg_data["egg"]
egg_coords = self.c.coords(egg)
if not egg_coords:
continue
egg_x, egg_y, egg_x2, egg_y2 = egg_coords
# Simple collision detection
if (catcher_x < egg_x and egg_x2 < catcher_x2 and
catcher_y2 - egg_y2 < 50):
# Remove egg from list and canvas
if egg_data in self.eggs:
self.eggs.remove(egg_data)
self.c.delete(egg_data["egg"])
self.c.delete(egg_data["shine"])
# Combo system
if current_time - self.last_catch_time < 2.0:
self.combo += 1
else:
self.combo = 1
self.last_catch_time = current_time
self.combo_label.config(text=f"Combo: {self.combo}x")
# Score with combo multiplier
points = self.egg_score * self.combo
self.create_explosion(egg_data, 8)
self.increase_score(points)
# Visual feedback
theme = self.themes[self.current_theme]
original_color = theme["catcher"]
self.c.itemconfig(self.catcher, outline="#00FF00")
self.win.after(100, lambda: self.c.itemconfig(self.catcher, outline=original_color))
self.win.after(50, self.catch_check)
def increase_score(self, points):
self.score += points
# Increase difficulty gradually
self.egg_speed = max(200, int(self.egg_speed * self.difficulty_factor))
self.egg_interval = max(1500, int(self.egg_interval * self.difficulty_factor))
self.c.itemconfig(self.score_text, text=f'🌟 Score: {self.score}')
def move_left(self, event):
if hasattr(self, 'catcher'):
catcher_coords = self.c.coords(self.catcher)
if catcher_coords:
x1, y1, x2, y2 = catcher_coords
if x1 > 30:
self.c.move(self.catcher, -25, 0)
def move_right(self, event):
if hasattr(self, 'catcher'):
catcher_coords = self.c.coords(self.catcher)
if catcher_coords:
x1, y1, x2, y2 = catcher_coords
if x2 < self.canvas_width - 30:
self.c.move(self.catcher, 25, 0)
def reset_game(self):
# Clear all game objects
self.c.delete("egg")
self.c.delete("particle")
self.eggs = []
self.particles = []
# Reset game state
self.score = 0
self.lives_remaining = 3
self.combo = 0
self.egg_speed = 500
self.egg_interval = 3500
# Update displays
self.c.itemconfig(self.score_text, text='🌟 Score: 0')
self.c.itemconfig(self.lives_text, text='💖 Lives: 3')
self.combo_label.config(text="Combo: 0x")
# Restart game loops
self.start_game_loops()
def run(self):
self.win.mainloop()
# Start the game
if __name__ == "__main__":
game = CosmicEggCatcher()
game.run()
کلاس اصلی و متغیرهای بازی
کلاس CosmicEggCatcher شامل تمامی متغیرهای مورد نیاز برای مدیریت بازی است:
class CosmicEggCatcher:
def __init__(self):
self.canvas_width = 900
self.canvas_height = 600
self.egg_width = 50
self.egg_height = 60
self.score = 0
self.lives_remaining = 3
self.eggs = []
self.particles = []
self.combo = 0
سیستم تمهای رنگی
این بازی از چندین تم رنگی پشتیبانی میکند که به صورت داینامیک قابل تغییر هستند:
self.themes = {
"Aurora Sky": {
"sky": "#667eea",
"ground": "#2E8B57",
"sun": "#FFD700",
"text": "#FFFFFF",
"catcher": "#FF6B6B",
"cloud": "#FFFFFF",
"particle": ["#FF6B6B", "#4ECDC4", "#45B7D1"]
},
"Sunset Dream": {
"sky": "#ff7e5f",
"ground": "#8B4513",
"sun": "#FF4500",
"text": "#FFFFFF",
"catcher": "#FF8C00",
"cloud": "#FFA07A",
"particle": ["#FF8C00", "#FF6347", "#FFD700"]
}
}
ایجاد تخممرغها
تخممرغها به صورت تصادفی در موقعیتهای مختلف ایجاد میشوند:
def create_eggs(self):
if self.lives_remaining > 0:
x = randrange(20, self.canvas_width - self.egg_width - 20)
y = 60
egg_color = next(self.color_cycle)
new_egg = self.c.create_oval(x, y, x + self.egg_width, y + self.egg_height,
fill=egg_color, width=0, tags="egg")
shine = self.c.create_oval(x + 10, y + 10, x + 20, y + 20,
fill='white', width=0, tags="egg")
self.eggs.append({"egg": new_egg, "shine": shine})
self.win.after(self.egg_interval, self.create_eggs)
سیستم کامبو و امتیازدهی
بازیکن با گرفتن تخممرغها در زمان کوتاه، کامبو میگیرد و امتیاز بیشتری دریافت میکند:
def catch_check(self):
catcher_coords = self.c.coords(self.catcher)
current_time = time.time()
for egg_data in self.eggs[:]:
egg_coords = self.c.coords(egg_data["egg"])
if (catcher_x < egg_x and egg_x2 < catcher_x2 and
catcher_y2 - egg_y2 < 50):
if current_time - self.last_catch_time < 2.0:
self.combo += 1
else:
self.combo = 1
self.last_catch_time = current_time
points = self.egg_score * self.combo
self.increase_score(points)
انیمیشنها و افکتهای بصری
افکتهای ذرهای
هنگام گرفتن تخممرغ یا پایان بازی، افکتهای ذرهای زیبا نمایش داده میشود:
def create_explosion(self, egg_data, particle_count=6):
egg_coords = self.c.coords(egg_data["egg"])
center_x = (egg_coords[0] + egg_coords[2]) / 2
center_y = (egg_coords[1] + egg_coords[3]) / 2
theme = self.themes[self.current_theme]
for _ in range(particle_count):
angle = randrange(0, 360)
speed = uniform(2, 6)
size = randrange(3, 6)
color = choice(theme["particle"])
life = randrange(20, 30)
particle = {
"x": center_x, "y": center_y,
"dx": math.cos(math.radians(angle)) * speed,
"dy": math.sin(math.radians(angle)) * speed,
"size": size,
"color": color,
"life": life,
"max_life": life
}
self.particles.append(particle)
انیمیشنهای محیطی
خورشید پالس میزند و ابرها به آرامی در حرکت هستند:
def update_animations(self):
self.sun_pulse += 0.1
self.cloud_offset += 0.5
if self.cloud_offset > self.canvas_width + 200:
self.cloud_offset = 0
self.draw_background()
self.c.tag_raise("game")
self.c.tag_raise("egg")
self.c.tag_raise("particle")
self.win.after(50, self.update_animations)
کنترلهای بازی
بازیکن میتواند از دو روش برای کنترل جمعکننده استفاده کند:
- کلیدهای جهتدار چپ و راست (← →)
- کلیدهای A و D
def move_left(self, event):
if hasattr(self, 'catcher'):
catcher_coords = self.c.coords(self.catcher)
if catcher_coords:
x1, y1, x2, y2 = catcher_coords
if x1 > 30:
self.c.move(self.catcher, -25, 0)
def move_right(self, event):
if hasattr(self, 'catcher'):
catcher_coords = self.c.coords(self.catcher)
if catcher_coords:
x1, y1, x2, y2 = catcher_coords
if x2 < self.canvas_width - 30:
self.c.move(self.catcher, 25, 0)
نحوه اجرا
برای اجرای بازی کافی است فایل پایتون را اجرا کنید:
python cosmic_egg_catcher.py
یا از بخش اصلی برنامه در انتهای فایل استفاده کنید:
if __name__ == "__main__":
game = CosmicEggCatcher()
game.run()
توسعه و بهبود
ایدههایی برای توسعه بیشتر بازی:
- افزودن قدرتهای ویژه (Power-ups)
- ایجاد مراحل مختلف با سختی progressive
- ذخیره امتیازهای بالا (High Score)
- افزودن صدا و موسیقی متن
- ایجاد تخممرغهای خاص با امتیازهای متفاوت
منابع و مستندات
منبع اصلی کد گرفته شده
منبع :
https://docs.python.org/3/library/tkinter.html
منبع :
https://docs.python.org/3/tutorial/