القائمة الرئيسية

الصفحات

كيفية إنشاء لعبة بناء مدن احترافية باستخدام بايثون و Pygame

How to create city-building game in Python Pygame، How to create city-building game in Python Pygame، خاتمة تطوير ألعاب بايثون, Pygame احترافي, تحديات تطوير الألعاب, إمكانيات إبداعية في الألعاب, تجربة مستخدم الألعاب, تحسين أداء الألعاب, استمرار تعلم تطوير الألعاب, مكتبات بايثون للألعاب, أدوات تطوير الألعاب, نجاح ألعاب بايثون، تجربة مستخدم (UX), تصميم ألعاب, إدارة الموارد المتقدمة, أنواع مباني متنوعة, تفاعلات اللاعب, اقتصاد اللعبة, رسومات متقدمة, صوت وموسيقى, مستويات صعوبة, نظام مهام, واجهة مستخدم تفاعلية، نشر ألعاب بايثون, تحويل إلى ملف تنفيذي, PyInstaller, توزيع الألعاب، خريطة, شبكة, خلايا, نقاط بناء, مصفوفة ثنائية الأبعاد, كائنات، UI, عناصر رسومية, أزرار, لوحات, pygame.Surface, pygame.draw.rect(), font.render()، Pygame, تهيئة, pygame.init(), pygame.display.set_mode(), pygame.display.set_caption()، بايثون, Pygame, برمجة ألعاب, بناء مدن, واجهة مستخدم رسومية, إدارة الموارد, تخطيط المدن, حفظ التقدم, نشر الألعاب, تصميم ألعاب احترافي, تجربة مستخدم, تطوير ألعاب بايثون، لعبة بناء المدن، برمجة لعبة بناء المدن، برمجة لعبة بناء المدن باستخدام بايثون، إنشاء لعبة بناء مدن احترافية باستخدام بايثون، مكتبة Pygame، دليلك لإنشاء لعبة بناء مدن احترافية باستخدام بايثون و Pygame، كيفية إنشاء لعبة بناء مدن احترافية باستخدام بايثون و Pygame، بايثون, Pygame, برمجة ألعاب, بناء مدن, UI, عناصر رسومية, برمجة لعبة بناء المدن، مكتبة Pygame،





كيفية إنشاء لعبة بناء مدن احترافية باستخدام بايثون و Pygame



لطالما كانت ألعاب بناء المدن من الأنماط المحبوبة التي تتيح للاعبين التحكم في إنشاء
 وتطوير مستوطناتهم الخاصة. باستخدام قوة بايثون ومرونة مكتبة Pygame، 
يمكنك بناء لعبة بناء مدن جذابة وتفاعلية. يهدف هذا المقال إلى تزويدك بالخطوات الأساسية
لبدء رحلتك في تطوير هذه اللعبة، مع التركيز على جعلها احترافية وقابلة للتوسع.



خطوات إنشاء لعبة بناء مدن احترافية باستخدام بايثون و Pygame 



1. تهيئة Pygame وإنشاء النافذة :





Python

import pygame

# تهيئة Pygame
pygame.init()

# أبعاد النافذة
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))

# عنوان النافذة
pygame.display.set_caption("لعبة بناء المدن")

# حلقة اللعبة الرئيسية
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # تحديث وعرض الشاشة
    pygame.display.flip()

# إنهاء Pygame
pygame.quit()


--

2. تصميم واجهة المستخدم الأساسية :
* (مثال بسيط لرسم لوحة وأزرار):




Python

import pygame

# ... (كود التهيئة السابق) ...

# ألوان
white = (255, 255, 255)
grey = (200, 200, 200)
black = (0, 0, 0)

# أبعاد لوحة الأدوات
toolbar_height = 50
toolbar_rect = pygame.Rect(0, screen_height - toolbar_height, screen_width, toolbar_height)

# أبعاد الأزرار (مثال لزر واحد)
button_width = 100
button_height = 30
button_x = 20
button_y = screen_height - toolbar_height + (toolbar_height - button_height) // 2
build_button_rect = pygame.Rect(button_x, button_y, button_width, button_height)
button_text = "بناء"
font = pygame.font.Font(None, 30)
text_surface = font.render(button_text, True, black)
text_rect = text_surface.get_rect(center=build_button_rect.center)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if build_button_rect.collidepoint(event.pos):
                print("تم الضغط على زر البناء")

    # رسم الخلفية
    screen.fill(white)

    # رسم لوحة الأدوات
    pygame.draw.rect(screen, grey, toolbar_rect)

    # رسم زر البناء
    pygame.draw.rect(screen, white, build_button_rect)
    screen.blit(text_surface, text_rect)

    # تحديث وعرض الشاشة
    pygame.display.flip()

