آموزش ساخت بازی با کانواس و جاوا اسکریپت

saalek110

Well-Known Member
من فکر می کنم که بهتره وقتی می خواهیم سمت راست کانواس چیزی قرار دهیم این طوری بنویسیم:

JavaScript:
       x = canvas.width;
           ctx.fillText(text, x-160, 77);
یعنی حداکثر x را اول بدست بیاوریم ، بعد ازش مقداری کم کنیم.
شاید این جوری در گوشی های مختلف احتمال بیرون افتادن از قسمت کانواس کمتر باشه
ثانیا ، پیدا کردن نقطه مورد نظر این طوری راحت تر است.
 

saalek110

Well-Known Member
پرچم بکارید

من برنامه ام دچار اشکال شد...
در تابع update حدود ۱۰ تا پرچم کاشتم.
به شکل زیر:


JavaScript:
document.getElementById("error").innerHTML+="1";

اون بعلاوه مساوی است نه مساوی خالی.

این کد هم هدف پرچم است. در قسمت html باید باشه.

HTML:
<p id="error"></p>

کلمه error دلخواه است و این کلمه کاری انجام نمی دهد.
سه تا پرچم هم در تابع start کاشتم. متن اون start باشه ودومی اش s2 و s3
پرچم های من شماره ۱ تا ۷ داشت ، دیدم شماره ۵ کار نمی کنه ،فهمیدم کد قبلی اش مشکل داره... کد قبلی اش فراخوانی یک تابع از کلاس hero بود... بعدا فهمیدم کلاس مشکل داره ، در یکی از توابعش یک غلط داشت...عدد بعد مساوی پاک شده بود. شاید دستم خورده بود..نمی دونم.

در بالا روشی برای خطایابی گفتم.

یک راه هم اینه قطعات مختلف برنامه را بزاری بیرون یا به شکل کامنت دربیاری ببینی چی میشه.

در شکل زیر اون اعدادی که چاپ شده هست:


Screenshot_۲۰۲۴-۰۲-۲۳_۱۸۲۱۰۶.jpg

با یک نگاه میشه فهمید اجرای برنامه کجا گیر کرده. اون نوشته بالاییربطی به قضیه نداره ، که نوشته How long can you...

بعدا میشه پرچم ها را به شکل کامنت درآورد یا پاک کرد.
 
آخرین ویرایش:

saalek110

Well-Known Member
فاز ساخت ، فاز عرضه:

تا می توانید چاپ کنید.

این طوری با نگاه به چیزهای چاپ شده می فهمید برنامه چطوری کار می کنه.

فاز ساخت ، با فاز عرضه بازی فرق داره ، این دو را با هم اشتباه نگیرید.

در همون خود کانواس تمام متغیرهای بازی را چاپ کنید تا جلوی چشمتون باشه.
 

saalek110

Well-Known Member
من فکر می کنم اگر از عکس استفاده کنیم بازی جلوه دیگری پیدا می کند.
از اشکال میشه برای ایجاد افکت ها اطراف عکس ها استفاده کرد. مثل خروج آتش از پشت هواپیما ، حتی اون را هم با عکس میشه ایجاد کرد.
 

saalek110

Well-Known Member
برخورد:



JavaScript:
function collides(a, b)
{
    if (a.x < b.x + b.width &&
        a.x + a.width > b.x &&
        a.y < b.y + b.height &&
        a.y + a.height > b.y) return true;
}



اون بازی سایت w3school این طوری نوشته بود:

JavaScript:
var crash = true;
        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
            crash = false;

من فکر می کنم این دو کد ، درنهایت به یک نتیجه می رسه.

من فکر می کنم ورژن های f4 و boing و تانک که من عکس به کار بردم ، ،مشکل برخورد دارند. دارم بررسی می کنم ببینم مشکل از کجا ناشی شده.
 

saalek110

Well-Known Member
کد یافتن طول و عرض عکس:



JavaScript:
<img id="plane" src="images/plane33.jpg" alt="plane" width="10" height="10">



  var img = document.getElementById("plane");



    var width = img.naturalWidth;

    var height = img.naturalHeight;



خط اول در قسمت html است و باقی خط ها در قسمت جا ا اسکریپت.

خط اول یک id داره ، که اون id در کدهای جاوا اسکریپت استفاده شده. که id اینجا plane
می نوانید نسبت را حساب کنید ک به کار برید یا اینکه خودتان اون نسبت را تا حدودی رعایت کنید تا عکس شکل طبیعی خود را ار دست ندهد.
 

saalek110

Well-Known Member
پترن:
به جای رنگ کردن یک شکل میشه طرحی درش به کار برد. گاه جلوه خیلی بهتری داره.


JavaScript:
function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");



  // create new image object to use as pattern
  const img = new Image();
  img.src = "canvas_createpattern.png";
  img.onload = () => {
    // create pattern
    const ptrn = ctx.createPattern(img, "repeat");
    ctx.fillStyle = ptrn;
    ctx.fillRect(0, 0, 150, 150);
  };
}



 

