ایجاد بازی مورد نظر

Ratings
(0)

در این لحظه ما به اندازه ی کافی درباره ی اپلیکیشن های کروم اطلاعات داریم و همچنین درباره ی کنترل کردن یک دسته ی بازی حسگر حرکت اطلاعات داریم. نوشتن یک بازی ویدئویی مستقیماً به برنامه نویسی آردوینو مربوط نمی شود. همیشه این برنامه تکنیک هایی را به ما نشان می دهد که می توانیم، از آنها در دیگر پروژه ها استفاده کنیم؛ و باعث می شود که درک بهتری از چگونگی کارکرد سخت افزار و نرم افزار داشته باشیم.

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

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="/css/arduinoid.css"/>
    <title>Arduinoid</title>
  </head>
  <body>
    <div id="game">
      <div id="playfield">
        <div id="paddle"></div>
        <div id="ball"></div>
        <div id="winner" class="message">
          <p>You win!</p>      
        </div>
        <div id="game_over" class="message">
          <p>Game Over</p>      
        </div>
      </div>
      <div id="stats">
        <div>Lives: <span id="lives"/></div>
        <div>Score: <span id="score"/></div>
      </div>
    </div>
    <audio src="/sound/awake10_megaWall.mp3" autoplay loop/>
    <script src="/js/jquery-1.11.1.min.js"></script>
    <script src="/js/serial_device.js"></script>
    <script src="/js/game_controller.js"></script>
    <script src="/js/arduinoid.js"></script>
  </body>
</html>

آدرس:

BrowserGame/Arduinoid/main.html

این سند HTML توضیح خاصی ندارد. در بالای این کدها، ما سند را با یک برگه ی استایل به نام arduinoid.css مرتبط کرده ایم. ما در داخل برگه ی استایل مذکور تمام کدهایی که برای چینش نیاز داریم را قرار داده ایم. سپس یک جفت عنصر <div> را تعریف کرده ایم. عنصر div اصلی یک id به نام game دارد و حاوی تمام دیگر عناصر است. اکثر این عناصر نسبتا واضح هستند. عنصر div که آی دی آن playfield مکانی است که عملیات صورت می گیرد. این عنصر حاوی عناصر با آی دی paddle و ball است. این عناصر اشیاء اصلی بازی، یعنی مانع(paddle ) و توپ(ball) را مشخص می کنند. عناصر بازی دیگر، یعنی عناصر winner و game_over حاوی پیغام هایی هستند که ما در صورتی که فرد، بازی را برنده شود یا بازنده شود، آنها را به او نشان می دهیم. وقتی که بازی شروع می شود، این پیغام ها غیر قابل مشاهده خواهند بود.

ما در عنصر stats می توانیم مهم ترین اطلاعات آماری بازی یعنی تعداد جان های باقی مانده، و امتیاز فعلی را مشاهده کنیم. پس از آن، ما یک موسیقی 8 بیتی که توسط آقای الکس اسمیت ایجاد شده است را با استفاده از عنصر audio به بازی خود اضافه می کنیم. برای دانلود این موسیقی اینجا کلیک کنید. خصوصیت autoplay باعث می شود که صدا بلافاصله پخش شود، و خصوصیت loop نیز باعث می شود که صدا به صورت حلقه مانند پخش شود. چون این موسیقی بلند است، مشکلی پیش نخواهد آمد. در نهایت ما تمام کدهای جاوا اسکریپت که نیاز داریم را اضافه(import) می کنیم. کتابخانه ی جی کوئری، یک ابزار بسیار معروف است که از آن برای ایجاد اپلیکیشن های وب داینامیک استفاده می شود. با این کتابخانه، دستکاری کردن عناصر HTML بسیار ساده است و می تواند باعث شود که کارهای ما بسیار ساده تر شود. ما قبلا با فایل های serial_device.js و game_controller.js آشنایی داریم. فایل arduinoid.js بسیار جالب تر است، زیرا حاوی منطق حقیقی بازی است. در ابتدای این فایل، تعدادی ساختار وجود دارد که حاوی مهمترین اطلاعات وضعیت بازی است:

const MAX_LIVES = 5;

var GameStates = {
  RUNNING: 'running',
  PAUSED: 'paused',
  LOST: 'lost',
  WON: 'won'
}

