日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java实现飞机大战小游戏(源码+注释)

發(fā)布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java实现飞机大战小游戏(源码+注释) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

整體的思路和博主其他博文java實現(xiàn)貪吃蛇小游戲(源碼+注釋)和java實現(xiàn)2048小游戲(源碼+注釋)是一樣的,都是利用Frame創(chuàng)建窗體,利用Panel添加組件,提前規(guī)劃好布局,調用鼠標和鍵盤監(jiān)聽,引用圖片元素。
此處的思路在于不斷的刷新敵機集合和子彈集合來實現(xiàn)動態(tài)效果。

文章目錄

      • 一.工程文件
      • 二.Main.java
      • 三.GameFrame.java
      • 四.GamePanel.java
      • 五.FlyObject.java
      • 六.Hero.java
      • 七.Ep.java
      • 八.Fire.java
      • 九.App.java
      • 十.效果演示

一.工程文件

二.Main.java

主函數(shù),實現(xiàn)類

package ui;//主函數(shù)實現(xiàn) public class Main {public static void main(String[] args) {//創(chuàng)建窗體GameFrame frame = new GameFrame();//創(chuàng)建面板GamePanel panel = new GamePanel(frame);//調用開始游戲的方法啟動游戲panel.action();//將面板加入到窗體中frame.add(panel);//設置窗體可見frame.setVisible(true);} }

三.GameFrame.java

窗體類,繪制窗體

package ui;import javax.swing.*;//創(chuàng)建窗體 public class GameFrame extends JFrame {//構造方法,初始化窗體屬性public GameFrame(){//設置標題,來源于JFramesetTitle("飛機大戰(zhàn)");//設置大小setSize(512,768);//設置居中setLocationRelativeTo(null);//設置窗體可見//setVisible(true);//不允許玩家修改界面大小setResizable(false);//設置默認的關閉選項setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);} }

四.GamePanel.java

畫布類,用于勾勒元素

