按照教程写了一个Java小游戏,花了19天时间去抄了一遍,今天终于抄完了?:.?ヽ(?????)??.:?+?
github地址:https://github.com/qq1367212627/kuaidi
坦克游戏主程序
package TankClient; import Blood.Blood; import Missile.*; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import TankClient.Tank.*; import Wall.Wall; public class TankClient extends Frame { public static final int GAME_WIDTH = 800; public static final int GAME_HEIGHT = 600; Tank myTank = new Tank(400, 400,true, Direction.STOP,this); //将本身的引用传递过去,实现获取Missile的数据 public ArrayListmissiles = new ArrayList (); public ArrayList expelodes =new ArrayList (); public ArrayList tanks = new ArrayList (); //多个坦克 Image offScreenImage = null; Wall w1=new Wall(100,200,20,150,this); Wall w2=new Wall(300,100,300,20,this); private Blood b= new Blood(); public void paint(Graphics g) { g.drawString("炮弹数量:"+missiles.size(),50,50); g.drawString("爆炸数量:"+expelodes.size(),50,70); g.drawString("敌人数量:"+tanks.size(),50,90); g.drawString("生命值:"+myTank.getLife(),50,110); if(tanks.size()<=0)addTanks(); for(int i=0;i
坦克类
package TankClient; import Blood.Blood; import Missile.Missile; import Wall.Wall; import com.sun.org.apache.bcel.internal.generic.DREM; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.Random; public class Tank { public static final int XSPEED = 5; public static final int YSPEED = 5; //坦克速度 public static final int WIDTH = 30; public static final int HEIGHT = 30; public TankClient tc = null; //持有TankClient的引用实现数据传输 private Direction ptDir = Direction.D; //炮筒的方向 private int x, y; private boolean good; //敌我标记 private boolean bL = false, bU = false, bR = false, bD = false; //方向的确定 public enum Direction {L, LU, U, RU, R, RD, D, LD, STOP}; //方向 private static Random r = new Random(); private int step = r.nextInt(8) + 3; //延时标记,使得坦克多移动一些距离 int oldx, oldy; private boolean Live = true; //记录坦克是否存活 private Direction dir = Direction.STOP; //初始化为停止 private BloodBar bb = new BloodBar(); public int getLife() { return life; } public void setLife(int life) { this.life = life; } private int life=100; public boolean isGood() { return good; } public void setGood(boolean good) { this.good = good; } public boolean isLive() { return Live; } public void setLive(boolean live) { Live = live; } public Tank(int x, int y, boolean _good) { this.x = x; this.y = y; this.oldx = x; this.oldy = y; this.good = _good; } public Tank(int _x, int _y, boolean _good, Direction _dir, TankClient _tc) { //将TankClient 引用传递,实现Missile的交换 this(_x, _y, _good); this.dir = _dir; tc = _tc; } public void draw(Graphics g) { //画出 if (!Live) { return; } if(this.isGood())bb.draw(g); //若是好坦克,画出血条 Color c = g.getColor(); if (good) g.setColor(Color.RED); //我方坦克为红色 else g.setColor(Color.blue); //敌方的颜色为蓝色 g.fillOval(x, y, WIDTH, HEIGHT); g.setColor(c); switch (ptDir) //画出炮筒的方向 { case L: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT / 2); break; case LU: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y); break; case U: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y); break; case RU: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y); break; case R: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT / 2); break; case RD: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT); break; case D: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y + Tank.HEIGHT); break; case LD: g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT); break; } if (x < 0) x = 0; if (y < 30) y = 30; if (x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH; if (y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;//判断坦克是否超出边界,如果超出就停下 move(); } 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 (!good) { //随机产生方向 if (step == 0) { step = r.nextInt(8) + 3; Direction[] dirs = Direction.values(); int rn = r.nextInt(dirs.length); while (dirs[rn] == Direction.STOP) rn = r.nextInt(dirs.length); dir = dirs[rn]; ptDir = dir; } step--; if (r.nextInt(40) > 38) this.fire(); } } public void keyPressed(KeyEvent e) { //按键被按住的动作 int key = e.getKeyCode(); switch (key) { 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; } locateDirection(); if (this.dir != Direction.STOP) //保存炮筒的方向 { ptDir = this.dir; } } void locateDirection() { //判断方向 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 if (!bL && !bU && !bR && !bD) dir = Direction.STOP; } public void keyReleased(KeyEvent e) { //按键释放的操作 int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_CONTROL: if (this.Live) this.fire(); //添加多个炮弹 break; 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; case KeyEvent.VK_A: if(this.isLive())superFire(); break; case KeyEvent.VK_F2: if(!tc.myTank.isLive()){ tc.myTank.setLive(true); tc.myTank.setLife(100); } break; } locateDirection(); } public Missile fire() { //开火方法 int _x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2; int _y = this.y + Tank.HEIGHT / 2 - Missile.HEIGHT / 2; //使子弹从中心发出 Missile m = new Missile(_x, _y, good, ptDir, this.tc); //传递自身引用 this.tc.missiles.add(m); return m; } public Missile fire(Direction Missiledir) { //开火方法 int _x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2; int _y = this.y + Tank.HEIGHT / 2 - Missile.HEIGHT / 2; //使子弹从中心发出 Missile m = new Missile(_x, _y, good, Missiledir, this.tc); //传递自身引用 this.tc.missiles.add(m); return m; } public Rectangle getRect() { return new Rectangle(x, y, WIDTH, HEIGHT); } public boolean coollideWithWall(Wall w) { //判断坦克撞墙 if (this.isLive() && this.getRect().intersects(w.getRect())) { this.dir = Direction.STOP; this.stay(); return true; } return false; } private void stay(){ //回溯到上一次的位置 this.x=this.oldx; this.y=this.oldy; } public boolean coollideWithTank(Tank t){ //与单辆坦克碰撞 if (this!=t&&this.isLive() &&t.isLive() && this.getRect().intersects(t.getRect())) { this.stay(); t.stay(); return true; } return false; } public boolean coollideWithTanks(ArrayListtanks){ //与多辆坦克碰撞 boolean IscoollideWithTanks=false; for(int i = 0;i
爆炸类
package TankClient; import java.awt.*; /** * Created by lewis on 2016/10/5. */ public class Explode { int x,y; private boolean Live=true; int step=0; //数组下标,记录爆炸的状态 TankClient tc=null; int [] diameter={4,7,12,18,26,32,49,30,14,6}; //爆炸直径大小 public boolean isLive() { return Live; } public void setLive(boolean live) { Live = live; } public Explode(int _x,int _y,TankClient _tc){ x=_x; y=_y; tc=_tc; } public void draw(Graphics g){ if(!Live)return ; if(step==diameter.length){ Live=false; step=0; return ; } Color c = g.getColor(); g.setColor(Color.ORANGE); g.fillOval(x,y,diameter[step],diameter[step]); step++; } }
墙类
package Wall; import TankClient.TankClient; import java.awt.*; /** * Created by lewis on 2016/10/6. */ public class Wall{ int x,y,w,h; TankClient tc; public Wall(int x, int y, int w, int h, TankClient tc) { this.x = x; this.y = y; this.w = w; this.h = h; this.tc = tc; } public void draw(Graphics g){ g.fillRect(x,y,w,h); } public Rectangle getRect(){ return new Rectangle(x,y,w,h); } }
加血血块类
package Blood; import TankClient.TankClient; import java.awt.*; /** * Created by lewis on 2016/10/6. * 加血模块 * */ public class Blood { int x,y,w,h,step=0; TankClient tc; private boolean Live=true; private int[][] pos={ //血块 轨迹 {350,300},{360,300},{375,275},{400,200},{360,270},{340,280} }; public Blood(int x, int y, int w, int h, TankClient tc) { this.x = x; this.y = y; this.w = w; this.h = h; this.tc = tc; } public Blood() { x=pos[0][0]; y=pos[0][1]; w=h=15; step=0; } public void draw(Graphics g){ if(!this.isLive())return; Color c = g.getColor(); g.setColor( Color.MAGENTA); g.fillRect(x,y,w,h); g.setColor(c); move(); } private void move(){ step++; if(step==pos.length) {step=0;} x=pos[step][0]; y=pos[step][1]; } public Rectangle getRect(){ return new Rectangle(x,y,w,h); } public boolean isLive() { return Live; } public void setLive(boolean live) { Live = live; } }
子弹类
package Missile; import TankClient.Tank; import TankClient.TankClient; import TankClient.Explode; import Wall.Wall; import java.awt.*; import java.util.ArrayList; 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 HEIGHT = 10; int x, y; private TankClient tc; private boolean good; private boolean Live=true; //判断炮弹是否存活 Tank.Direction dir; public boolean isLive() { return Live; } public void setLive(boolean live) { Live = live; } public Missile(int x, int y ,Tank.Direction dir) { this.x = x; this.y = y; this.dir = dir; } public Missile(int x, int y,boolean _good, Tank.Direction dir,TankClient _tc) { this(x,y,dir); this.good=_good; this.tc=_tc; } public void draw(Graphics g) { if(!Live){ tc.missiles.remove(this); return ; } Color c = g.getColor(); g.setColor(Color.BLACK); g.fillOval(x, y, WIDTH, HEIGHT); g.setColor(c); move(); } private 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.GAME_WIDTH||y>TankClient.GAME_HEIGHT) { //判断炮弹是否跑出边界 Live=false; tc.missiles.remove(this); //若炮弹跑出边界则从集合中移除 } } public Rectangle getRect(){ return new Rectangle(x,y,WIDTH, HEIGHT); } 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.setLive(false); //炮弹死亡 Explode e = new Explode(x,y,tc); tc.expelodes.add(e); return true; } return false; } public boolean hitTanks(ArrayListtanks) { //攻击多个坦克 for (int i = 0; i < tanks.size(); i++){ if(hitTank(tanks.get(i))){ return true; } } return false; } public boolean hitWall(Wall w){ //判断子弹撞墙 if(this.isLive()&&this.getRect().intersects(w.getRect())){ this.setLive(false); //撞上墙则设为死亡 return true; } return false; } }