var Game = {
  lives: MAX_LIVES,
  score: 0,
  state: GameStates.PAUSED,

  paddle: {
    speed: 15,
    width: $("#paddle").width(),
    height: $("#paddle").height()
  },

  playfield: {
    width: $("#playfield").width(),
    height: $("#playfield").height(),
    rows: 4,
    columns: 10
  },

  ball: {
    diameter: $("#ball").width(),
    vx: 5 + Math.random() * 5,
    vy: -10
  },

  controller: new GameController('/dev/tty.usbmodem24321')
}

آدرس:

BrowserGame/Arduinoid/js/arduinoid.js

در ابتدای کدها، یک ثابت(constant) به نام MAX_LIVES تعریف می کنیم که حاوی ماکزیمم مقدار جان ها(lives) در بازی است.

شیء GameStates حالت های امکان پذیر بازی را تعریف می کند. این یک الگوی متداول در برنامه نویسی بازی است، و بعدا خواهید دید که نوشتن حلقه ی(loop) اصلی، وقتی که ما حالت های بازی را شناسایی می کنیم، چقدر ساده است. شیء Game تمام پروپرتی های بازی را تعریف می کند؛ مانند امتیاز فعلی و حالت فعلی بازی. این شیء همچنین حاوی تمامی اطلاعات در مورد اشیاء بازی است، مثل سرعت فعلی توپ در تمام جهت ها یا سرعت مانع(paddle).

البته این شیء یک شیء دیگر را تعریف می کند و ما باید مسیر پورت سریال آردوینو را در آن تنظیم کنیم. اکثر اشیاء درون شیء Game، در ابتدا ثابت ها(constants) هستند. ما تنها سرعت توپ(ball) را در جهت محور X به صورت یک مقدار تصادفی تنظیم می کنیم.

به این طریق، وقتی که ما یک بازی جدید را شروع می کنیم، توپ همواره در یک جهت یکسان قرار نمی گیرد. توجه کنید که ما برای اولین بار است، که وقتی که داریم width و height اشیاء بازی را مشخص می کنیم، از جی کوئری استفاده می کنیم. به قطعه کد زیر دقت کنید:

width: $("#paddle").width()

این دستور در ابتدا کمی مبهم است،اما اگر دقت کنید، معلوم است که عرض(width) مانع(paddle) را مشخص می کند. در کد بالا، از مهمترین متد جی کوئری استفاده شده است. نام این متد $ است و ما در جاوا اسکریپت می توانیم یک تابع به نام $ تعریف کنیم. متد مذکور یک متد همه کاره است که ما می توانیم برای اهداف مختلفی از آن استفاده کنیم.

 

تابع $ تنها یک آرگومان از ما می خواهد که می توانیم با استفاده از آن، یک عنصر مشخص در صفحه ی HTML فعلی را انتخاب و مشخص کنیم. برای مشخص کردن این عنصر، ما می توانیم از سلکتورهای CSS استفاده کنیم. در اینجا ما می خواهیم عنصری که آی دی آن paddle است را انتخاب کنیم و با استفاده از CSS می توانیم یک علامت # را قبل از نام ID آن عنصر قرار دهیم، تا این عنصر مورد جستجو قرار گیرد. پس از اینکه ما این عنصر را جستجو و دریافت کردیم، از متد width جی کوئری استفاده می کنیم تا عرض(width) آن عنصر را بخوانیم.جی کوئری برای دسترسی به تمام خصوصیت های CSS متدهای بیشتری را به ما ارائه می دهد.

 


با استفاده از این متدها، نسبت به تابع های محلی جاوااسکریپت، خیلی راحت تر می توانیم مقدار خصوصیت های CSS را تنظیم(set) یا دریافت(get) کنیم. اکنون که ما ساختار داده های بازی را ایجاد کرده ایم، می توانیم منطق اصلی بازی را پیاده سازی کنیم. برای شروع، ما تعدادی متد برای مقداردهی اولیه(initializing) کردن و ریست(resetting) کردن بازی تعریف می کنیم:

function initGame() {
  Game.state = GameStates.PAUSED;
  Game.lives = MAX_LIVES;
  Game.score = 0;
  resetMovingObjects();
  updateStatistics();
  drawPlayfield();
}