saalek110

Well-Known Member
JavaScript:
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255 165 0)";
ctx.fillStyle = "rgb(255 165 0 / 100%)";



معرفی رنگ به روشهای مختلف.

 

saalek110

Well-Known Member
تعیین فازهای بازی:

یک یا چند متغیر اول بازی تعریف می کنیم تا تعیین بشه بازی در چه فازی است.
مثلا من یک بازی هواپیما ساختم.. وقتی تماس با زمین برقرار شد ، متغیر landing را یک کردم... و کارهایی انجام دادم... بعد متغیر landing مساوی ۲ شده....وقتی متغیر landing برابر صفر باشد ، یعنی در حال فرود نیست و بازی در حالت پرواز است ولی متغیر landing که 1 یا ۲ یا ۳ باشه ... فازهای فرود استو شما با نوشتن یک if و گذاشتن کروشه...این طوری:

JavaScript:
if (landing==1)
{



}

کدهای فاز یک landing را داخلش می نویسید..مثلا من یک متغیر به نام run را ۶۰۰ دادم.. و شروع به کم کردنش کردم... و در این فاصله هواپیما روی زمین در حال حرکت بود. وقتی متغیر run برابر صفر میشد ، متغیری به نام forod برابر ۱ میشه ، یعنی هواپیما در فاز فرود است... در فاز فرود بعضی چیزها انجام می شود و بعضی چیزها انجام نمی شود.....

مثلا وقتی در بازی کامبون ، مماشین در حالت خلموش باشه ، تنها کار روشن کردن ماشین است و خیلی چیزها دیگه کار نمی کنه...

پس باید فاز تعیین بشه و با گذاشتن if ، گدهای اون فاز را بنویسیم . در بازی هواپیمای من با زدن دکمه شروع متغیرهای landing و forod برابر با صفر می شوند و از فاز landing و فرود خارج میشیم.
با تعریف کردن دو متغیر میشه زیر فاز تعریف کرد ، ،مثلا فاز landing هستیم و زیرفاز فلان چیز.
 

saalek110

Well-Known Member
عدد بالا رونده به عنوان تقویم و ساعت بازی:


در بازی سایت w3school که در اون یکی تاپیک است ، در تابع uldate که همیشه در حال چرخش است،
یک عدد مدام در حال افزایش است... و در اون برنامه از اون عدد ، به عنوان تقویم کاری استفاده شده... با تقسیم اون عدد مثلا به ۱۰۰۰ و دریافت باقی مانده ، ،یشه هر ۱۰۰۰ عدد در جای خاصی کاری کرد....مثلا من میگم اگر باقی مانده بر ۱۰۰۰ برابر ۱۲۳ بود، فلان فاز را شروع کن یا فلان چیزها رسم شود.

در یک بازی دیگر دیدم ، از تاریخ ، ثانیه اون را گرفته و با استفاده از ثانیه کارهایی انجام می داد...
 

saalek110

Well-Known Member
فاز برخورد:

وقتی برخورد صورت میگیره ، میشه متغیر برخورد را یک قرار داد و دیگه ازبرخورد بعدی جلوگیری کرد....
قضیه همون بحث فازهای بازی است... بعد ثبت برخورد ، وارد فاز برخورد می شیم ودیگه اجازه چک برخورد را نمی دهیم....چون بعد برخورد باید کارهایی انجام بشه ، و اگر صلاح بود از فاز برخورد خورج بشیم تا برخورد بعدی میسر شود.. دیگه اینها را خودنان باید تصمیم بگیرید....فرض کنید برخود صدایی داشته باشد، اگر پشت سر هم برخورد کند ، صداها ممکن است ناجور شود...پس با تعیین متغیر فاز برخورد و ایجاد فاز برخورد ، می توانیم وقایع بعد برخورد را به شکل کنترل شده در اختیار داشته باشیم.

فرض کنید دو چیز نزدیک هم باشند و بعد برخورد با اولی ، وسیله به راه خودش ادامه دهد و با دومی برخورد کند...مثلا کامیون به لایه رویی دیوار می خورد و بعد به لایه پشتی میرسد ، این دو برخورد می تواند همزمان رخ دهد و نتوانیم ا ن را درست مدیریت کنیم ، پس می توانیم بعد برخورد با اولی وارد فاز برخورد شویم و جلوی وقوع برخورد دوم را بگیریم یا کارهایی انجام دهیم و برای برخورد دوم آماده شویم و بعد از فاز برخورد خارج شویم تا برخورد دوم میسر شود.
 

saalek110

Well-Known Member
رفتارهای پی در پی و متنوع قهرمان یا دشمن:

در بازی هواپیما و فرودگاه .
من ابتدا با تعریف یک متغیر یک فاز تعریف کردم....مثلا فاز فرود یا فاز برخواست هواپیما..
مثلا متغیر landing یا take_off که در حالت شروع بازی مقدارشون صفره... وقتی بخواد بره توی فاز مقدارش ۱ یا ۲ و ..میشه...
بعد یک متغییر را عددی بین ۵۰۰ تا ۱۵۰۰ دادم.

