ایجاد قابلیت شلیک در بازی دوبعدی سفینه
سلام عرض میکنم خدمت همه ی همراهان عزیز.
کشاورز هستم و با قسمت ششم از سری آموزش های بازیسازی با جاوا در خدمتتونم.
اگر خاطرتون باشه از جلسه ی گذشته شروع به ساخت بازی سفینه ی جنگی کردیم .
تا اونجا پیش رفتیم که یک سفینه در برد ایجاد کردیم و قابلیت حرکت با کلیدهای جهت نما را به این کاراکتر دادیم .
در این جلسه ،قابلیت شلیک رو هم به سفینه اضافه خواهیم کرد .پس اسپرایت گلوله را به برنامه مون اضافه میکنیم ، بطوریکه وقتی کلید 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 ، گلوله شلیک میشود.
بسیار خب بحث رو تا همینجا نگه میداریم . در جلسه ی آینده ، کاراکتر دشمن رو ، به برنامه اضافه خواهیم کرد.
انشالله بهره ی کافی رو از این آموزش برده باشید...
نظرات کاربران