function resetMovingObjects() {
  $("#paddle").css("left", (Game.playfield.width - Game.paddle.width) / 2);
  $("#ball").css("left", (Game.playfield.width - Game.ball.diameter) / 2);
  $("#ball").css("top", parseInt($("#paddle").css("top")) - Game.paddle.height);
}

function updateStatistics() {
  $('#lives').text(Game.lives);
  $('#score').text(Game.score);
}

function drawPlayfield() {
  var colors = ['blue', 'green', 'red', 'yellow'];
  var $playfield = $('#playfield');
  $playfield.children('.row').remove(); 

  for (var row = 0; row < Game.playfield.rows; row++) {
    var $row = $('<div class="row"></div>'); 
    $row.appendTo($playfield);
    for (var col = 0; col < Game.playfield.columns; col++) {
      var $block = $("<div class='block'></div>");
      $block.css("background", 'url("img/' + colors[row] + '.png")');
      $block.appendTo($row);
    }
  }
}

آدرس:

BrowserGame/Arduinoid/js/arduinoid.js

نام initGame بسیار خوب انتخاب شده است، زیرا این تابع به طور واقعی، بازی را مقدار دهی اولیه می کند. این تابع مستقیما چند پروپرتی شیء بازی را به مقادیر پیش فرض شان تنظیم می کند. سپس چند تابع را برای مقدار دهی اولیه کردن اشیاء خاص بازی فراخوانی می کند. تابع resetMovingObjects موقعیت های توپ و مانع را به مقادیر پیش فرض آنها تنظیم می کند. مانع(paddle) در پایین ناحیه ی بازی نشان داده می شود. سپس توپ(ball) در بالای مانع قرار می گیرد. تابع updateStatistics تعداد فعلی جان هاو امتیاز فعلی را در صفحه ی HTML کپی می کند. این تابع از متد text جی کوئری برای تنظیم متن(text) عناصر با آی دی های lives و score استفاده می کند. در تابع initGame مقادیر پیش فرض بازی کپی می شوند. اما این تابع را بعدا، وقتی که بازی در حال اجرا است، فراخوانی خواهیم کرد. تابع drawPlayfield آجرهایی که فرد بازی کننده باید توسط توپ به آنها ضربه بزند را ترسیم می کند. این تابع چهار عنصر <div> را ایجاد می کند که همه ی آنها کلاسی به نام row دارند.

 

 

در داخل هر عنصر که از کلاس row استفاده می کند، 10 عنصر <div> با کلاس block ایجاد می شود. برای انجام این کار، ابتدا تمام عناصر با کلاس row که ممکن است از قبل در خط 24 وجود داشته باشند، حذف می شوند. سپس ما از جی کوئری برای انجام کارها استفاده می کنیم. ما با استفاده از متد children تمام فرزندان عنصر playfield که کلاسی به نام row دارند را انتخاب می کنیم. سپس با استفاده از متد remove تمام این عناصر را از صفحه ی HTML حذف می کنیم.

توجه کنید که در جاوا اسکریپت، نام متغیرها می تواند حاوی علامت $ نیز باشد. ما از این علامت برای نام گذاری متغیرهایی از قبیل playfield$ که به اشیاء جی کوئری رجوع می کند و قرار داد مفیدی است، استفاده می کنیم. سپس با استفاده از دو حلقه ی for، ما آجرها را پس از آن ایجاد می کنیم. ما از تابع omnipotent$ دوباره برای ایجاد تمام عناصر <div> که نیاز داریم استفاده می کنیم. اگر ما یک رشته که حاوی کدهای HTML است را به متد $ بدهیم، این متد عنصر مورد نظر را ایجاد می کند. در خط 27 ما یک row جدید ایجاد می کنیم و در خط زیر، ما row جدید ایجاد شده را در صفحه ی HTML فعلی وارد می کنیم.

در حلقه ی for زیر، همین کار را برای بلوک های حقیقی انجام داده ایم.

در اینجا ما نه تنها عناصر <div> را ایجاد می کنیم، بلکه پروپرتی background را نیز بسته به row بلوک(block) تنظیم می کنیم.