بعد با نوشتن یک if این جوری:
JavaScript:
if ( landing > 0 )
{


}
یک منطقه کد تعیین کردم.
بعدش که اون عدد را مقدار هزار دادم ، landing را ۲ کردم.
بعد در همون منطقه ایجاد شده با کد بالا ، اون عدد که مثلا اسمش run بود را یکی یکی کم کردم...
و در ایستگاههای مختلف از run یک رفتار خاصی از قهرمان یا دشمن انجام میشه... مثلا هواپیما اوج می گیره یا کارهای دیگه می کنه.
کد کلی:
JavaScript:
if ( landing>0)
{

if (landing == 1){

run = 600;
hero.elevation=0;
hero.y=322;
landing=2;
    }//landing==1


if (run==540)
{
    hero.y+=4;
}//   run=450



if (landing == 2 && run==1) {
forod=1;
}//if end run


if (run > 0 )
{
    run -= 1;
}  // if run



}   // if landing>0

در کد بالا ، بعد از عدد دادن به run مقدار landing برابر با ۲ میشه ، که دیگه به run عدد ندهیم..
بعدش در درون همین قسمت landing>0 یعنی داخل کروشه های landing بزرگتر از صفر ، مقدار run یکی یکی کم میشه... و با هر run اش کاری انجام میشه ، مثلا در run==400 قهرمان یک رفتار خاص انجام می دهد. که با تغییر متغیرهای قهرمان ، مثلا تغییر سرعت بالا رفتن هواپیما ، یا تغییر y هواپیما ، انجام میشه...همون متغیرهای تعریف شده در کلاس قهرمان منظور است.

در کد بالا می بینید که وقتی run به صفر می رسه ، متغیری به نام forod برابر یک میشه....یعنی از فاز landing به فاز forod می رسیم. در فاز forod اتفاقات دیگری می افتد... هواپیما از حرکت می ایستد و کارهای دیگر فاز فرود انجام می شود.

بعد یک دکمه است که بازیکن می زند، اسمش دکمه take_off است، و متغیرهای landing و forod برابر صفر میشن تا بازی به حالت عادی وارد بشه...

ولی بعدش من فاز take_off هم تعریف کردم.. و هواپیما به طور خودکار با رفتارهایی مثل همین کد landing از زمین بلند شد.... و بعد اینکه اون متغیر که در موقع برخواستن اسمش دیگه run نبود و run_take_off بود... بله ، وقتی متغیر برخواستن یکی یکی ، کم شد و به صفر رسید ، خودبخود فاز برخواستن تمام شد با صفر دادن به متغیر take_off..

در کد بالا ، چند تا رفتار متفاوت از هواپیما به طور پشت سر هم و منظم انجام شد ، در موقع فرود و در موقع برخواستن...
مثلا می توانید یک دکمه تعیین کنید که بازیکن با زدن اون یک برخواستن اتوماتیک را داشته باشه.... یا می تواند نزند و خودش بلند شود.

در بالا خواستم چگونگی تعریف کردن یک فاز در بازی با چند متغیر را بگویم.هواپیمای بازی من با این کدها رفتارهای فرود و برخواستن اتوماتیک داشت. یک سکویی بود ، وقتی بازیکن هواپیما را با اون سکو برخورد می داد ، فاز فرود شروع میشد، یعنی در موقع برخورد هواپیما با اون شی خاص روی فرودگاه ، متغیر landing برابر ۱ میشد و می رفت توی فاز فرود.... (یک دردسری هایی قبلش داشتم، چون بعد برخورد به اون سکوی خاص هواپیما باز برخورد با همون سکو داشت یا با چیزهای دیگه برخود داشت و برنامه هنگ می کرد...چون فکر کنم برخورد مکرر ایجاد میشد، پس تعریف فاز نشستن یک باید و اجبار بود برام اون موقع.... ولی میشد مسیرهای دیگری برای مدیریت برخورد رفت ولی من مسیر ایجاد خلبان اتوماتیک را این بار رفتم)

اگر فاز فرود وجود نداشت ، بازیکن باید خودش فرود می آمد ، که بازی من امکانات چنین کاری نداشت ، ،مثلا کاهش قدرت موتور ، ترمز ، باله های کمکی هواپیما... و شاید بازیکن حوصله انجام چنین مراحلی را نداشت... و با تعیین فاز فرود با دو تا متغییر ، خلبان خودکار ساخته شد.

لینک بازی اینه:


