<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
文末有原始碼,以及本遊戲使用的所有素材,將plane2檔案複製在src檔案下可以直接執行。
關鍵程式碼:
JFrame jf = new JFrame("飛機大戰"); //建立表單 jf.setSize(670,800); jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jf.setLayout(new BorderLayout()); //佈局 //建立三個JPanel,左上為按鈕,左下為分數顯示 右為遊戲頁面 JPanel left = new JPanel(); JPanel leftUp = new JPanel(); //左上 JPanel leftDown = new JPanel(); //左下 game = new JPanel(); //遊戲顯示區 left.setPreferredSize(new Dimension(170,800)); left.setBackground(new Color(-3355444)); jf.add(left,BorderLayout.WEST); jf.add(game,BorderLayout.CENTER); game.requestFocus(); left.setLayout(new BorderLayout()); leftUp.setPreferredSize(new Dimension(0,250)); leftUp.setBackground(new Color(-3355444)); left.add(leftUp,BorderLayout.NORTH); leftDown.setBackground(new Color(-6710887)); leftDown.setPreferredSize(new Dimension(0,550)); left.add(leftDown,BorderLayout.SOUTH);
判斷FlyObject物件是否碰撞
public boolean judge_crash(FlyObject fo){ if(x+sizeX<fo.x || y+sizeY<fo.y || x > fo.x + fo.sizeX || y > fo.y+ fo.sizeY ){ return false; }else{ return true; } }
要想繪製動態的背景,首先我們要先畫一張靜態的背景圖,那麼如何繪製一張靜態的背景圖呢?
獲取包中的圖片:
String fileName_0 = "src\plane2\z_img\img_bg_0.jpg"; //相對地址(和絕對地址區分開) BufferedImage bufferedImage; bufferedImage = ImageIO.read(new File(fileName_0)); //將檔案讀出記錄在bufferedImage中,記得丟擲異常 g.drawImage(bufferedImage,0,0,null); // 將bufferedImage中的內容畫在畫筆g對應的地方
我們的地圖是一張可以從上往下無縫捲動的圖片,就像是這樣的圖
接下來,如何讓畫出連續的圖片呢?
在繪製函數中,有一個函數可以完美實現我們的需求
img – the specified image to be drawn. This method does nothing if img is null. dx1 – the x coordinate of the first corner of the destination rectangle. dy1 – the y coordinate of the first corner of the destination rectangle. dx2 – the x coordinate of the second corner of the destination rectangle. dy2 – the y coordinate of the second corner of the destination rectangle. sx1 – the x coordinate of the first corner of the source rectangle. sy1 – the y coordinate of the first corner of the source rectangle. sx2 – the x coordinate of the second corner of the source rectangle. sy2 – the y coordinate of the second corner of the source rectangle. observer – object to be notified as more of the image is scaled and converted. public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer);
比如說,我們的圖片高度為712個畫素點,我們在下一時刻,圖片向下移動了m個畫素點,那麼我們就將這張圖片的0 ~ 712-m 部分,繪製到遊戲介面的m ~ 712部分,
再將712-m ~ 712 部分繪製到遊戲介面的0 ~ m 部分;
接下來,我們就要確定 m 的值,這個就很簡單了,在繪製執行緒中,定義一個整數變數m ,每次繪製完 m++ 就可以了。(個人建議m+=2比較舒服)
/** * @author liTianLu * @Date 2022/5/21 23:33 * @purpose 繪製背景 * 提醒: 這裡我寫了四種地圖的繪製,後面在選擇地圖時會用到。 */ public class BackGround { Graphics g; BufferedImage bufferedImage_1; BufferedImage bufferedImage_2; BufferedImage bufferedImage_3; BufferedImage bufferedImage_4; int w; int h; String fileName_1 = "src\plane2\z_img\img_bg_1.jpg"; //地圖1 String fileName_2 = "src\plane2\z_img\img_bg_2.jpg"; //地圖2 String fileName_3 = "src\plane2\z_img\img_bg_3.jpg"; //地圖3 String fileName_4 = "src\plane2\z_img\img_bg_4.jpg"; //地圖4 public BackGround(Graphics g) throws IOException { this.g = g; bufferedImage_1 = ImageIO.read(new File(fileName_1)); bufferedImage_2 = ImageIO.read(new File(fileName_2)); bufferedImage_3 = ImageIO.read(new File(fileName_3)); bufferedImage_4 = ImageIO.read(new File(fileName_4)); w = bufferedImage_1.getWidth(); h = bufferedImage_1.getHeight(); } /** * i : 向下移動了i個畫素 * num : 用來控制繪製哪一個地圖 */ public void draw(int i , int num){ switch(num){ case 1 : g.drawImage(bufferedImage_1,0,i,w,i+h,0,0,w,h,null); g.drawImage(bufferedImage_1,0,0,w,i,0,h-i,w,h,null); break; case 2 : g.drawImage(bufferedImage_2,0,i,w,i+h,0,0,w,h,null); g.drawImage(bufferedImage_2,0,0,w,i,0,h-i,w,h,null); break; case 3 : g.drawImage(bufferedImage_3,0,i,w,i+h,0,0,w,h,null); g.drawImage(bufferedImage_3,0,0,w,i,0,h-i,w,h,null); break; case 4 : g.drawImage(bufferedImage_4,0,i,w,i+h,0,0,w,h,null); g.drawImage(bufferedImage_4,0,0,w,i,0,h-i,w,h,null); break; } } public int getH() { return h; } }
繪製執行緒:
backGround.draw(m, player.mapNum); m = m+2; if(m>= backGround.getH()){ m = 0; }
使用的飛機素材圖片:
飛機扇動翅膀的原理與視訊的原理相同,不停更換圖片,形成視覺暫留效果
//這裡僅使用了三張圖片來回切換,更多的圖片會有更好的效果 public void draw(int i){ //此處的i是用來控制顯示哪一張圖片的 int j = i%30; // 150ms換一張 if (j<10){ g.drawImage(plane_img,x,y,x+sizeX,y+sizeY,0,0,sizeX,sizeY,null); }else if(j<20) { g.drawImage(plane_img,x,y,x+sizeX,y+sizeY,0,sizeY,sizeX,2*sizeY,null); }else if(j<30){ g.drawImage(plane_img,x,y,x+sizeX,y+sizeY,288,0,424,112,null); } }
敵方飛機,敵方子彈等飛行物的繪製原理與MyPlane相同,後面不在贅述。(為了簡化開發流程,飛行物可以不”扇動翅膀“)
@Override //鍵盤按壓時,設定速度 public void keyPressed(KeyEvent e) { int c = e.getKeyCode(); if(DrawThread.myPlane!=null){ switch (c){ case 37: DrawThread.myPlane.setSpeedX(-speed); break; case 38: DrawThread.myPlane.setSpeedY(-speed); break; case 39: DrawThread.myPlane.setSpeedX(speed); break; case 40: DrawThread.myPlane.setSpeedY(speed); break; } } } @Override //鍵盤釋放時,速度設為0 public void keyReleased(KeyEvent e) { int c = e.getKeyCode(); switch (c){ case 37: case 39: DrawThread.myPlane.setSpeedX(0); break; case 38: case 40: DrawThread.myPlane.setSpeedY(0); break; } }
每隔一段時間,在遊戲面板的頂部,產生一個敵方飛機
/** * @author liTianLu * @Date 2022/5/22 0:30 * @purpose 產生敵機的執行緒 */ @Override public void run() { int sleepTime = 800; while (true){ if(DrawThread.player.score>=500){ //當分數高於500時,加快敵機產生的頻率 sleepTime = 300; } EnemyPlane enemyPlane = null; try { enemyPlane = new EnemyPlane(); } catch (IOException e) { e.printStackTrace(); } enemyPlanes.add(enemyPlane); new Thread(new EnemyBulletThread(enemyPlane)).start(); //啟動一個發射子彈執行緒 try { sleep(sleepTime+ random.nextInt(300)); } catch (InterruptedException e) { e.printStackTrace(); } } }
我們為每一個敵方飛機建立一個生成子彈的執行緒,要確定子彈產生的具體位置,就要知道敵方飛機的位置,所以我們要傳入一個敵方飛機物件給該執行緒。
public EnemyBulletThread(EnemyPlane enemyPlane){ this.enemyPlane = enemyPlane; } @Override public void run() { try { sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } while(enemyPlane.isAlive() ){ EnemyBullet enemyBullet = null; int enemyBullet_x = enemyPlane.getX()+25; int enemyBullet_y = enemyPlane.getY()+66; try { enemyBullet = new EnemyBullet(enemyBullet_x,enemyBullet_y); } catch (IOException e) { e.printStackTrace(); } enemyBullets.add(enemyBullet); try { sleep(2000+ random.nextInt(2000)); } catch (InterruptedException e) { e.printStackTrace(); } } }
synchronized (MyPlane.myBulletList){ if(MyPlane.myBulletList.size()!=0){ for (int i = 0; i < MyPlane.myBulletList.size(); i++) { MyPlane.myBulletList.get(i).setY(MyPlane.myBulletList.get(i).getY()+MyPlane.myBulletList.get(i).getSpeedY() ); if(MyPlane.myBulletList.get(i).getY() <= -100){ MyPlane.myBulletList.remove(i); continue; } } } }
TestCrashThread 檢測我的子彈與敵方飛機碰撞
synchronized (MyPlane.myBulletList){ for (int i = 0; i < MyPlane.myBulletList.size(); i++) { for (int j = 0; j < EnemyPlaneThread.enemyPlanes.size() ;j++) { if(MyPlane.myBulletList.get(i).judge_crash(EnemyPlaneThread.enemyPlanes.get(j)) ){ EnemyPlaneThread.enemyPlanes.get(j).setAlive(false); //關執行緒 DrawThread.player.score+=5; //分數+5 EnemyPlaneThread.enemyPlanes.remove(j); MyPlane.myBulletList.remove(i); j = -1; } if(i >= MyPlane.myBulletList.size()){ break; } } } }
原始碼下載:
連結: https://pan.baidu.com/s/1ORdS-Ep0MNmVsslv9YFjiQ
提取碼: hvz4
到此這篇關於Java實現飛機大戰遊戲 附完整原始碼的文章就介紹到這了,更多相關java飛機大戰內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45