java坦克大战练习。java基础项目。巩固java基础部分。
項(xiàng)目演示視頻
項(xiàng)目下載地址:Java坦克大戰(zhàn)項(xiàng)目源碼。-Java文檔類資源-CSDN文庫(kù)
也可以關(guān)注我之后私信我留個(gè)郵箱留言要哪個(gè)源碼,我會(huì)把源碼
免費(fèi)發(fā)送到你的郵箱。
用到的java技術(shù)
1.多線程
2.文件i/o操作
3.數(shù)據(jù)庫(kù)
4.java面向?qū)ο缶幊?/p>
多線程技術(shù)應(yīng)用到了坦克的子彈,移動(dòng),繪制,敵人坦克等等;
文件i/o操作作用到了保存坦克的數(shù)量以及坐標(biāo)來(lái)實(shí)現(xiàn)繼續(xù)上一局;
數(shù)據(jù)庫(kù)當(dāng)時(shí)是用Vector代替;
坦克及子彈的顯示:顯示是用的JPanel繪制實(shí)現(xiàn)的。
switch (direction) {case 0: //表示向上g.fill3DRect(x, y, 10, 60, false);//畫出坦克左邊輪子g.fill3DRect(x + 30, y, 10, 60, false);//畫出坦克右邊輪子g.fill3DRect(x + 10, y + 10, 20, 40, false);//畫出坦克蓋子g.fillOval(x + 10, y + 20, 20, 20);//畫出圓形蓋子g.drawLine(x + 20, y + 30, x + 20, y);//畫出炮筒break;部分實(shí)現(xiàn)代碼
單獨(dú)寫的繪制坦克類,根據(jù)傳進(jìn)的方向參數(shù)而繪制出相應(yīng)方向的坦克;
子彈碰撞檢測(cè):根據(jù)傳進(jìn)的子彈對(duì)象參數(shù)和坦克參數(shù)來(lái)進(jìn)行相應(yīng)的判定。
// 子彈碰撞檢測(cè)方法public void BulletCollision(ShotBullet bulletBody, Tank TankBody) {switch (TankBody.getDirectionNum()) {case 0:case 2:if (bulletBody.x > TankBody.getX() &&bulletBody.x < TankBody.getX() + 40 &&bulletBody.y > TankBody.getY() &&bulletBody.y < TankBody.getY() + 60) {// 將子彈和敵人狀態(tài)設(shè)為false,等同于殺死bulletBody.bulletState = false;TankBody.TankState = false;// 子彈擊中就把敵方坦克從vector里刪除掉enemyTankVector.remove(TankBody);// 判斷擊中的坦克是不是enemytank類型如果是就把擊毀坦克數(shù)加一if (TankBody instanceof EnemyTank) {Recorder.addWreckTankNum();}// 如果子彈碰到敵人則新建一個(gè)爆炸動(dòng)畫Bomb bomb = new Bomb(TankBody.getX(), TankBody.getY());bombVector.add(bomb);}break;部分實(shí)現(xiàn)代碼
// 判斷己方子彈是否擊中敵方坦克,依次遍歷每個(gè)子彈依次判斷public void hitEnemyTank() {for (int i = 0; i < ownHero.shotBulletVector.size(); i++) {ShotBullet shotBullet = ownHero.shotBulletVector.get(i);// shotBullet不能為空,同時(shí)shotBullet是活著的狀態(tài)if (shotBullet != null && shotBullet.bulletState) {for (int j = 0; j < enemyTankVector.size(); j++) {EnemyTank enemyTank = enemyTankVector.get(j);BulletCollision(shotBullet, enemyTank);}}}}
這里是己方坦克是否擊中敵方坦克
// 判斷敵方子彈是否擊中己方坦克,依次遍歷每個(gè)子彈依次判斷public void hitHeroTank() {// 先遍歷敵方坦克數(shù)量for (int i = 0; i < enemyTankVector.size(); i++) {EnemyTank enemyTank = enemyTankVector.get(i);// 遍歷取得敵方坦克// 遍歷敵方坦克的子彈數(shù)量for (int j = 0; j < enemyTank.bulletsVector.size(); j++) {ShotBullet shotBullet = enemyTank.bulletsVector.get(j);// 取得敵方坦克子彈// 己方英雄和子彈必須是活的才會(huì)繼續(xù)判斷是否擊中if (ownHero.TankState && shotBullet.bulletState) {BulletCollision(shotBullet, ownHero);}}}}
判斷敵方坦克是否擊中自己
實(shí)現(xiàn)繼續(xù)上一局:主要是把坦克的坐標(biāo)寫入到文件,需要的時(shí)候在讀取。
//寫入txt文件的方法public static void infoWrite() {try {// 要存入的文件路徑bw = new BufferedWriter(new FileWriter(filePath));bw.write(wreckTankNum + "\r\n");// 遍歷坦克個(gè)數(shù),把坐標(biāo)寫入到文件for (int i = 0; i < Recorder.enemyTankVector.size(); i++) {EnemyTank enemyTank = enemyTankVector.get(i);String tankInfo = enemyTank.getX() +" " + enemyTank.getY() +" " + enemyTank.getDirectionNum();bw.write(tankInfo + "\r\n");}} catch (IOException e) {e.printStackTrace();} finally {try {bw.close();} catch (IOException e) {e.printStackTrace();}}}寫入文件的方法
//用于讀取filePath里的信息public static Vector<Nodes> getNodeAndEnemyTankInfo() {try {br = new BufferedReader(new FileReader(filePath));wreckTankNum = Integer.parseInt(br.readLine());String line = "";while ((line = br.readLine()) != null) {// 分割字符串,取得想要的部分String[] fileSplit = line.split(" ");Nodes nodes = new Nodes(Integer.parseInt(fileSplit[0]), Integer.parseInt(fileSplit[1]), Integer.parseInt(fileSplit[2]));// 把nodes放到nodesVector里面nodesVector.add(nodes);}} catch (IOException e) {e.printStackTrace();} finally {try {if (br != null) {br.close();}} catch (IOException e) {e.printStackTrace();}}return nodesVector;}
讀取文件方法
把讀取的信息賦給一個(gè)集合里,到時(shí)候使用
如果用戶選擇的是繼續(xù)上一局,用被賦值的集合初始化游戲坦克坐標(biāo)
switch (userChoose) {case "1":// 表示開(kāi)始新游戲// 把擊毀坦克數(shù)量重置為零Recorder.setWreckTankNum(0);// 把敵方坦克遍歷到enemyTanks里面for (int i = 0; i < enemyTankNumber; i++) {EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);//創(chuàng)建敵人坦克// 把enemyTankVector傳到setEnemyTankVector方法中enemyTank.setEnemyTankVector(enemyTankVector);enemyTank.setDirectionNum(2);// 2表示下面方向enemyTank.setSpeed(3);// 設(shè)置敵方坦克移動(dòng)速度new Thread(enemyTank).start();//啟動(dòng)敵方坦克移動(dòng)線程enemyTankVector.add(enemyTank);// 往vector里添加敵方坦克ShotBullet enemyShotBullet = new ShotBullet(enemyTank.getX() + 20,enemyTank.getY() + 60, enemyTank.getDirectionNum());enemyTank.bulletsVector.add(enemyShotBullet);new Thread(enemyShotBullet).start();// 啟動(dòng)敵方坦克子彈線程}// 表示用戶輸入正確judgeUserChoose = true;break;case "2":// 表示繼續(xù)上次游戲// 把敵方坦克遍歷到enemyTanks里面for (int i = 0; i < nodesVector.size(); i++) {Nodes nodes = nodesVector.get(i);EnemyTank enemyTank = new EnemyTank(nodes.getX(), nodes.getY());//創(chuàng)建敵人坦克// 把enemyTankVector傳到setEnemyTankVector方法中enemyTank.setEnemyTankVector(enemyTankVector);enemyTank.setDirectionNum(nodes.getDirection());// 表示方向enemyTank.setSpeed(3);// 設(shè)置敵方坦克移動(dòng)速度new Thread(enemyTank).start();//啟動(dòng)敵方坦克移動(dòng)線程enemyTankVector.add(enemyTank);// 往vector里添加敵方坦克ShotBullet enemyShotBullet = new ShotBullet(enemyTank.getX() + 20,enemyTank.getY() + 60, enemyTank.getDirectionNum());enemyTank.bulletsVector.add(enemyShotBullet);new Thread(enemyShotBullet).start();// 啟動(dòng)敵方坦克子彈線程}// 表示用戶輸入正確judgeUserChoose = true;break;}判斷用戶是否繼續(xù)上一局
項(xiàng)目難點(diǎn)
這個(gè)項(xiàng)目的難點(diǎn)主要是設(shè)置敵方坦克不重疊的地方,其實(shí)用到的東西沒(méi)那么難,主要是需要想到的地方很多。
//編寫方法,判斷當(dāng)前的這個(gè)敵人坦克,是否和 enemyTanks 中的其他坦克發(fā)生的重疊或者碰撞public boolean judgeTankCollice() {// 判斷當(dāng)前敵人坦克(this)方向switch (this.getDirectionNum()) {case 0://上//讓當(dāng)前敵人坦克和其它所有的敵人坦克比較for (int i = 0; i < enemyTankVector.size(); i++) {//從vector中取出一個(gè)敵人坦克EnemyTank enemyTankGat = enemyTankVector.get(i);//不和自己比較if (enemyTankGat != this) {//如果敵人坦克是上/下//1. 如果敵人坦克是上/下 x的范圍 [enemyTank.getX(), enemyTank.getX() + 40]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTankGat.getDirectionNum() == 0 || enemyTankGat.getDirectionNum() == 2) {//2. 當(dāng)前坦克 左上角的坐標(biāo) [this.getX(), this.getY()]if (this.getX() >= enemyTankGat.getX()&& this.getX() <= enemyTankGat.getX() + 40&& this.getY() >= enemyTankGat.getY()&& this.getY() <= enemyTankGat.getY() + 60) {return true;}//3. 當(dāng)前坦克 右上角的坐標(biāo) [this.getX() + 40, this.getY()]if (this.getX() + 40 >= enemyTankGat.getX()&& this.getX() + 40 <= enemyTankGat.getX() + 40&& this.getY() >= enemyTankGat.getY()&& this.getY() <= enemyTankGat.getY() + 60) {return true;}}//如果敵人坦克是 右/左//1. 如果敵人坦克是右/左 x的范圍 [enemyTank.getX(), enemyTank.getX() + 60]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTankGat.getDirectionNum() == 1 || enemyTankGat.getDirectionNum() == 3) {//2. 當(dāng)前坦克 左上角的坐標(biāo) [this.getX(), this.getY()]if (this.getX() >= enemyTankGat.getX()&& this.getX() <= enemyTankGat.getX() + 60&& this.getY() >= enemyTankGat.getY()&& this.getY() <= enemyTankGat.getY() + 40) {return true;}//3. 當(dāng)前坦克 右上角的坐標(biāo) [this.getX() + 40, this.getY()]if (this.getX() + 40 >= enemyTankGat.getX()&& this.getX() + 40 <= enemyTankGat.getX() + 60&& this.getY() >= enemyTankGat.getY()&& this.getY() <= enemyTankGat.getY() + 40) {return true;}}}}break;case 1://右//讓當(dāng)前敵人坦克和其它所有的敵人坦克比較for (int i = 0; i < enemyTankVector.size(); i++) {//從vector 中取出一個(gè)敵人坦克EnemyTank enemyTank = enemyTankVector.get(i);//不和自己比較if (enemyTank != this) {//如果敵人坦克是上/下//老韓分析//1. 如果敵人坦克是上/下 x的范圍 [enemyTank.getX(), enemyTank.getX() + 40]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 2) {//2. 當(dāng)前坦克 右上角的坐標(biāo) [this.getX() + 60, this.getY()]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}//3. 當(dāng)前坦克 右下角的坐標(biāo) [this.getX() + 60, this.getY() + 40]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 40&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 60) {return true;}}//如果敵人坦克是 右/左//老韓分析//1. 如果敵人坦克是右/左 x的范圍 [enemyTank.getX(), enemyTank.getX() + 60]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 3) {//2. 當(dāng)前坦克 右上角的坐標(biāo) [this.getX() + 60, this.getY()]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}//3. 當(dāng)前坦克 右下角的坐標(biāo) [this.getX() + 60, this.getY() + 40]if (this.getX() + 60 >= enemyTank.getX()&& this.getX() + 60 <= enemyTank.getX() + 60&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 40) {return true;}}}}break;case 2://下//讓當(dāng)前敵人坦克和其它所有的敵人坦克比較for (int i = 0; i < enemyTankVector.size(); i++) {//從vector 中取出一個(gè)敵人坦克EnemyTank enemyTank = enemyTankVector.get(i);//不和自己比較if (enemyTank != this) {//如果敵人坦克是上/下//老韓分析//1. 如果敵人坦克是上/下 x的范圍 [enemyTank.getX(), enemyTank.getX() + 40]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 2) {//2. 當(dāng)前坦克 左下角的坐標(biāo) [this.getX(), this.getY() + 60]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 60) {return true;}//3. 當(dāng)前坦克 右下角的坐標(biāo) [this.getX() + 40, this.getY() + 60]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 40&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 60) {return true;}}//如果敵人坦克是 右/左//老韓分析//1. 如果敵人坦克是右/左 x的范圍 [enemyTank.getX(), enemyTank.getX() + 60]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 3) {//2. 當(dāng)前坦克 左下角的坐標(biāo) [this.getX(), this.getY() + 60]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 40) {return true;}//3. 當(dāng)前坦克 右下角的坐標(biāo) [this.getX() + 40, this.getY() + 60]if (this.getX() + 40 >= enemyTank.getX()&& this.getX() + 40 <= enemyTank.getX() + 60&& this.getY() + 60 >= enemyTank.getY()&& this.getY() + 60 <= enemyTank.getY() + 40) {return true;}}}}break;case 3://左//讓當(dāng)前敵人坦克和其它所有的敵人坦克比較for (int i = 0; i < enemyTankVector.size(); i++) {//從vector 中取出一個(gè)敵人坦克EnemyTank enemyTank = enemyTankVector.get(i);//不和自己比較if (enemyTank != this) {//如果敵人坦克是上/下//老韓分析//1. 如果敵人坦克是上/下 x的范圍 [enemyTank.getX(), enemyTank.getX() + 40]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 60]if (enemyTank.getDirectionNum() == 0 || enemyTank.getDirectionNum() == 2) {//2. 當(dāng)前坦克 左上角的坐標(biāo) [this.getX(), this.getY() ]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 60) {return true;}//3. 當(dāng)前坦克 左下角的坐標(biāo) [this.getX(), this.getY() + 40]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 40&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 60) {return true;}}//如果敵人坦克是 右/左//老韓分析//1. 如果敵人坦克是右/左 x的范圍 [enemyTank.getX(), enemyTank.getX() + 60]// y的范圍 [enemyTank.getY(), enemyTank.getY() + 40]if (enemyTank.getDirectionNum() == 1 || enemyTank.getDirectionNum() == 3) {//2. 當(dāng)前坦克 左上角的坐標(biāo) [this.getX(), this.getY() ]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() >= enemyTank.getY()&& this.getY() <= enemyTank.getY() + 40) {return true;}//3. 當(dāng)前坦克 左下角的坐標(biāo) [this.getX(), this.getY() + 40]if (this.getX() >= enemyTank.getX()&& this.getX() <= enemyTank.getX() + 60&& this.getY() + 40 >= enemyTank.getY()&& this.getY() + 40 <= enemyTank.getY() + 40) {return true;}}}}break;}return false;}判斷重疊代碼
結(jié)尾
通過(guò)這些項(xiàng)目讓我學(xué)到了很多很多。讓我鞏固了java基礎(chǔ)部分。
總結(jié)
以上是生活随笔為你收集整理的java坦克大战练习。java基础项目。巩固java基础部分。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。