این عکس ها، تصاویر شیب رنگ(gradient) هستند که باعث می شوند بلوک ها رنگی تر باشند. اکنون که بازی ما مقدار دهی اولیه شده است، می توانیم حلقه ی بازی را توسعه دهیم که برای هر فریم فراخوانی باید بشود.

 

function gameLoop() {
  switch (Game.state) {
    case GameStates.PAUSED:
      if (Game.controller.buttonPressed) {
        Game.state = GameStates.RUNNING;
      }
      break;
    case GameStates.RUNNING:
      movePaddle();
      moveBall();
      checkCollisions();
      updateStatistics();
      break;
    case GameStates.WON:
      handleMessageState("winner");
      break;
    case GameStates.LOST:
      handleMessageState("game_over");
      break;
    default:
      break;
  }
}
function handleMessageState(message) {
  $("#" + message).show();
  if (Game.controller.buttonPressed) {
    $("#" + message).hide();
    initGame();
  }
}

آدرس:

BrowserGame/Arduinoid/js/arduinoid.js

تابع gameLoop بسیار ساده است، زیرا تنها حالت فعلی بازی را بررسی می کند و سپس بقیه ی کار را دیگر متدها انجام می دهند. اگر بازی در حال حاظر متوقف(paused) شده باشد، این تابع بررسی می کند که آیا فرد بازی کننده دکمه ی دسته ی بازی را فشار داده است یا نه.

اگر جواب بله باشد، حالت(state) بازی را به GameStates.RUNNING تغییر می دهد. اگر بازی قبلا در حال اجرا است، gameLoop تمام اشیاء بازی را حرکت می دهد و بررسی می کند که برخوردهای احتمالی وجود نداشته باشد و آمار بازی را آپدیت می کند. اگر فرد در بازی برنده(won) یا بازنده(lost) شود، تابع handleMessageState فراخوانی می شود، و یک پیغام مناسب را نمایش می دهد. تابع handleMessageState با دستکاری محتوای یک عنصر HTML یک پیغام را نمایش می دهد. این تابع همچنین بررسی می کند که دکمه ی دسته ی بازی فشار داده شده باشد. اگر جواب بله باشد، این تابع پیغام مورد نظر را مخفی کرده و بازی را مقدار دهی اولیه می کند، تا فرد بازی کننده بتواند یک راند جدید را شروع کند. پس از اینکه یک بازی کننده، برنده یا بازنده شد، او می تواند با فشار دادن دکمه ی روی دسته ی بازی، یک بازی جدید را شروع کند. مهمترین کار در بیشتر بازی های ویدئویی، حرکت دادن اشیاء در صفحه ی نمایش است.

function moveBall() {
  var ball_pos = $("#ball").position(); 
  var ball_x = ball_pos.left;
  var ball_y = ball_pos.top; 
  var next_x_pos = ball_x + Game.ball.vx;
  var next_y_pos = ball_y + Game.ball.vy;

  if (next_x_pos <= 0) { 
    Game.ball.vx *= -1;
    next_x_pos = 1;
  } else if (next_x_pos >= Game.playfield.width - Game.ball.diameter) {
    Game.ball.vx *= -1;
    next_x_pos = Game.playfield.width - Game.ball.diameter - 1;
  } 

  var paddle_y = $("#paddle").position().top; 
  if (next_y_pos <= 0) {
    Game.ball.vy *= -1;
    next_y_pos = 1;
  } else if (next_y_pos + Game.ball.diameter >= paddle_y) {
    var paddle_x = $("#paddle").position().left;
    if (next_x_pos >= paddle_x && 
        next_x_pos <= paddle_x + Game.paddle.width)
    {
      Game.ball.vy *= -1;
      next_y_pos = paddle_y - Game.ball.diameter;
    }
  } 

  $("#ball").css({ "left" : next_x_pos, "top" : next_y_pos }); 
}

function movePaddle() {
  if (Game.controller.moveLeft) {
    var paddle_x = $("#paddle").position().left;
    if (paddle_x - Game.paddle.speed >= 0) {
      $("#paddle").css("left", paddle_x - Game.paddle.speed);
    } else {
      $("#paddle").css("left", 0);
    }
  }

  if (Game.controller.moveRight) {
    var paddle_x = $("#paddle").position().left;
    var next_pos = paddle_x + Game.paddle.width + Game.paddle.speed;
    if (next_pos < Game.playfield.width) {
      $("#paddle").css("left", paddle_x + Game.paddle.speed); 
    }
  }
}