# ... (كود الإنهاء السابق) ...


--

3. تمثيل خريطة المدينة ونقاط البناء:





* (مثال بسيط لتمثيل خريطة كشبكة):

Python

# ... (كود التهيئة والألوان) ...

grid_size = 32  # حجم كل خلية في الخريطة
grid_width = screen_width // grid_size
grid_height = (screen_height - toolbar_height) // grid_size
grid = [[None for _ in range(grid_height)] for _ in range(grid_width)]

def draw_grid():
    for x in range(grid_width):
        for y in range(grid_height):
            rect = pygame.Rect(x * grid_size, y * grid_size, grid_size, grid_size)
            pygame.draw.rect(screen, grey, rect, 1) # رسم خطوط الشبكة

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # زر الفأرة الأيسر
            mouse_x, mouse_y = event.pos
            if mouse_y < screen_height - toolbar_height:
                grid_x = mouse_x // grid_size
                grid_y = mouse_y // grid_size
                if 0 <= grid_x < grid_width and 0 <= grid_y < grid_height:
                    grid[grid_x][grid_y] = "مبنى سكني" # مثال لوضع مبنى
                    print(f"تم وضع مبنى في ({grid_x}, {grid_y})")

    # رسم الخلفية
    screen.fill(white)

    # رسم الشبكة
    draw_grid()

    # رسم المباني الموجودة
    for x in range(grid_width):
        for y in range(grid_height):
            if grid[x][y] is not None:
                rect = pygame.Rect(x * grid_size, y * grid_size, grid_size, grid_size)
                pygame.draw.rect(screen, (0, 128, 0), rect) # لون أخضر للمباني

    # رسم لوحة الأدوات وزر البناء (كما في الخطوة 2)
    pygame.draw.rect(screen, grey, toolbar_rect)
    pygame.draw.rect(screen, white, build_button_rect)
    screen.blit(text_surface, text_rect)

    # تحديث وعرض الشاشة
    pygame.display.flip()

# ... (كود الإنهاء السابق) ...


--

4. حفظ نقاط البناء وتقدم اللعبة :
* (مثال بسيط لحفظ وتحميل حالة الخريطة):





Python

import pygame
import json

# ... (كود التهيئة والألوان وحجم الشبكة) ...

def save_game():
    data = {"grid": grid}
    with open("savegame.json", "w") as f:
        json.dump(data, f)
    print("تم حفظ اللعبة")

def load_game():
    try:
        with open("savegame.json", "r") as f:
            data = json.load(f)
            global grid
            grid = data.get("grid", [[None for _ in range(grid_height)] for _ in range(grid_width)])
        print("تم تحميل اللعبة")
    except FileNotFoundError:
        print("لا يوجد ملف حفظ")

# إضافة زر حفظ وتحميل
save_button_rect = pygame.Rect(button_x + button_width + 20, button_y, button_width, button_height)
save_text_surface = font.render("حفظ", True, black)
save_text_rect = save_text_surface.get_rect(center=save_button_rect.center)

load_button_rect = pygame.Rect(button_x + 2 * (button_width + 20), button_y, button_width, button_height)
load_text_surface = font.render("تحميل", True, black)
load_text_rect = load_text_surface.get_rect(center=load_button_rect.center)

load_game() # تحميل اللعبة عند البدء

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if build_button_rect.collidepoint(event.pos):
                # ... (منطق بناء المباني) ...
            if save_button_rect.collidepoint(event.pos):
                save_game()
            if load_button_rect.collidepoint(event.pos):
                load_game()

    # ... (باقي كود الرسم) ...
    pygame.draw.rect(screen, white, save_button_rect)
    screen.blit(save_text_surface, save_text_rect)
    pygame.draw.rect(screen, white, load_button_rect)
    screen.blit(load_text_surface, load_text_rect)

    pygame.display.flip()

# ... (كود الإنهاء السابق) ...


--