و در بازی ، متغیر run و run_take_off هم روی صفحه چاپ میشه و کاهش اون از مثلا ۱۰۰۰ به صفر را می تونید روی صفحه ببینید...
و من با نگاه به اون عدد و نگاه به وضعیت هواپیما ، تصمیم گرفتم که در هر عدد run چه کاری انجام بشه.. مثلا در موقع برخواست گفتم اول کمی روی باند فرودگاه راه برود ، بعد مختصری ارتفاه بگیره. مثلا از run برابر ۵۰۰ تا run برابر ۲۰۰ در حالت ارتفاع کم روی باند بود...
یعنی خودتون عدد متغییر run. را روی صفحه می بینید و تصمیم می گیرید در کدام شماره از run کدام رفتار هواپیما انجام شود.
من می خواستم هواپیما موقع برخواست در قسمتی از فاز برخواست بدنه اش رو به بالا باشد.. ولی کدش را آماده نداشتم ، کد چرخش شکل را آماده نداشتم. میشه برای قهرمان که اینجا هواپیما است رفتارهای مختلف ساخت و در فازهای مختلف ازشون استفاده کرد.

من در فازهای landing و take_off کلیدهای بازیکن را از کار انداختم تا اخلال در کار نکند..این جوری:
JavaScript:
function accelerate(n) {
    if (landing==0 && take_off==0){
    hero.elevation = n;
 if(n==0)
 {
    hero.elevation = 0;
  // hero. = 0;

 }//n==0
          }//landing ==0
}    //accelerate
یعنی گفتم وقتی در فاز نشستن یا برخواست است ، کلیدهای کاربر کار نکند... تابع accelerate مسئول دریافت از کلیدهای برنامه است.


ولی فکر کنم بشه فازهایی را تعریف کرد که کلیدهای کاربر از کار نیافته..
یعنی اتوپایلوت(خلبان اتوماتیک) ، به شکل کمکی در کنار خلبان کار کند... مثلا خلبان با زدن دکمه ای فاز خط را فعال می کند ، و وقتی موشک دشمن به سمت هواپیما می آید ، اتوپایلوت جاخالی می دهد...یعنی ارتفاع هواپیما را مقداری کن یا زیاد می کند تا موشک به هواپیما نخورد. البته کدش را کار نکردم ، فقط فعلا همکاری خلبان اتوماتیک با خلبان زنده در حد بحث است.

در این پست خواستم با if و استفاده از متغیرها به عنوان نشانه آشنا بشوید.
متغیرهای مورد نیاز در فایل اصلی برنامه در کف اسکریپت تعریف میشه.... کف اسکریپت یعنی داخل تابعی نیست...تا تمام توابع بتونن ازش استفاده کنن ، مثل این است چیزی را بزاریم توی پارکینگ آپارتمان تا تمام ساکنین طبقات بتونن بردارن.تعریف متغیرها در فایل اصلی:
JavaScript:
var landing=0;
var forod=0;
var run=0;

var take_off=0;
var run_take_off=0;
 
آخرین ویرایش:

saalek110

Well-Known Member
ما زیاد دنبال یاد گرفتن جوا اسکریپت نیستیم در این تاپیک ، و مثل کد پست بالا ، من کدهای لازم برای ساخت قسمتهای مختلف بازی را میگم.

یعنی درحدی جاوا اسکریپت یاد می گیریم که برای ساخت بازی نیاز باشه.


وقتی بازی کار می کنه ، یعنی کدی که نوشتیم کارمون را راه انداخته..همین کافیه.

در پستهای قبلی قالب کدهای بازی را گفتیم....
یک تابع update داشتیم....
داخل اون تابع من این جوری نوشتم:
JavaScript:
if (landing > 0 ) my_landing();
if (take_off > 0 ) my_take_off();
بعدش داخل فایلهای landing و take_off تابع های my_landing و my_take_off نوشته میشه ، این طوری:
JavaScript:
function my_landing() {
...
...
...
}
البته یک جا باید اون فایل معرفی بشه به برنامه. فایلهای من از نوع php است و include می کنم فایلهای جدید را ، ولی در جاوا اسکریپت اینها را استفاده می کنن:
JavaScript:
<script src="landing.js"></script>
<script src="take_off.js"></script>
ببینید کدهای بالا را باید کجا بزارید تا برنامه بتونه ازش استفاده کند.

بعدش داخل تابع های فوق ، اون کد پست قبل ،‌یعنی کد زیر :
JavaScript:
if (landing == 1){

run = 600;
hero.elevation=0;
hero.y=322;
landing=2;
    }//landing==1


if (run==540)
{
    hero.y+=4;
}//   run=450



if (landing == 2 && run==1) {
forod=1;
}//if end run


if (run > 0 )
{
    run -= 1;
}  // if run

قرار گرفت... البته اول همه کدها داخل تابع update بود.....
شما هم می تونید اولش کدها را داخل تابع update بنویسید و چک کنید..

برای خلوت شدن تابع update ، بعد تکمیل هر قسمت ، اون قسمت می رود به فایل خودش.
ولی اجباری به ساخت فایل و تابع نیست.

اولش اسم تابع من landing بود ولی دیدم با متغیر landing برنامه داره قاطی می کنه ، پس اسمش را کردم my_landing....تا با اون متغیر عوضی نگیره.

پس در دو پست فوق دیدیم که چطور باید فایل جدید و تابع جدید ساخت...
و چطور با چند تا متغیریک فاز بسازیم و در اون فاز رفتارهایی داشته باشیم.
 
