فصل پنجم:تشخیص برخورد
تشخیص برخورد یکی از نیاز های اساسی بازی به شمار می رود .شما برای تشخیص برخورد تیر به هدف یا برخورد شی با زمین یا هزار اتفاق دیگر نیاز دارید که این برخورد ها را تشخیص دهید .دو راه معمول برای تشخیص برخورد وجود دارد:
- یکی از راه ها استفاده از چهار ضلعی است که از آن می توان برای بیشتر بازی های معمولی استفاده کرد و روند خیلی ساده ای دارد .
- راه دوم استفاده از انجین فیزیک است که برای اشیاء با پیچدگی های ظاهری زیاد و چند ظلعی های نامتوازن استفاده می شود .استفاده از این روش نیازمند آشنایی با انجین فیزیک و یک سری اصول فیزیک می باشد و پیچیدگی آن نسبت به روش اول بیشتر است .
در بازی FlappyBird ما از همان روش چهار ضلعی استفاده می کنیم .
برای شروع در ابتدا یک آرایه ایجاد می کنیم .سپس در فواصل زمانی مشخص لوله هایی را به صحنه اضافه کرده و آنها را در صحنه حرکت می دهیم .و در هر بار تغیر مکان برخورد آن با پرنده را بررسی می کنیم .
پس :
اول آرایه مورد نظر را تعریف می کنیم .
_pipes:[],
در ادامه یک تابع تعریف می کنیم که کار اضافه کردن لوله ها را انجام می دهد و در هر بار اجرا دو لوله یکی در بالا و یکی در پایین با یک فاصله معقول در مکانی تصادفی ایجاد می کند (نحوه اضافه کردن عکس به فایل resource.jsرو که احتمالا فراموش نکردید حتما باید قبلش این کار رو انجام بدهید و عکس دو لوله را که جدیداَ به پروژه اضافه کردیم به این فایل همانند مراحل قبلی اضافه کنید).
addPipe:function(){ //add top pipe var topPipe=new cc.Sprite(res.PipeUp_png); topPipe.setAnchorPoint(0.5, 0); topPipe.attr({ x:350, y:Math.floor((Math.random() * (400-320)) + 320) }); this.addChild(topPipe,0); this._pipes.push(topPipe); var btmPipe=new cc.Sprite(res.PipeDown_png); btmPipe.setAnchorPoint(0.5,1); btmPipe.attr({ x:350, y:topPipe.getPositionY()-150 }); this.addChild(btmPipe,0); this._pipes.push(btmPipe); }
کل کاری که این تابع انجام میدهد اضافه کردن دو لوله یکی در پایین و یکی در بالا با یک فاصله معقول و در یک مکان تصادفی است و لوله اضافه شده را نیز به آرایه ای که به این منظور در نظر گرفته شده است اضافه می کند.
بحث مربوط به متد ancherpoint هم مربوط به محل اتکا برای تغیر موقعیت شی بر اساس خود شی است.برای درک بهتر از شکل زیر کمک بگیرید.به صورت پیش فرض این مقدار برابر با 0.5 ,0.5 است که به مرکز اشاره میکند میتوان با تغیر دادن هرکدوم از این مقادیر به گوشه ها مختلف شی اشاره کرد.
بعد لازم است که این تابع را در یک بازه زمانی خاص فراخوانی کنیم .
this.schedule(this.addPipe,5);
برای حرکت دادن لوله ها هم می توان از متد runAction استفاده کرد هم می توان به صورت یک تابع جداگانه حرکت لوله ها را انجام داد که من از روش تعریف تابع استفاده کردم و در تابع update که قبلا نوشته شده بود برای حرکت لوله ها هم استفاده کردم .
for(i=0;i<this._pipes.length;i++ ){ var curPipe=this._pipes[i]; curPipe.setPositionX(curPipe.getPositionX()-1); //chec collision //remove Object in End path if(curPipe.getPositionX()< -30){ this._pipes.splice(i,1); this.removeChild(curPipe, true); } if(cc.rectIntersectsRect(_bird.getBoundingBox(), curPipe.getBoundingBox())){ cc.log("Game Over.."); this.unschedule(update); this.unschedule(scrollGround); _bird.stopAllActions(); } }
در قطعه کد بالا تابع
cc.rectIntersectsRect
دو چهار ضلعی را می گیرد و مشخص می کند که آیا با هم برخورد داشته اند یا نه .
در این قطعه کد در یک حلقه به اندازه تمامی لوله های موجود در صحنه شرط برخورد با پرنده را چک میکند و در صورت بخورد بازی متوقف می شود .
وقتی که لوله از صحنه خارج می شود باید از بازی و ارایه حذف شود .
در بخش های بعدی باید تعداد لوله هایی را که بازیکن با موفقیت پشت سر میگذارد حساب کنیم ....
لینک پروژه در gitHub بدون پوشه frameworks