5. نشر اللعبة :




* الخطوات :
* تثبيت PyInstaller : افتح سطر الأوامر أو الطرفية وقم بتشغيل: pip install pyinstaller
* تحويل السكربت إلى ملف تنفيذي : انتقل إلى المجلد الذي يحتوي على ملف بايثون الرئيسي
 للعبتك (مثل main.py) وقم بتشغيل الأمر التالي: pyinstaller --onefile main.py
* تجميع الموارد : قد تحتاج إلى تجميع الموارد الأخرى للعبة مثل الصور والملفات الصوتية. 
يمكنك القيام بذلك باستخدام خيارات إضافية في PyInstaller أو 
عن طريق وضعها في مجلد بجانب الملف التنفيذي.
* اختبار الملف التنفيذي : قم بتشغيل الملف التنفيذي الناتج الموجود في مجلد dist للتأكد
 من أن اللعبة تعمل بشكل صحيح على جهازك.
* التوزيع : يمكنك الآن توزيع المجلد dist الذي يحتوي على الملف التنفيذي للعبتك. 
قد تحتاج إلى إنشاء حزمة تثبيت أكثر احترافية لتوزيع أوسع.

6. جعل اللعبة احترافية - إضافات وميزات متقدمة :
لجعل لعبتك احترافية، يمكنك إضافة الميزات التالية :

* مثال لإضافة فئة بسيطة لتمثيل المباني :




Python

class Building(pygame.sprite.Sprite):
    def __init__(self, image_path, grid_x, grid_y, grid_size):
        super().__init__()
        self.image = pygame.image.load(image_path).convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.topleft = (grid_x * grid_size, grid_y * grid_size)
        self.grid_x = grid_x
        self.grid_y = grid_y

# ... (في حلقة اللعبة عند بناء مبنى) ...
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
    # ...
    if build_button_rect.collidepoint(event.pos):
        building_image_path = "assets/residential.png" # مثال لمسار صورة
        new_building = Building(building_image_path, grid_x, grid_y, grid_size)
        all_sprites.add(new_building)
        grid[grid_x][grid_y] = new_building

# ... (في حلقة الرسم) ...
all_sprites = pygame.sprite.Group() # لادارة جميع الكائنات الرسومية

# ...
for entity in all_sprites:
    screen.blit(entity.image, entity.rect)


--

هذه خطوات متقدمة تتطلب بنية لعب أكثر تعقيدًا، إليك أكواد توضيحية ومفاهيم أساسية لكل خطوة :

1. تصميم مرئي جذاب :
* استخدام رسومات عالية الجودة :
- قم بإنشاء مجلد assets داخل مجلد مشروعك لتخزين الصور.
- حمّل الصور باستخدام 
pygame.image.load("assets/اسم_الصورة.png").convert_alpha()
 للحفاظ على الشفافية.
- استخدم كائنات pygame.sprite.Sprite لعرض وإدارة الكائنات الرسومية :




Python

class Building(pygame.sprite.Sprite):
    def __init__(self, image_path, grid_x, grid_y, grid_size):
        super().__init__()
        self.image = pygame.image.load(image_path).convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.topleft = (grid_x * grid_size, grid_y * grid_size)
        self.grid_x = grid_x
        self.grid_y = grid_y

# ... عند إنشاء مبنى ...
building_image_path = "assets/residential_high_quality.png"
new_residential = Building(building_image_path, grid_x, grid_y, grid_size)
all_sprites.add(new_residential)
grid[grid_x][grid_y] = new_residential

# ... في حلقة الرسم ...
for entity in all_sprites:
    screen.blit(entity.image, entity.rect)

--

* تصميم واجهة مستخدم بديهية وسهلة الاستخدام :
استخدم مكتبات واجهة مستخدم رسومية مثل pygame_gui لإنشاء عناصر
 تفاعلية بسهولة (أزرار، لوحات، إلخ) :




Python

import pygame
import pygame_gui

pygame.init()
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
manager = pygame_gui.UIManager((screen_width, screen_height))
clock = pygame.time.Clock()

build_button = pygame_gui.elements.UIButton(relative_rect=pygame.Rect((10, 10), (100, 30)),
                                            text='بناء',
                                            manager=manager)