آخرین ویرایش:

saalek110

Well-Known Member
کلاس چیست و طرز استفاده از کلاس:

کد زیر کلاس هواپیمای من است:
JavaScript:
<script>

function hero(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.speedX = 0;
    this.speedY = 0;
    this.x = x;
    this.y = y;
    this.elevation = 0;
    this.gravitySpeed = 0;
this.update = function() {
              //var img = document.getElementById("plane");
 ctx.drawImage(   document.getElementById("img") ,this.x,this.y,this.width,this.height);
 
  }
    this.newPos = function() {
       // this.gravitySpeed += this.gravity;
       // this.x += this.speedX;
      //  this.y += this.speedY + this.gravitySpeed;
        //  this.gravitySpeed += this.gravity;
       // this.x += this.speedX;
        this.y += this.elevation ;
        this.hitBottom();
         this.hittop();
    }
 
this.hitBottom = function() {
          var rockbottom = canvas.height - this.height;
        if (this.y > rockbottom) {
            this.y = rockbottom;
            this.elevation = 0;
        }
    }
 this.hittop = function() {
      
        if (this.y < 0) {
            this.y = 0;
            this.elevation = 0;
        }
    }

  this.crashWith = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
            crash = false;
        }
        return crash;
    }

  this.crashWith_b = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
            crash = false;
        }else {
        this.y-=20;
            this.elevation=-1;
        } // else
        return crash;
    }
//zzzzzzzzzzzzz

  this.crashWith_a = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
            crash = false;
        }else {
        landing=1;
       // this.y-=2;
            //this.elevation=-1;
        } // else
        return crash;
    }
//zzzzzzzzzzzzz
}    // class

</script>

در اون فاز برخواستن و نشستن در فرودگاه از متغیرهای این کلاس ، که اول برنامه با کلمه this نوشته شده ، استفاده شده. مثلا this.elevation یعنی سرعت بالا رفتن هواپیما... ولی در اون کداای فازها باید بنویسی hero.elevation


بزار داستان را کامل بگم....
این را ببین:
HTML:
<body onload="startGame()">
تگ html به نام body است که بدنه فایل html باهاش شروع میشه. یک فایل html این طوری است:
HTML:
<html>
<body>
....
....
....
...
..
</body>
</html>
دیگه from زیرو آموزش دادم یعنی از صفر که تگ های html است.. در کد بالا در تگ body تابع start صدا زده میشه
داخل تابع start من اینو دارم:
JavaScript:
 <script type='text/javascript'>

var hero;
var hero2;
var landing=0;
var forod=0;
var run=0;
var take_off=0;
var run_take_off=0;
var frameNo=0;
let heart=1000;
var myObstacles = [];



// code haye ijade canvas
// code e doreh ii kardene update function



function startGame() {

hero = new hero(73, 25 ,"red", 10,120);

}  // start function

</script>

در کد بالا علاوه بر تابع start مقداری دور و برش را هم توضیح دادم....
داخل تابع استارت اینو داریم:
JavaScript:
hero = new hero(73, 25 ,"red", 10,120);
ببینید یک کلاس مثل یک قالب است..مثل قالب کفش....قالب کفش را نمیشه پوشید ، چون برای ساخت کفش است..
یک خط کد بالا از کلاس hero یک hero ساخته ، یعنی از قالب کفش ، یک کفش ساخت..
حالا اسم قهرمان ما hero است و تصادفی اسم قهرمان با اسم کلاس یکی است ، شاید من باید اسم های متفاوتی می دادم... به تشابه اسمی توجه نکنید... حالا شی ‌hero با یک خط کد بالا که در تابع start بود ساخته شد..میشه بنویسیم:
JavaScript:
hero2 = new hero(73, 25 ,"red", 10,120);

hero3 = new hero(73, 25 ,"red", 10,120);

این جوری ۳ تا هواپیما داریم که می تونیم هر کدام را به سمتی بفرستیم مثلا این جوری:
JavaScript:
hero.x=130;
hero.y=300;

hero2.x=100;
hero2.y=20;

her3.x=20;
hero3.y=20;

در کد بالا هر کفش یا هواپیما را در جای خاصی از صفحه قرار دادم. الان ۳ هواپیما ، ۳ جای صفحه داریم...
پس کد خلق شی ، می تواند بی نهایت کفش یا شی برای شما بسازه... ولی اگر این کد را ننویسیم ، کلاس فقط یک قالب است و قابل استفاده نیست..
در کد زیر:
JavaScript:
hero = new hero(73, 25 ,"red", 10,120);
اون ۴ تا عدد ، دو تایش xو y است ، یعنی محل قرار گیری.و دو تایش طول و عرض شی است.اون red هم کاربردی ندارد، قبلا کلاس برای رسم مستطیل بوده ، رنگ مستطیل را می دادیم.. باید حذف بشه از کلاس.. چون کلاس هواپیما با عکس کار می کنه نه با رسم مستطیل.
پس x y ئی که می دهیم دریک خط کد بالا ، یعنی موقع تولد شی ، شی کجا قرار گیرد..که بعدا با hero.x و hero.y میشه جایش را عوض کرد...
همان طور که می بینید یک تابع update داره کلاس فوق ....که داخلش کد کانواس رسم شکل است. رسم یک عکس است اون کد...