آدرس:

BrowserGame/Arduinoid/js/arduinoid.js

کاربردی ترین متد جی کوئری وقتی که می خواهیم اشیاء را جابه جا کنیم، متد position است. این متد، یک شیء را برمی گرداند که حاوی خصوصیت های left و top از یک عنصر HTML است. در CSS این خصوصیت ها در حقیقت مختصات x و y شیء در صفحه را مشخص می کنند. در خط های 2 تا 4 از تابع moveBall ما از تابع position برای مشخص کردن مختصات فعلی یک توپ(ball) در صفحه ی نمایش استفاده می کنیم. در دو خط بعدی، ما موقعیت جدید توپ را با اضافه کردن سرعت های فعلی برای هردو جهت محاسبه می کنیم.

پس از آن، ما بررسی می کنیم که آیا موقعیت جدید توپ در خارج از صفحه قرار می گیرد یا نه. اگر جواب بله باشد، ما مختصات را برای مرزها معکوس می کنیم. در خط های 8 تا 14، ما اطمینان حاصل می کنیم که مختصات x توپ بیشتر از صفر باشد و کمتر از عرض میدان بازی باشد. اگر توپ به مرز چپ یا راست میدان بازی برخورد کند، ما vx را در 1- ضرب می کنیم، تا جهت آن تغیر کند. در خط های 16 تا 28، نیز چنین چیزی برای مختصات y توپ اتفاق می افتد. هنگامی که توپ به بالای ناحیه ی بازی برخورد ی کند، ما vy را در 1- ضرب می کنیم. ناحیه ی بازی(playfield)، از سمت پایین هیچ مرزی ندارد، اما ما باید بررسی کنیم که آیا توپ به مانع(paddle) برخورد می کند یا نه. اگر چنین باشد، ما vy را نیز معکوس می کنیم.

 

در نهایت ما در خط 30، موقعیت توپ را به مقادیر جدید تنظیم می کنیم. حرکت دادن مانع نیز به همین طریق است، اما به وضعیت فعلی دسته ی بازی بستگی دارد.

 

 

اگر فرد بازی کننده بخواهد مانع به سمت چپ حرکت کند، ما باید سرعت فعلی مانع را از مختصات x مانع تفریق کنیم. ما همچنین اطمینان حاصل می کنیم که مانع از صفحه ی نمایش خارج نشود. حرکت به سمت راست نیز تقریبا مشابه است. ما تنها باید سرعت فعلی مانع(paddle) را اضافه کنیم. یک مسئله ی مشکل دیگر در بازی ویدئویی، تشخیص برخورد است. احتمالا شما بازی هایی را انجام انجام داده اید که در آن پیغام هایی مشابه زیر را صادر کرده اند:

"نه، این شیء با من برخورد نکرده است"، یا "من مطمئنم که زودتر دشمن را کشته ام". در اکثر تشخیص برخوردهای نادرست به خاطر ناامیدی ما است. حتی برای بازی ساده ی ما، تشخیص برخورد ساده نیست. گوشه های بلوک ها گرد شده است، بنابراین بررسی اینکه توپ(ball) با یکی از گوشه ها همپوشانی کند یا اینکه دقیقا بلوک را لمس کند، اهمیت دارد. اما برای تجربه ی یک بازی خوب، این کار حتما ضروری نیست. بنابراین ما تشخیص برخورد را ساده تر کرده ایم.

function checkCollisions() {
  if (ballDropped()) {
    Game.lives = Game.lives - 1;
    if (Game.lives == 0) {
      Game.state = GameStates.LOST;
    } else {
      Game.state = GameStates.PAUSED;
      resetMovingObjects();
    }
  }
  if (!checkBlockCollision()) {
    Game.state = GameStates.WON;
  }
}

function ballDropped() {
  var ball_y = $("#ball").position().top;
  var paddle_y = $("#paddle").position().top;
  return ball_y + Game.ball.diameter > paddle_y + Game.paddle.height;
}