package ui;import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Random;//自定義游戲面板(創(chuàng)建畫布) public class GamePanel extends JPanel {//定義背景圖BufferedImage bg;//構造游戲機Hero hero = new Hero();//敵機集合List<Ep> eps = new ArrayList<Ep>();//彈藥集合List<Fire> fs = new ArrayList<Fire>();//定義分數(shù)int score;//設置游戲開關Boolean gameover=false;//設置火力int power = 1;//動作函數(shù),描繪場景內飛行物的運動狀態(tài)public void action(){//創(chuàng)建線程(基本模板)new Thread(){public void run(){//無線循環(huán)創(chuàng)建while (true){//判斷如果游戲沒有失敗,則執(zhí)行以下操作if(!gameover){//敵機進場epEnter();//調用敵機移動方法epMove();//發(fā)射子彈shoot();//子彈移動fireMove();//判斷子彈是否擊中敵機shootEp();//檢測敵機是否撞到游戲機hit();}//每執(zhí)行一次,線程休眠一會兒try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//重繪界面repaint();}}}.start();//讓線程開始運行}//每執(zhí)行20次,釋放一個敵機,創(chuàng)建計數(shù)器計數(shù)int index = 0;protected void epEnter(){index++;//創(chuàng)建敵機if(index>=20){//創(chuàng)建敵機Ep e = new Ep();//加入集合eps.add(e);//重置計數(shù)器index = 0;}}//讓敵機移動protected void epMove(){//遍歷敵機集合,依次移動for (int i = 0; i < eps.size(); i++) {//獲取集合中敵機Ep e = eps.get(i);//調用敵機類中的移動方法e.move();}}//每執(zhí)行20次,創(chuàng)建一顆子彈,創(chuàng)建計數(shù)器計數(shù)int findex = 0;protected void shoot(){findex++;if(findex>=20){//根據(jù)火力判斷子彈行數(shù)//一排子彈if(power==1){//創(chuàng)建子彈Fire fire1 = new Fire(hero.x+45,hero.y,1);//將子彈存入子彈集合中fs.add(fire1);}//兩排子彈else if(power==2){//創(chuàng)建子彈Fire fire1 = new Fire(hero.x+15,hero.y,0);//將子彈存入子彈集合中fs.add(fire1);//創(chuàng)建子彈Fire fire2 = new Fire(hero.x+75,hero.y,2);//將子彈存入子彈集合中fs.add(fire2);}//三排子彈else{//創(chuàng)建子彈Fire fire1 = new Fire(hero.x+15,hero.y,0);//將子彈存入子彈集合中fs.add(fire1);//創(chuàng)建子彈Fire fire2 = new Fire(hero.x+75,hero.y,2);//將子彈存入子彈集合中fs.add(fire2);//創(chuàng)建子彈Fire fire3 = new Fire(hero.x+45,hero.y-10,1);//將子彈存入子彈集合中fs.add(fire3);}//使計數(shù)器歸0findex = 0;}}//讓子彈移動protected void fireMove(){//遍歷子彈集合for (int i = 0; i < fs.size(); i++) {//獲取每一顆子彈位置Fire f = fs.get(i);//依次移動每一顆子彈f.move();}}//判斷子彈是否擊中敵機protected void shootEp(){//遍歷所有子彈for (int i = 0; i < fs.size(); i++) {//獲取每一顆子彈Fire f = fs.get(i);//判斷一顆子彈是否擊中敵機bang(f);}}//判斷一顆子彈是否擊中敵機protected void bang(Fire f){for (int i = 0; i < eps.size(); i++) {//取出每一張敵機Ep e = eps.get(i);//判斷這個子彈是否擊中敵機if(e.shootBy(f)&&e.type!=15){//判斷游戲機機是否擊中道具機if(e.type==12){//火力增加power++;//如果火力值大于三,增加血量if(power>3){//恢復血量if(hero.hp<3){hero.hp++;}//使游戲機血量不超過3power = 3;}}//如果敵機被子彈擊中//敵機消失eps.remove(e);//刪除子彈fs.remove(f);//增加分數(shù)score += 10;}}}//檢測敵機是否撞到主機protected void hit() {for (int i = 0; i < eps.size(); i++) {//獲取每一個敵機Ep e = eps.get(i);//調用敵機的方法判斷if(e.shootBy(hero)){//刪除敵機eps.remove(e);//主機血量減少hero.hp--;//火力恢復初始值power = 1;//分數(shù)增加score += 10;//當主機血量減少到0時游戲結束if(hero.hp==0){gameover = true;}}}}//構造函數(shù)public GamePanel(GameFrame frame){//設置背景bg = App.getImg("/img/bg2.jpg");//創(chuàng)建鼠標監(jiān)聽和鼠標適配器MouseAdapter adapter = new MouseAdapter() {//點擊鼠標時會執(zhí)行的代碼@Overridepublic void mouseClicked(MouseEvent e) {//游戲結束時候,點擊屏幕時重新開始游戲if(gameover){//重新初始化主機hero = new Hero();//重置游戲開關gameover = false;//分數(shù)清0score = 0;//清空敵機集合eps.clear();//隨機背景圖Random random = new Random();int index = random.nextInt(5)+1;bg = App.getImg("/img/bg"+index+".jpg");//重新繪制repaint();}}//確定需要監(jiān)聽的事件,此處監(jiān)聽鼠標移動事件@Overridepublic void mouseMoved(MouseEvent e) {//讓游戲機的橫縱坐標等于鼠標的移動坐標//獲取鼠標的橫縱坐標int mx = e.getX();int my = e.getY();//傳遞坐標if(!gameover){//使鼠標坐標正好位于圖片中央hero.moveToMouse(mx-114/2,my-93/2);}//重新繪制界面repaint();}};//將適配器加入到監(jiān)聽器中addMouseListener(adapter);addMouseMotionListener(adapter);//使用鍵盤監(jiān)聽,創(chuàng)建鍵盤適配器KeyListener kd = new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {}//當鍵盤被按下是觸發(fā)@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();//上鍵if(keyCode == KeyEvent.VK_UP){hero.y-=10;}//下鍵else if(keyCode == KeyEvent.VK_DOWN){hero.y+=10;}//左鍵else if(keyCode == KeyEvent.VK_LEFT){hero.x-=10;}//右鍵else if(keyCode == KeyEvent.VK_RIGHT){hero.x+=10;}repaint();}@Overridepublic void keyReleased(KeyEvent e) {}};//將適配器加入窗體的監(jiān)聽器中frame.addKeyListener(kd);}//畫圖方法@Overridepublic void paint(Graphics g) {//調用父類中的一些渲染方法super.paint(g);//畫背景g.drawImage(bg,0,0,null);//畫敵機for (int i = 0; i < eps.size(); i++) {Ep ep = eps.get(i);g.drawImage(ep.img,ep.x,ep.y,null);}//畫子彈for (int i = 0; i < fs.size(); i++) {Fire fire = fs.get(i);g.drawImage(fire.img,fire.x,fire.y,fire.w,fire.h,null);}//畫分數(shù)g.setColor(Color.white);//設置字體型號,設置加粗,設置字體大小g.setFont(new Font("\u6977\u4F53",Font.BOLD,30));//顯示分數(shù)g.drawString("分數(shù):"+score,10,30);//畫游戲機g.drawImage(hero.img,hero.x,hero.y,null);//畫游戲機血量for (int i = 0; i < hero.hp; i++) {g.drawImage(hero.img,380+i*35,5,30,30,null);}//畫游戲結束if(gameover){//設置字體顏色為紅色g.setColor(Color.red);//設置字體型號,設置加粗,設置字體大小g.setFont(new Font("楷體",Font.BOLD,35));//顯示字體g.drawString("GAMEOVER",170,300);//設置字體顏色為綠色g.setColor(Color.green);//設置字體型號,設置加粗,設置字體大小g.setFont(new Font("楷體",Font.BOLD,29));//顯示字體g.drawString("yh提醒你點擊屏幕任意位置重新開始",10,350);}//重新繪制界面repaint();} }

