坦克大戰遊戲背景:html
1. 需求分析java
1.1環境要求git
操做系統:Windows 7(SP1)以上網絡
JAVA虛擬機:JDK1.8以上架構
開發環境:Eclipse(4.5以上)dom
1.2角色設定ide
用戶在系統中扮演的角色,以及能夠執行的職責。函數
玩 家 操縱玩家坦克,與敵方坦克做戰,同時保護本基地。敵方坦克隨機移動,發射子彈。工具
1.3設定玩家(玩家一,玩家二,即一我的玩仍是兩我的玩),我方坦克的方向和子彈由用戶控制,全部牆塊均可以打碎,可是鐵牆是打不碎的,草地不能阻止坦克和子彈的前進,河流能阻止坦克前進,可是不能阻止子彈前進。我方基地被毀則遊戲結束,本身的坦克被毀遊戲也結束,惟一贏得方式是消滅全部的敵方坦克,則能夠進入下一關。一關比一關的難度大,經過地圖來實現。學習
學號 | 班級 | 姓名 | 簡介 |
201721123094 | 網絡1714 | 何昕桐(組長) | 學習能力強,漂亮又可愛![]() |
201721123068 | 網絡1713 | 梁琦珧 | 有思想,有能力,有擔當![]() |
201721123093 | 網絡1714 | 李志婷 | 有專研精神,刻苦,積極向上![]() |
201721123069 | 網絡1713 | 陳慧琳 | 低調~![]() |
成員 | 任務 | 博客連接 |
何昕桐 | 坦克類 (電腦坦克類,玩家坦克類),代碼整合 | http://www.javashuo.com/article/p-cbkitdfd-cb.html |
梁琦珧 | 枚舉,子彈類,工具類 | http://www.javashuo.com/article/p-atqevwbm-ee.html |
李志婷 | GUI界面(遊戲面板,登陸面板,主窗體) | http://www.javashuo.com/article/p-cdftvyxi-eq.html |
陳慧琳 | 基地類,牆塊類,爆炸效果類,地圖類 | http://www.javashuo.com/article/p-vbjqpztl-gs.html |
時間過短,能力有限啊!
https://gitee.com/mayun126/TankWar.git
3.面向對象類設計圖
Wall:
Visible:
乖乖獻上了類圖:
演示:
雙人遊戲和界面地圖的設計是咱們這個課設的特色:
代碼太多,主要列出了主要的類以及特點的功能代碼,耐心看看,O(∩_∩)O哈哈~
玩家坦克類:
public class Tank extends VisibleImage{ GamePanel gamePanel; //遊戲界面,提供當前面板的內容進行判斷 Direction direction; //移動方向 protectedbooleanalive=true; //是否存活 protectedintspeed=3; //移動速度 privatebooleanattackCoolDown =true;//攻擊冷卻狀態 privateintattackCoolDownTime =500;//攻擊冷卻時間毫秒間隔500ms發射子彈 TankType type;//坦克類型 private String upImage; //向上移動時的圖片 private String downImage;//向下移動時的圖片 private String rightImage;//向右移動時的圖片 private String leftImage;//向左移動時的圖片 //坦克構造方法初始化橫縱座標xy //url默認爲向上的圖片 public Tank(int x,int y,String url,GamePanel gamePanel,TankType type){ super(x,y,url); this.gamePanel=gamePanle; this.type=type; direction= Directon.UP; switch(type){ case player1://玩家1 upImage=ImageUtil.PLAYER1_UP_IMAGE_URL; downImage=ImageUtil.PLAYER1_DOWN_IMAGE_URL; rightImage=ImageUtil.PLAYER1_LEFT_IMAGE_URL; leftImage=ImageUtil.PLAYER1_RIGHT_IMAGE_URL; break; case player2://玩家2 upImage=ImageUtil.PLAYER2_UP_IMAGE_URL; downImage=ImageUtil.PLAYER2_DOWN_IMAGE_URL; rightImage=ImageUtil.PLAYE2_LEFT_IMAGE_URL; leftImage=ImageUtil.PLAYER2_RIGHT_IMAGE_URL; break; case bot: upImage=ImageUtil.BOT_UP_IMAGE_URL; downImage=ImageUtil.BOT_DOWN_IMAGE_URL; rightImage=ImageUtil.BOT_LEFT_IMAGE_URL; leftImage=ImageUtil.BOT_RIGHT_IMAGE_URL; break; } } //向左 public void leftward(){ if(direxction!=Directon.LEFT) setImage(leftImage);//若以前的移動方向不是左移,跟換左移圖片 direxction=Directon.LEFT; if(!hitWall(x-speed,y)&&hitTank(x-speed,y)){ x-=speed;//橫座標遞減 moveToborder();//判斷是否移動到遊戲面板的邊界 } } //向右 public void rightward(){ if(direxction!=Directon.RIGHT) setImage(rightImage); direxction=Directon.RIGHT; if(!hitWall(x+speed,y)&&hitTank(x+speed,y)){ x+=speed; moveToborder();//判斷是否移動到遊戲面板的邊界 } } //向上 public void upward(){ if(direxction!=Directon.UP) setImage(upImage); direxction=Directon.UP; if(!hitWall(x,y-speed)&&hitTank(x,y-speed)){ y-=speed; moveToborder();//判斷是否移動到遊戲面板的邊界 } } //向下 public void downward(){ if(direxction!=Directon.DOWN) setImage(downImage); direxction=Directon.DOWN; if(!hitWall(x,y+speed)&&hitTank(x,y+speed)){ y+=speed; moveToborder();//判斷是否移動到遊戲面板的邊界 } } //是否撞到牆塊 public boolean hitWall(int x,int y){ Rectangle next=new Rectangle(x,y,width,height);//建立坦克移動後的目標區域 List<Wall> walls=gamePanel.getWalls();//獲取面板上全部的牆體對象 for(int i=0,length=walls.size();i<length;i++){ Wall w=walls.get(i);//獲取牆塊對象 if(w instanceof GrassWall){//碰到草坪 continue; }elseif(w.hit(next)){ //撞到牆 return true; } } return false;//沒撞到牆 } //是否撞到坦克 public boolean hitTank(int x,int y){ Rectangle next=new Rectangle(x,y,width,height);//建立坦克移動後的目標區域 List<Tank> tanks=gamePanel.getTanks();//獲取面板上全部的坦克對象 for(int i=0,length=tanks.size();i<length;i++){ Tank t=tanks.get(i);//獲取坦克對象 if(!this.equals(t)){//此坦克與自身不是一個對象 if(t.isAlive()&&t.hit(next)){//此坦克存活而且與自身相撞 return true; } } } return false;//沒撞到坦克 } //移動到面板的邊界 protected void moveToBorder(){ if(x<0){ x=0; }else if(x>gamePanel.getWidth()-width){ x=gamePanel.getWidth-width; } if(y<0){ y=0; }else if(y>gamePanel.getHeight()-height){ y=gamePanel.getHeight-height } } //獲取坦克頭 private Point getHeadPoint(){ Point p=new Point();//建立頭對象,做爲頭點 switch(direxction){//判斷移動方向 case UP: p.x=x+width/2; p.y=y; break; case DOWN: p.x=x+width/2; p.y=y+height; break; case RIGHT: p.x=x+width; p.y=y+height/2; break; case LEFT: p.x=x; p.y=y+height/2; break; default: p=null; } return p;//返回頭點 } //攻擊 public void attack(){ if(attackCoolDown){//若是攻擊功能完成冷卻 Point p=getHeadPoint();//獲取坦克頭對象 Bullet b=new Bullet(p.x-Bullet.LENGTH/2,p.y-Bullet.LENGTH/2,direction,gamePanel,type); gamePanel.addBullet(b);//遊戲面板添加子彈 new AttackCD().start();//開始冷卻倒計時 } } //坦克是否存活 public boolean isAlive(){ return alive; } public void setAlive(boolean alive){ this.alive=alive; } //坦克的速度 public void setSpeed(int speed){ this.speed=speed; } //攻擊冷卻時間線程 private class AttackCD extends Thread{ public void run(){ attackCoolDown=false;//將攻擊功能設置爲冷卻狀態 try{ Tread.sleep(attackCoolDown);//休眠0.5秒 }catch(InterruptedException e){ e.printStackTrace(); } attackCoolDown=true;//將攻擊功能解除冷卻狀態 } } //獲取攻擊功能是否處於冷卻 public boolean isAttackCoolDown(){ return attackCoolDown; } public void setAttackCoolDownTime(int attackCoolDownTime){ this.attackCoolDownTime=attackCoolDownTime; } }
敵方坦克類:
public class Bot extends Tank{ private Random random=new Random();// private Direction dir; private int fresh=GamePanel.FRESH; private int MoveTimer=0; public Bot(int x,int y,GamePanel gamePanel,TankType type) { super(x,y,ImageUtil.BOT_DOWN_IMAGE_URL,gamePanel,type); dir=Direction.DOWN; setAttackCoolDownTime(1000); //setSpeed(2); } public void go() { if(isAttackCoolDown()) { attack(); } if(MoveTimer>=3000) { dir=randomDirection(); MoveTimer=0; }else { MoveTimer+=fresh; } switch(dir) { case UP: upward(); break; case DOWN: downward(); break; case RIGHT: rightward(); break; case LEFT: leftward(); break; } } protected void moveToBorder() { if(x<0) { x=0; dir=randomDirection(); }else if(x>gamePanel.getWidth()-width) { x=gamePanel.getWidth()-width; dir=randomDirection(); } if(y<0) { y=0; dir=randomDirection(); }else if(y>gamePanel.getHeight()-height) { y=gamePanel.getHeight()-height; dir=randomDirection(); } } //重寫碰到坦克的方法 boolean hitTank(int x,int y) { Rectangle next=new Rectangle(x,y,width,height);//建立坦克移動後的目標區域 List<Tank> tanks=gamePanel.getTanks();//獲取面板上全部的坦克對象 for(int i=0,length=tanks.size();i<length;i++){ Tank t=tanks.get(i);//獲取坦克對象 if(!this.equals(t)){//此坦克與自身不是一個對象 if(t.isAlive()&&t.hit(next)){//此坦克存活而且與自身相撞 if(t instanceof Bot) { dir=randomDirection(); } return true; } } } return false;//沒撞到坦克 } public Direction randomDirection() { int rnum =random.nextInt(4); switch(rnum) { case 0: return Direction.UP; case 1: return Direction.RIGHT; case 2: return Direction.LEFT; default: return Direction.DOWN; } } public void attack() { int rnum =random.nextInt(100); if(rnum<4) { super.attack(); } } }
子彈類:
public class Bullet extends VisibleImage{ Direction direction; static final int LENGTH = 8; //子彈的(正方體)邊長 private GamePanel gamePanel;//遊戲面板 private int speed = 7;//移動速度 private boolean alive = true;//子彈是否有效 Color color = Color.ORANGE;//子彈顏色 TankType owner;//發出子彈的坦克類型 /** * 子彈構造方法 * * @param x - 子彈的初始橫座標 * @param y - 子彈的初始縱座標 * @param direction - 子彈的發射方向 * @param gamePanel - 遊戲面板對象 * @param Owner - 發出子彈的坦克類型 */ public Bullet(int x, int y, Direction direction, GamePanel gamePanel, TankType owner) { super(x, y, LENGTH, LENGTH); //調用父類構造方法 // TODO 自動生成的構造函數存根 this.direction = direction; this.gamePanel = gamePanel; this.owner = owner; init();//初始化組件 } /** * 初始化組件 */ private void init() { // TODO 自動生成的方法存根 Graphics g = image.getGraphics();//獲取圖片的繪圖方法 g.setColor(Color.WHITE);//使用白色繪圖 g.fillRect(0, 0, LENGTH, LENGTH);// 繪製一個鋪滿整個圖片的白色實心矩形 g.setColor(color);//使用子彈顏色 g.fillOval(0, 0, LENGTH, LENGTH);// 鋪滿整個圖片的實心圓形 g.setColor(Color.BLACK); //使用黑色 g.drawOval(0, 0, LENGTH-1, LENGTH-1); //繪製黑色邊框,防止出界 } /** * 子彈移動 */ public void move() { switch(direction) { //判斷移動方向 case UP: upward(); break; case DOWN: downword(); break; case LEFT: leftword(); break; case RIGHT: rightword(); break; } } /** * 移動函數 */ private void rightword() { // TODO 自動生成的方法存根 x += speed; moveToBorder(); } private void leftword() { // TODO 自動生成的方法存根 x -= speed; moveToBorder(); //移動出面板後銷燬子彈 } private void downword() { // TODO 自動生成的方法存根 y += speed; moveToBorder(); } private void upward() { // TODO 自動生成的方法存根 y -= speed; moveToBorder(); } /** * 擊中坦克 */ public void hitTank() { List<Tank> tanks = gamePanel.getTanks(); //獲取坦克的集合 for(int i = 0,length = tanks.size();i<length;i++) {//遍歷坦克集合 Tank t = tanks.get(i); if (t.isAlive()&&this.hit(t)) {//坦克活着而且子彈擊中坦克 switch (owner) { case player1://玩家的子彈 case player2: if (t instanceof Bot) {//擊中電腦 alive = false;//子彈銷燬 t.setAlive(false);//電腦坦克死亡 }else if(t instanceof Tank){//擊中玩家 alive = false; } break; case bot://電腦的子彈 if (t instanceof Bot) { alive = false; }else if (t instanceof Tank) { alive = false; t.setAlive(false); } break; default: alive = false; t.setAlive(false); break; } } } } //擊中基地 public void hitBase() { Base b=gamePanel.getBase(); if(this.hit(b)) { alive =false; b.setAlive(false); } } public void hitWall(){ List<Wall> walls=gamePanel.getWalls(); for(int i=0,length=walls.size();i<length;i++) { Wall w=walls.get(i); if(this.hit(w)) { if(w instanceof BrickWall) { alive=false; w.setAlive(false); } if(w instanceof IronWall) { alive=false; } } } } //移除面板邊界時銷燬子彈 private void moveToBorder() { if(x < 0|| x > gamePanel.getWidth() - getWidth()|| y < 0 || y > gamePanel.getHeight() - getHeight()) { dispose(); } } // private synchronized void dispose() { alive=false; } // public boolean isAlive() { return alive; } }
主窗體:
1.調整屏幕尺寸及位置
2.創建窗口事件監聽,使得在關閉窗口時會提示咱們是否就此退出遊戲。
3.添加登陸面板。
public class MainFrame extends JFrame{ public MainFrame() { setTitle("坦克大戰"); setSize(800,610); setResizable(false); Toolkit tool=Toolkit.getDefaultToolkit(); Dimension d=tool.getScreenSize(); setLocation((d.width-getWidth())/2, (d.height-getHeight())/2); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addListener(); setPanel(new LoginPanel(this)); } private void addListener(){ addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { int closeCode=JOptionPane.showConfirmDialog(MainFrame.this, "是否退出遊戲","提示!", JOptionPane.YES_NO_OPTION); if(closeCode==JOptionPane.YES_OPTION) { System.exit(0); } } }); } public void setPanel(JPanel panel) { Container c=getContentPane(); c.removeAll(); c.add(panel); c.validate(); } }
碰撞檢測:
public class VisibleImage { /** * 橫、縱座標 */ public int x; public int y; /** * 長、寬 */ int width; int height; /** * 圖像對象 */ BufferedImage image; /** * 構造方法 * @param x -橫座標 * @param y -縱座標 * @param width -寬 * @param height -高 */ public VisibleImage(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);//實例化圖片 } /** * 構造方法 * @param x -橫座標 * @param y -縱座標 * @param url -圖片路徑 */ public VisibleImage(int x, int y, String url) { this.x = x; this.y = y; try { image = ImageIO.read(new File(url));//獲取此路徑的圖片對象 this.width = image.getWidth(); this.height = image.getHeight(); }catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } /** * 獲取圖片 * @return 所顯示的圖片 */ public BufferedImage getImage() { return image; } /** * 設置圖片 * @param image -所顯示的圖片 */ public void setImage(BufferedImage image) { this.image = image; } /** * 設置圖片 * @param image -所顯示的圖片 */ public void setImage(String url) { try { this.image = ImageIO.read(new File(url)); }catch (IOException e) { // TODO: handle exception e.printStackTrace(); } } /** * 判斷是否發生碰撞 * @param v - 目標圖片對象 * @return 若是二者相交,返回true,不然返回false */ public boolean hit(VisibleImage v) { return hit(v.getBounds());//執行重載方法 } /** * 判斷是否發生碰撞 * @param r - 目標邊界 * @return 若是二者相交,返回true,不然返回false */ public boolean hit(Rectangle r){ if(r == null) { return false; //不發生碰撞 } return getBounds().intersects(r); //判斷邊界對象是否相交 } /** * 獲取邊界對象 */ public Rectangle getBounds() { //建立一個座標在(x,y)位置,寬高爲(width,height)的矩形邊界對象並返回 return new Rectangle(x, y, width, height); } /** * setter,getter方法獲取並設置長寬高 */ public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } @Override public String toString() { return "VisibleImage [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "]"; } }
碰撞:子彈的碰撞有銷燬他人,自我銷燬,而坦克沒有該功能。
刷新幀:(關鍵技術)
public GamePanel(MainFrame frame,int level,GameType gameType) { this.frame =frame ; this.level=level; this.gameType=gameType; setBackground(Color.GRAY); init(); Thread t=new FreshThead(); t.start(); addListener(); } private void init() { bullets=new ArrayList<Bullet>(); allTanks=new ArrayList<>(); walls=new ArrayList<>(); boomImage=new ArrayList<>(); image=new BufferedImage(794,572,BufferedImage.TYPE_INT_BGR); g2 =image.createGraphics(); playerTanks=new ArrayList<>(); play1=new Tank(278,537,ImageUtil.PLAYER1_UP_IMAGE_URL,this,TankType.player1); if(gameType==GameType.TWO_PLAYER) { play2=new Tank(500,537,ImageUtil.PLAYER2_UP_IMAGE_URL,this,TankType.player2); playerTanks.add(play2); } playerTanks.add(play1); botTanks=new Vector<>(); botTanks.add(new Bot(botX[0],1,this,TankType.bot)); botTanks.add(new Bot(botX[1],1,this,TankType.bot)); botTanks.add(new Bot(botX[2],1,this,TankType.bot)); botReadyCount-=3; allTanks.addAll(playerTanks); allTanks.addAll(botTanks); base=new Base(367,532); initWalls(); } private void addListener() { frame.addKeyListener(this); } private void initWalls() { Map map=Map.getMap(level); walls.addAll(map.getWalls()); walls.add(base); } public void paint(Graphics g) { paintTankActoin(); CreateBot(); paintImage(); g.drawImage(image, 0, 0, this); } private void paintImage() { g2.setColor(Color.BLACK); g2.fillRect(0, 0, image.getWidth(),image.getHeight() ); panitBoom(); paintBotTanks(); paintBotCount(); panitPlayerTanks(); allTanks.addAll(playerTanks); allTanks.addAll(botTanks); paintWalls(); paintBullets(); if(botSurplusCount==0) { stopThread(); paintBotCount(); g2.setFont(new Font("楷體",Font.BOLD,50)); g2.setColor(Color.GREEN); g2.drawString("勝利", 250, 400); gotoNextLevel(); } if(gameType ==GameType.ONE_PLAYER) { if(!play1.isAlive()) { stopThread(); boomImage.add(new Boom(play1.x,play1.y)); panitBoom(); paintGameOver(); gotoPrevisousLevel(); } } else {//雙人模式 if(play1.isAlive()&&!play2.isAlive()) { survivor=play1; } else if(!play1.isAlive()&&play2.isAlive()) { survivor=play2; } else if(!(play1.isAlive()||play2.isAlive())) { stopThread(); boomImage.add(new Boom(survivor.x,survivor.y)); panitBoom(); paintGameOver(); gotoPrevisousLevel();//從新進入本關 } } if(!base.isAlive()) { stopThread(); paintGameOver(); base.setImage(ImageUtil.BREAK_BASE_IMAGE_URL); gotoPrevisousLevel(); } g2.drawImage(base.getImage(),base.x,base.y,this); } private void paintBotCount() { g2.setFont(new Font("楷體",Font.BOLD,25)); g2.setColor(Color.BLUE); g2.drawString("敵方坦克剩餘:"+ botSurplusCount, 10,30); } private void paintGameOver() { g2.setFont(new Font("楷體",Font.BOLD,50)); g2.setColor(Color.RED); g2.drawString("Game Over !",250,400); } private void panitBoom() { for(int i=0;i<boomImage.size();i++) { Boom boom=boomImage.get(i); if(boom.isAlive()) { boom.show(g2); } else { boomImage.remove(i); i--; } } } private void paintWalls() { for(int i=0;i<walls.size();i++) { Wall w=walls.get(i); if(w.isAlive()) { g2.drawImage(w.getImage(),w.x,w.y,this); } else { walls.remove(i); i--; } } } private void paintBullets() { for(int i=0;i<bullets.size();i++) { Bullet b=bullets.get(i); if(b.isAlive()) { b.move(); b.hitBase(); b.hitWall(); b.hitTank(); g2.drawImage(b.getImage(), b.x,b.y,this); }else { bullets.remove(i); i--; } } } private void paintBotTanks() { for(int i=0;i<botTanks.size();i++) { Bot t=(Bot)botTanks.get(i); if(t.isAlive()) { t.go(); g2.drawImage(t.getImage(), t.x,t.y,this); }else { botTanks.remove(i); i--; boomImage.add(new Boom(t.x,t.y)); decreaseBot(); } } } private void panitPlayerTanks() { for(int i=0;i<playerTanks.size();i++) { Tank t=playerTanks.get(i); if(t.isAlive()) { g2.drawImage(t.getImage(), t.x,t.y,this); }else { playerTanks.remove(i); i--; boomImage.add(new Boom(t.x,t.y)); } } } private synchronized void stopThread() { frame.removeKeyListener(this); finish=true; } private class FreshThead extends Thread { public void run() { while(!finish) { repaint(); try { Thread.sleep(FRESH); } catch(InterruptedException e) { e.printStackTrace(); } } } } private void CreateBot() { createBotTimer +=FRESH; if(botTanks.size()<botMaxInMap&&botReadyCount>0&&createBotTimer>=4000) { int index=r.nextInt(3); Rectangle bornRect=new Rectangle(botX[index],1,35,35); for(int i=0,lengh=allTanks.size();i<lengh;i++) { Tank t=allTanks.get(i); if(t.isAlive()&&t.hit(bornRect)) { return; } } botTanks.add(new Bot(botX[index],1,GamePanel.this,TankType.bot)); botReadyCount--; createBotTimer=0; } } private void gotoNextLevel() { Thread jump=new JumpPageThead(Level.nextLevel()); jump.start(); } private void gotoPrevisousLevel() { Thread jump=new JumpPageThead(Level.previsousLevel()); jump.start(); } public void decreaseBot() { botSurplusCount--; } @Override public void keyPressed(KeyEvent e) { // TODO 自動生成的方法存根 switch(e.getKeyCode()) { case KeyEvent.VK_Y: y_key=true; break; case KeyEvent.VK_W: w_key=true; a_key=false; s_key=false; d_key=false; break; case KeyEvent.VK_A: w_key=false; a_key=true; s_key=false; d_key=false; break; case KeyEvent.VK_S: w_key=false; a_key=false; s_key=true; d_key=false; break; case KeyEvent.VK_D: w_key=false; a_key=false; s_key=false; d_key=true; break; case KeyEvent.VK_HOME: case KeyEvent.VK_NUMPAD1: num1_key=true; break; case KeyEvent.VK_UP: up_key=true; down_key=false; right_key=false; left_key=false; break; case KeyEvent.VK_DOWN: up_key=false; down_key=true; right_key=false; left_key=false; break; case KeyEvent.VK_LEFT: up_key=false; down_key=false; right_key=false; left_key=true; break; case KeyEvent.VK_RIGHT: up_key=false; down_key=false; right_key=true; left_key=false; break; } } private void paintTankActoin() { if(y_key) { play1.attack(); } if(w_key) { play1.upward(); } if(d_key) { play1.rightward(); } if(a_key) { play1.leftward(); } if(s_key) { play1.downward(); } if(gameType==GameType.TWO_PLAYER) { if(num1_key) { play2.attack(); } if(up_key) { play2.upward(); } if(right_key) { play2.rightward(); } if(left_key) { play2.leftward(); } if(down_key) { play2.downward(); } } } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成的方法存根 switch(e.getKeyCode()) { case KeyEvent.VK_Y: y_key=false; break; case KeyEvent.VK_W: w_key=false; break; case KeyEvent.VK_A: a_key=false; break; case KeyEvent.VK_S: s_key=false; break; case KeyEvent.VK_D: d_key=false; break; case KeyEvent.VK_HOME: case KeyEvent.VK_NUMPAD1: num1_key=false; break; case KeyEvent.VK_UP: up_key=false; break; case KeyEvent.VK_DOWN: down_key=false; break; case KeyEvent.VK_LEFT: left_key=false; break; case KeyEvent.VK_RIGHT: right_key=false; break; } } public void addBullet(Bullet b) { bullets.add(b); } public List<Wall>getWalls(){ return walls; } public Base getBase() { return base; } public List<Tank>getTanks() { return allTanks; } private class JumpPageThead extends Thread{ int level; public JumpPageThead (int level) { this.level=level; } public void run() { try { Thread.sleep(1000); frame.setPanel(new LevelPanel(level,frame,gameType)); }catch(InterruptedException e) { e.printStackTrace(); } } } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成的方法存根 } }
幀是一個量詞,一個靜態的畫面就是一幀,幀的刷新頻率決定了動畫是否流暢。
repaint();每隔一段時間畫一張圖片,這樣實現了刷新的效果。在遊戲面板的構造方法裏建立遊戲幀線程,結束經過一個finsh來判斷。
本次的坦克大戰課設實現的是一些最基本坦克大戰遊戲功能,比較簡單易懂,對於該遊戲咱們還存在不少的不足,好比能夠嘗試着作可以聯網的多人遊戲,一個遊戲排行榜(好友,非好友)。