ایجاد قابلیت شلیک در بازی دوبعدی سفینه

1395/10/12 لیلا کشاورز 1200

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

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

package sprite;

import java.awt.Image;
import javax.swing.ImageIcon;


public class missile {

    private int x, y;
    private Image image;
    boolean visible;

    private final int BOARD_WIDTH = 599;
    private final int MISSILE_SPEED = 3;

    public missile(int x, int y) {

        ImageIcon im =
            new ImageIcon(this.getClass().getResource("missile.png"));
        image = im.getImage();
        visible = true;
        this.x = x;
        this.y = y;
    }


    public Image getImage() {
        return image;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public boolean isVisible() {
        return visible;
    }

    public void move() {
        x += MISSILE_SPEED;
        if (x > BOARD_WIDTH)
            visible = false;
    }
}

خب در پکیجی که ساخته بودیم ، کلاسی به عنوان missile ،برای پیاده سازی اسپرایت گلوله،  ایجاد میکنیم .

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

 

private final int MISSILE_SPEED = 3;

سپس در تابع move ، که تابع پیاده سازی حرکت گلوله است ، این مقدار را به مختصه ی x گلوله ، در زمان حرکت ، نسبت داده ایم.
دقت کنید که وقتی گلوله به حاشیه ی سمت راست پنجره ی خروجی برخورد میکند، باید ناپدید شود. یعنی وقتی مختصه ی x گلوله ، بیشتر از طول پنجره شود( که این مقداررا برابر  ; private final int BOARD_WIDTH = 380 قرار دادیم) ، باید گلوله را از لیست  گلوله هایی که در ArrayList تعریف کردیم حذف شوند.(این ارایه را در craft  اضافه خواهیم کرد) این عملیات را به شکل زیر ، به تابع move   اضافه میکنیم:

if (x > BOARD_WIDTH)
            visible = false;

توابع get  رانیز  برای هر سه متغیر x ,y ,image  پیاده سازی کردیم.
(توجه کنید که تصویر گلوله را مطابق روند همیشگی، درمحل ذخیره ی پروژه و درکنار کلاسهای ایجاد شده ، کپی کنید.)

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

بسیار خب بعد از کامل کردن این کلاس، به سراغ کلاسهایی که قبلا ایجاد کرده بودیم میریم و تغییرات لازم را در آنها اعمال میکنیم.

ابتدا به شرح تغییراتی که در کلاس craft  (کلاس پیاده سازی اسپرایت سفینه) بایستی ایجاد شود میپردازیم:

package sprite;

import java.awt.Image;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;


public class craft {

    private Image image;
    private int x;
    private int y;
    private int dx;
    private int dy;
    private String craft = "craft.png";

    private ArrayList missiles;
    private final int CRAFT_SIZE = 20;

    public craft(){

    ImageIcon im =new ImageIcon(this.getClass().getResource(craft));
    image =im.getImage();
    missiles = new ArrayList();
    x=40;
    y=40;
}
  public void  move() {
  x+=dx;
  y+=dy;
if (x < 1) {
            x = 1;
        }
 
        if (y < 1) {
            y = 1;
        }
}


  public int getx(){
  return x;
  }
    
  public int gety(){
  return y;
  }

  public Image getimage(){
  return image;
  }

  public ArrayList getMissiles() {
        return missiles;
    }
 
public void keyPressed(KeyEvent e) {

        int key=e.getKeyCode();

        if (key == KeyEvent.VK_SPACE) {
            fire();
        }

        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
        }
        if (key== KeyEvent.VK_RIGHT) {
             dx = +1;
        }
         if (key== KeyEvent.VK_DOWN) {
             dy = +1;
        }
         if (key== KeyEvent.VK_UP) {
             dy = -1;
         }
            }

 public void fire() {
        missiles.add(new missile(x + CRAFT_SIZE, y + CRAFT_SIZE/2));
    }

     public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

       if (key == KeyEvent.VK_LEFT) {
            dx = 0;
        }
     if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
        }

       if (key == KeyEvent.VK_DOWN) {
           dy = 0;
        }
    if (key == KeyEvent.VK_UP) {
            dy = 0;
       }
     }

}

در ابتدا برای اینکه مشخص کنیم گلوله ، ازچه فاصله ای نسبت به سفینه ، شروع به شلیک شدن کند ، متغییری برای این منظور تعریف میکنیم.

private final int CRAFT_SIZE =20;

 برای اینکه لیست گلوله ها را ذخیره کنیم ، ارایه ای تعریف میکنیم :

private ArrayList missiles;
و قرار میدهیم :
missiles = new ArrayList();

حال کد دکمه ی شلیک گلوله را به متد keyPressed  اضافه میکنیم:

if (key == KeyEvent.VK_SPACE) {
            fire();
        }

مطابق این دستور ، اگر کلید  spaceفشرده شود، متد fire()  ،فراخوانی میشود.
تابع fire هم یک گلوله دیگر تعریف می کند و مکان اولیه ی گلوله را به کمک متغییر CRAFT_SIZE تعریف میکند و در نهایت آن را به لیست گلوله ها اضافه می کند .

public void fire() {
        missiles.add(new missile(x + CRAFT_SIZE, y + CRAFT_SIZE/2));
    }

و حالا تغییراتی که در کلاس Board  باید انجام شود را مورد بررسی قرار میدهیم:

package sprite;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.Timer;

public class Board extends javax.swing.JPanel implements ActionListener{


    private Timer timer;
    private craft craft;

    public Board() {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);

        craft=new craft();

        timer=new Timer(10,this);
        timer.start();

    }

   public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(craft.getimage(), craft.getx(), craft.gety(), this);

        ArrayList ms = craft.getMissiles();
 
        for (int i = 0; i < ms.size(); i++ ) {
            missile m = (missile) ms.get(i);
            g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

    public void actionPerformed(ActionEvent e) {

         ArrayList ms = craft.getMissiles();

        for (int i = 0; i < ms.size(); i++) {
            missile m = (missile) ms.get(i);
            if (m.isVisible())
                m.move();
            else ms.remove(i);
        }

        craft.move();
        repaint();
    }
    
      private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }
  }

در تابع paint کل گلوله ها را که در یک ArrayList وجود داشتند را  ابتدا توسط دستور getMissiles  دریافت و سپس در صفحه ترسیم می کنیم .

ArrayList ms = craft.getMissiles();
 
        for (int i = 0; i < ms.size(); i++ ) {
            missile m = (missile) ms.get(i);
            g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }

در تابع  actionPerformed هم،جداگانه تک تک گلوله ها را که در یک arraylist وجود داشتند ، از حیث اینکه قابل دیدن هستند یا خیر، مورد بررسی قرار میدهیم و  آنها را حرکت می دهیم و یا حذف می کنیم.  

ArrayList ms = craft.getMissiles();

        for (int i = 0; i < ms.size(); i++) {
            missile m = (missile) ms.get(i);
            if (m.isVisible())
                m.move();
            else ms.remove(i);
        }

کلاس حاوی متد main هم نیازی به تغییر ندارد.

تصویری از خروجی را درشکل زیر مشاهده میکنید :

بازیسازی با جاوا

میبینید که سفینه با کلید های جهت نما حرکت کرده ، و با فشردن کلید space ، گلوله شلیک میشود.

بسیار خب بحث رو تا همینجا نگه میداریم . در جلسه ی آینده ، کاراکتر دشمن رو ، به برنامه اضافه خواهیم کرد.

انشالله بهره ی کافی رو از این آموزش برده باشید...

کلمات کلیدی