পাইথন প্রজেক্টস ও লাইব্রেরি

৪০. স্ক্র্যাচ থেকে থ্রিডি গেম ইঞ্জিন (3D Game Engine)

গ্রাফিক্স প্রোগ্রামিং বা গেম ডেভেলপমেন্টের দুনিয়াটা খুবই চমৎকার! ইউনিটি (Unity) বা আনরিয়েল ইঞ্জিন (Unreal Engine) এর মতো বড় বড় গেম ইঞ্জিনগুলো আসলে কীভাবে কাজ করে? তার পেছনের মূল লজিকটি বোঝার জন্য এই প্রজেক্টটি দারুণ।

এই প্রজেক্টে আমরা অন্য কোনো গেম ইঞ্জিন ব্যবহার না করে, পাইথনের PyOpenGL লাইব্রেরি দিয়ে একেবারে স্ক্র্যাচ থেকে একটি থ্রিডি (3D) এনভায়রনমেন্ট তৈরি করবো এবং সেখানে একটি থ্রিডি কিউব বা বক্সকে রেন্ডার করে অ্যানিমেট করবো।

কীভাবে কাজ করে? (How it works):

  1. Window Management: প্রথমে Pygame ব্যবহার করে একটি উইন্ডো বা স্ক্রিন ওপেন করা হবে, যেখানে আমাদের গেমটি চলবে।
  2. 3D Projection: OpenGL.GLU ব্যবহার করে স্ক্রিনটিকে 3D পার্সপেক্টিভে (Perspective) সেট করা হবে, যাতে দূর থেকে দেখলে জিনিস ছোট এবং কাছে থেকে দেখলে বড় মনে হয় (যাকে Field of View বলে)।
  3. Vertices and Edges: একটি থ্রিডি বক্স তৈরি করার জন্য বক্সটির ৮টি কোণা (Vertices) এবং ১২টি লাইন (Edges) গাণিতিকভাবে ডিফাইন করতে হবে।
  4. Rendering Loop: গেমের মেইন লুপের (Main Loop) ভেতরে বক্সটিকে একটু একটু করে ঘুরিয়ে স্ক্রিনে ড্র (Draw) করা হবে, ফলে এটি একটি 3D অ্যানিমেশনের রূপ নিবে।

প্রয়োজনীয় লাইব্রেরি (Libraries):

টার্মিনালে নিচের কমান্ডটি লিখে লাইব্রেরিগুলো ইনস্টল করে নিন:

pip install pygame PyOpenGL PyOpenGL_accelerate

প্রজেক্টের কোড:

নিচের কোডটি কপি করে রান করুন। আপনার স্ক্রিনে একটি চমৎকার থ্রিডি কিউব ভাসতে এবং ঘুরতে দেখবেন!

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

# থ্রিডি কিউব বা বক্সের ৮টি কোণা (Coordinates: x, y, z)
vertices = (
    (1, -1, -1),
    (1, 1, -1),
    (-1, 1, -1),
    (-1, -1, -1),
    (1, -1, 1),
    (1, 1, 1),
    (-1, -1, 1),
    (-1, 1, 1)
)

# কিউবের ১২টি লাইন (কোন কোণার সাথে কোন কোণা যুক্ত হবে)
edges = (
    (0,1), (0,3), (0,4), (2,1),
    (2,3), (2,7), (6,3), (6,4),
    (6,7), (5,1), (5,4), (5,7)
)

def draw_cube():
    """বক্সটি ড্র করার ফাংশন"""
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(vertices[vertex])
    glEnd()

def game_engine():
    print("Starting Custom 3D Engine...")
    
    # Pygame উইন্ডো চালু করা
    pygame.init()
    display = (800, 600)
    
    # উইন্ডোটিকে OpenGL মোডে সেট করা
    pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
    pygame.display.set_caption("My First 3D Game Engine")
    
    # 3D পার্সপেক্টিভ সেটআপ (Field of View 45, Aspect Ratio, Near/Far clipping)
    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
    
    # ক্যামেরা বা ভিউকে কিছুটা পেছনে (z-axis বরাবর -5 এ) নিয়ে যাওয়া
    glTranslatef(0.0, 0.0, -5)

    # গেমের মেইন লুপ
    while True:
        # ইভেন্ট চেকিং (ক্রস বাটনে ক্লিক করলে বন্ধ হবে)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return

        # বক্সটিকে X এবং Y অক্ষ বরাবর একটু একটু করে ঘোরানো
        glRotatef(1, 3, 1, 1)
        
        # স্ক্রিনের আগের ড্রয়িং ক্লিয়ার করা (যাতে কালার ওভারল্যাপ না হয়)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        
        # কিউবটি নতুন করে ড্র করা
        draw_cube()
        
        # স্ক্রিন আপডেট করা (Flip)
        pygame.display.flip()
        
        # ফ্রেমরেট কন্ট্রোল (যাতে খুব বেশি ফাস্ট না ঘোরে)
        pygame.time.wait(10)

if __name__ == "__main__":
    game_engine()

কোডটি কীভাবে শিখবেন?

  1. GL_LINES: glBegin(GL_LINES) দিয়ে আমরা পাইথনকে বলে দিচ্ছি যে আমরা এখন শুধু লাইন বা দাগ টানতে চাই। এরপর glVertex3fv দিয়ে লাইনের শুরু এবং শেষের পয়েন্টগুলো দেওয়া হয়েছে।
  2. glRotatef: এই ফাংশনটি কোনো বস্তুকে ঘোরানোর জন্য ব্যবহৃত হয়। glRotatef(1, 3, 1, 1) মানে হলো প্রতি ফ্রেমে এটি ১ ডিগ্রি করে (x, y, z) অক্ষে ঘুরবে।
  3. Double Buffering: DOUBLEBUF এর কাজ হলো স্ক্রিনে ফ্লিকারিং (Flickering) কমানো। এটি পেছনের স্ক্রিনে বক্সটিকে ড্র করে এবং ড্রয়িং শেষ হলে একসাথে সামনের স্ক্রিনে নিয়ে আসে (pygame.display.flip()), যার ফলে আমরা একদম স্মুথ অ্যানিমেশন দেখতে পাই।
  4. glClear: প্রতিবার বক্সটিকে একটু ঘুরিয়ে ড্র করার আগে স্ক্রিন মুছে ফেলতে হয়, নাহলে আগের বক্সের দাগগুলো স্ক্রিনেই থেকে যাবে! glClear ফাংশনটি সেই মোছার কাজটি করে।

অভিনন্দন! আপনি মাত্র কয়েকটি লাইনের কোড দিয়ে পাইথনে একটি থ্রিডি ইঞ্জিন বানিয়ে ফেলেছেন!