داخل پرانتز بگم کلاس همینی است که در کد بالا می بینید.. ازش نترسید.. چند خط کد بیشتر نیست... اسمش گنده است ، خودش چیزی نیست.. یک کمی دقت کنید می توانید ازش استفاده کنید.

تابع بعدی کلاس newpos است ، این کد داخلشه:
JavaScript:
  this.y += this.elevation ;
این this.elevation مثل this.x اون بالا جزو متغیرهای کلاس است... یعنی مقدار بالا رفتن...
داخل تابع update این دو خط کد را داریم:
JavaScript:
hero.newPos();
hero.update();
می دونید که تابع update مثلا هر ۳۰ میلی ثانیه یک بار داره اجرا میشه... پس با دو خط کد بالا یعنی y هواپیما با مقدار this.elvation جمع زده میشه و مجدد هواپیما رسم میشه...
پس من اگر جایی بنویسیم که:
JavaScript:
hero.elavation=1;
باعث میشه هواپیما مدام به سمت پایین بیاد تا از صفحه خارج بشه... برای همین کلاس دو تابع hitBottom و hittop هم داره ، تا نزاره هواپیما از صفحه خارج بشه...

پس ببینید کلاس چه ابزار خوبیه... تمام کارهای هواپیما داخلش هست... و میشه ۱۰۰ تا هواپیما ساخت و به همشون دستورات جداگانه داد...پس تلاش کنید کد کلاس را یاد بگیرید....

دیگر تابع های کلاس تابع برخورد است... من دو کپی از تابع برخورد دارم در کلاس....تابع برخورد دومی این کد داخلشه:
JavaScript:
landing=1;
پس از اینجا بوده که فاز landing شروع می شده.. یعنی یک تابع از کلاس hero... بقیه داستان فاز landing را در پستهای قبل گفتم...

کلاس هم یک کد است ، در یک فایل می گذاری و در فایل اصلی برنامه اسمش را ذکر می کنی.. و در بالا گفتم چطور با یک خط کد ، کفش یا هواپیما یا شی ساخته میشه...

حالا چرا کدهای کلاس اون طوریه ...چون قرارداد است... شما شکل نوشتنش را یاد بگیر و استفاده کن...
دو تا تابع برخورد دیگر کلاس دارد.. برخورد با کنار باند فرودگاه بوده تا اجازه نشستن ندهد و هواپیما به بالا برمی گرده وقتی برخورد می کنه ، نوشتم:
JavaScript:
 this.y-=20;
 this.elevation=-1;
با دو متغیر کلاس یعنی elevation و y بازی می کنه ، و باعث میشه هواپیما ۲۰ تا بره بالا و سمت حرکتش هم به سمت بالا بشه..
 
آخرین ویرایش:

saalek110

Well-Known Member
شرح کلمه this:

پس در تابع start هواپیما متولد شد،و در تابع update دو تابع رسم و تغییر مکان هواپیما صدا زده میشه...
و هر جای برنامه میشه متغیرهای hero را مقدار داد...مثلا hero.x را اگر تغییر دهیم ، هواپیما به سمت راست و چپ میره...
کلاس مثل یک کلوپ است ، داخل کلوم میگن this.x بیرون کلوم میگن hero.x یا hero2.x یا hero3.x
پس this.x همون hero.x است ... مثلا توی خونه به شما میگن حامد ، در مدرسه میگن آقای حیدری... ولی هر دو یک نفرند.
داخل کلاس هم با پیشوند this اجزای کلاس نام برده میشن... یعنی اعضای کلوپ هستند... ،مثل اعضای ثبت نام شده یک کتابخانه عمومی ، جلوی در میگن کارت کتابخانه ات را نشان بده... بعد میگن this.ali یعنی همون ali خودمون است برو داخل کتابخانه..
 

saalek110

Well-Known Member
پس در دو پست بالا فهمیدیم کلاس چیه و چطوری استفاده کنیم.
قطاری آبجکت باهاش خلق می کنیو قطاری تکونشان می دهی ....

در بالا کلاس hero را دیدید ، ولی یک کلاس دیگر داره برنامه من به نام کلاس componet ....خوب بود اول با اون آشنا می شدید ، چون کوچکتره....
JavaScript:
function component(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
     ctx.fillStyle = color;
     ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}
مثلا یک مربع باهش رسم می کنید ، اول تولدش x,y یعنی محل تولد و سایز ، یعنی طول و عرض و رنگ مستطیل را می دهید.
کد خلق شی مثل خلق hero است... ولی اینجا اون رنگ دیگه کاربرد داره.
JavaScript:
mostatil = new componemt(73, 25 ,"red", 10,120);

