java實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)小游戲(源碼加注釋)
一.工程文件

二.Main.java
主函數(shù),實(shí)現(xiàn)類
package ui;
//主函數(shù)實(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);
//調(diào)用開始游戲的方法啟動(dòng)游戲
panel.action();
//將面板加入到窗體中
frame.add(panel);
//設(shè)置窗體可見
frame.setVisible(true);
}
}
三.GameFrame.java
窗體類,繪制窗體
package ui;
import javax.swing.*;
//創(chuàng)建窗體
public class GameFrame extends JFrame {
//構(gòu)造方法,初始化窗體屬性
public GameFrame(){
//設(shè)置標(biāo)題,來源于JFrame
setTitle("飛機(jī)大戰(zhàn)");
//設(shè)置大小
setSize(512,768);
//設(shè)置居中
setLocationRelativeTo(null);
//設(shè)置窗體可見
//setVisible(true);
//不允許玩家修改界面大小
//setResizable(false);
//設(shè)置默認(rèn)的關(guān)閉選項(xiàng)
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;
//自定義游戲面板
public class GamePanel extends JPanel {
//定義背景圖
BufferedImage bg;
BufferedImage heroImg;
BufferedImage epImg;
Hero hero = new Hero();
//敵機(jī)集合
List<Ep> eps = new ArrayList<Ep>();
//彈藥庫
List<Fire> fs = new ArrayList<Fire>();
//定義分?jǐn)?shù)
int score;
//設(shè)置游戲開關(guān)
Boolean gameover=false;
//設(shè)置火力
int power = 1;
//Ep ep = new Ep();
public void action(){
//創(chuàng)建線程
new Thread(){
public void run(){
while (true){
if(!gameover){
epEnter();
//調(diào)用敵機(jī)移動(dòng)方法
epMove();
//發(fā)射子彈
shoot();
//子彈移動(dòng)
fireMove();
//判斷子彈是否擊中敵機(jī)
shootEp();
//檢測(cè)敵機(jī)是否撞到主機(jī)
hit();
}
//每執(zhí)行一次,線程休眠一會(huì)兒
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//重繪界面
repaint();
}
}
}.start();
}
//每執(zhí)行n次,釋放一個(gè)敵機(jī)
int index = 0;
protected void epEnter(){
index++;
//創(chuàng)建敵機(jī)
if(index>=20){
Ep e = new Ep();
//加入集合
eps.add(e);
index = 0;
}
}
int findex = 0;
protected void shoot(){
findex++;
if(findex>=20){
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);
}
//使計(jì)數(shù)器歸0
findex = 0;
}
}
//讓敵機(jī)移動(dòng)
protected void epMove(){
for (int i = 0; i < eps.size(); i++) {
Ep e = eps.get(i);
e.move();
}
}
//讓子彈移動(dòng)
protected void fireMove(){
for (int i = 0; i < fs.size(); i++) {
Fire f = fs.get(i);
f.move();
}
}
//判斷子彈是否擊中敵機(jī)
protected void shootEp(){
//遍歷所有子彈
for (int i = 0; i < fs.size(); i++) {
//獲取每一顆子彈
Fire f = fs.get(i);
//判斷一顆子彈是否擊中敵機(jī)
bang(f);
}
}
//判斷一顆子彈是否擊中敵機(jī)
protected void bang(Fire f){
for (int i = 0; i < eps.size(); i++) {
//取出每一張敵機(jī)
Ep e = eps.get(i);
//判斷這個(gè)子彈是否擊中敵機(jī)
if(e.shootBy(f)&&e.type!=15){
//判斷敵機(jī)是否擊中道具機(jī)
if(e.type==12){
//火力增加
power++;
//如果火力值大于三,增加血量
if(power>3){
//恢復(fù)血量
if(hero.hp<3){
hero.hp++;
}
power = 3;
}
}
//如果敵機(jī)被子彈擊中
//敵機(jī)消失
eps.remove(e);
//刪除子彈
fs.remove(f);
//增加分?jǐn)?shù)
score += 10;
}
}
}
//檢測(cè)敵機(jī)是否撞到主機(jī)
protected void hit() {
for (int i = 0; i < eps.size(); i++) {
//獲取每一個(gè)敵機(jī)
Ep e = eps.get(i);
if(e.shootBy(hero)){
//刪除敵機(jī)
eps.remove(e);
//主機(jī)血量減少
hero.hp--;
//火力恢復(fù)初始值
power = 1;
//分?jǐn)?shù)增加
score += 10;
//當(dāng)主機(jī)血量減少到0時(shí)游戲結(jié)束
if(hero.hp==0){
gameover = true;
}
}
}
}
//構(gòu)造函數(shù)
public GamePanel(GameFrame frame){
//設(shè)置背景
bg = App.getImg("/img/bg2.jpg");
//創(chuàng)建鼠標(biāo)監(jiān)聽
//創(chuàng)建鼠標(biāo)適配器
MouseAdapter adapter = new MouseAdapter() {
//點(diǎn)擊鼠標(biāo)時(shí)會(huì)執(zhí)行的代碼
@Override
public void mouseClicked(MouseEvent e) {
//游戲結(jié)束時(shí)候,點(diǎn)擊屏幕時(shí)重新開始游戲
if(gameover){
//重新初始化主機(jī)
hero = new Hero();
//重置游戲開關(guān)
gameover = false;
//分?jǐn)?shù)清0
score = 0;
//清空敵機(jī)集合
eps.clear();
//隨機(jī)背景圖
Random random = new Random();
int index = random.nextInt(5)+1;
bg = App.getImg("/img/bg"+index+".jpg");
//重新繪制
repaint();
}
}
//確定需要監(jiān)聽的事件
@Override
public void mouseMoved(MouseEvent e) {
//讓主機(jī)的橫縱坐標(biāo)等于鼠標(biāo)的移動(dòng)坐標(biāo)
//獲取鼠標(biāo)的橫縱坐標(biāo)
int mx = e.getX();
int my = e.getY();
//傳遞坐標(biāo)
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() {
@Override
public void keyTyped(KeyEvent e) {
}
//當(dāng)鍵盤被按下是觸發(fā)
@Override
public 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();
}
@Override
public void keyReleased(KeyEvent e) {
}
};
//將適配器加入窗體的監(jiān)聽器中
frame.addKeyListener(kd);
}
//畫圖方法
@Override
public void paint(Graphics g) {
super.paint(g);
//畫背景
g.drawImage(bg,0,0,null);
//畫敵機(jī)
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);
}
//畫分?jǐn)?shù)
g.setColor(Color.white);
g.setFont(new Font("\u6977\u4F53",Font.BOLD,30));
g.drawString("分?jǐn)?shù):"+score,10,30);
g.drawImage(hero.img,hero.x,hero.y,null);
//畫主機(jī)血量
for (int i = 0; i < hero.hp; i++) {
g.drawImage(hero.img,380+i*35,5,30,30,null);
}
//畫游戲結(jié)束
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提醒你點(diǎn)擊屏幕任意位置重新開始",10,350);
}
repaint();
}
}
五.FlyObject.java
飛行物類,設(shè)定飛行物特性
package ui;
import java.awt.image.BufferedImage;
//具有共同特點(diǎn),故抽離成父類
public class FlyObject {
BufferedImage img;
int x;
int y;
int w;
int h;
}
六.Hero.java
主機(jī)類,設(shè)定游戲時(shí)候操控的飛機(jī)屬性
package ui;
import java.awt.image.BufferedImage;
//主機(jī)
public class Hero extends FlyObject{
//主機(jī)血量
int hp;
public Hero(){
img = App.getImg("/img/hero.png");
//確認(rèn)初始位置
x = 200;
y = 500;
w = img.getWidth();
h = img.getHeight();
hp = 3;
}
public void moveToMouse(int mx,int my){
x = mx;
y = my;
}
}
七.Ep.java
敵機(jī)類
package ui;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
//敵機(jī)類
public class Ep extends FlyObject{
int sp;
//設(shè)置敵機(jī)類型
int type;
public Ep(){
Random random = new Random();
int index = random.nextInt(15)+1;
type = index;
String path = "/img/ep" + (index<10?"0":"")+index+".png";
img = App.getImg(path);
//確定敵機(jī)圖片
w = img.getWidth();
x = random.nextInt(512-w);
y = 0;
//設(shè)置速度
sp = 17-index;
}
public void move() {
if(type==5){
x -= 5;
y += sp;
}
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{
//子彈當(dāng)前移動(dòng)方向,0為左上角飛,1垂直飛,2右上角飛
int dir;
//構(gòu)造方法,初始化子彈
public Fire(int hx,int hy,int dir){
//確定子彈的圖片
img = App.getImg("/img/fire.png");
//確定圖片的大小
w = img.getWidth()/4;
h = img.getHeight()/4;
//確定子彈的位置
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可以公用所有對(duì)象都共用該方法,并且可以不依賴對(duì)象實(shí)現(xiàn)
public static BufferedImage getImg(String path){
//io流,輸送數(shù)據(jù)的管道
try {
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 {
return new ImageIcon(ImageIO.read(is));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
十.效果演示



到此這篇關(guān)于java實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)小游戲(源碼加注釋)的文章就介紹到這了,更多相關(guān)Java飛機(jī)大戰(zhàn)小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java實(shí)現(xiàn)打飛機(jī)小游戲(附完整源碼)
- 微信游戲打飛機(jī)游戲制作(java模擬微信打飛機(jī)游戲)
- java版飛機(jī)大戰(zhàn)實(shí)戰(zhàn)項(xiàng)目詳細(xì)步驟
- java實(shí)現(xiàn)飛機(jī)大戰(zhàn)案例詳解
- Java實(shí)現(xiàn)飛機(jī)大戰(zhàn)-連接數(shù)據(jù)庫并把得分寫入數(shù)據(jù)庫
- java實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
- Java實(shí)現(xiàn)飛機(jī)航班管理系統(tǒng)的思路詳解
- java實(shí)現(xiàn)飛機(jī)游戲代碼
- java實(shí)現(xiàn)抖音飛機(jī)大作戰(zhàn)
- java實(shí)現(xiàn)雷霆戰(zhàn)機(jī)
相關(guān)文章
MyBatisPlus標(biāo)準(zhǔn)數(shù)據(jù)層CRUD的使用詳解
這篇文章主要介紹了MyBatisPlus標(biāo)準(zhǔn)數(shù)據(jù)層CRUD的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Java中的權(quán)限修飾符(protected)示例詳解
這篇文章主要給大家介紹了關(guān)于Java中權(quán)限修飾符(protected)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Java?MyBatis實(shí)戰(zhàn)之QueryWrapper中and和or拼接技巧大全
在Java中QueryWrapper是MyBatis-Plus框架中的一個(gè)查詢構(gòu)造器,它提供了豐富的查詢方法,其中包括and和or方法,可以用于構(gòu)建復(fù)雜的查詢條件,這篇文章主要給大家介紹了關(guān)于Java?MyBatis實(shí)戰(zhàn)之QueryWrapper中and和or拼接技巧的相關(guān)資料,需要的朋友可以參考下2024-07-07
Java兩個(gè)乒乓球隊(duì)比賽名單問題(判斷素?cái)?shù))
兩個(gè)乒乓球隊(duì)進(jìn)行比賽,各出三人。甲隊(duì)為a,b,c三人,乙隊(duì)為x,y,z三人。已抽簽決定比賽名單。有人向隊(duì)員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請(qǐng)編程序找出三隊(duì)賽手的名單2017-02-02
Springboot錯(cuò)誤頁面和錯(cuò)誤信息定制操作
這篇文章主要介紹了Springboot錯(cuò)誤頁面和錯(cuò)誤信息定制操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
java實(shí)現(xiàn)計(jì)算周期性提醒的示例
本文分享一個(gè)java實(shí)現(xiàn)計(jì)算周期性提醒的示例,可以計(jì)算父親節(jié)、母親節(jié)這樣的節(jié)日,也可以定義如每月最好一個(gè)周五,以方便安排會(huì)議2014-04-04