running = True
while running:
    time_delta = clock.tick(60)/1000.0
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame_gui.UI_BUTTON_PRESSED:
            if event.ui_element == build_button:
                print('تم الضغط على زر البناء')
        manager.process_events(event)

    screen.fill((255, 255, 255))
    manager.update(time_delta)
    manager.draw_ui(screen)
    pygame.display.flip()

pygame.quit()



--

* رسوم متحركة وتأثيرات بصرية :
- استخدم pygame.transform لتغيير حجم أو تدوير الصور.
- قم بتحديث موضع أو حالة الكائنات بمرور الوقت لإنشاء رسوم متحركة.
- استخدم الشفافية (.set_alpha()) لإنشاء تأثيرات تلاشي :




Python

class AnimatedBuilding(Building):
    def __init__(self, image_paths, grid_x, grid_y, grid_size, animation_speed=5):
        super().__init__(image_paths[0], grid_x, grid_y, grid_size)
        self.frames = [pygame.image.load(path).convert_alpha() for path in image_paths]
        self.current_frame = 0
        self.animation_speed = animation_speed
        self.frame_count = 0

    def update(self):
        self.frame_count += 1
        if self.frame_count >= self.animation_speed:
            self.frame_count = 0
            self.current_frame = (self.current_frame + 1) % len(self.frames)
            self.image = self.frames[self.current_frame]

# ... إنشاء مبنى متحرك ...
animated_building = AnimatedBuilding(["assets/building_frame_1.png", "assets/building_frame_2.png"], 2, 2, grid_size)
all_sprites.add(animated_building)

# ... في حلقة اللعبة ...
all_sprites.update()



--

2. إدارة موارد متقدمة :
- تتبع الموارد : قم بإنشاء قاموس أو كائن لتتبع كميات الموارد المختلفة (الطاقة، المياه، الغذاء، المال) :
Python

resources = {"energy": 100, "water": 50, "food": 200, "money": 500}
def update_resources(delta_energy, delta_water, delta_food, delta_money):
    resources["energy"] += delta_energy
    resources["water"] += delta_water
    resources["food"] += delta_food
    resources["money"] += delta_money
    print(f"الموارد: {resources}")
--

-  ربط توفر الموارد بالبناء والتطوير : تحقق من توفر الموارد قبل السماح للاعب ببناء مبنى أو تطويره :




Python

building_costs = {"residential": {"money": 100, "energy": 5},
                  "commercial": {"money": 150, "water": 10}}

def can_build(building_type):
    costs = building_costs.get(building_type)
    if costs:
        return all(resources[resource] >= cost for resource, cost in costs.items())
    return False

def build_building(building_type, grid_x, grid_y):
    if can_build(building_type):
        costs = building_costs[building_type]
        for resource, cost in costs.items():
            resources[resource] -= cost
        # ... إنشاء كائن المبنى وإضافته إلى الخريطة ...
        print(f"تم بناء {building_type}")
        update_resources(0, 0, 0, 0) # تحديث عرض الموارد
    else:
        print("لا تملك موارد كافية")


--

3. أنواع مباني متنوعة :
استخدم نظام الفئات لتمثيل أنواع المباني المختلفة (سكنية، تجارية، صناعية، خدمات، ترفيهية). 




يمكن أن ترث هذه الفئات من فئة Building الأساسية وتضيف وظائف محددة :




Python

class Residential(Building):
    def __init__(self, grid_x, grid_y, grid_size):
        super().__init__("assets/residential.png", grid_x, grid_y, grid_size)
        self.population_capacity = 10

class Commercial(Building):
    def __init__(self, grid_x, grid_y, grid_size):
        super().__init__("assets/commercial.png", grid_x, grid_y, grid_size)
        self.job_capacity = 5
        self.resource_consumption = {"energy": 2}

    def update(self):
        super().update()
        update_resources(-self.resource_consumption["energy"], 0, 0, 0)

# ... عند بناء مبنى ...
if selected_building_type == "residential":
    new_building = Residential(grid_x, grid_y, grid_size)
elif selected_building_type == "commercial":
    new_building = Commercial(grid_x, grid_y, grid_size)


--

4. تفاعلات اللاعب :
- التفاعل مع المباني : استخدم أحداث الفأرة (pygame.MOUSEBUTTONDOWN)
 لتحديد المباني عند النقر عليها وعرض معلومات أو خيارات تفاعلية (مثل الترقية أو الصيانة) :
