Java之详解坦克大战游戏(五)
来源:互联网 发布:安卓手机网络修复工具 编辑:程序博客网 时间:2024/05/22 01:56
我们上次实现了击毁敌人坦克的功能,但是敌人坦克秒消失,没带一点效果好像不给力,这次我们来做爆炸效果,主要分为四步:1.先准备三张图片 2.定义Bomb类,在击中敌人坦克时,把炸弹放入Vector 4.绘制。首先我们要以图片连续闪现来体现爆炸效果,如下:
首先需要定义一个爆炸类,到Members.java文件定义
//炸弹类(没有坐标改变,不用做成线程)class Bomb{ //定义炸弹的坐标 int x,y; //炸弹的生命 int life=9; //炸一次少一次 boolean isLive=true; public Bomb(int x,int y) { this.x=x; this.y=y; } //减少生命值 public void lifeDown() { if(life>0) { life--; } else { this.isLive=false; } }}
爆炸效果还是在面板显示,我们到MyPanel定义
//...... //定义炸弹集合 Vector<Bomb> bombs=new Vector<Bomb>(); //定义三张图片,三张图片才能组成一颗炸弹 Image image1=null; Image image2=null; Image image3=null;
(把三张图片复制粘贴到src目录下)
再到构造函数初始化
public MyPanel(){ //......//初始化图片,三张图片才能组成一颗炸弹image1=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif")); image2=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif")); image3=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));}
画炸弹的话当然还是在paint方法
public void paint(Graphics g){ //...... //画出炸弹 for(int i=0;i<bombs.size();i++) { //取出炸弹 Bomb b=bombs.get(i); //给炸弹不同 if(b.life>6) {//下列画图片的数据还是经测试比较好看才写出来的,可以自己琢磨一下 g.drawImage(image1, b.x, b.y, 30,30,this); }else if(b.life>3) { g.drawImage(image2, b.x, b.y, 30,30,this); } else { g.drawImage(image3, b.x, b.y, 30,30,this); } //让b的生命值减小 b.lifeDown(); //如果炸弹生命值为0,就把该炸弹从bombs向量去掉 if(b.life==0) { bombs.remove(b); } }}
爆炸效果当然是击中敌人坦克时才出现的,所以我们要到hitTank方法里写段代码
//写一个函数专门判断子弹是否会击中敌人坦克 public void hitTank(Shot s,EnemyTank et) { //判断该坦克的方向 switch (et.direct) { //如果敌人坦克方向是上或是下 case 0: case 2: if(s.x>et.x && s.x<et.x+20 && s.y>et.y && s.y<et.y+30) { //击中 //子弹死亡 s.isLive=false; //敌人坦克死亡 et.isLive=false; //创建一颗炸弹,放入Vector Bomb b=new Bomb(et.x, et.y); //放入Vector bombs.add(b); } case 1: case 3: if(s.x>et.x && s.x<et.x+30 && s.y>et.y && s.y<et.y+20) { //击中 //子弹死亡 s.isLive=false; //敌人坦克死亡 et.isLive=false; //创建一颗炸弹,放入Vector Bomb b=new Bomb(et.x, et.y); //放入Vector bombs.add(b); } } }
这时就能看到爆炸效果了..接下来,我们来实现如何让敌人坦克自由移动和能发子弹…
首先得把敌人的坦克做成线程类,实现Runnable接口
(这里我们首先都想想坦克可以自由移动但是不要让它乱跑,比如跑到我们看不到的地方,所以我们一开始就得设定边界,一开始我们是setSize(400,300))
//敌人的坦克,把敌人做成线程类class EnemyTank extends Tank implements Runnable{ //... int times=0;//作为连发子弹设下的标志 (下面将用到) public void run() { while(true) { switch(this.direct) { case 0: //说明坦克正在向上移动 for(int i=0;i<30;i++)//30可以改成其他数,这里是控制坦克移动距离 { //保证坦克不出边界 (下面思路相同) if(y>0) { y-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 1: //向右 for(int i=0;i<30;i++) { if(x<400) { x+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 2: //向下 for(int i=0;i<30;i++) { if(y<300) { y+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 3: //向左 for(int i=0;i<30;i++) { if(x>0) { x-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; } //让坦克随机产生一个新的方向 this.direct=(int)(Math.random()*4);//随机产生0-3的数 //判断敌人坦克是否死亡 if(this.isLive==false) { //让坦克死亡后退出线程 break; } } }}
老规矩,下一步要做的就是启动线程,到MyPanel类的构造函数中
public MyPanel(){ //初始化敌人的坦克 for(int i=0;i<enSize;i++) { //... //启动敌人的坦克 Thread t = new Thread(et); t.start(); }}
这时运行程序,敌人坦克就可以自由移动了
接下来的任务是让敌人的坦克可以自由发射子弹
class EnemyTank extends Tank implements Runnable{//.......public void run() { while(true) { switch(this.direct) { case 0: //说明坦克正在向上移动 for(int i=0;i<30;i++) { //保证坦克不出边界 if(y>0) { y-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 1: //向右 for(int i=0;i<30;i++) { if(x<400) { x+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 2: //向下 for(int i=0;i<30;i++) { if(y<300) { y+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 3: //向左 for(int i=0;i<30;i++) { if(x>0) { x-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; } this.times++; //判断是否给坦克加入新的子弹 if(times%2==0) { if(isLive) { if(ss.size()<5)// 够不够五颗子弹 { Shot s=null; //没有子弹 //添加 switch(direct) { case 0: //创建一颗子弹 s=new Shot(x+10, y,0); //把子弹加入向量 ss.add(s); break; case 1: s=new Shot(x+30,y+10,1); ss.add(s); break; case 2: s=new Shot(x+10,y+30,2); ss.add(s); break; case 3: s=new Shot(x,y+10,3); ss.add(s); break; } //启动子弹线程 Thread t=new Thread(s); t.start(); } } } //让坦克随机产生一个新的方向 this.direct=(int)(Math.random()*4); //判断敌人坦克是否死亡 if(this.isLive==false) { //让坦克死亡后退出线程 break; } } }}}
接下来到MyPanel类构造函数
public MyPanel(){ hero =new Hero(100,100); //坦克的初始位置(10,10) //... //给敌人坦克添加一颗子弹 Shot s=new Shot(et.x+10,et.y+30,2); //加入给敌人坦克 et.ss.add(s); Thread t2=new Thread(s); t2.start();}
画子弹我们选择到画敌人坦克的函数
//画出敌人的坦克 for(int i=0;i<ets.size();i++) { EnemyTank et =ets.get(i); if(et.isLive) { this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0); //再画出敌人的子弹 for(int j=0;j<et.ss.size();j++) { //取出子弹 Shot enemyShot=et.ss.get(j); if(enemyShot.isLive) { g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); } else {//如果敌人坦克死亡就从Vector去掉 et.ss.remove(enemyShot); } } } }
运行程序,效果如图
接下来继续完成,我们被敌人坦克击中还不会死亡,所以我们要做的是让敌人的子弹击中我们坦克我们也会死亡..为了程序的可读性良好,我们需要改动一些代码的位置,到MyPanel类的run方法剪切下列代码..
//判断我的子弹是否击中敌人的坦克 for(int i=0;i<hero.ss.size();i++) { //取出子弹 Shot myShot=hero.ss.get(i); //判断子弹是否有效 if(myShot.isLive) { //取出每个坦克,与它判断 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et = ets.get(j); if(et.isLive) { this.hitTank(myShot, et); } } } }
再到MyPanel类添加两个函数,一个函数是把我们剪切的代码放进去
//敌人的子弹是否击中我 public void hitMe() { //取出每一个敌人的坦克 for(int i=0;i<this.ets.size();i++) { //取出坦克 EnemyTank et=ets.get(i); //取出每一颗子弹 for(int j=0;j<et.ss.size();j++) { //取出子弹 Shot enemyShot=et.ss.get(j); this.hitTank(enemyShot, hero); } } } //判断我的子弹是否击中敌人的坦克 public void hitEnemyTank() { for(int i=0;i<hero.ss.size();i++) { //取出子弹 Shot myShot=hero.ss.get(i); //判断子弹是否有效 if(myShot.isLive) { //取出每个坦克,与它判断 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et = ets.get(j); if(et.isLive) { this.hitTank(myShot, et); } } } } }
这个时候就会报错了,我们只需再做一下改动:
hitTank的参数类型EnemyTank改为Tank
Members.java文件中EnemyTank的boolean isLive=true;属性可以删掉了
然后到Tank类添加属性boolean isLive=true;
这样敌人子弹对我们的攻击就有效了
最后,还是扔一堆源代码
TankGame3.java
package com.TankGame3;import javax.swing.*;import java.awt.*;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Vector;public class TankGame3 extends JFrame{ MyPanel mp =null; public static void main(String[] args) { TankGame3 tankgame3 = new TankGame3(); } public TankGame3() { mp=new MyPanel(); Thread t = new Thread(mp); t.start(); this.addKeyListener(mp);//注册监听 this.setVisible(true); this.setSize(400, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(mp); }}//我的面板class MyPanel extends Panel implements KeyListener,Runnable{//子弹要看到,要不停的重绘,paint函数每隔段时间久更新,重绘是在paint函数发生的,所以MyPanel要实现Runnable接口 //定义一个我的坦克 Hero hero =null; //敌人的坦克组 Vector<EnemyTank> ets = new Vector<EnemyTank>(); //定义炸弹集合 Vector<Bomb> bombs=new Vector<Bomb>(); int enSize=3; //敌人坦克初始数量 //定义三张图片,三张图片才能组成一颗炸弹 Image image1=null; Image image2=null; Image image3=null; public MyPanel() { hero =new Hero(100,100); //坦克的初始位置(10,10) //初始化敌人的坦克 for(int i=0;i<enSize;i++) { //创建一辆敌人的坦克对象 EnemyTank et =new EnemyTank((i+1)*50,0); et.setColor(0); et.setDirect(2); //启动敌人的坦克 Thread t = new Thread(et); t.start(); //给敌人坦克添加一颗子弹 Shot s=new Shot(et.x+10,et.y+30,2); //加入给敌人坦克 et.ss.add(s); Thread t2=new Thread(s); t2.start(); //加入 ets.add(et); } //初始化图片,三张图片才能组成一颗炸弹 image1=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif")); image2=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif")); image3=getToolkit().getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif")); } //重新paint public void paint(Graphics g) { super.paint(g); g.fillRect(0, 0, 1200, 900); //填充使背景变为黑色 //从ss中取出每颗子弹,并画出 for(int i=0;i<hero.ss.size();i++) { Shot myShot = hero.ss.get(i); //画出一颗子弹 if(myShot!=null && myShot.isLive == true) { g.setColor(Color.yellow); g.draw3DRect(myShot.x, myShot.y, 1, 1, false); } if(myShot.isLive==false) { //从ss中删除该子弹 hero.ss.remove(myShot); } } //画出炸弹 for(int i=0;i<bombs.size();i++) { //取出炸弹 Bomb b=bombs.get(i); if(b.life>6) { g.drawImage(image1, b.x, b.y, 30,30,this); }else if(b.life>3) { g.drawImage(image2, b.x, b.y, 30,30,this); } else { g.drawImage(image3, b.x, b.y, 30,30,this); } //让b的生命值减小 b.lifeDown(); //如果炸弹生命值为0,就把该炸弹从bombs向量去掉 if(b.life==0) { bombs.remove(b); } } //画出自己的坦克 if(hero.isLive) { this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); } //画出敌人的坦克 for(int i=0;i<ets.size();i++) { EnemyTank et =ets.get(i); if(et.isLive) { this.drawTank(et.getX(), et.getY(), g, et.getDirect(), 0); //再画出敌人的子弹 for(int j=0;j<et.ss.size();j++) { //取出子弹 Shot enemyShot=et.ss.get(j); if(enemyShot.isLive) { g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); } else {//如果敌人坦克死亡就从Vector去掉 et.ss.remove(enemyShot); } } } } } //敌人的子弹是否击中我 public void hitMe() { //取出每一个敌人的坦克 for(int i=0;i<this.ets.size();i++) { //取出坦克 EnemyTank et=ets.get(i); //取出每一颗子弹 for(int j=0;j<et.ss.size();j++) { //取出子弹 Shot enemyShot=et.ss.get(j); this.hitTank(enemyShot, hero); } } } //判断我的子弹是否击中敌人的坦克 public void hitEnemyTank() { for(int i=0;i<hero.ss.size();i++) { //取出子弹 Shot myShot=hero.ss.get(i); //判断子弹是否有效 if(myShot.isLive) { //取出每个坦克,与它判断 for(int j=0;j<ets.size();j++) { //取出坦克 EnemyTank et = ets.get(j); if(et.isLive) { this.hitTank(myShot, et); } } } } } //写一个函数专门判断子弹是否会击中敌人坦克 public void hitTank(Shot s,Tank et) { //判断该坦克的方向 switch (et.direct) { //如果敌人坦克方向是上或是下 case 0: case 2: if(s.x>et.x && s.x<et.x+20 && s.y>et.y && s.y<et.y+30) { //击中 //子弹死亡 s.isLive=false; //敌人坦克死亡 et.isLive=false; //创建一颗炸弹,放入Vector Bomb b=new Bomb(et.x, et.y); //放入Vector bombs.add(b); } case 1: case 3: if(s.x>et.x && s.x<et.x+30 && s.y>et.y && s.y<et.y+20) { //击中 //子弹死亡 s.isLive=false; //敌人坦克死亡 et.isLive=false; //创建一颗炸弹,放入Vector Bomb b=new Bomb(et.x, et.y); //放入Vector bombs.add(b); } } } //画出坦克的函数 public void drawTank(int x,int y,Graphics g,int direct,int type) { switch(type)//判断是什么类型的坦克 { case 0: g.setColor(Color.cyan); break; case 1: g.setColor(Color.yellow); break; } //判断方向 switch(direct) { //向上 case 0: //画出我的坦克(到时再封装成一个函数) //1.画出左边的矩形 g.fill3DRect(x, y, 5, 30,false); //2.画出右边矩形 g.fill3DRect(x+15, y, 5, 30,false); //3.画出中间矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //4.画出圆形 g.fillOval(x+5, y+10, 10, 10); //5.画直线 g.drawLine(x+10, y+15, x+10, y); break; case 1://炮筒向右 //画出上面矩形 g.fill3DRect(x, y, 30, 5,false); //2.画出右边矩形 g.fill3DRect(x, y+15, 30, 5,false); //3.画出中间矩形 g.fill3DRect(x+5, y+5, 20, 10,false); //4.画出圆形 g.fillOval(x+10, y+5, 10, 10); //5.画直线 g.drawLine(x+15, y+10, x+30, y+10); break; case 2://炮筒向下 //画出上面矩形 g.fill3DRect(x, y, 5, 30,false); //2.画出右边矩形 g.fill3DRect(x+15, y, 5, 30,false); //3.画出中间矩形 g.fill3DRect(x+5, y+5, 10, 20,false); //4.画出圆形 g.fillOval(x+5, y+10, 10, 10); //5.画直线 g.drawLine(x+10, y+15, x+10, y+30); break; case 3://炮筒向左 //画出上面矩形 g.fill3DRect(x, y, 30, 5,false); //2.画出右边矩形 g.fill3DRect(x, y+15, 30, 5,false); //3.画出中间矩形 g.fill3DRect(x+5, y+5, 20, 10,false); //4.画出圆形 g.fillOval(x+10, y+5, 10, 10); //5.画直线 g.drawLine(x+15, y+10, x, y+10); break; } }/*实现KeyListener接口的方法*/ //键入某个键时调用此方法。 public void keyTyped(KeyEvent e) { } //释放某个键时调用此方法 public void keyReleased(KeyEvent e) { } //按下某个键时调用此方法: a代表向左,w代表向上,d代表向右,s代表向下 public void keyPressed(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_W)//向上 { this.hero.setDirect(0); this.hero.moveUp(); } else if(e.getKeyCode() == KeyEvent.VK_D)//向右 { this.hero.setDirect(1); this.hero.moveRight(); } else if(e.getKeyCode() == KeyEvent.VK_S)//向下 { this.hero.setDirect(2); this.hero.moveDown(); } else if(e.getKeyCode() == KeyEvent.VK_A)//向左 { this.hero.setDirect(3); this.hero.moveLeft(); } //判断玩家是否按下j键 if(e.getKeyCode() == KeyEvent.VK_J) { //开火 if(this.hero.ss.size()<=4) //子弹最多连发5颗 { this.hero.shotEnemy(); } } this.repaint();//调用repaint()函数,来重绘页面 } public void run() { //每隔100毫秒来重绘 while(true) { try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } this.hitEnemyTank(); //判断敌人的子弹是否击中我 this.hitMe(); //重绘 this.repaint(); } }}
Members.java
package com.TankGame3;import java.util.Vector;//炸弹类(没有坐标改变,不用做成线程)class Bomb{ //定义炸弹的坐标 int x,y; //炸弹的生命 int life=9; //炸一次少一次 boolean isLive=true; public Bomb(int x,int y) { this.x=x; this.y=y; } //减少生命值 public void lifeDown() { if(life>0) { life--; } else { this.isLive=false; } }}//坦克类class Tank{ //表示坦克的横坐标 int x=0; //表示坦克的纵坐标 int y=0; //坦克方向 //0表示上,1表示右,2表示下,3表示左 int direct=0; int color;//坦克的颜色 boolean isLive=true; public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getDirect() { return direct; } public void setDirect(int derect) { this.direct = derect; } //坦克速度 int speed=1; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public Tank(int x,int y) { this.x=x; this.y=y; }}//敌人的坦克,把敌人做成线程类class EnemyTank extends Tank implements Runnable{ //boolean isLive=true; int times=0;//作为连发子弹设下的标志 //定义一个向量,可以存放敌人的子弹 Vector<Shot> ss = new Vector<Shot>(); //敌人添加子弹,应当在刚刚创建坦克和敌人坦克子弹死亡后 public EnemyTank(int x, int y) { super(x, y); } public void run() { while(true) { switch(this.direct) { case 0: //说明坦克正在向上移动 for(int i=0;i<30;i++) { //保证坦克不出边界 if(y>0) { y-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 1: //向右 for(int i=0;i<30;i++) { if(x<400) { x+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 2: //向下 for(int i=0;i<30;i++) { if(y<300) { y+=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; case 3: //向左 for(int i=0;i<30;i++) { if(x>0) { x-=speed; } try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } } break; } this.times++; //判断是否给坦克加入新的子弹 if(times%2==0) { if(isLive) { if(ss.size()<5)// 够不够五颗子弹 { Shot s=null; //没有子弹 //添加 switch(direct) { case 0: //创建一颗子弹 s=new Shot(x+10, y,0); //把子弹加入向量 ss.add(s); break; case 1: s=new Shot(x+30,y+10,1); ss.add(s); break; case 2: s=new Shot(x+10,y+30,2); ss.add(s); break; case 3: s=new Shot(x,y+10,3); ss.add(s); break; } //启动子弹线程 Thread t=new Thread(s); t.start(); } } } //让坦克随机产生一个新的方向 this.direct=(int)(Math.random()*4); //判断敌人坦克是否死亡 if(this.isLive==false) { //让坦克死亡后退出线程 break; } } }}//我的坦克class Hero extends Tank{ //子弹 //Shot s = null; Vector<Shot> ss = new Vector<Shot>(); Shot s=null; public Hero(int x,int y) { super(x,y); } //开火 public void shotEnemy() { switch (this.direct) //子弹的方向 {//s只是代号而已,指向谁就谁,不要理解它是同一个子弹 case 0: //创建一颗子弹 s=new Shot(x+10, y,0); //把子弹加入向量 ss.add(s); break; case 1: s=new Shot(x+30,y+10,1); ss.add(s); break; case 2: s=new Shot(x+10,y+30,2); ss.add(s); break; case 3: s=new Shot(x,y+10,3); ss.add(s); break; } //启动子弹线程 Thread t = new Thread(s); t.start(); } //坦克向上移动 public void moveUp() { y-=speed; } //坦克向右移动 public void moveRight() { x+=speed; } //坦克向下移动 public void moveDown() { y+=speed; } //坦克向左移动 public void moveLeft() { x-=speed; }}//子弹类class Shot implements Runnable{ int x; int y; int direct;//子弹的方向 int speed=1; //子弹速度 boolean isLive=true;//子弹是否活着 public Shot(int x,int y,int direct) { this.x=x; this.y=y; this.direct=direct; } public void run() { while(true) { try { Thread.sleep(50); } catch (Exception e) { // TODO: handle exception } switch(direct) { case 0://向上打出 y-=speed; break; case 1: x+=speed; break; case 2: y+=speed; break; case 3: x-=speed; break; } //判断子弹是否碰到边缘 if( x<0 || x>400 || y<0 || y>300) { this.isLive=false; break; } } }}
- Java之详解坦克大战游戏(五)
- Java之详解坦克大战游戏(一)
- Java之详解坦克大战游戏(二)
- Java之详解坦克大战游戏(六)
- Java之详解坦克大战游戏(三)
- Java之详解坦克大战游戏(四)
- HTML5之坦克大战游戏
- HTML5之坦克大战游戏
- 【Java_项目篇<1>】--JAVA实现坦克大战游戏--赋予敌人行动和攻击(五)
- java之坦克大战(一)
- Android坦克大战游戏设计解析五
- Java开发的游戏之三 坦克大战 完整源代码
- 【Java_项目篇<1>】--JAVA实现坦克大战游戏--坦克移动+添加敌方坦克(二)
- 基于JAVA的简易坦克大战(五)
- JAVA练手项目(三):坦克大战游戏源代码
- Java坦克大战游戏(人机对战)
- Java坦克大战 (五) 之产生敌方坦克和爆炸效果
- HTML网页之坦克大战游戏
- HashMap与ConCurrentHashMap
- Linux下可执行文件的格式
- Java四舍五入取巧方式
- poj 1364 King[差分约束]
- 23种设计模式(2):工厂方法模式
- Java之详解坦克大战游戏(五)
- 169. Majority Element
- 设计模式之单例模式
- Spring MVC 关键点 理解
- 常用Bracket插件
- Linux终端命令汇总
- JAVA面向对象-----成员内部类访问细节
- 根据jsonobject中的部分数据更新javabean中对应的属性[PATCH]
- 阅读积累