function inXRange(ball_left, block_left, block_width) {
  return (ball_left + Game.ball.diameter >= block_left) && 
         (ball_left <= block_left + block_width);
}

function inYRange(ball_top, block_top, block_height) {
  return (ball_top + Game.ball.diameter >= block_top) &&
         (ball_top <= block_top + block_height);
}

function checkBlockCollision() {
  var block_width = $(".block").first().width(); 
  var block_height = $(".block").first().height();
  var ball_left = $("#ball").position().left;
  var ball_top = $("#ball").position().top;
  var blocks_left = false;
  $(".block").each(function() { 
    if ($(this).css("visibility") == "visible") {
      blocks_left = true;
      var block_top = $(this).position().top;
      var block_left = $(this).position().left;
      var in_x = inXRange(ball_left, block_left, block_width);
      var in_y = inYRange(ball_top, block_top, block_height);
      if (in_x && in_y) {
        Game.score += 10;
        $(this).css("visibility", "hidden");
        if (in_x) {
          Game.ball.vy *= -1;
        }
        if (in_y) {
          Game.ball.vx *= -1;
        }
      }
    }
  });
  return blocks_left;
}

آدرس:

BrowserGame/Arduinoid/js/arduinoid.js

تابع checkCollisions ابتدا بررسی می کند که آیا بازی کننده(player) توپ را از دست داده است یا نه. در این صورت ما تعداد جان ها(lives) را کاهش می دهیم. سپس ما بررسی می کنیم که آیا بازی کننده(player) تمام جان های خود را از دست داده است یا نه. اگر جواب بله باشد، ما حالت(state) بازی را به GameStates.LOST تنظیم می کنیم. در غیر این صورت، ما بازی را متوقف(pause) می کنیم و موقعیت توپ و مانع به مقادیر پیش فرض تنظیم می کنیم. تابع ballDropped مختصات y پایین(bottom) توپ را با مختصات y پایین(bottom) مانع مقایسه می کند. اگر پایین() توپ بزرگتر باشد، در این صورت توپ از دست رفته است. سپس ما دو تابع کمک کننده(helper)، به نام های inXRange و inYRange ایجاد می کنیم. این تابع ها بررسی می کنند که آیا توپ با یک بلوک به صورت افقی یا عمودی برخورد کرده است یا نه. ما از این تابع ها، در تابع checkBlockCollision استفاده می کنیم تا ببینیم که آیا بلوک قابل مشاهده ای با توپ برخورد کرده است یا نه.

بنابراین ما نیاز داریم تا از تعداد بیشتری متد جی کوئری استفاده کنیم. در خط 33، ما تمام عناصری را که به کلاس block تعلق دارند را با استفاده از دستور $(".block") انتخاب می کنیم. اگر ما یک سلکتور را به تابع $ که بیش از یک عنصر را انتخاب می کند پاس دهیم، این تابع به طور اتوماتیک یک لیست از اشیاء(عناصر) را برمی گرداند. وقتی که این عناصر انتخاب شدند، ما با استفاده از متد first اولین عنصر از آنها را انتخاب می کنیم. سپس ما عرض یا همان width آن عنصر را قرائت می کنیم. در خط بعد، ما همین کار برای به دست آوردن ارتفاع عنصر(height) انجام می دهیم.

چونکه تمام بلوک ها ارتفاع و عرض یکسانی دارند، ما این کار را فقط یک بار انجام می دهیم. پس از آن ما موقعیت فعلی توپ را مشخص می کنیم. در خط 38، ما از متد each برای ایجاد حلقه(loop) بر روی تمام بلوک ها در سند HTML استفاده می کنیم. در متد each یک تابع وجود دارد که برای هر بلوک فراخوانی می شود.

 

جمله ی زیر بررسی شود:

توجه کنید که این تابع هیچ آرگومانی دریافت نمی کند؛ زیرا ما می توانیم بلوک فعلی را در $(this) پیدا کنیم.

 

در تابع loop، ما بررسی می کنیم که آیا بلوک فعلی آشکار(visible) است یا نه؛ زیرا اگر آشکار نباشد، ما نباید آن را برای برخورد بررسی(check) کنیم. ما از تابع های inXRange و inYRange که helper هستند، برای بررسی اینکه آیا بلوک فعلی توسط توپ ضربه خورده است یا نه، استفاده می کنیم.

