1.画出坦克
2.我的坦克可以上下左右移动
3.批量生产敌方坦克
4.我方坦克要求可以打出移动的子弹,按下J键发射子弹
5.可以连发子弹(5颗吧)
6.子弹击中敌方坦克时,敌方坦克消失
所以我们此时要做的就是第四点,但是我想直接把代码写上。ok 就这样办
点开,Viem Code,这是其中的Member类
package re_code2; import java.util.Vector; //子弹类 class Shot implements Runnable{ int x; int y; int direct; int speed=2; boolean isLive=true; public Shot(int x,int y,int direct) { this.x=x; this.y=y; this.direct=direct; } @Override public void run() { // TODO Auto-generated method stub while(true) { try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } switch(direct) { case 0: //上 y-=speed; break; case 1: //右 x+=speed; break; case 2: //下 y+=speed; break; case 3: //左 x-=speed; break; } // System.out.println("子弹的坐标为X="+x+"Y="+y); //子弹何时死亡? //判断子弹是否碰到墙壁边缘 if(x < -2 || x > 800 || y< -2 || y > 600) { this.isLive=false; break; } } } } //坦克类 class Tank{ int x=0; //表示坦克的横坐标 int y=0; //表示坦克的纵坐标 int direct =0; //坦克方向 0表示上,1右面,2下,3左 int speed = 2; //坦克的移动速度 int color; //定义坦克的颜色 public int getColor() { return color; } public void setColor(int color) { this.color = color; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public int getDirect() { return direct; } public void setDirect(int direct) { this.direct = direct; } public Tank(int x,int y) { this.x=x; this.y=y; } 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; } } //我的坦克 class Hero extends Tank{ //子弹 Vector <Shot> ss=new Vector<Shot>(); //存储子弹 Shot s=null; public Hero(int x,int y) { super(x,y); } //开火 上下左右移动,这是我的坦克的所有行为 /** * 关于开火,也取决于我的坦克的朝向 * */ public void shotEnmpy() { switch(this.direct) { case 0: s=new Shot(x,y-15,0); ss.add(s); break; case 1: s=new Shot(x+20,y,1); ss.add(s); break; case 2: s=new Shot(x,y+20,2); ss.add(s); break; case 3: s=new Shot(x-20,y,3); ss.add(s); break; } //启动子弹线程 Thread t=new Thread(s); t.start(); System.out.println("我方发射的存活子弹数量"+ss.size()); } public void move_up() { y-=speed; } public void move_down() { y+=speed; } public void move_left() { x-=speed; } public void move_right() { x+=speed; } } //敌人的坦克 class Enmpy extends Tank{ boolean isLive = true; public Enmpy(int x, int y) { super(x, y); // TODO Auto-generated constructor stub } }
这是主类
package re_code2; import java.awt.*; import java.awt.event.*; import java.util.Vector; import javax.swing.*; import javax.swing.event.*; /** * 功能:坦克游戏的3.1版 * 1.画出坦克 * 2.我的坦克可以上下左右移动 * 3.批量生产敌方坦克 * 4.我方坦克要求可以打出移动的子弹,按下J键发射子弹 * 5.可以连发子弹(5颗吧) * 6.子弹击中敌方坦克时,敌方坦克消失 * @author ybz *Last_update2018年9月24日下午7:30:40 */ public class MyTankGame3 extends JFrame { MyPanel mp=null; public static void main(String[] args) { // TODO Auto-generated method stub MyTankGame3 mtg=new MyTankGame3(); } public MyTankGame3() { mp=new MyPanel(); //启动mp线程 Thread tt=new Thread(mp); tt.start(); this.addKeyListener(mp); this.add(mp); this.setSize(800,600); this.setTitle("坦克大战"); this.setVisible(true); } } //我的面板 class MyPanel extends JPanel implements KeyListener,Runnable{ Hero hero=null; //定义一个我的坦克 Vector<Enmpy> ets=new Vector<Enmpy>(); //定义敌人的坦克组 int enSize=3; //敌方坦克数量 //构造函数 public MyPanel () { hero=new Hero(100,400); //初始化敌方坦克 for(int i=0;i<enSize;i++) { Enmpy et=new Enmpy((i+1)*50,30); et.setColor(0); et.setDirect(2); ets.add(et); } } //重写paint方法 public void paint(Graphics g) { super.paint(g); //画出我的坦克(到时再封装成一个函数) //1.画出左边矩形 g.fillRect(0,0,800,600); //画出自己的坦克 this.drawTank(hero.getX(), hero.getY(), g,this.hero.direct, 1); //绘制炮弹 for(int i=0;i<this.hero.ss.size();i++) { Shot Myshot = hero.ss.get(i); if(Myshot != null && Myshot.isLive ==true) { g.draw3DRect(Myshot.x, Myshot.y, 2, 2, false); } if(Myshot.isLive == false) { this.hero.ss.remove(Myshot); } } //画出敌方坦克 //重新绘制坦克,过滤掉isLive = false 的坦克 for(int i=0;i<ets.size();i++) {//-------------------------------------------new //取出每辆坦克,判断状态 Enmpy em =ets.get(i); if(em.isLive == true) { //符合状态的敌方坦克才会被绘制出来 for(int j=0;j<ets.size();j++) { this.drawTank(em.getX(), em.getY(), g, em.getDirect(), 0 ); } } } } //构建一个函数用来判断子弹是否击中坦克----------------------------------------new public void HitTank(Shot s,Enmpy e) { switch(e.direct) { case 0: case 2: if(s.x > (e.x - 10)&&s.x < (e.x + 10)&&s.y>(e.y-20)&&s.y<(e.y+20)) { s.isLive = false; e.isLive = false; }break; case 1: case 3: if(s.x > (e.x - 20)&&s.x < (e.x + 20)&&s.y>(e.y-10)&&s.y<(e.y+10)) { s.isLive = false; e.isLive = false; } } } //画出坦克的函数 public void drawTank(int x,int y,Graphics g,int direct,int type) { //判断是什么类型的坦克 switch(type) { case 0: g.setColor(Color.red); break; case 1: g.setColor(Color.yellow); break; } //判断方向 switch(direct) { //向上 case 0: g.fill3DRect(x-10, y-10, 5, 30,false); //2.画出右边矩形 g.fill3DRect(x+5, y-10, 5, 30,false); //3.画出中间矩形 g.fill3DRect(x-5, y-5, 10, 20,false); //4.画出圆形 g.fillOval(x-5, y, 10, 10); //5.画出炮管 g.drawLine(x, y,x,y-15); break; case 1: g.fill3DRect(x-15, y-10, 30, 5,false); //2.画出右边矩形 g.fill3DRect(x-15, y+5, 30, 5,false); //3.画出中间矩形 g.fill3DRect(x-10, y-5, 20, 10,false); //4.画出圆形 g.fillOval(x-5, y-5, 10, 10); //5.画出炮管 g.drawLine(x, y,x+20,y); break; case 2: g.fill3DRect(x-10, y-10, 5, 30,false); //2.画出右边矩形 g.fill3DRect(x+5, y-10, 5, 30,false); //3.画出中间矩形 g.fill3DRect(x-5, y-5, 10, 20,false); //4.画出圆形 g.fillOval(x-5, y, 10, 10); //5.画出炮管 g.drawLine(x, y,x,y+25); break; case 3: g.fill3DRect(x-15, y-10, 30, 5,false); //2.画出右边矩形 g.fill3DRect(x-15, y+5, 30, 5,false); //3.画出中间矩形 g.fill3DRect(x-10, y-5, 20, 10,false); //4.画出圆形 g.fillOval(x-5, y-5, 10, 10); //5.画出炮管 g.drawLine(x, y,x-20,y); break; } } @Override //键值处理 public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override //键按下处理 w s a d public void keyPressed(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_W) { this.hero.setDirect(0); this.hero.move_up(); }else if(e.getKeyCode() == KeyEvent.VK_D) { this.hero.setDirect(1); this.hero.move_right(); }else if(e.getKeyCode() == KeyEvent.VK_S) { this.hero.setDirect(2); this.hero.move_down(); }else if(e.getKeyCode() == KeyEvent.VK_A) { this.hero.setDirect(3); this.hero.move_left(); } //判断玩家是否按下J键 if(e.getKeyCode() == KeyEvent.VK_J) { //开火 if(this.hero.ss.size() < 5) { //控制我方坦克发射子弹的数量 this.hero.shotEnmpy(); } } this.repaint(); } @Override //键释放处理 public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } @Override public void run() { // TODO Auto-generated method stub //每隔100毫秒去重绘 while(true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=0;i<hero.ss.size();i++) {//--------------------------------------new //取出每颗炮弹 Shot myshot = hero.ss.get(i); if(myshot.isLive == true) { //判断状态是否符合要求,只有存活的子弹 才能击中坦克 for(int j=0;j<ets.size();j++) { //别写成hero.ets了,ets不是hero对象上的 //取出每辆敌方坦克 Enmpy ee = ets.get(j); if(ee.isLive == true) { //判断状态是否符合要求,只有存活的坦克 才能 被击中 //取出了每辆坦克和每个子弹,确保是符合状态的,然后调用方法判断是否击中 this.HitTank(myshot, ee); } } } } //重绘 this.repaint(); } } }
看着是挺麻烦挺乱的,但是机构还不错,拓展性很好,后面的所有功能的实现也是基于主类来写的。
行吧,慢慢来,有时候我也得写好几遍才能弄懂的。