فهرست
برای این که بتونید توی برنامهتون انیمیشن درست کنید، p5.js به صورت پیشفرض کدی که داخل draw
نوشته باشیدو شصت بار در هر ثانیه اجرا میکنه؛ به هر بار اجرا شدن این کد، اصطلاحاً میگن یک «فرِیم».
فرِیم رِیت
یه اصطلاحی هست به نام «فرِیم رِیت» که ممکنه قبلاً توی نرمافزارای تولید انیمیشن باهاش برخورد کرده باشید یا توی بعضی از بازیها دیدهباشید. فرِیم رِیت یعنی در یک بازه زمانی مشخص، مثلاً یه ثانیه، چند فریم روی صفحه نمایش به تصویر درمیاد. برنامهای که توی هر ثانیه شصت فریم نمایش بده، یعنی داره با فریم رِیتِ شصت فریم بر ثانیه اجرا میشه. توی برنامههای p5.js برای این که فریم رِیتو چک کنیم، میتونیم از تابع frameRate
استفاده کنیم.
function setup() {
createCanvas(windowWidth, windowHeight)
}
function draw() {
console.log(frameRate())
}
اگه دوست نداشتید برنامهتون با این فریم رِیت اجرا بشه با همین تابع frameRate
میتونید مشخص کنید که برنامه با چه فریم رِیتی اجرا بشه؛ فقط کافیه فریم رِیت مورد نظرتون رو در قالب یک پارامتر توی تابع frameRate
مشخص کنید؛ دقت کنید که p5.js سعی میکنه فرِیم رِیت برنامه رو به اون حدی که شما مشخص کردید برسونه، اما در واقعیت فریم رِیتِ برنامه ممکنه نسبت به ویژگیهای دستگاهی که برنامه داره توش اجرا میشه کاهش پیدا کنه.
function setup() {
createCanvas(windowWidth, windowHeight);
// specify frame rate
frameRate(30)
}
function draw() {
console.log(frameRate())
}
سرعت و جهت انیمیشن
برای این که بتونیم یه انیمیشنِ روان درست کنیم، متغیرهایی میسازیم تا بتونیم یه سری اعداد توش ذخیره کنیم و بعد با اجرای هر فریم، تغییرشون میدیم. مثال بعدی یه شکل رو از سمت چپ صفحه نمایش سمت به راست حرکت میده:
let radius = 45
let x = -radius
let theSpeed = 5
function setup() {
createCanvas(windowWidth, windowHeight);
ellipseMode(RADIUS)
}
function draw() {
background(0)
// change the position based on speed
x += theSpeed
// draw the shape
arc(x, windowHeight/2, radius, radius, 0.5, 5.5)
}
وقتی کد بالا رو اجرا کنید میبینید که شکل، بعد از مدتی از سمت راست تصویر خارج میشه و ما دیگه نمیبینیمش؛ یه شرط به کد بالا اضافه میکنم تا وقتی شکل از سمت راستِ تصویر خارج شد، برگرده به جای اولش و دوباره از سمت چپ شروع به حرکت کنه:
let radius = 45
let x = -radius
let theSpeed = 5
function setup() {
createCanvas(windowWidth, windowHeight);
ellipseMode(RADIUS)
}
function draw() {
background(0)
// change the position based on speed
x += theSpeed
// if the shape is off screen
if(x > windowWidth + radius) {
x = -radius
}
// draw the shape
arc(x, windowHeight/2, radius, radius, 0.5, 5.5)
}
کد بالا توی هر فریم، شرطی که گذاشتیم رو چک میکنه: اگه مقدار x
از عرض صفحه بهعلاوه شعاع دایره بیشتر شده بود، دوباره شکل رو برمیگردونه به جای اولش.
حرکت بین دو نقطه
بعضی وقتا نیاز داریم یه شکل بین دو نقطه جابجا بشه. با چند خط کُد، میشه نقطه شروع و پایانو مشخص کرد و بعد مختصات مسیرو محاسبه کرد. کد پایینو اجرا کنید و مقادیر متغیرها رو تغییر بدید و خودتون ببینید چطوری کار میکنه:
const startX = 50
const startY = 50
const stopX = 500
const stopY = 500
let x = startX
let y = startY
// speed
const step = 0.005
// percentage traveled
let pct = 0
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(0)
if(pct < 1) {
x = startX + ((stopX - startX) * pct)
y = startY + ((stopY - startY) * pct)
pct += step
}
ellipse(x, y, 15, 15)
}
انیمیشن رندوم
بر خلاف حرکت خطیای که توی اسکیسهای قبل دیدید، توی دنیای واقعی معمولاً سرعتها متغیر و بعضاً تصادفی هستن. مثل جابجا شدن یه برگ توی باد یا حرکت مورچه روی زمین؛ میشه تلاش کرد و این طور کیفیتهای پیشبینیناپذیرِ دنیای واقعی رو با به وجود آوردن اعداد تصادفی شبیهسازی کرد. قبلاً درباره روش استفاده کردن از اعداد تصادفی نوشته بودم. تابع random
توی p5.js این طور مقادیرو محاسبه میکنه؛ میتونیم دو تا عدد به عنوان پارامترهای این تابع استفاده کنیم و برای تولید یه عدد تصادفی از یه بازهی عددی استفاده کنیم. توی اسکیس بعدی، جای دایرههایی که داره کشیده میشه توسط مقادیر تصادفی مشخص میشه. دقت کنید که این بار از تابع background
داخل draw
استفاده نمیکنیم تا بتونیم همه دایرههایی که کشیده میشن رو ببینیم:
const theSpeed = 10
const diameter = 100
let x
let y
function setup() {
createCanvas(windowWidth, windowHeight);
x = windowWidth/2
y = windowHeight/2
background(205)
}
function draw() {
x += random(-theSpeed, theSpeed)
y += random(-theSpeed, theSpeed)
ellipse(x, y, diameter, diameter)
}
استفاده از مثلثات برای ساختن انیمیشن
امیدوارم مثلثاتِ محدودی که توی این دوره استفاده میکنیم شما رو کنجکاو کنه درباره مثلثات مطالعه کنید. ما توی این دوره خیلی عمیق وارد ریاضیات و مثلثات نمیشیم، اما چند تا از کاربردای مثلثات توی انیمیشنو با همدیگه میبینیم.
تابعهای sin
و cos
در p5.js مقادیری بین 1
و -1
به ما برمیگردونن که همون سینوس و کسینوس زاویهایه که مشخص میکنیم؛ زاویهها باید با واحد رادیان مشخص بشن. معمولاً اعدادی که توابع sin
و cos
به ما میدن باید در یه عددی ضرب بشن که بشه خوب ازشون استفاده کرد:
let angle = 0
const scalar = 100
const theSpeed = 0.1
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
// adjust the angle
angle += theSpeed
// set y position
const y1 = sin(angle + 0.25) * scalar
const y2 = sin(angle + 0.50) * scalar
const y3 = sin(angle + 0.75) * scalar
// create 3 circles
ellipse(width/2 - 50, height/2 + y1, 45, 45)
ellipse(width/2 + 00, height/2 + y2, 45, 45)
ellipse(width/2 + 50, height/2 + y3, 45, 45)
}
وقتی sin
و cos
با هم استفاده بشن، میتونن حرکت دورانی به وجود بیارن. توی مثال بعدی، مقادیر تابع cos
مختصات x
رو تعیین میکنن و مقادیر تابع sin
مشخصکننده مختصات y
هستن:
let angle = 0
const scalar = 100
const theSpeed = 0.1
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
// adjust the angle
angle += theSpeed
// positions
const x = cos(angle) * scalar
const y = sin(angle) * scalar
// create the circles
ellipse(width/2 + x, height/2 + y, 50, 50)
}
اگه توی کد قبلی یه تغیر کوچیک ایجاد کنیم و مقدار scalar
رو توی هر فریم یه خُرده زیاد کنیم، میتونیم به جای دایره، یه مارپیچ درست کنیم:
let angle = 0
let scalar = 100
const theSpeed = 0.1
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
// adjust the angle and scalar
angle += theSpeed
scalar += theSpeed * 3
// positions
const x = cos(angle) * scalar
const y = sin(angle) * scalar
// create the circles
ellipse(width/2 + x, height/2 + y, 50, 50)
}
میبینید یه تغییر کوچیک چقدر میتونه توی تصویر خروجی تأثیر داشته باشه؟ حالا وقتشه از چیزایی که یاد گرفتید استفاده کنید، یه خُرده خلاقیت به خرج بدید و هر جوری که دوست دارید با کد بازی کنید. خروجیهای مختلف رو تست کنید، من یه تغییراتی روی کد انجام دادم و خروجی کارم این طوری شد:
اصلاً انیمیشن نمیخوام
اگه برنامه شما نیاز به انیمیشن نداشت، میتونید از تابع noLoop
داخل setup
استفاده کنید، این طوری هر چیزی که داخل draw
باشه هم فقط یک بار فراخوانی میشه.