از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
مقدمه ای بر فاز 3: توسعه BreakoutGame شاخه ای منحصر به فرد از توسعه نرم افزار است که می تواند به همان اندازه که پیچیده است مفید باشد. وقتی به ساخت بازی فکر می کنیم، معمولاً به برنامه ای برای نصب و بازی فکر می کنیم روی رایانه ها یا کنسول های ما مشخصات HTML5 بسیاری از API ها را برای فعال کردن توسعه بازی معرفی کرد روی …
سرفصلهای مطلب
معرفی
توسعه بازی یک شاخه منحصر به فرد از توسعه نرم افزار است که می تواند به همان اندازه که پیچیده است، پاداش دهنده باشد. وقتی به ساخت بازی فکر می کنیم، معمولاً به برنامه ای برای نصب و بازی فکر می کنیم روی رایانه ها یا کنسول های ما مشخصات HTML5 بسیاری از API ها را برای فعال کردن توسعه بازی معرفی کرد روی وب، به بازی های ما اجازه می دهد تا به کاربران زیادی دسترسی پیدا کنند روی دستگاه های محاسباتی متفاوت Phaser یک چارچوب بازی محبوب است که ما را قادر می سازد تا به سرعت بازی هایی را برای وب بسازیم.
بهترین راه برای تسلط بر توسعه بازی، ساخت بازی است. ما از Phaser برای ایجاد یک Breakout clone، نسخه ای از بازی کلاسیک و همیشگی Atari در سال 1976 استفاده خواهیم کرد.
این آموزش حاوی HTML و CSS بسیار ابتدایی است. شما باید با توابع و اشیاء جاوا اسکریپت راحت باشید. از ویژگیهای ES2015 استفاده سبکی میکند.
حلقه بازی
همه بازی ها در یک حلقه اجرا می شوند. پس از راه اندازی دنیای بازی خود، وارد حلقه بازی می شویم که وظایف زیر را انجام می دهد:
- ورودی فرآیند
- دنیای بازی را به روز کنید
- تغییرات را رندر کنید
بیایید ببینیم که حلقه بازی در بازی مانند Megaman چگونه کار می کند. پس از غربال کردن منو برای شروع یک سطح، بازی تصمیم می گیرد که در کجا پلتفرم ها را قرار دهد و موسیقی را برای پخش بارگذاری می کند. این تنظیم معمولاً در هنگام بارگیری صفحه انجام می شود.
هنگامی که بازی شروع می شود، در دنیایی با پلتفرم ها، دشمنان و آهنگی خاص برای آن سطح، کنترل مگامن را در دست دارید. می توانید از جوی استیک خود برای حرکت مگامن استفاده کنید و یک دکمه را برای پرش یا شلیک فشار دهید. حلقه بازی ورودی را پردازش می کند، موقعیت مگامن را به روز می کند و آن تغییرات را چندین بار در یک ثانیه ارائه می کند.
فازر چیست؟
فازر یک چارچوب بازی HTML5 است. از بسیاری از API های HTML5 مانند Canvas، WebGL، Audio، Gamepad و غیره استفاده می کند و منطق مفیدی مانند مدیریت حلقه بازی و ارائه موتورهای فیزیک به ما اضافه می کند. با Phaser میتوانیم بازیهای دو بعدی را با چیزی جز HTML، CSS و جاوا اسکریپت بسازیم.
قوانین برک آوت
قبل از اینکه از Phaser برای ساخت کلون Breakout خود استفاده کنیم، اجازه دهید ابتدا محدوده بازی را تعریف کنیم:
- این بازی تک نفره دارای یک سطح با 30 آجر، پارو و توپ است
- هدف این است که توپ را به نابودی هر آجر برسانید، در حالی که اطمینان حاصل کنید که از پایین صفحه بازی خارج نمی شود.
- بازیکن یک دست و پا زدن را کنترل می کند که می تواند به چپ و راست حرکت کند
- این بازی برای کاربران وب دسکتاپ ساخته شده است، صفحه کلید برای ورودی استفاده خواهد شد
راه اندازی Phaser
Phaser یک کتابخانه جاوا اسکریپت است، برای توسعه و اجرای بازی خود به چند HTML اولیه برای بارگذاری JS نیاز داریم. یک دایرکتوری به نام ایجاد کنید breakout
در یکی از محیط های کاری شما فایل ها و پوشه های زیر را در دایرکتوری خود ایجاد کنید:
- یک
index.html
فایل - آ
breakout.js
فایل - پوشه ای به نام
assets
- در درون شما
assets
پوشه، ایجاد کنیدimages
پوشه
دارایی های بازی هنر، صدا، ویدئو و سایر داده های مورد استفاده بازی است. برای این شبیه سازی ساده Breakout، دارایی های زیادی وجود ندارد که سازماندهی با پوشه ها را ضروری کند. با این حال، تمرین خوبی است که دارایی های خود را از کد خود جدا نگه دارید و دارایی های خود را بر اساس نوع آنها جدا کنید.
کد زیر را به خود اضافه کنید index.html
فایل:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Breakout</title>
<style>
html,
body {
margin: 0 auto;
padding: 0;
width: 100%;
height: 100%;
}
#game {
margin: 10px auto;
padding: 0;
width: 800px;
height: 640px;
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="game"></div>
<script src="//cdn.jsdelivr.net/npm/(email protected)/dist/phaser.min.js"></script>
<script src="breakout.js"></script>
</body>
</html>
این کد اصلی HTML کارهای زیر را انجام می دهد:
- حاشیه های مرورگر و padding را از html و برچسب بدنه حذف می کند.
- الف را اضافه می کند
game
عنصر div که شامل کلون Breakout ما خواهد بود - Phaser نسخه 3.17 را از طریق CDN بارگیری می کند
- ما را بار می کند
breakout.js
فایلی که در حال حاضر هیچ کاری انجام نمی دهد اما حاوی منطق بازی ما خواهد بود
برای توسعه مؤثر بازیها با Phaser، به این فایلها نیاز داریم که توسط یک وب سرور ارائه شوند. بدون سرور وب، مرورگر ما به دلایل امنیتی اجازه نمی دهد اسکریپت بازی ما دارایی های ما را بارگیری کند.
خوشبختانه برای دریافت یک وب سرور در حال اجرا نیازی به راه اندازی Apache یا Nginx نیست. اگر از کدهای VisualStudio مانند من استفاده می کنید، می توانید آن را نصب کنید سرور زنده افزونه. اکثر IDE ها و ویرایشگرهای متن دارای یک پلاگین با عملکرد مشابه هستند. اگر پایتون نسخه 3 را نصب کرده اید، می توانید از طریق آن به فضای کاری خود بروید terminal و وارد شوید python3 -m http.server
. ابزارهای CLI دیگری وجود دارند که وب سرورهای ساده ای را ارائه می دهند، یکی را انتخاب کنید که سریع ترین زمان را برای توسعه بازی خود در اختیار شما قرار دهد.
در آخر، دانلود کنید دارایی های تصویری ما برای این بازی ایجاد کرده ایم. فایل های PNG را کپی کرده و در پوشه تصاویر پیست کنید.
نکته توسعه – هنگامی که در حال توسعه یک بازی هستید احتمالاً می خواهید جاوا اسکریپت را داشته باشید console قابل مشاهده است تا بتوانید خطاهای ظاهر شده را مشاهده کنید. اگر از کروم یا فایرفاکس استفاده می کنید، کلیک راست کنید روی را page و “Inspect Element” را انتخاب کنید. یک کادر باید از پایین یا کنار پنجره مرورگر شما ظاهر شود. برای مشاهده بهروزرسانیها، خطاها یا گزارشها از کد جاوا اسکریپت، برگه «کنسول» را انتخاب کنید.
ایجاد دنیای بازی ما
با راه اندازی HTML و CSS، بیایید خود را ویرایش کنیم breakout.js
فایل برای راه اندازی دنیای بازی ما.
شروع فازر
ابتدا باید Phaser را پیکربندی کرده و نمونه Game خود را ایجاد کنیم. این نمونه بازی کنترلر مرکزی یک بازی Phaser است، تمام تنظیمات را انجام می دهد و حلقه بازی را برای ما شروع می کند.
موارد زیر را برای پیکربندی و ایجاد نمونه بازی خود اضافه کنید:
// This object contains all the Phaser configurations to load our game
const config = {
type: Phaser.AUTO,
parent: 'game',
width: 800,
height: 640,
scale: {
mode: Phaser.Scale.RESIZE,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: {
preload,
create,
update,
},
physics: {
default: 'arcade',
arcade: {
gravity: false
},
}
};
// Create the game instance
const game = new Phaser.Game(config);
این type
ویژگی به Phaser می گوید که از چه رندری استفاده کند. Phaser می تواند بازی ما را با استفاده از عنصر WebGL یا Canvas HTML5 رندر کند. با تنظیم نوع Phaser.AUTO
، به Phaser می گوییم که ابتدا رندر با WebGL را امتحان کند و اگر موفق نشد با استفاده از Canvas رندر بگیرید.
این parent
ویژگی نشان دهنده شناسه عنصر HTML است که بازی ما در آن بازی خواهد شد. width
و height
. این scale
شی دو کار برای ما انجام می دهد:
mode
به Phaser می گوید که چگونه از فضای عنصر والد خود استفاده کند، در این صورت ما اطمینان می دهیم که بازی با اندازه div والد مطابقت دارد.autoCenter
به Phaser می گوید که اگر بخواهیم چگونه بازی خود را در قسمت اصلی خود متمرکز کنیم. در این حالت، ما بازی خود را به صورت عمودی و افقی در داخل div والد قرار می دهیم. این ویژگی زمانی مفیدتر است که بازی کل فضای div والد را اشغال نکند، در اینجا به عنوان یک سوال متداول نشان داده شده است.
در Phaser منطق بازی ما در Scenes تعریف شده است. صحنه ها را به عنوان حالت های مختلف در بازی ما در نظر بگیرید: صفحه عنوان یک صحنه است، هر سطح از یک بازی صحنه مخصوص به خود خواهد بود، یک صحنه برش صحنه مخصوص به خود خواهد بود. Phaser ارائه می دهد شی صحنه اما می تواند با یک شی جاوا اسکریپت معمولی که حاوی preload
، create
و update
توابع تعریف شده
آخرین پیکربندی به Phaser می گوید که از کدام موتور فیزیک استفاده کند. Phaser می تواند از 3 موتور فیزیکی مختلف استفاده کند: گذرگاه طاقدار، تأثیر و موضوع. Arcade ساده ترین راه برای شروع است و برای نیازهای بازی ما کافی است.
Breakout برای کار کردن به نیروی جاذبه نیاز ندارد، بنابراین ویژگی را غیرفعال می کنیم. اگر ما در حال ساختن یک پلتفرم بودیم، احتمالاً گرانش را فعال میکردیم، به طوری که وقتی بازیکنان ما میپرند، به طور طبیعی به زمین میافتند.
برای اطمینان از اینکه تنظیمات بازی ما کار می کند، باید آن را اضافه کنیم preload
، create
و update
توابع، پس از ایجاد نمونه بازی، توابع خالی زیر را به آن اضافه کنید:
function preload() { }
function create() { }
function update() { }
در حالی که وب سرور شما در حال اجرا است، به مسیر بروید page جایی که بازی شما در حال اجراست شما باید یک صفحه خالی مانند این را ببینید:
بارگیری دارایی ها
دارایی های این بازی از 5 تصویر تشکیل شده است. در بازیهای دیگری که ممکن است ایجاد کنید، داراییهای شما میتواند بسیار زیاد باشد. تصاویر با کیفیت بالا، فایل های صوتی و تصویری می توانند مگابایت فضا را اشغال کنند. هر چه دارایی بزرگتر باشد، مدت زمان بیشتری طول می کشد. به همین دلیل، Phaser دارای یک preload
عملکردی که در آن میتوانیم تمام داراییها را قبل از شروع بازی بارگیری کنیم. انجام یک بازی هرگز یک تجربه کاربری خوب نیست و ناگهان سرعت آن کاهش می یابد زیرا در تلاش برای بارگذاری دارایی های جدید است.
تغییر دادن preload
به صورت زیر عمل کنید تا بتوانیم تصاویر خود را قبل از شروع حلقه بازی بارگذاری کنیم:
function preload() {
this.load.image('ball', 'assets/images/ball_32_32.png');
this.load.image('paddle', 'assets/images/paddle_128_32.png');
this.load.image('brick1', 'assets/images/brick1_64_32.png');
this.load.image('brick2', 'assets/images/brick2_64_32.png');
this.load.image('brick3', 'assets/images/brick3_64_32.png');
}
آرگومان اول کلیدی است که بعداً برای ارجاع تصویر از آن استفاده خواهیم کرد، آرگومان دوم مکان تصویر است.
با لود شدن تصاویر، می خواهیم اسپرایت ها را قرار دهیم روی صفحه نمایش در بالای breakout.js
، این متغیرها را اضافه کنید که حاوی داده های sprite ما هستند:
let player, ball, violetBricks, yellowBricks, redBricks;
هنگامی که آنها به صورت جهانی تعریف شدند، همه توابع ما می توانند از آنها استفاده کنند.
افزودن Sprites
اسپرایت هر تصویر دو بعدی است که بخشی از صحنه بازی باشد. در Phaser، یک sprite یک تصویر را به همراه موقعیت، سرعت، خواص فیزیکی و سایر ویژگیهای آن کپسوله میکند. بیایید با ایجاد اسپرایت بازیکن خود شروع کنیم. در create
تابع موارد زیر را اضافه کنید:
player = this.physics.add.sprite(
400, // x position
600, // y position
'paddle', // key of image for the sprite
);
اکنون باید بتوانید یک پارو را ببینید روی صفحه نمایش:
اولین استدلال از sprite
روش مختصات X برای قرار دادن sprite است. آرگومان دوم مختصات Y است و آخرین آرگومان کلید دارایی تصویر اضافه شده در آن است preload
تابع.
درک اینکه چگونه Phaser و اکثر چارچوب های بازی دو بعدی از مختصات استفاده می کنند بسیار مهم است. نمودارهایی که در مدرسه یاد گرفتیم معمولاً مبدأ یعنی نقطه (0، 0) را در مرکز قرار می دهند. در Phaser، مبدا در سمت چپ بالای صفحه است. با افزایش x، اساساً به سمت راست حرکت می کنیم. با افزایش y، ما به سمت پایین حرکت می کنیم. عرض بازی ما 800 پیکسل و ارتفاع 640 پیکسل است، بنابراین مختصات بازی ما به این صورت خواهد بود:
بیایید توپ را اضافه کنیم تا بالای بازیکن بنشیند. کد زیر را به create
تابع:
ball = this.physics.add.sprite(
400, // x position
565, // y position
'ball' // key of image for the sprite
);
همانطور که توپ است در بالا بازیکن ما، مقدار Y Coordinate است پایین تر از مختصات Y بازیکن.
اضافه کردن Sprite Groups
در حالی که Phaser اضافه کردن sprite را آسان می کند، اگر هر sprite به صورت جداگانه تعریف شود، به سرعت خسته کننده خواهد شد. آجرهای Breakout تقریباً یکسان هستند. موقعیت ها متفاوت است، اما ویژگی های آنها مانند رنگ و روش تعامل آنها با توپ یکسان است. به جای ایجاد 30 شیء sprite آجری، می توانیم از گروه های Create Sprite برای مدیریت بهتر آنها استفاده کنیم.
بیایید ردیف اول آجرهای بنفش را اضافه کنیم. در شما create
تابع موارد زیر را اضافه کنید:
// Add violet bricks
violetBricks = this.physics.add.group({
key: 'brick1',
repeat: 9,
setXY: {
x: 80,
y: 140,
stepX: 70
}
});
بجای this.physics.add.sprite
ما استفاده می کنیم this.physics.add.group
و یک شی جاوا اسکریپت را ارسال کنید. ویژگی key به کلید تصویری اشاره می کند که همه sprites در گروه sprite از آن استفاده خواهند کرد. این repeat
ویژگی به Phaser می گوید که چند بار دیگر یک sprite ایجاد کند. هر گروه جن یک اسپرایت ایجاد می کند. با repeat
با تنظیم 9، Phaser 10 sprite در آن گروه sprite ایجاد می کند. این setXY
شی سه ویژگی جالب دارد:
x
مختصات X اولین جن استy
مختصات Y از جن دوم استstepX
طول بین اسپرایت های مکرر بر حسب پیکسل است روی محور x
وجود دارد stepY
دارایی نیز هست اما نیازی به استفاده از آن برای این بازی نداریم. بیایید دو گروه جن باقی مانده برای آجرها را اضافه کنیم:
// Add yellow bricks
yellowBricks = this.physics.add.group({
key: 'brick2',
repeat: 9,
setXY: {
x: 80,
y: 90,
stepX: 70
}
});
// Add red bricks
redBricks = this.physics.add.group({
key: 'brick3',
repeat: 9,
setXY: {
x: 80,
y: 40,
stepX: 70
}
});
بازی ما در حال حاضر گرد هم آمده است، صفحه نمایش شما باید شبیه این باشد:
برد و باخت
این تمرین خوبی برای توسعه بازی (و برنامه نویسی) است تا پایان را در چشم نگه دارید. در Breakout، اگر توپ ما به پایین صفحه بیفتد، می توانیم یک بازی را ببازیم. در Phaser، برای اینکه توپ زیر صفحه باشد، مختصات Y توپ بیشتر از ارتفاع دنیای بازی است. بیایید یک تابع ایجاد کنیم که این را بررسی کند، پایین آن را اضافه کنید breakout.js
موارد زیر را اضافه کنید:
function isGameOver(world) {
return ball.body.y > world.bounds.height;
}
تابع ما شی جهان را از ویژگی فیزیک صحنه می گیرد، که در دسترس خواهد بود update
تابع. بررسی می کند که آیا مختصات Y توپ اسپرایت بزرگتر از ارتفاع مرزهای جهان بازی است یا خیر.
برای برنده شدن در بازی باید از شر تمام آجرها خلاص شویم. Sprites در Phaser همه دارای یک ویژگی فعال هستند. ما می توانیم از آن ویژگی برای تعیین اینکه آیا برنده شده ایم یا نه استفاده کنیم. گروههای Sprite میتوانند مقدار اسپرایتهای فعال موجود در آنها را بشمارند. اگر در هر یک از گروههای بریک اسپرایت، هیچ جن فعالی وجود نداشته باشد، یعنی 0 اسپرایت آجری فعال وجود داشته باشد، بازیکن برنده بازی است. در پایین شما breakout.js
تابع زیر را اضافه کنید:
function isWon() {
return violetBricks.countActive() + yellowBricks.countActive() + redBricks.countActive() == 0;
}
هر یک از گروههای اسپرایت را بهعنوان پارامتر میپذیریم، تعداد اسپرایتهای فعال درون آنها را اضافه میکنیم و بررسی میکنیم که آیا برابر با ۰ است یا خیر.
اکنون که شرایط برد و باخت خود را مشخص کردهایم، میخواهیم Phaser آنها را هر بار در ابتدای حلقه بازی بررسی کند. به محض اینکه بازیکن برنده یا ببازد، بازی باید متوقف شود. تغییر دادن update
عملکرد به موارد زیر:
function update() {
// Check if the ball left the scene i.e. game over
if (isGameOver(this.physics.world)) {
// TODO: Show "Game over" message to the player
} else if (isWon()) {
// TODO: Show "You won!" message to the player
} else {
// TODO: Logic for regular game time
}
}
هیچ تغییر بصری برای آن به روز رسانی کد وجود ندارد.
توجه داشته باشید – وقتی استفاده می کنیم this
در ما preload
، create
و update
توابع، ما به صحنه اجرا شده توسط نمونه بازی اشاره می کنیم که قبلا ایجاد شده بود.
حرکت پخش کننده با ورودی صفحه کلید
حرکت بازیکن بستگی دارد روی ورودی صفحه کلید برای اینکه بتوانیم ورودی صفحه کلید را ردیابی کنیم، یک متغیر سراسری به نام اضافه می کنیم cursors
در بالای breakout.js
:
let player, ball, violetBricks, yellowBricks, redBricks, cursors;
و در پایین ما create
تابع، موارد زیر را اضافه کنید:
cursors = this.input.keyboard.createCursorKeys();
کلیدهای مکان نما در Phaser استفاده از 6 کلید صفحه کلید را ردیابی می کنند: بالا، راست، پایین، چپ، شیفت و فاصله.
اکنون باید به وضعیت خود واکنش نشان دهیم cursors
اعتراض به به روز رسانی موقعیت بازیکن ما. در else
بند ما update
تابع موارد زیر را اضافه کنید:
// Put this in so that the player stays still if no key is being pressed
player.body.setVelocityX(0);
if (cursors.left.isDown) {
player.body.setVelocityX(-350);
} else if (cursors.right.isDown) {
player.body.setVelocityX(350);
}
حالا ما می توانیم پخش کننده خود را از چپ به راست حرکت دهیم!
متوجه خواهید شد که بازیکن اسپرایت می تواند از صفحه بازی خارج شود، در حالت ایده آل اینطور نباشد. بعداً وقتی برخوردها را کنترل کنیم به آن خواهیم پرداخت.
در انتظار شروع
قبل از اینکه منطق را برای حرکت دادن توپ اضافه کنیم، اگر بازی منتظر بماند کمک خواهد کرد روی ورودی کاربر قبل از جابجایی این تجربه خوبی نیست که یک بازی را بارگذاری کنید و بلافاصله مجبور شوید بازی کنید، بازیکن زمان مناسبی برای واکنش نخواهد داشت!
اجازه دهید پس از اینکه بازیکن کلید فاصله را فشار داد، توپ را به سمت بالا حرکت دهیم. اگر کاربر دست و پا را به سمت چپ یا راست حرکت دهد، توپ نیز به گونهای حرکت میکند که همیشه در مرکز پارو باشد.
اول، ما به متغیر خود نیاز داریم تا ردیابی کنیم که آیا بازی شروع شده است یا نه. در بالای breakout.js
، پس از اعلام متغیرهای بازی ما موارد زیر را اضافه کنید:
let gameStarted = false;
همانطور که از نام آن پیداست، آن متغیر ردیابی می کند که آیا بازی ما شروع شده است یا نه. در حال حاضر، در else
بند تابع به روز رسانی ما موارد زیر را اضافه کنید:
if (!gameStarted) {
ball.setX(player.x);
if (cursors.space.isDown) {
gameStarted = true;
ball.setVelocityY(-200);
}
}
اگر بازی شروع نشده است، X Coordinate یا توپ خود را در مرکز بازیکن قرار دهید. مختصات یک شی بازی مبتنی است روی مرکز آنها، بنابراین x
و y
خواص جن ها به مرکز جن ما مربوط می شود.
توجه داشته باشید که در عین حال خوب است که ارزش یک ملک را مانند x
با ارجاع مستقیم به آن، هنگام تنظیم خصوصیات، همیشه سعی می کنیم از تابع تنظیم کننده مناسب استفاده کنیم. توابع تنظیم کننده می تواند شامل منطق برای اعتبارسنجی ورودی ما، به روز رسانی یک ویژگی دیگر یا فعال کردن یک رویداد باشد. کد ما را قابل پیش بینی تر می کند.
مانند قبل با حرکت پخش کننده، چک می کنیم که آیا کلید فاصله فشرده شده است یا خیر. اگر فشار داده می شد، آن را تغییر می دادیم gameStarted
پرچم به true
بنابراین توپ دیگر از موقعیت افقی بازیکن پیروی نمی کند و سرعت Y توپ را روی 200- تنظیم کنید. سرعت های منفی y اجسام را به سمت بالا می فرستند. برای سرعت های مثبت، مقادیر بزرگتر اجسام را سریعتر به سمت پایین حرکت می دهند. برای سرعت های منفی، مقادیر کوچکتر اجسام را سریعتر به سمت بالا حرکت می دهند.
حالا وقتی بازیکن را حرکت می دهیم، توپ دنبال می شود و اگر فاصله را فشار دهیم توپ به سمت بالا شوت می کند:
شما می توانید چند نکته را از روش رفتار بازی ما تا کنون مشاهده کنید:
- توپ در پشت آجرها رندر می شود
- بازیکن می تواند از محدوده های صفحه خارج شود
- توپ می تواند از محدوده های صفحه خارج شود
توپ در پشت آجرها رندر می شود زیرا در عملکرد ایجاد ما قبل از گروه های آجر اسپرایت به بازی اضافه شده است. در فازر و به طور کلی با عنصر بوم HTML5، جدیدترین تصویر اضافه شده ترسیم می شود روی بالای تصاویر قبلی
دو مسئله آخر را می توان با اضافه کردن مقداری برخورد جهانی حل کرد.
رسیدگی به برخوردها
برخورد جهانی
تمام تعاملات جن ما در تعریف شده است create
تابع. فعال کردن برخورد با صحنه جهان با Phaser بسیار آسان است، موارد زیر را به انتهای آن اضافه کنید create
تابع:
player.setCollideWorldBounds(true);
ball.setCollideWorldBounds(true);
باید خروجی اینگونه به ما بدهد:
در حالی که حرکت بازیکن خوب است، به نظر می رسد توپ در بالا گیر کرده است. برای رفع این مشکل، باید آن را تنظیم کنیم bounce
خاصیت توپ اسپرایت این bounce
ویژگی به Phaser می گوید که پس از برخورد با یک جسم چقدر سرعت را حفظ کند. این را به انتهای خود اضافه کنید create
تابع:
ball.setBounce(1, 1);
این به فازر می گوید که توپ باید تمام سرعت X و Y خود را حفظ کند. اگر توپ را با نوار فاصله رها کنیم، توپ باید در دنیای بازی بالا و پایین بپرد. ما باید تشخیص برخورد را از قسمت پایین دنیای بازی غیرفعال کنیم. اگر این کار را نکنیم، هرگز نخواهیم فهمید که بازی چه زمانی تمام می شود. با اضافه کردن این خط در انتهای بازی، برخورد با پایین دنیای بازی را غیرفعال کنید create
تابع:
this.physics.world.checkCollision.down = false;
اکنون باید یک بازی مانند این داشته باشیم:
برخورد آجر
حالا که جن های متحرک ما به درستی با دنیای بازی ما برخورد می کنند، بیایید کار کنیم روی برخورد بین توپ و آجر و سپس توپ و بازیکن.
در تابع ایجاد ما در خطوط کد زیر تا انتها:
this.physics.add.collider(ball, violetBricks, hitBrick, null, this);
this.physics.add.collider(ball, yellowBricks, hitBrick, null, this);
this.physics.add.collider(ball, redBricks, hitBrick, null, this);
این collider
روش به سیستم فیزیک Phaser می گوید که آن را اجرا کند hitBrick
عملکرد زمانی که ball
با گروه های مختلف آجری برخورد می کند.
هر بار که فاصله را فشار می دهیم، توپ به سمت بالا شوت می کند. X Velocity وجود ندارد تا توپ مستقیماً به پارو برگردد. این یک بازی خسته کننده خواهد بود. بنابراین، هنگامی که برای اولین بار به یک آجر برخورد می کنیم، سرعت X را تنظیم می کنیم. در پایین breakout.js
تعریف کردن hitBrick
زیر:
function hitBrick(ball, brick) {
brick.disableBody(true, true);
if (ball.body.velocity.x == 0) {
randNum = Math.random();
if (randNum >= 0.5) {
ball.body.setVelocityX(150);
} else {
ball.body.setVelocityX(-150);
}
}
}
این hitBrick
تابع دو آرگومان قبلی را که در collider
روش مثلا ball
و violetBricks
. این disableBody(true, true)
زنگ زدن روی آجر به Phaser می گوید که آن را غیرفعال کند و آن را از صفحه پنهان کند. اگر سرعت X توپ 0 باشد، بسته به آن سرعتی به توپ می دهیم روی مقدار یک عدد تصادفی
اگر یک توپ کوچک با سرعت آهسته به سمت پای شما بغلتد، روی برخورد آن را متوقف خواهد کرد. موتور Arcade Physics برخورد ضربه ای را مدل می کند روی سرعت به صورت پیش فرض برای بازی ما، نمیخواهیم توپ با برخورد به آجر، سرعت خود را از دست بدهد. ما باید تنظیم کنیم immovable
اموال به گروه های جن ما به true
. تعاریف را به روز کنید violetBricks
، yellowBricks
و redBricks
به موارد زیر:
// Add violet bricks
violetBricks = this.physics.add.group({
key: 'brick1',
repeat: 9,
immovable: true,
setXY: {
x: 80,
y: 140,
stepX: 70
}
});
// Add yellow bricks
yellowBricks = this.physics.add.group({
key: 'brick2',
repeat: 9,
immovable: true,
setXY: {
x: 80,
y: 90,
stepX: 70
}
});
// Add red bricks
redBricks = this.physics.add.group({
key: 'brick3',
repeat: 9,
immovable: true,
setXY: {
x: 80,
y: 40,
stepX: 70
}
});
برخورد آجری ما اکنون کامل شده است و بازی ما باید به این صورت عمل کند:
نکته توسعه – هنگام توسعه فیزیک بازی خود، ممکن است بخواهید حالت اشکال زدایی را فعال کنید تا جعبه های مرزی اسپرایت ها و روش برخورد آنها با یکدیگر را ببینید. در بازی شما config
شیء، در داخل arcade
ملکی که در آن تعریف کردیم gravity
، می توانید اشکال زدایی را با اضافه کردن این به شی فعال کنید:
debug: true
برخورد بازیکن
مدیریت برخورد بین توپ و بازیکن نیز تلاشی مشابه است. اول، بیایید مطمئن شویم که بازیکن غیرقابل حرکت است. در پایان از create
تابع موارد زیر را اضافه کنید:
player.setImmovable(true);
و سپس a را اضافه می کنیم collider
بین توپ و بازیکن:
this.physics.add.collider(ball, player, hitPlayer, null, this);
وقتی توپ به بازیکن برخورد می کند، ما می خواهیم دو اتفاق بیفتد:
- توپ باید کمی سریعتر حرکت کند تا به تدریج سختی بازی افزایش یابد
- جهت افقی توپ بستگی دارد روی به کدام سمت بازیکن ضربه می زند – اگر توپ به سمت چپ بازیکن برخورد کند باید به سمت چپ برود و اگر به سمت راست بازیکن برخورد کند باید به سمت راست برود.
در پایین شما breakout.js
اضافه کردن hitPlayer
تابع:
function hitPlayer(ball, player) {
// Increase the velocity of the ball after it bounces
ball.setVelocityY(ball.body.velocity.y - 5);
let newXVelocity = Math.abs(ball.body.velocity.x) + 5;
// If the ball is to the left of the player, ensure the X Velocity is negative
if (ball.x < player.x) {
ball.setVelocityX(-newXVelocity);
} else {
ball.setVelocityX(newXVelocity);
}
}
توجه داشته باشید – یک اسپرایت می تواند با دیگری برخورد کند، یک جن می تواند با یک گروه اسپرایت برخورد کند و گروه های جن می توانند با یکدیگر برخورد کنند. Phaser به اندازه کافی هوشمند است تا از تابع برخوردی که ما در زمینه مناسب تعریف می کنیم استفاده کند.
اکنون بازی ما هم برخورد بازیکن و هم برخورد آجری دارد:
اضافه کردن متن
در حالی که بازی ما کاملاً کاربردی است، کسی که این بازی را بازی می کند نمی داند چگونه بازی را شروع کند یا بداند چه زمانی بازی تمام شده است. اضافه کردن 3 متغیر جهانی اخبار که داده های متنی ما را بعد از ذخیره می کند gameStarted
اعلامیه در بالای breakout.js
:
let openingText, gameOverText, playerWonText;
باز کردن متن
بیایید وقتی بازی لود می شود، متنی اضافه کنیم تا به بازیکن بگوییم فاصله را فشار دهد. در create
تابع کد زیر را اضافه کنید:
openingText = this.add.text(
this.physics.world.bounds.width / 2,
this.physics.world.bounds.height / 2,
'Press SPACE to Start',
{
fontFamily: 'Monaco, Courier, monospace',
fontSize: '50px',
fill: '#fff'
},
);
openingText.setOrigin(0.5);
دو استدلال اول از text
متد مختصات X و Y جعبه متن هستند. ما از عرض و ارتفاع صحنه بازی برای تعیین محل قرارگیری آن – در مرکز استفاده می کنیم. آرگومان سوم متنی است که باید نمایش داده شود. آرگومان چهارم یک شی JS است که حاوی داده های مرتبط با فونت است.
بر خلاف sprites، اشیاء متنی X و Y مختصات به قسمت بالای سمت چپ شی اشاره میکنند، نه مرکز آنها. به همین دلیل است که ما از setOrigin
روشی برای اینکه سیستم مختصات مانند sprites کار کند، در این مورد موقعیت قرار گرفتن در مرکز را آسانتر میکند.
وقتی در حال بازی هستیم، دیگر نمی خواهیم متن آغازین را ببینیم. در update
تابع، عبارت if را که بررسی می کند که آیا نوار فاصله فشرده شده است را به صورت زیر تغییر دهید:
if (cursors.space.isDown) {
gameStarted = true;
ball.setVelocityY(-200);
openingText.setVisible(false);
}
اشیاء متنی جن نیستند، نمیتوانیم بدنه آنها را غیرفعال کنیم. زمانی که نیازی به دیدنشان نداریم، می توانیم آنها را نامرئی کنیم. بازی ما اکنون به این صورت شروع می شود:
Game Over و Game Won Text
مانند قبل، باید اشیاء متنی را در آن اضافه کنیم create
عملکرد، و آنها را نامرئی کنید تا هنگام شروع بازی دیده نشوند:
// Create game over text
gameOverText = this.add.text(
this.physics.world.bounds.width / 2,
this.physics.world.bounds.height / 2,
'Game Over',
{
fontFamily: 'Monaco, Courier, monospace',
fontSize: '50px',
fill: '#fff'
},
);
gameOverText.setOrigin(0.5);
// Make it invisible until the player loses
gameOverText.setVisible(false);
// Create the game won text
playerWonText = this.add.text(
this.physics.world.bounds.width / 2,
this.physics.world.bounds.height / 2,
'You won!',
{
fontFamily: 'Monaco, Courier, monospace',
fontSize: '50px',
fill: '#fff'
},
);
playerWonText.setOrigin(0.5);
// Make it invisible until the player wins
playerWonText.setVisible(false);
اکنون آنها تعریف شده اند، ما باید دید آنها را در آن تغییر دهیم update
تابع:
// Check if the ball left the scene i.e. game over
if (isGameOver(this.physics.world)) {
gameOverText.setVisible(true);
ball.disableBody(true, true);
} else if (isWon()) {
playerWonText.setVisible(true);
ball.disableBody(true, true);
} else {
...
ما بدنه توپ را غیرفعال میکنیم تا دیگر بهروزرسانی نشود و بهعنوان دیگر به آن نمایش داده نشود.
اگر بازی را ببازیم، این را خواهیم دید:
اگر بازی را ببریم، این را خواهیم دید:
کلون Breakout ما کامل شد!
نتیجه
Phaser یک چارچوب توسعه بازی HTML5 است که به ما اجازه می دهد تا به سرعت بازی های ویدیویی بسازیم روی وب. جدا از انتزاع بر روی API های HTML5، ابزارهای مفیدی مانند موتورهای فیزیک را نیز در اختیار ما قرار می دهد و حلقه بازی را مدیریت می کند – چرخه عمر اجرای همه بازی ها.
ما یک کلون Breakout ساختیم توسط:
- بارگیری دارایی های ما، در این مورد تصاویر ما
- ایجاد اسپرایت برای بازیکن و توپ ما و گروه های جن برای آجرهایمان
- گوش دادن به رویدادهای صفحه کلید تا بتوانیم پخش کننده را حرکت دهیم
- استفاده از موتور فیزیک برای رسیدگی به برخورد بین اشیاء جن و دنیای بازی
- نمایش متن برای آموزش بازیکن و اطلاع دادن به آنها در صورت برد یا باخت
از یک رویکرد مشابه برای توسعه می توان برای ایجاد بازی های دیگر در Phaser استفاده کرد.
بهترین راه برای بهبود مهارت های توسعه بازی، ادامه ساختن بازی ها است. اگر دوست دارید در مورد ساخت بازی با Phaser بیشتر بدانید، به مقدمه وب سایت رسمی نگاهی بیندازید. آموزش.
می توانید کد منبع حاشیه نویسی بازی را مشاهده کنید اینجا.
(برچسبها به ترجمه)# روش
منتشر شده در 1403-01-25 07:49:11