您好,登錄后才能下訂單哦!
Java實(shí)現(xiàn)坦克大戰(zhàn)小游戲代碼如何編寫(xiě),很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
紅色坦克是我們的操縱坦克,黑色是敵人坦克。
上下左右鍵控制坦克移動(dòng)方向
按ctrl鍵發(fā)射炮彈
紅色坦克可以穿墻,黑色不可以
具體頁(yè)面如下:
奉上全部源代碼:
Tank.java
import java.awt.*; import java.awt.event.*; import java.util.*; public class Tank { private int x; private int y; private int oldx; private int oldy; private int life = 100; private boolean bL = false ,bU = false ,bR = false ,bD= false; //產(chǎn)生隨機(jī)數(shù) private static Random r = new Random(); //九種坦克運(yùn)動(dòng)方向 enum Direction{L,LU,U,RU,R,RD,D,LD,STOP}; //初始化坦克方向 private Direction dir = Direction.STOP; //初始化炮筒方向 private Direction ptDir = Direction.U; //坦克移動(dòng)速度 private static final int XSPEED = 5; private static final int YSPEED = 5; //坦克大小 private static final int WIDTH = 30; private static final int HIGHT =30; //定義TankClient類(lèi) TankClient tc; public int getLife(){ return life; } public void setLife(int life){ this.life =life; } private boolean good =true ;//定義坦克類(lèi)型,敵方還是我方 public boolean isgood() { return good; } //定義坦克狀態(tài) private boolean live = true; //設(shè)置enemy坦克隨機(jī)移動(dòng)步數(shù) private static int step = r.nextInt(12)+3; //構(gòu)造坦克狀態(tài)方法 public boolean islive () { return live; } public void setlive(boolean live) { this.live = live; } //構(gòu)造方法 public Tank(int x, int y) { this.x = x; this.y = y; } public Tank (int x,int y,Boolean good ,Direction dir,TankClient tc) { this (x,y); this.good = good; this.dir = dir ; this.tc = tc; } public void draw (Graphics g) { if (!live) { if (!good) { tc.tanks.remove(this); } return; } Color c = g.getColor();//? if(good==true) {g.setColor(Color.RED);}//定義我方坦克顏色 else g.setColor(Color.BLACK);//定義敵方坦克顏色 g.fillOval(x,y, WIDTH, HIGHT);//定義坦克位置及大小 g.setColor(c);//? move(); switch (ptDir)//畫(huà)炮筒 { case L: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y + Tank.HIGHT / 2); break; case LU: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y); break; case U: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH / 2, y); break; case RU: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH, y); break; case R: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH, y + Tank.HIGHT / 2); break; case RD: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH, y + Tank.HIGHT); break; case D: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x + Tank.WIDTH / 2, y + Tank.HIGHT); break; case LD: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HIGHT / 2, x, y + Tank.HIGHT); break; } } private void stay() { this.x=oldx; this.y=oldy; } //坦克移動(dòng) void move () { this.oldx=x; this.oldy=y; switch(dir) { case L: x-=XSPEED; break; case LU: x-=XSPEED; y-=YSPEED; break; case U: y-=YSPEED; break; case RU: x+=XSPEED; y-=YSPEED; break; case R: x+=XSPEED; break; case RD: x+=XSPEED; y+=YSPEED; break; case D: y+=YSPEED; break; case LD: x-=XSPEED; y+=YSPEED; break; case STOP: break; } if (this.dir!=Direction.STOP) { ptDir = dir; } if (x<0) x=0; if (y<20) y=20; if (x>TankClient.WinWidth-Tank.WIDTH) x=TankClient.WinWidth-Tank.WIDTH; if (y>TankClient.WinHigh-Tank.HIGHT) y=TankClient.WinHigh-Tank.HIGHT; //讓enemy坦克自由移動(dòng) if (!good) { Direction[] dirs= Direction.values();//將枚舉轉(zhuǎn)化為數(shù)組 if (step ==0) { step = r.nextInt(12)+3; int rn = r.nextInt(dirs.length);//產(chǎn)生隨機(jī)數(shù) dir = dirs[rn]; } step--; if (r.nextInt(40)>38) {this.fire();} } } //坦克方向 void localDirection() { if (bL&&!bU&&!bR&&!bD) dir= Direction.L; else if (bL&&bU&&!bR&&!bD) dir= Direction.LU; else if (!bL&&bU&&!bR&&!bD) dir= Direction.U; else if (!bL&&bU&&bR&&!bD) dir= Direction.RU; else if (!bL&&!bU&&bR&&!bD) dir= Direction.R; else if (!bL&&!bU&&bR&&bD) dir= Direction.RD; else if (!bL&&!bU&&!bR&&bD) dir= Direction.D; else if (bL&&!bU&&!bR&&bD) dir= Direction.LD; else dir =Direction.STOP; } public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_CONTROL: fire(); break; case KeyEvent.VK_LEFT: bL=true; break; case KeyEvent.VK_UP: bU=true; break; case KeyEvent.VK_RIGHT: bR=true; break; case KeyEvent.VK_DOWN: bD=true; break; } localDirection();//獲取執(zhí)行方向 } public void keyReleased(KeyEvent e) { int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_LEFT: bL=false; break; case KeyEvent.VK_UP: bU=false; break; case KeyEvent.VK_RIGHT: bR=false; break; case KeyEvent.VK_DOWN: bD=false; break; } localDirection(); } //定義坦克發(fā)射子彈類(lèi) public Missile fire() { if (!live) return null; int x= this.x+Tank.WIDTH/2-Missile.WIDTH/2; int y= this.y +Tank.HIGHT/2-Missile.HIGHT/2; Missile m = new Missile(x,y,ptDir,good,tc); tc.Missiles.add(m); return m; } //《碰撞檢測(cè)》獲取坦克矩形屬性 public Rectangle getRect() { return new Rectangle(x,y,WIDTH,HIGHT); } //《碰撞檢測(cè)》 public boolean tankHitWall(Wall w) { if(this.getRect().intersects(w.getRect())) { stay(); return true; } return false; } public boolean tankHitTank(java.util.List<Tank> tanks) { for (int i=0;i<tanks.size();i++) { Tank t = tanks.get(i); if (this!=t) { if (this.live&&t.islive()&&this.getRect().intersects(t.getRect())) { this.stay(); t.stay(); return true ; } } } return false; } }
Wall.java
import java.awt.*; public class Wall { int x; int y; int width; int height; TankClient tc; public Wall (int x,int y,int width,int height, TankClient tc) { this.x= x; this.y= y; this.width = width; this.height = height; this.tc = tc; } public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.GRAY); g.fillRect(x, y, width, height); g.setColor(c); } //《碰撞檢測(cè)》獲取矩形屬性 public Rectangle getRect() { return new Rectangle(x,y,width,height); } }
TankClient.java
import java.awt.*; import java.awt.event.*; import java.util.List; import java.util.ArrayList; public class TankClient extends Frame { Tank myTank = new Tank(400,430,true,Tank.Direction.STOP,this);//創(chuàng)建自己的坦克 List <Tank> tanks= new ArrayList<Tank>(); //創(chuàng)建敵人坦克容器 List<Explode> Explodes = new ArrayList<Explode>();//創(chuàng)建爆炸容器 List<Missile> Missiles = new ArrayList<Missile>();//定義容器,存放炮彈 Wall wall1 = new Wall(100,100,30,400,this); Wall wall2 = new Wall(350,400,400,30,this); /* * 定義窗口大小變量 */ public static final int WinWidth=800; public static final int WinHigh=600; //定義框架大小 public void launchFrame() { //添加10輛敵人坦克 for (int i = 0;i<10;i++) { tanks.add(new Tank(50+40*i,100,false,Tank.Direction.D,this)); } this.setLocation(40,40);//定義窗口位置 this.setSize(WinWidth,WinHigh);//設(shè)置窗口大小 this.setTitle("坦克大戰(zhàn)");//設(shè)置窗口標(biāo)題 //設(shè)置監(jiān)聽(tīng)器,使窗口關(guān)閉 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.setBackground(Color.WHITE);//設(shè)置窗口背景顏色 this.setVisible(true);//設(shè)置窗口可見(jiàn) this.setResizable(false);//設(shè)置為不可調(diào)整窗口大小 this.addKeyListener(new KeyMonitor()); new Thread(new PaintThread()).start(); } //定義一個(gè)新圖片為空,雙緩沖 Image OffScreenImage = null; /* * 定義畫(huà)板 */ public void paint(Graphics g) { //g.drawString("當(dāng)前炮彈數(shù)"+Missiles.size(), 40, 80); //g.drawString("當(dāng)前爆炸數(shù)"+Explodes.size(), 40, 100); g.drawString("Tank數(shù)量"+tanks.size(),40,40); g.drawString("MyTank血量"+myTank.getLife(),40,60); for (int i=0;i<Missiles.size();i++) { Missile m = Missiles.get(i); m.hitTanks(tanks); m.hitTank(myTank); m.hitWall(wall1); m.hitWall(wall2); m.draw(g); } for (int i=0;i<Explodes.size();i++) { Explode e = Explodes.get(i); e.draw(g); } for (int i = 0;i<tanks.size();i++) { Tank t = tanks.get(i); t.tankHitWall(wall1); t.tankHitWall(wall2); t.tankHitTank(tanks); t.draw(g); } myTank.draw(g); wall1.draw(g); wall2.draw(g); } //重寫(xiě)update 刷新屏幕先調(diào)用update方法再調(diào)用畫(huà)筆工具,故刷新屏幕讓其直接調(diào)用update方法 public void update (Graphics g) { if (OffScreenImage == null ) { OffScreenImage = this.createImage(WinWidth,WinHigh); } Graphics gOffScreen = OffScreenImage.getGraphics(); Color c = gOffScreen.getColor(); gOffScreen.setColor(Color.WHITE); gOffScreen.fillRect(0,0,WinWidth,WinHigh); gOffScreen.setColor(c); paint(gOffScreen); g.drawImage(OffScreenImage,0,0,null); } public static void main(String[] args) { TankClient tankClient = new TankClient(); tankClient.launchFrame(); } //線程類(lèi)--刷新屏幕 private class PaintThread implements Runnable { public void run() { while(true) { repaint(); //刷新屏幕 try { Thread.sleep(40); }catch (InterruptedException e) { e.printStackTrace(); } } } } /** * * 內(nèi)部類(lèi) 添加鍵盤(pán)監(jiān)聽(tīng) * */ private class KeyMonitor extends KeyAdapter { //按鍵時(shí) public void keyPressed(KeyEvent e) { myTank.keyPressed(e); } //松鍵時(shí) public void keyReleased(KeyEvent e) { myTank.keyReleased(e); } } }
Explode.java
import java.awt.*; public class Explode { int x; int y; private boolean live = true; private TankClient tc ; int[] diameter = {30,40,50,40,30,10,5}; int step = 0; //結(jié)構(gòu) public Explode (int x ,int y,TankClient tc) { this.x =x; this.y = y; this.tc = tc; } public void draw (Graphics g) { if(!live){ tc.Explodes.remove(this); return ; } if (step ==diameter.length) { live = false ; step = 0; return ; } Color c = g.getColor(); g.setColor(Color.RED); g.fillOval(x, y, diameter[step], diameter[step]); g.setColor(c); step++; } }
Missile.java
import java.awt.*; import java.util.List; //定義子彈類(lèi) public class Missile { //定義子彈速度 public static final int XSPEED=10; public static final int YSPEED=10; //定義子彈大小 public static final int WIDTH =10; public static final int HIGHT =10; private boolean live= true ;//定義炮彈狀態(tài) //定義發(fā)出的炮彈歸屬 private boolean good; public boolean islive() { return live; } int x,y ;//子彈坐標(biāo) TankClient tc; Tank.Direction dir; public Missile (int x,int y ,Tank.Direction dir) { this.x=x; this.y=y; this.dir=dir; } public Missile(int x,int y,Tank.Direction dir,boolean good,TankClient tc) { this(x,y,dir); this.good = good; this.tc=tc; } public void draw (Graphics g) { if (!live) { tc.Missiles.remove(this); } Color c= g.getColor(); if (good) { g.setColor(Color.RED); }else { g.setColor(Color.BLACK); } g.fillOval(x, y, WIDTH,HIGHT);//設(shè)置炮彈大小 g.setColor(c); move(); } void move () { switch(dir) { case L: x-=XSPEED; break; case LU: x-=XSPEED; y-=YSPEED; break; case U: y-=YSPEED; break; case RU: x+=XSPEED; y-=YSPEED; break; case R: x+=XSPEED; break; case RD: x+=XSPEED; y+=YSPEED; break; case D: y+=YSPEED; break; case LD: x-=XSPEED; y+=YSPEED; break; } if (x<0||y<0||x>TankClient.WinWidth||y>TankClient.WinHigh) { live =false; } } //《碰撞檢測(cè)》獲取子彈矩形屬性 public Rectangle getRect() { return new Rectangle(x,y,WIDTH,HIGHT); } //《碰撞檢測(cè)》 public boolean hitTank(Tank t) { if(this.live&&this.getRect().intersects(t.getRect())&&t.islive()&& this.good!=t.isgood()) { if (t.isgood()) { t.setLife(t.getLife()-20); if (t.getLife()<=0) {t.setlive(false);} }else{t.setlive(false);} this.live = false; Explode e = new Explode(x-10,y-10,tc); tc.Explodes.add(e); return true; } return false; } public boolean hitTanks(List<Tank> tanks) { for (int i=0;i<tanks.size();i++) { if (hitTank(tanks.get(i))) { return true; } } return false ; } //撞墻碰撞檢測(cè) public boolean hitWall (Wall w) { if (this.live&&this.getRect().intersects(w.getRect())) { this.live =false; return true; } return false ; } }
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。