Python

def handle_building_interaction(mouse_pos):
    for building in all_sprites:
        if building.rect.collidepoint(mouse_pos):
            print(f"تم النقر على {type(building).__name__} في ({building.grid_x}, {building.grid_y})")
            # عرض قائمة خيارات التفاعل
            show_interaction_menu(building)
            break
def show_interaction_menu(building):
    # ... إنشاء وعرض قائمة بأزرار التفاعل (ترقية، صيانة، إلخ) باستخدام pygame_gui ...
    pass
# ... في حلقة الأحداث ...
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
    handle_building_interaction(event.pos)
--

- التفاعل مع السكان (أكثر تعقيدًا) : يمكن تمثيل السكان ككائنات منفصلة تتفاعل 
مع المباني (يعيشون في المنازل، يعملون في المتاجر، إلخ). 
يتطلب هذا نظام محاكاة أكثر تفصيلاً.

5. اقتصاد اللعبة :
- إنتاج واستهلاك الموارد : اربط إنتاج واستهلاك الموارد بأنواع المباني وعدد السكان. 
على سبيل المثال، تنتج المباني السكنية سكانًا يستهلكون الغذاء والماء، بينما تنتج المصانع الطاقة وتستهلكها :
Python

population = 0

def update_economy():
    global population
    population = sum(1 for building in all_sprites if isinstance(building, Residential))
    food_consumption = population * 0.1 # مثال: كل ساكن يستهلك 0.1 وحدة غذاء في الدورة
    update_resources(0, 0, -food_consumption, 0)

    # ... حساب إنتاج واستهلاك الموارد الأخرى بناءً على أنواع المباني ...

# ... استدعاء update_economy() في كل دورة لعبة ...
--

- الدخل : يمكن أن يأتي الدخل من الضرائب التي يدفعها السكان أو من الأنشطة التجارية :
Python

tax_rate = 0.05

def calculate_income():
    income = population * 1 # مثال: كل ساكن يدفع 1 وحدة مال كضريبة
    commercial_income = sum(5 for building in all_sprites if isinstance(building, Commercial)) # مثال
    update_resources(0, 0, 0, income + commercial_income)
--

6. رسومات متقدمة :
طبقات متعددة للخريطة: قم بإنشاء طبقات منفصلة للخريطة 
(مثل الأرض، الأنهار، الطرق) وارسمها بترتيب معين :




Python

ground_layer = [[0 for _ in range(grid_height)] for _ in range(grid_width)] # 0: عشب, 1: رمل
river_layer = [[None for _ in range(grid_height)] for _ in range(grid_width)]

def draw_map():
    for x in range(grid_width):
        for y in range(grid_height):
            ground_type = ground_layer[x][y]
            if ground_type == 0:
                pygame.draw.rect(screen, (0, 150, 0), (x * grid_size, y * grid_size, grid_size, grid_size))
            elif ground_type == 1:
                pygame.draw.rect(screen, (210, 180, 140), (x * grid_size, y * grid_size, grid_size, grid_size))
            if river_layer[x][y] is not None:
                pygame.draw.rect(screen, (0, 0, 200), (x * grid_size, y * grid_size, grid_size, grid_size))

# ... استدعاء draw_map() في حلقة الرسم قبل رسم المباني ...


--

- تأثيرات إضاءة وظلال: يمكن تحقيق ذلك باستخدام أسطح إضافية ذات شفافية
 أو باستخدام مكتبات إضاءة أكثر تعقيدًا (ليست مدمجة بشكل مباشر في Pygame).
- دعم التكبير والتصغير: قم بتغيير حجم عرض الخريطة وعناصرها بناءً على مستوى التكبير. 
يمكن تحقيق ذلك عن طريق تغيير عامل ضرب لحجم الرسم أو باستخدام طرق 
عرض (pygame.Surface أصغر يتم تكبيره).

7. صوت وموسيقى :
إضافة مؤثرات صوتية: استخدم pygame.mixer.Sound لتحميل وتشغيل المؤثرات الصوتية :
Python

pygame.mixer.init()
build_sound = pygame.mixer.Sound("assets/build_sound.wav")
# ... عند بناء مبنى ...
build_sound.play()
--

- إضافة موسيقى خلفية : استخدم pygame.mixer.music لتحميل وتشغيل الموسيقى :
Python

