فصل اول روز دوم : چهارچوب اصلی

دانلود نسخه PDF امروز :دانلود

۱-۲-  روز دوم : چهارچوب اصلی

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

ابتدا با گرافیک ساده برای ربات و محیط اطرافش شروع خواهیم کرد و همینطور که پیش خواهیم رفت گرافیک ها ارتقاء داده خواهد شد.

اما بگذارید ابتدا درباره حلقه بازی و ریسمان صحبت کنیم.

۱-۲-۱-            اجرای یک ریسمان (implementing a Thread)

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

برای اضافه کردن کلاس ریسمان می توان به شکل زیر عمل کرد:

در کلاس شروع که در بخش قبل تعریف کردید در متد start() کد های زیر را اعمال نمایید.

@Override
	public void start() {
		Thread thread = new Thread();
		thread.start();
}

 

@Override
public void start() {
  Thread thread = new Thread();
  thread.start();
 }

کار ساده ای انجام گرفت. ابتدا یک شی از کلاس Thread با نام thread تعریف نمودیم سپس با فراخوانی متد thread.start(); آن را به راه انداختیم. خوب طبیعتا با به راه انداختن آن در اینجا اتفاق خاصی نمی افتد. اما چرا؟ همان طور که احتمالا می دانید با فراخوانی thread.start(); باید دستوراتی اجرا شوند. اگر به یاد داشته باشید با فراخوانی این متد در حقیقت متدی با نام run(); که توسط شما باید نوشته شود اجرا می شود. نحوه تعریف این متد راه های مختلفی دارد اما در اینجا کافی است در زمانی که کلاس شروع را تعریف نمودید و آن را با کلاس applet بسط دادید جمله implements Runnable را قرار دهید.

