اخیرا با کتابخانه ای از پایتون آشنا شدم که بر مبنای جاوا اسکریپت ساخته شده و ساختن انیمیشن در آن بسیار ساده است. اسم این کتابختانه p5 است و هنوز در حال توسعه است اما ویژگی های عالی ای که دارد استفاده از آن را بسیار جذاب می کند.
سایت https://p5js.org/ شامل بخش های زیادی است که روش کار کردن با این کتابخانه را در جاوااسکریپت آموزش می دهد. بخش مهمی از این کتابخانه به انیمیشن سازی سه بعدی اختصاص دارد که هنوز در نسخه پایتون آن پیاده سازی نشده است اما بزودی هم این اتفاق می افتد. با این حال حتی بخش دو بعدی آن بسیار جذاب است.
نصب در لینوکس و مک: شما در لینوکس باید ابتدا کتابخانه GLFW را نصب کنید:
$ sudo apt-get install libglfw3
و در مک:
$ brew install glfw
نصب در ویندوز:
برای نصب در ویندوز اول به این صفحه بروید و نسخه باینری متناسب با سیستم خودتان (32 یا 64 بیتی) رو دانلود کنید و بعد از اکسترکت کردن در یک فولدر ترجیحا جایی در درایو سی (بجز روت سی) قرار بدهید سپس آدرس خودتان را به Environmental Variable اضافه کنید. مثلا در مورد من آدرس به صورت زیر می شد:
C:\tmp\glfw-3.3.bin.WIN64\glfw-3.3.bin.WIN64\lib-mingw-w64
سپس شما نیاز دارید که کتابخانه پایتون p5 را نصب کنید:
pip install p5
تمام شد! هم اکنون آماده کار کردن می شویم!
در اینجا برای ساختن یک انمیشن فقط به دو تابع نیاز داریم:
آماده سازی: setup این تابع بوم شما را آماده می کند. منظور از آماده سازی می تواند هر چیزی باشد. معمولا در این قسمت اندازه بوم یا رنگ آن را تعیین می کنیم. در مواقع دیگر ممکن است آماده سازی های دیگری داشته باشیم (شبیه به constructor در کلاس). هر چه هست این تابع فقط یک بار و در اول هر انیمیشن اجرا می شود.
نقاشی (draw): این تابع فریم های انمیشن را می سازد. این تابع توسط p5 در یک حلقه اجرا می شود. شما تنها باید تعیین کنید در هر بار چه چیزی بر روی بوم باید نقاشی شود.
و یک تابع run که کل انمیشن را اجرا می کند (شبیه به main برنامه ست)
همین! برویم تا کار را شروع کنیم.
ساده ترین برنامه ای که می توانید بنویسید ایجاد یک بوم خالی است:
from p5 import * def setup(): size(800, 800)
run()
اگر این کد را اجرا کنید یک بوم مربعی شکل می بینید:
حالا می توانیم کارهای بیشتری بکنیم. حالا به تابع draw بپردازیم. در این تابع می توان کارهای مختلفی کرد و بیشتر کد هم اینجا می رود. در ساده ترین حالت ممکن می توانیم یک رنگ به بوم بدهیم.
from p5 import * def setup(): size(800, 800) def draw(): background(220, 0, 200, 10)
run()
که سه عدد درون تابع background بر اساس RGBA هستند. A همان آلفا ست و میزان روشنایی را تعیین می کند. اگر این را اجرا کنید همان بوم بالا را با پس زمینه صورتی خواهید داشت:
سوال می پرسید که انمیشینی وجود ندارد! جواب واضح است چون تغییری اینجا نداریم! یعنی در تابع draw شما هر بار فقط با یک رنگ بوم را رنگ می کنید. در اولین قدم بیایید رنگ بوم را هر بار به رنگی تصادفی عوض کنیم! برای این کار نیاز داریم تابع رندم را فراخوانی کنیم. من از تابع random کتابخانه numpy استفاده می کنم اما از کتابخانه خود random هم می توان استفاده کرد. قبل از آن نیاز داریم numpy را نصب کنیم:
pip install numpy
حالا دنبال تابع رندمی هستم که یک عدد تصادفی در بازه دلخواه بدهد. کد به صورت زیر می شود:
from p5 import * import numpy as np def setup(): size(800, 800) #instead of create_canvas def draw(): r = np.random.randint(0, 255) g = np.random.randint(0, 255) b = np.random.randint(0, 255) background(r, g, b) run()
و خروجی آن به صورت زیر است:
توابع زیادی وجود دارند که شما می توانید با استفاده از آن ها خط، مربع دایره و غیره بکشید. یک مثال که همه آن ها را با هم نشان می دهد در زیر آورده ام:
from p5 import * import numpy as np def setup(): size(800, 800) #instead of create_canvas def draw(): background(200, 200, 200) # (R, G, B, alpha) line((50, 50), (100, 100)) stroke(100, 100, 50) fill(0, 0, 255) rect((10, 50), 100, 150) #coordinates should come in tuple form (x, y) fill(255, 200, 0) circle((100, 50), radius=40) fill(100, 40, 150) no_stroke() triangle((50, 10), (100, 200), (300, 300)) run()
چند نکته مهم وجود دارد که باید به آن ها اشاره کنیم.
۱- ترتیب آمدن هر دستور مهم است. دستور های بعدی اگر شکلی می کشند بر روی قبلی ها قرار می گیرند. این درست مانند یک بوم واقعی است که شکل های بعدی بر روی قبلی ها می افتند.
۲-برخی از تابع ها شرایط را برای تابع بعدی تعیین می کنند. مثلا در بالا تابع fill مشخص می کند شکلی که با دستور بعدی می آید باید چه رنگی باشد. یا مثلا no_stroke مشخص می کند که شکل بعدی نباید لبه داشته باشد.
۳- در p5 برای پایتون نقطه ها به صورت تاپل نمایش داده می شوند. مثلا در تابع line دو ورودی داریم که اولی نقطه ی شروع و دومی نقطه پایان است. هر نقطه به صورت تاپل مثلا (50,50) نمایش داده می شود. در تابع rect سه ورودی میگیرد. یک نقطه (گوشه سمت چپ بالا) و دو عدد که طول و عرض مستطیل هستند.
خروجی به صورت زیر می شود:
در قسمت بعد با event ماوس کار میکنیم.