pygame.mixer.music.load("assets/background_music.mp3")
pygame.mixer.music.play(-1) # -1 للتكرار اللانهائي

8. مستويات صعوبة :
قم بتعيين متغيرات صعوبة تؤثر على قيم مثل معدل توفر الموارد الأولي، وتكاليف البناء،
 وسرعة استهلاك الموارد، وتواتر الأحداث العشوائية :
Python

difficulty = "easy"
if difficulty == "easy":
    initial_money = 1000
    resource_spawn_rate = 1.0
elif difficulty == "hard":
    initial_money = 500
    resource_spawn_rate = 0.5
--

9. نظام مهام :
قم بإنشاء قائمة أو نظام لتتبع المهام والأهداف (مثل "بناء 10 منازل سكنية" أو 
"جمع 5000 وحدة مال"). تحقق من تقدم اللاعب وامنح مكافآت عند إكمال المهام :




Python

tasks = [{"description": "بناء 5 منازل سكنية", "target": 5, "current": 0, "reward": 200},
         {"description": "جمع 1000 وحدة مال", "target": 1000, "current": 0, "reward": 500}]

def check_tasks():
    for task in tasks:
        if task["description"].startswith("بناء منازل سكنية"):
            task["current"] = sum(1 for building in all_sprites if isinstance(building, Residential))
        elif task["description"].startswith("جمع وحدات مال"):
            task["current"] = resources["money"]

        if task["current"] >= task["target"] and not task.get("completed", False):
            print(f"تم إكمال المهمة: {task['description']}, المكافأة: {task['reward']}")
            update_resources(0, 0, 0, task["reward"])
            task["completed"] = True

# ... استدعاء check_tasks() في كل دورة لعبة ...


--

10. واجهة مستخدم تفاعلية :
- نوافذ منبثقة: استخدم pygame_gui لإنشاء نوافذ لعرض المعلومات أو طلب تأكيد الإجراءات.
- قوائم سياقية: اعرض قوائم عند النقر بزر الفأرة الأيمن على العناصر.
- معلومات عند التحويم: استخدم حدث pygame.MOUSEMOTION 
للتحقق مما إذا كان الفأرة فوق عنصر ما وعرض معلومات تفصيلية :




Python

hovered_building = None

def check_hover(mouse_pos):
    global hovered_building
    hovered_building = None
    for building in all_sprites:
        if building.rect.collidepoint(mouse_pos):
            hovered_building = building
            break

def draw_hover_info():
    if hovered_building:
        font = pygame.font.Font(None, 20)
        text_surface = font.render(f"{type(hovered_building).__name__} ({hovered_building.grid_x}, {hovered_building.grid_y})", True, (0, 0, 0))
        screen.blit(text_surface, (mouse_pos[0] + 10, mouse_pos[1] + 10))

# ... في حلقة الأحداث ...
if event.type == pygame.MOUSEMOTION:
    mouse_pos = event.pos
    check_hover(mouse_pos)

# ... في حلقة الرسم ...
draw_hover_info()


--

11. نظام حدث عشوائي :
استخدم وحدة random لإنشاء أحداث عشوائية بناءً على احتمالية معينة في كل دورة لعبة.
 يمكن أن تكون هذه الأحداث إيجابية (زيادة الموارد) أو سلبية (كارثة طبيعية) :




Python

import random

def trigger_random_event():
    if random.random() < 0.01: # احتمالية 1% لحدوث حدث في كل دورة
        event_type = random.choice(["resource_boost", "minor_disaster"])
        if event_type == "resource_boost":
            boost_amount = random.randint(50, 100)
            resource_type = random.choice(["money", "food"])
            resources[resource_type] += boost_amount
            print(f"حدث عشوائي: زيادة في {resource_type} بمقدار {boost_amount}!")
            # عرض رسالة على الشاشة
        elif event_type == "minor_disaster":
            disaster_type = random.choice(["power_outage", "water_shortage"])
            duration = random.randint(5, 15)  # مدة الحدث بالدورات
            global active_disaster
            active_disaster = {"type": disaster_type, "duration": duration}
            print(f"حدث عشوائي: {disaster_type} لمدة {duration} دورة!")
            # تعطيل بعض وظائف المدينة أو فرض عقوبات

active_disaster = None