در این صورت، ما عنصر را مخفی(invisible) می کنیم، و بسته به طریقی که توپ به بلوک برخورد کرده است، ما سرعت توپ را معکوس می کنیم.در نهایت، ما باید مطمئن شویم که تابع gameLoop هر 30 میلی ثانیه، فراخوانی شود تا بازی نرم تر اجرا شود:

$(function() {
  initGame();
  setInterval(gameLoop, 30);
});

ولی ما از یک تابع مختلف $ جی کوئری استفاده می کنیم. این دفعه ما به تابع $ یک تابع بی نام پاس می دهیم که به محض اینکه صفحه ی html کاملا لود شد، فراخونی می شود. در این تابع، ما بازی را مقدار دهی اولیه می کنیم و مطمئن می شویم که تابع gameLoop هر 30 میلی ثانیه فراخوانی می شود. اکنون بازی ما کامل است، بنابراین می توانیم شروع به اجرای این بازی کنیم.


اگر بازی کار نکرد چه کنیم؟

اگر کدهای این فصل را اجرا کنید، باید کدها را از وب سایت این کتاب دانلود کنید و سعی کنید آن را اجرا کنید. مطمئن شوید که از پورت سریال(serial port) صحیحی در فایل های arduinoid.js و game_controller.js در آدرس زیر استفاده کنید:

code/BrowserGame/Arduinoid/js/

تمرین ها

  • با استفاده از شتاب سنج ADXL335 ماوس کامپیوتر خود را ایجاد کنید. این ماوس باید درهوای آزاد کار کند، و باید شتاب فعلی دور محور های x و y را منتشر(emit) کند. این ماوس همچنین باید دکمه های راست و چپ داشته باشد. برای این کار، یک اپلیکیشن کروم بنویسید(یا اینکه به هر زبانی که با آن آشنا هستید) تا یک نشانگر ماوس را بر روی صفحه ی نمایش کنترل کنید.

 


ایجاد بازی ها و دسته های بازی با آردوینو

اگر به دنبال یک مورد مناسب برای دسته ی بازی ای که در این فصل ایجاد کرده اید می گردید، به این آدرس مراجعه کنید. قطعات داخلی این دسته با قطعات دسته ای که ما ساختیم، متفاوت است؛ اما واقعا جالب است.  ما می توانیم با استفاده از آردوینو، چیزی های بهتر از دسته ای که ساختیم را ایجاد کنیم. ما همچنین می توانیم با استفاده از آن برخی بازی های جالب را ایجاد کنیم. با استفاده از شیلدهای توسعه(extension shields) ما حتی می توانیم یک برد آردوینو را به کنسول بازی قدرتمندتبدیل کنیم. قدرتمند ترین شیلدهای توسعه، احتمالا شیلد Gameduinob و جانشین آن شیلد Gameduino 2 هستند. اگر شما به گرفیک های رنگی و صدای استریو نیاز ندارید، می توانید از راه حل های ارزان تر، مانند Video Game Shieldd یا Hackvision استفاده کنید. برای مشاهده این شیلدها می توانید به این آدرس مراجعه کنید. این شیلدها یک سیگنال ویدئوی سیاه و سفید(تک رنگ) تولید می کنند،  و ما در فصل 8، در بخش "تولید سیگنال های ویدئویی با آردوینو" در ص 127 می توانیم متوجه شویم که چگونه این کار را انجام دهیم.

{module کمک نقدی به نویسنده}

  • بازدید: 611

نوشتن دیدگاه

لطفا نظرات خود را بیان کنید. به سوالات در سریع ترین زمان پاسخ داده خواهد شد.اما به نکات زیر توجه کنید:
1. سعی کنید نظرات شما مرتبط با مقاله ی مورد نظر باشد، در غیر این صورت پاسخ داده نخواهد شد.
2. سوالات خود را به صورت کوتاه بیان کنید و از پرسیدن چند سوال به طور همزمان خودداری کنید.
3. سوال خود را به طور واضح بیان کنید و از کلمات مبهم استفاده نکنید.

ارسال