五.FlyObject.java

飛行物類,設定飛行物特性

package ui;import java.awt.image.BufferedImage;//飛行物具有共同特點,故抽離成父類 public class FlyObject {//均采用照片素材BufferedImage img;//位置的橫坐標int x;//位置的縱坐標int y;//圖片元素的寬度int w;//圖片元素的高度int h; }

六.Hero.java

主機類,設定游戲時候操控的飛機屬性

package ui;import java.awt.image.BufferedImage;//游戲機 public class Hero extends FlyObject{//設置游戲機血量int hp;//構造函數(shù)public Hero(){//獲取游戲機元素img = App.getImg("/img/hero.png");//確認初始位置x = 200;y = 500;//獲取游戲機圖片元素的寬和高w = img.getWidth();h = img.getHeight();//設置初始血量為3hp = 3;}//根據(jù)傳入?yún)?shù)移動相應位置public void moveToMouse(int mx,int my){x = mx;y = my;} }

七.Ep.java

敵機類

package ui;import javax.swing.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Random;//敵機類 public class Ep extends FlyObject{//設置敵機速度int sp;//設置敵機類型,不同的敵機類型有不同的屬性int type;//構造函數(shù)public Ep(){//引入隨機數(shù)隨機調用敵機Random random = new Random();//調用[1,15]范圍內的敵機int index = random.nextInt(15)+1;//保存敵機類型type = index;//如果序號小于10,則補充前導0,實質符合圖片命名規(guī)律String path = "/img/ep" + (index<10?"0":"")+index+".png";//根據(jù)路徑調用方法類函數(shù)獲取圖片io流img = App.getImg(path);//確定敵機位置//獲取敵機照片元素寬度參數(shù)w = img.getWidth();//邊界長減去照片寬度,防止照片越界x = random.nextInt(512-w);y = 0;//設置速度sp = 17-index;}//設置敵機移動方法public void move() {//如果敵機類型為5,則向左方傾斜移動if(type==5){x -= 5;y += sp;}//如果敵機類型為5,則向右方傾斜移動else if(type==6){x += 5;y += sp;}//如果是其他類型,則正常向下移動else {y+=sp;}}//判斷敵機是否被子彈擊中public boolean shootBy(Fire f) {//獲取圖片元素屬性,確定相應的坐標算法,判斷是否滿足條件,滿足則被擊中Boolean hit = x <= f.x+f.w &&x>f.x-w&&y<=f.y+f.h&&y>f.y-h;return hit;}//判斷敵機是否被玩家機擊中public boolean shootBy(Hero f) {//獲取圖片元素屬性,確定相應的坐標算法,判斷是否滿足條件,滿足則被擊中Boolean hit = x <= f.x+f.w &&x>f.x-w&&y<=f.y+f.h&&y>f.y-h;return hit;} }

八.Fire.java

子彈類

package ui;public class Fire extends FlyObject{//子彈當前移動方向,0為左上角飛,1垂直飛,2右上角飛int dir;//構造方法,初始化子彈public Fire(int hx,int hy,int dir){//獲取子彈的圖片img = App.getImg("/img/fire.png");//確定圖片的大小,此處把子彈大小縮小了4倍w = img.getWidth()/4;h = img.getHeight()/4;//根據(jù)構造函數(shù)傳進來的參數(shù)設置子彈的位置以及子彈的方向x = hx;y = hy;this.dir=dir;}//子彈的移動方法public void move() {//左上角飛if(dir==0){x -= 1;y -= 10;}//垂直上飛else if(dir == 1){y -= 10;}//右上角飛else if(dir == 2){x += 1;y -= 10;}} }

九.App.java

方法類

package ui;import javax.imageio.ImageIO; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream;//處理圖片的工具類 //此處我定義了兩種獲取圖片的方法,可以對照參考 public class App {//static可以公用所有對象都共用該方法,并且可以不依賴對象實現(xiàn)public static BufferedImage getImg(String path){//用try方法捕獲異常try {//io流,輸送數(shù)據(jù)的管道BufferedImage img = ImageIO.read(App.class.getResource(path));return img;}//異常處理,打印異常catch (IOException e) {e.printStackTrace();}//沒找到則返回空return null;}//此處與貪吃蛇小游戲的調用方法是一樣的public static ImageIcon getImg2(String path){InputStream is;//從主類文件所在的路徑尋找相應路徑的圖片is = App.class.getClassLoader().getResourceAsStream(path);//用try方法捕獲異常try {return new ImageIcon(ImageIO.read(is));}//異常處理,打印異常catch (IOException e) {e.printStackTrace();}//沒找到則返回空return null;} }

十.效果演示

總結

以上是生活随笔為你收集整理的java实现飞机大战小游戏(源码+注释)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。