ولی در برنامه ، یک مستطیل تولید نشده ، پشت سر هم دیوار ساخته شده تا قهرمان از لای دیوارها رد بشه...
برای همین یک آرایه ساخته شده اول برنامه:
JavaScript:
در مورد hero داشتیم:
JavaScript:
var hero;
چون قهرمان ما ، یکی بود فقط...همون هواپیما که ما خلبانش هستیم.

ولی در مورد دیوارها ، تعدادشون خیلی زیاده. پس آرایه اول بازی ساختیم.
JavaScript:
myObstacles.push(new component(100 ,7, "#889922", 20,60));
کد بالا ، کد ساخت یک مستطیل است با استفاده از کلاس component.
یعنی اگر کد بالا را اجرا کنی یک مستطیل ساخته میشه ، برای نمایش اون یا بهتره بگیم نمایش کل اون اشیای داخل آرایه می نویسیم:
JavaScript:
for (i = 0; i < myObstacles.length; i += 1) {
        myObstacles[i].x += -1;
        myObstacles[i].update();
    }
چون تعدادشون زیاده ، مثل سر صف توی مدرسه ابتدایی ، یکی یکی نام برده شدند با حلقه...
و بعد گفتن شماره هر یک ، اول یک واحد به x اونها اضافه میشه و بعدش نمایش داده میشن.
راستش را بخواهید کد خلق دیوار این شکلی بود:
JavaScript:
   x = canvas.width;
myObstacles.push(new component(100 ,7, "#889922", x,60));
یعنی دیوارها در منتهی الیه سمت راست صفحه تولید می شوند و با حلقه فوق ، به سمت چپ هل داده میشن...

پس دیدید که حلقه تابع update از کلاس کامپوننت را صدا می زنه. خود این حلقه داخل تابع update قالب برنامه ماست...
پس دیدید با کلاس توانستیم در و دیوار بازی را هم بسازیم... قهرمان یعنی هواپیما هم کلاس داشت...

حالا من کدهای ساخت فرودگاهم را میدارم تا ببینید:
JavaScript:
    x = canvas.width;
    var y1=303;
     var base1=2600;
      myObstacles.push(new component(base1          ,7, "#889922",      x,              y1+58));
      myObstacles.push(new component_z(base1        ,2, "#ffffff",      x,              y1+65));
      myObstacles_b.push(new component_b(base1      ,2, "#ffffff",      x,               y1+56));
      myObstacles_b.push(new component_b(base1-300  ,7, "#eeee66",      x+200,           y1+49));
 
      airport.push(new component_airport(80,4, "#ff0000",    x+220,             y1+45));
 
      myObstacles_airport.push(new component_b_airport(300,150, "#887922", x+910, y1-75));
در کد بالا می بینید از چند تا آرایه من استفاده کردم. پس در تابع update هم باید چند تا حلقه داشته باشم برای تکون دادن و رسم این اعضای این آرایه ها.
حالا چرا چند تا ارایه دارم؟ یک قسمت فرودگاه ، برای فرود ممنوع است ، پس آرایه اش جداست...
یک قسمت فرودگاه ، در اصل فرودگاه واقعی اونه ، و جاذب هواپیماست.

من هر ۴ کیلومتر یک فرودگاه می سازم.. پس جاذب هواپیما هم تعدادشون یکی نیست و در هر فرودگاه یکی است. فعلا یک مستطیل قرمز است که هواپیما باید بهش تاچ کنه تا متغیر landing. P برابر ۱ بشود.

کد بالا فکر نکنم دیگه شرحی بخواد ، اون y1 هم برای اینه که اگر خواستم کل فرودگاه را بالا و پایین ببرم در صفحه ، اون را تغییر دهم.اون base1 هم طول فرودگاه است... یعنی از چپ تا راستش...
در کد بالا ، دو تا شی اول ، از نوع معمولی است... دو تا شی بعدی از نوع دافع هواپیما ، پنجمی جاذب هواپیما است ، یک مستطیل قرمز است. ff0000 یعنی قرمز. خط آخر یک ساختمان است که همان ساختمان فرودگاه است. ممکن است بعدا خودروهایی با همین روش کد خط آخر به فرودگاه اضافه شود.

اون گلاس کامپوننت که در بالا گفتم برای اشیای معمولی است...دیدید که هیچ تابعی اون کلاس نداشت. ولی کلاس های دیگری من دارم که در پست بعد می بینیم.
 
آخرین ویرایش:

saalek110

Well-Known Member
JavaScript:
<?php
?>
<script>
function component(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
     ctx.fillStyle = color;
     ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}



function component2(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
    ctx.drawImage(   document.getElementById("img2") ,this.x,this.y,this.width,this.height);
    }
}

function component3(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
    ctx.drawImage(   document.getElementById("img3") ,this.x,this.y,this.width,this.height);
    }
}

function component_z(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
             ctx.fillStyle = color;
     ctx.fillRect(this.x, this.y, this.width, this.height);
         }
}
function component_b(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
             ctx.fillStyle = color;
     ctx.fillRect(this.x, this.y, this.width, this.height);
         }
}
function component_airport(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
             ctx.fillStyle = color;
     ctx.fillRect(this.x, this.y, this.width, this.height);
         }
}