def handle_disasters():
    global active_disaster
    if active_disaster:
        print(f"كارثة نشطة: {active_disaster['type']}, المدة المتبقية: {active_disaster['duration']}")
        active_disaster['duration'] -= 1
        if active_disaster['duration'] <= 0:
            active_disaster = None
            print("انتهت الكارثة")
        # تطبيق تأثيرات الكارثة (مثل تقليل إنتاج الطاقة أو المياه)

# ... في حلقة اللعبة الرئيسية ...
while running:
    # ... معالجة الأحداث ...

    trigger_random_event()
    handle_disasters()
    update_economy()
    check_tasks()

    # ... رسم العناصر ...

    pygame.display.flip()

# ... إنهاء Pygame ...


--

12. تحسين الأداء 
- Batching للرسومات : إذا كنت ترسم عددًا كبيرًا من الكائنات المتشابهة
 (مثل بلاط الأرضية)، ففكر في تجميعها في سطح واحد ورسم هذا السطح مرة واحدة
 بدلاً من رسم كل كائن على حدة. يمكن استخدام pygame.Surface
 لرسم عدة كائنات عليها ثم عرض السطح :
Python

ground_surface = pygame.Surface((grid_width * grid_size, grid_height * grid_size))
for x in range(grid_width):
    for y in range(grid_height):
        ground_type = ground_layer[x][y]
        color = (0, 150, 0) if ground_type == 0 else (210, 180, 140)
        pygame.draw.rect(ground_surface, color, (x * grid_size, y * grid_size, grid_size, grid_size))

# ... في حلقة الرسم ...
screen.blit(ground_surface, (0, 0))
# ثم رسم الطبقات الأخرى والمباني فوقها
--

- تقليل العمليات غير الضرورية: تجنب إجراء عمليات حسابية أو رسم أشياء غير مرئية أو لم تتغير. 
قم بتحديث الشاشة فقط عند الحاجة.
- استخدام Sprites و Groups بكفاءة: توفر pygame.sprite.Group طرقًا محسّنة
 للتعامل مع مجموعات كبيرة من الكائنات (مثل تحديث ورسم المجموعة بأكملها مرة واحدة).
- التحسين المكاني: إذا كان لديك عدد كبير جدًا من الكائنات، ففكر في استخدام
 هياكل بيانات مكانية (مثل Quadtrees) لتسريع عمليات البحث عن الكائنات القريبة.
- تقليل حجم الصور: استخدم صورًا بحجم مناسب وقم بتحسينها لتقليل استهلاك الذاكرة ووقت التحميل.

هذه الأكواد والنقاط توفر أساسًا قويًا لتطوير لعبة بناء مدن احترافية باستخدام بايثون و Pygame. 
تذكر أن التطوير المستمر والتجريب هما مفتاح إضافة المزيد من العمق والجاذبية إلى لعبتك. حظًا موفقًا!

الخاتمة :

رحلة بناء لعبة مدينة باستخدام بايثون و Pygame مليئة بالتحديات والإمكانيات الإبداعية. 
من خلال البدء بالأساسيات وتوسيع نطاق مشروعك تدريجيًا ليشمل الرسومات الجذابة،
 وإدارة الموارد المعقدة، وأنواع المباني المتنوعة، وتفاعلات اللاعب، والاقتصاد الديناميكي، 
والميزات المتقدمة الأخرى مثل الصوت والموسيقى والمهام والأحداث العشوائية، 
يمكنك إنشاء تجربة لعب غامرة وممتعة. تذكر أن التحسين المستمر للأداء والتركيز 
على تجربة المستخدم البديهية هما أساس بناء لعبة ناجحة واحترافية. استمر في التعلم والتجريب،
 ولا تتردد في استكشاف المزيد من مكتبات وأدوات بايثون لرفع مستوى لعبتك.
بناء لعبة بناء مدن باستخدام بايثون و Pygame هو مشروع طموح ولكنه مجزٍ للغاية. 
باتباع هذه الخطوات الأساسية وتوسيعها بالميزات المتقدمة، يمكنك إنشاء لعبة جذابة وممتعة.
 تذكر أن التصميم الجيد، والتجربة الممتعة للمستخدم، والتطوير المستمر هي مفاتيح النجاح. 
حظًا موفقًا في بناء مدينتك الرقمية!



جدول المحتويات