
經典坦克大戰,我學習的一個案例,案例實作功能比較簡單,我做了大幅改進,
1所有元素坦克,炮彈,圍墻,心形 都是利用函式畫出來的,沒有使用圖片
2 加入游戲編輯關卡功能,可以自己編輯關卡,保存讀取
3 加入a*演算法實作自動尋路殺敵,加入躲避炮彈演算法實習自動躲避炮彈功能
4 加入跟蹤彈演算法,實作跟蹤彈追蹤敵人
exe程式下載地址
下載地址 提取碼:iz9y
需要原始碼聯系下

編輯關卡模式,設計自己的關卡

實作自動尋路規劃路線,自動打堵住的黃色圍墻

紅色跟蹤彈鎖定敵人,加入攻擊狀態,被攻擊隨機進入各種狀態

package 坦克大戰;
import java.util.Random;
import java.util.Vector;
public class DnTank extends Tank implements Runnable{//繼承坦克,執行緒介面
ZiDan zd=null;//子彈
MyTank mt=null;//我的坦克
int gzbh = 0;//跟蹤編號(用于跟蹤彈鎖定,碰撞檢測區分)
int xljg=0;//尋路間隔(-1 被鎖定 >0自動模式電腦坦克被堵,不可到達再次被檢測間隔時間)
public DnTank(int x, int y, int suD, int fangX, int leiX, int xuel, int zdSd) {
super(x, y, suD, fangX, leiX, xuel, zdSd);
}
public void run() {
while(true) {
if(this.TankXs==false) {//檢測電腦坦克被消滅,結束執行緒
break;
}
try {
Thread.sleep(50);//改變電腦運動重繪速度
} catch (Exception e) {
e.printStackTrace();
}
if(StartGame.yxzt) { //檢測是否游戲暫停
if(ShiJ>0) { //狀態時間
ShiJ--;
}else {
Zuangt=0;
}
mt=MyPanel.mt;//復制我的坦克
this.wbjz();//呼叫我的坦克可被擊中
int sd=SuD;
if(Zuangt==1) {//1減速,2慢射 3定身 4禁彈 5封禁
sd=1;
}else if(Zuangt==3 || Zuangt==5) {
sd=0;
}
boolean dz=true;//是否被擋住
for(int i=0;i<JiLu.wq.size();i++) {//碰墻檢測
Qiang q=JiLu.wq.get(i);
boolean[] pq={(q.X>=X-40 && q.X<=X+57 && Y<=q.Y+40+sd && Y>=q.Y && q.qxs),
(q.Y>=Y-40 && q.Y<=Y+57 && q.X<=X+57+sd && q.X>=X && q.qxs),
(q.X>=X-40 && q.X<=X+57 && Y>=q.Y-57-sd && Y<=q.Y && q.qxs),
(q.Y>=Y-40 && q.Y<=Y+57 && q.X>=X-40-sd && q.X<=X && q.qxs)};
if(pq[FangX-1] && q.leiX!=2 && q.leiX!=4){//緊靠墻磚時移動
int[][] sf= {{X,q.Y+41},{q.X-61,Y},{X,q.Y-61},{q.X+41,Y}};
X=sf[FangX-1][0];
Y=sf[FangX-1][1];
dz=false;
break;
}
}
if(dz) {//坦克碰撞檢測
for(int i=0;i<MyPanel.dntk.size();i++) {//檢測電腦坦克周圍是否有其他坦克阻擋
DnTank dt=MyPanel.dntk.get(i);
int cx,cy;
if(this.gzbh==dt.gzbh) {//如果是敵人自己就檢測我的坦克
cx=mt.X;
cy=mt.Y;
}else {
cx=dt.X;//電腦坦克坐標x
cy=dt.Y;//電腦坦克坐標y
}
boolean[] pt={(cx>X-57 && cx<X+57 && Y<cy+57+sd && Y>cy),
(cy>Y-57 && cy<Y+57 && cx<X+57+sd && cx>X),
(cx>X-57 && cx<X+57 && Y>cy-57-sd && Y<cy),
(cy>Y-57 && cy<Y+57 && cx>X-57-sd && cx<X)};
if(pt[FangX-1]) {
boolean[] zx= {Y>cy+61,X<cx-61,Y<cy-61,X>cx+61};
if(zx[FangX-1]) {//緊靠坦克時移動
int[][] sf= {{X,cy+61},{cx-61,Y},{X,cy-61},{cx+61,Y}};
X=sf[FangX-1][0];
Y=sf[FangX-1][1];
}
dz=false;
break;
}
}
}
if(dz) {//無阻擋移動
boolean[] zx= {Y-sd>0,X+sd<740,Y+sd<504,X-sd>0};
if(zx[FangX-1]) {
int[][] sf= {{X,Y-sd},{X+sd,Y},{X,Y+sd},{X-sd,Y}};
X=sf[FangX-1][0];
Y=sf[FangX-1][1];
}else{//靠近邊界是移動
int[][] sf= {{X,2},{738,Y},{X,502},{2,Y}};
X=sf[FangX-1][0];
Y=sf[FangX-1][1];
}
}
Random a=new Random();//此類的實體用于生成偽亂數流
int s=new Random().nextInt(22);//
if(this.leiX>9) {//型別大于10是boss重繪方向子彈
if (s>17) {//BOSS坦克改變方向幾率
this.FangX=a.nextInt(4)+1; //獲取1-4亂數
}
if(s>15 && this.zdlf.size()<10) {//BOSS坦克子彈發射幾率,子彈發射數量限制
if(Zuangt<4 || Zuangt==6) {//1減速,2慢射 3定身 4禁彈 5封禁
this.Fszd();
}
}
}else {//普通坦克重繪方向子彈
if (s>18) {//電腦坦克改變方向幾率
this.FangX=a.nextInt(4)+1; //獲取1-4亂數
}
if(s>17 && this.zdlf.size()<4) {//電腦坦克子彈發射幾率,子彈發射數量限制
if(Zuangt<4 || Zuangt==6) {//1減速,2慢射 3定身 4禁彈 5封禁
this.Fszd();
}
}
}
}
}
}
public void wbjz() {//電腦坦克擊中我或墻
for(int j=0;j<zdlf.size();j++) {
ZiDan dd=zdlf.get(j);//電腦子彈坐標xy
if(dd.zdxs) {
for(int n=0;n<JiLu.wq.size();n++) {//比對墻與子彈坐標
Qiang q=JiLu.wq.get(n);//
if(dd.x>=q.X-6 && dd.x<=q.X+34 && dd.y>=q.Y-6 && dd.y<=q.Y+34 && q.qxs && dd.zdxs) {//如果坦克是長方形,需要判斷橫向縱向兩個方向子彈與坦克坐標比對)
if(q.leiX!=0 && q.leiX!=2 ){//0不可穿墻不可擊碎可穿子彈,1不可穿墻不可擊碎不可穿子彈,2可穿墻不可擊碎可穿子彈,35不可穿墻可擊碎不可穿子彈 4可穿墻不可擊碎不可穿子彈
dd.zdxs=false;//子彈消失
if(q.leiX==3 || q.leiX==5) {
q.qxs=false;
JiLu.wq.remove(q);
Music qs=new Music(".//YinXiao/qiangsui.wav");//爆炸音樂
qs.start();
if(mt.TankXs && mt.Zuangt!=6 && q.leiX==5 && mt.Xuel>1) {
mt.Xuel=1;
}
}
}
}
}
if(dd.x>=mt.X-6 && dd.x<=mt.X+53 && dd.y>=mt.Y-6 && dd.y<=mt.Y+53 && dd.zdxs) {//如果坦克是長方形,需要判斷橫向縱向兩個方向子彈與坦克坐標比對)
if(mt.TankXs) {
if(mt.Zuangt!=6) {
Bjz();//被擊中
if(fyzt==1 || fyzt==3) {
jzzt(leiX);//賦予擊中狀態
}
}
dd.zdxs=false;//消失擊中我的電腦坦克子彈
}
}
}
}
}
public void Bjz() {//我的坦克被擊中
if(mt.Xuel>1) {
mt.Xuel--;
Music bd=new Music(".//YinXiao/wobeida.wav");
bd.start();
}else {
mt.Xuel=0;
mt.Zuangt=7;//戰敗,
mt.ShiJ=0;
mt.TankXs=false;
Music wz=new Music(".//YinXiao/wozha.wav");//爆炸音樂
wz.start();
}
}
public void jzzt(int lex) {//被電腦坦克擊中進入狀態
int s=0;
if(lex>9) {
s=new Random().nextInt(10);//被boss擊中不良狀態幾率
}else if(lex>0){
s=new Random().nextInt(30);//被普通坦克擊中不良狀態幾率
}
if(s==0 && mt.TankXs && mt.Zuangt==0 ) {
mt.ShiJ=150;//3秒狀態
mt.Zuangt=new Random().nextInt(5)+1;//隨機獲得狀態
Music wt=new Music(".//YinXiao/wozhongte.wav");//射擊音效
wt.start();
}
}
public void Fszd() {
int n;
Random a=new Random();//此類的實體用于生成偽亂數流
if(this.leiX>9) {
n=a.nextInt(6)+1;// BOSS子彈隨機個數
}else {
n=a.nextInt(this.leiX)+1;//普通坦克子彈隨機個數
}
for(int i=1;i<n+1;i++) {//生成子彈
int [][] zzd= {{X+23*i,Y-27},{X+77,Y+22*i},{X+23*i,Y+77},{X-27,Y+22*i}};
zd=new ZiDan(zzd[FangX-1][0],zzd[FangX-1][1],FangX);
if(Zuangt==2) {//
zd.suDu=3;//1減速,2慢射 3定身 4禁彈 5封禁
}else {
zd.suDu=this.ZdSd;//子彈速度
}
if(this.leiX>9 && a.nextInt(50)==0) {//boss生成追蹤彈幾率
zd.Lei=2;
}
zdlf.add(zd);
Thread t=new Thread(zd);//子彈物件添加到執行緒(不能用上面zd物件呼叫start方法,把介面類創建物件作為引數加到thread物件中)
t.start();//啟動子彈位置改變執行緒
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395250.html
標籤:其他