function component_b_airport(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    this.update = function() {
    
 
     ctx.drawImage(   document.getElementById("img4") ,this.x,this.y,this.width,this.height);
         }
}

</script>
<?php
?>

کلاسهای دوم به بعد از اولی کپی شده..
برای هر آرایه یک کلاس دارم من تا رسمش کنه.
می بینید بعضی از این کلاس ها ، مستطیل رسم می کنند و بعضی هاشون عکس رسم می کنند.

اون کلاس component_z باید پاک شود.. اولش فرودگاه توی آسمان معلق بود و وقتی هواپیما از زیر به فرودگاه می خورد ، یک رفتار نیاز بوده ، حرف z از کلمه ((زیر)) گرفته شده... بعدا فرودگاه را آوردم روی زمین .

شاید بشه با یک کلاس یا دو کلاس ، کل آرایه ها را رسم کرد ، نمی دونم، فعلا من این جوری کار کردم.
 
آخرین ویرایش:

saalek110

Well-Known Member
من کل کدهای بازی خودم را گذاشتم و شرح دادم ، شاید به کار شما بیاید.

البته کدهای بازی من از کدهای بازی سایت wschool است که در اون یکی تاپیک کدش هست و من شرحش دادم و بعد تکه تکه اش کردم. در اون تاپیک می تونید شرحش را بخوانید.
در این تاپیک کلاس را شرح دادم. در اون تاپیک قطعات اون بازی را شرح دادم.
 

saalek110

Well-Known Member
چطور هر ۴ کیلومتر یک فرودگاه بسازیم؟

یک عدد در تابع update در حال افزایش است به نام frameNo ، البته هر اسمی میشه رویش گذاشت..
در کد زیر با نگاه به اون عدد فرودگاه ها با فاصله شاخته میشن.

update v
JavaScript:
if (frameNo == 1 || everyinterval(4000)) {
}


برای عکس های ساختمون اینو نوشتم:
JavaScript:
 if (frameNo == 1 || everyinterval(300 )) {

}

شاید چون ساختمون عرضش ۳۰۰ بوده.

برای اینکه ساختمونها روی فرودگاه رسم نشوند و بین فرودگاهها رسم بشوند. کد:
JavaScript:
     for (i = 0; i < 20; i += 1) {
    if (frameNo>4000*i+2500 && frameNo<(i+1)*4000-350)  draw();
    }   //   for loop

که تابع draw رسم کننده ساختمونها بوده که کدش اینه:
JavaScript:
function draw(){
  if (frameNo == 1 || everyinterval(300 )) {
        x = canvas.width;

       myObstacles_city1.push(new component2(300,150, "#887922", x, 225));
       myObstacles_city2.push(new component3(300,110, "#887922", x, 205));
 
    }  // interval 300
}  //function
 

saalek110

Well-Known Member
تابع چیست؟

تابع چند خط کد است ، که اسمی رویط بزاریم،
و بعد با صدا زدن اسمش اون چند خط کد اجرا بشه.. چیز پیچیده ای نیست.
در پست قبل تابع draw را صدا زدیم. بعد اسم تابع پرانتز باز و پرانتز بسته داریم. کدهای تابع هم بین کروشه باز و کروشه بسته نوشته میشه. در موقع طدا زدن تابع بعد پرانتز سمی کلون می ذاریم ولی در خود تابع با پرانتز سمی کلون نداره. تابع پست قبل را ببینید.

گاه تابع ورودی دارد، یعنی داخل پرانتز چیزی برای تابع ارسال میشه ، و تابع با توجه به اسم اون ورودی ، اون ورودی را استفاده می کند.
مثلا تابع زیر:
JavaScript:
function myFunction(p1, p2) {
  return p1 * p2;
}
دو ورودی با نام p1 و p2 داره ، و اونها را ضرب در هم می کنه و به عنوان خروجی پس می فرسته... برای دریافت خروجی از تابع باید یک متغیر داشته باشیم. مثلا این جوری:
JavaScript:
let result = myFunction(4, 3);

در لینک زیر:

تابع فوق هست. می توانید کد را تغییر دهید و نتیجه را ببینید.
مثلا من به جای p1 * p2 نوشتم p1 + p2 و داد 7
یعنی تابع جمع دو عدد را پس فرستاد.

تابع از جهتی مثل کارخانه است ، موال اولیه داره و محصول.
البته گاه هیج کدام را نداره. مثلا تابعی مسئول پاک کردن صفحه است ، اسمش را میاریم مثلا clear و اون صفحه را پاک می کنه و ورودی و خروجی به شکل عدد نداره ولی یک کاری را تابع بالاخره انجام می دهد وگرنه بی دلیل که صدایش نمی زنیم که بگیم گفتیم بیا هیچ کاری نکن که معنی نداره.
 

جدیدترین ارسال ها

بالا