Public class ShoroClass extends Applet implements Runnable{

پس از این کار نیاز است تا متد run(); را اضافه کنید برای این کار کافیست در کلاس شروع چند حرف اول آن را نوشته و با زدن Ctrl+Space به صورت خودکار آن را اضافه نمایید.

هم اکنون هنگامی که ریسمان راه اندازی شود دستوراتی که در این متد قرار می گیرند اجرا خواهند شد. اما برای آن که به ریسمانی که تعریف کردیم بفهمانیم متد run(); آن کجا قرار گرفته باید هنگام تعریف آن به این صورت عمل کنیم. شما هم به جایی که ریسمان را تعریف کردید رفته و این تغییر را اعمال کنید:

Thread thread = new Thread(this);

در این جا کلمه this به ریسمان می گوید متد run(); در همین کلاس تعریف شده است.

 

۱-۲-۲-            ایجاد حلقه بی نهایت بازی

در این درس، ما یک حلقه بازی را ایجاد خواهیم نمود. در بخش اول ذکر شد که حلقه بازی قلب تپنده بازی خواهد بود. این حلقه مدام تغییرات را بررسی می کند و براساس آن بروزرسانی های لازم را انجام می‌دهد.

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

  • شخصیت های بازی (ربات و دشمن های آن) را بروز رسانی کند.
  • ترسیم مجدد صحنه بازی
  • بروز رسانی ابزارآلات
  • ایجاد تاخیر برای ۱۷ میلی ثانیه

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

من مطمئنم خیلی از شما میدونید وقتی که در حال مشاهده یک فیلم در رایانه تان هستید، در واقع یک سری عکس پشت سرهم رو می بینید که به سرعت در حال تغییر هستند. جابجایی این عکس ها وقتی با سرعت کافی انجام گیرد برای ذهن شما تداعی یک فیلم را خواهد کرد که در حال اجرا می باشد. تعداد عکسی که در یک ثانیه نشان داده می شود را به عنوان تعداد عکس در ثانیه یا frame per second می شناسند.

اگر این نرخ حدود ۳۰ باشد یعنی ۳۰ عکس در یک ثانیه جای خود را به دیگری دهد نتیجه برای چشم ما یک فیلم یا صحنه خواهد بود. هرچند که نرخ ۶۰ کیفیتی مطلوب تر را بهمراه خواهد داشت.

تاخیر ۱۷ میلی ثانیه بالا به خاطر همین امر است. با این تاخیر ما می توانیم هر ۱ ثانیه ۶۰ بار صفحه نمایش را به روز رسانی کنیم به طوری که بازیکن احساس خوبی از بازی کردن داشته باشد و گویی تمام حرکات طبیعی است. این امر در رایانه های جدید مشکلی بوجود نمی آورد اما در رایانه های قدیمی تر بدلیل سرعت پردازنده پایین ممکن بود با مشکل ارائه تصویر مواجه شوند.

خوب حالا نوبت این است که حلقه بی نهایت بازی را ایجاد کنیم. این کار در همان متد run() باید صورت گیرد.

  • این حلقه از نوع while خواهد بود که بی نهایت بار تکرار می شود. برای این کار کافیست شرط آن همواره درست باشد به صورت زیر:

while(true){

 

}

  • داخل این حلقه کد های زیر را وارد نمایید:
while (true) {

    repaint();// این خط، متد پینت را فراخوانی میکند.
    Try {
      Thread.sleep(17);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
}

هم اکنوت متد run(); شما باید به این شکل باشد.

بیاید دستورات این متد را خط به خط مرور کنیم:

repaint(); : این یک متد از پیش تعریف شده می باشد که متد paint(); که بعدا اضافه خواهیم کرد را صدا میزند. در متد paint(); دستورات ترسیم را خواهیم آورد. این متد هر ۱۷ میلی ثانیه فراخوانده می شود.

برای آن که این تاخیر را بوجود آوریم باید از دستور Thread.sleep(17); استفاده کنیم، یعنی ریسمان ما برای ۱۷ میلی ثانیه به خواب برود. اما این دستور به تنهایی کافی نیست و اکلیپس خطا خواهد گرفت پس ضروری است تا آن را داخل یک try catch قرار دهیم.

چیزی که try/catch برایمان انجام می دهد در حقیقت این است که:

  • در داخل try آن چیزی را که میخواهیم انجام دهیم را قرار خواهیم داد. در اینجا تاخیر.
  • اگر به دلیلی رایانه نتوانست این تاخیر را ایجاد کند catch اطلاعات را با در نظر گرفتن خطا حفظ کرده و خطا را گزارش خواهد داد.

در مورد آن زیاد نگران نباشید. در حقیقت ایجاد یک ایمنی در سیستم است که توسط خود آن(سیستم) ارائه می شود.

پس تا اینجا یک حلقه بازی داریم که دائما در حال اجراست و هر ۱۷ میلی ثانیه متد paint را فراخوانی میکند.

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

Package codeandroid;

import java.applet.Applet;

public class ShoroClass extends Applet implements Runnable {
  @Override
  public void init() {
    // TODO Auto-generated method stub

  }

  @Override
  public void start() {
    Thread thread = new Thread(this);
    thread.start();
  }

  @Override
  public void stop() {
    // TODO Auto-generated method stub

  }

  @Override
  public void destroy() {
    // TODO Auto-generated method stub

  }

  @Override
  public void run() {
    while (true) {

      repaint();// این خط متد پینت را فراخوانی میکند

      try {
        Thread.sleep(17);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

  }
}

۱-۲-۳-            تعریف اندازه، پس زمینه، و عنوان

در بخش قبل مختصرا درباره متدهای init(); start(); destroy(); stop(); صحبت کردیم. این متدها در طول اجرای برنامه فراخوانی می شوند. وقتی برنامه آغاز می شود متد start()  و init() صدا زده میشوند. وقتی برنامه متوقف می شود متد stop و وقتی تمام می شود متد destroy(); صدا زده خواهد شد.

در اینجا می خواهیم متد init(); را مقدار دهی کنیم این متد وقتی برنامه شروع می شود برای انجام تنطیمات اولیه چون رنگ، اندازه، فونت و … اجرا می شود. در اینجا ما تنظیمات زبر را خواهیم انجام داد:

  • اندازه پنجره اپلت
  • رنگ پس زمبنه
  • عنوان پنجره

بنابراین کدها در متد init(); به این شکل خواهند بود:

  • تنظیم اندازه setSize(800,480);

در این حالت اندازه پنجره بازی ۸۰۰ پیکسل در ۴۸۰ پیکسل خواهد بود

  • تنظیم رنگ پس زمینه setBackground(Color.BLACK);

در اینجا رنگ پس زمینه مشکی تعریف خواهد شد. به ورودی این متد Color.Black را داده ایم که میفهماند رنگ پس زمنیه باید مشکی باشد. یادتتان نرود که کلاس Color را به پروژه تان اضافه کنید. این کار را می توانید با فشردن Ctrl+Space+O انجام دهید.

  • تنظیم فعال بودن پنجره بازی : setFocusable(true);

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

  • تنظیم عنوان بازی روی پنجره باز شده

Frame frame=(Frame)this.getParent().getParent();

Frame.setTitle(“بازی ربات”);

ابتدا یک شی از کلاس فریم ایجاد کردیم تا به کمک آن کنترل پنجره باز شده را به عهده بگیریم. سپس با فراخوانی متد setTitle عنوان این پنجره را تنظیم نمودیم.

این هم از کلاس شروع در پایان بخش دوم.

Package codeandroid;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;

public class ShoroClass extends Applet implements Runnable {
  @Override
  public void init() {
    setSize(800, 480);
    setBackground(Color.BLACK);
    setFocusable(true);
    Frame frame = (Frame) this.getParent().getParent();
    frame.setTitle("بازی ربات");

  }

  @Override
  public void start() {
    Thread thread = new Thread(this);
    thread.start();
  }

  @Override
  public void stop() {
    // TODO Auto-generated method stub

  }

  @Override
  public void destroy() {
    // TODO Auto-generated method stub

  }

  @Override
  public void run() {
    while (true) {

      repaint();// این خط متد پینت را فراخوانی میکند

      try {
        Thread.sleep(17);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

  }
}

تا اینجای کار با اجرای بازی خروجی زیر در صفحه نمایش نشان داده خواهد شد.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *