按照教程写了一个Java小游戏,花了19天时间去抄了一遍,今天终于抄完了?:.?ヽ(?????)??.:?+?
github地址:https://github.com/qq1367212627/kuaidi
坦克游戏主程序
packageTankClient;
importBlood.Blood;
importMissile.*;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.ArrayList;
importTankClient.Tank.*;
importWall.Wall;
publicclassTankClient extendsFrame {
publicstaticfinalintGAME_WIDTH = 800;
publicstaticfinalintGAME_HEIGHT = 600;
Tank myTank = newTank(400, 400,true, Direction.STOP,this); //将本身的引用传递过去,实现获取Missile的数据
publicArrayList missiles = newArrayList();
publicArrayList expelodes =newArrayList();
publicArrayList tanks = newArrayList(); //多个坦克
Image offScreenImage = null;
Wall w1=newWall(100,200,20,150,this);
Wall w2=newWall(300,100,300,20,this);
privateBlood b= newBlood();
publicvoidpaint(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(inti=0;i
坦克类
packageTankClient;
importBlood.Blood;
importMissile.Missile;
importWall.Wall;
importcom.sun.org.apache.bcel.internal.generic.DREM;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.ArrayList;
importjava.util.Random;
publicclassTank {
publicstaticfinalintXSPEED = 5;
publicstaticfinalintYSPEED = 5; //坦克速度
publicstaticfinalintWIDTH = 30;
publicstaticfinalintHEIGHT = 30;
publicTankClient tc = null; //持有TankClient的引用实现数据传输
privateDirection ptDir = Direction.D; //炮筒的方向
privateintx, y;
privatebooleangood; //敌我标记
privatebooleanbL = false, bU = false, bR = false, bD = false; //方向的确定
publicenumDirection {L, LU, U, RU, R, RD, D, LD, STOP}; //方向
privatestaticRandom r = newRandom();
privateintstep = r.nextInt(8) + 3; //延时标记,使得坦克多移动一些距离
intoldx, oldy;
privatebooleanLive = true; //记录坦克是否存活
privateDirection dir = Direction.STOP; //初始化为停止
privateBloodBar bb = newBloodBar();
publicintgetLife() {
returnlife;
}
publicvoidsetLife(intlife) {
this.life = life;
}
privateintlife=100;
publicbooleanisGood() {
returngood;
}
publicvoidsetGood(booleangood) {
this.good = good;
}
publicbooleanisLive() {
returnLive;
}
publicvoidsetLive(booleanlive) {
Live = live;
}
publicTank(intx, inty, boolean_good) {
this.x = x;
this.y = y;
this.oldx = x;
this.oldy = y;
this.good = _good;
}
publicTank(int_x, int_y, boolean_good, Direction _dir, TankClient _tc) { //将TankClient 引用传递,实现Missile的交换
this(_x, _y, _good);
this.dir = _dir;
tc = _tc;
}
publicvoiddraw(Graphics g) { //画出
if(!Live) {
return;
}
if(this.isGood())bb.draw(g); //若是好坦克,画出血条
Color c = g.getColor();
if(good) g.setColor(Color.RED); //我方坦克为红色
elseg.setColor(Color.blue); //敌方的颜色为蓝色
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(c);
switch(ptDir) //画出炮筒的方向
{
caseL:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y + Tank.HEIGHT / 2);
break;
caseLU:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y);
break;
caseU:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y);
break;
caseRU:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y);
break;
caseR:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT / 2);
break;
caseRD:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH, y + Tank.HEIGHT);
break;
caseD:
g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH / 2, y + Tank.HEIGHT);
break;
caseLD:
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();
}
voidmove() { //运动函数
this.oldx = x;
this.oldy = y;
switch(dir) {
caseL:
x -= XSPEED;
break;
caseLU:
x -= XSPEED;
y -= YSPEED;
break;
caseU:
y -= YSPEED;
break;
caseRU:
x += XSPEED;
y -= YSPEED;
break;
caseR:
x += XSPEED;
break;
caseRD:
x += XSPEED;
y += YSPEED;
break;
caseD:
y += YSPEED;
break;
caseLD:
x -= XSPEED;
y += YSPEED;
break;
caseSTOP:
break;
}
if(!good) { //随机产生方向
if(step == 0) {
step = r.nextInt(8) + 3;
Direction[] dirs = Direction.values();
intrn = 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();
}
}
publicvoidkeyPressed(KeyEvent e) { //按键被按住的动作
intkey = e.getKeyCode();
switch(key) {
caseKeyEvent.VK_LEFT:
bL = true;
break;
caseKeyEvent.VK_UP:
bU = true;
break;
caseKeyEvent.VK_RIGHT:
bR = true;
break;
caseKeyEvent.VK_DOWN:
bD = true;
break;
}
locateDirection();
if(this.dir != Direction.STOP) //保存炮筒的方向
{
ptDir = this.dir;
}
}
voidlocateDirection() { //判断方向
if(bL && !bU && !bR && !bD) dir = Direction.L;
elseif(bL && bU && !bR && !bD) dir = Direction.LU;
elseif(!bL && bU && !bR && !bD) dir = Direction.U;
elseif(!bL && bU && bR && !bD) dir = Direction.RU;
elseif(!bL && !bU && bR && !bD) dir = Direction.R;
elseif(!bL && !bU && bR && bD) dir = Direction.RD;
elseif(!bL && !bU && !bR && bD) dir = Direction.D;
elseif(bL && !bU && !bR && bD) dir = Direction.LD;
elseif(!bL && !bU && !bR && !bD) dir = Direction.STOP;
}
publicvoidkeyReleased(KeyEvent e) { //按键释放的操作
intkey = e.getKeyCode();
switch(key) {
caseKeyEvent.VK_CONTROL:
if(this.Live) this.fire(); //添加多个炮弹
break;
caseKeyEvent.VK_LEFT:
bL = false;
break;
caseKeyEvent.VK_UP:
bU = false;
break;
caseKeyEvent.VK_RIGHT:
bR = false;
break;
caseKeyEvent.VK_DOWN:
bD = false;
break;
caseKeyEvent.VK_A:
if(this.isLive())superFire();
break;
caseKeyEvent.VK_F2:
if(!tc.myTank.isLive()){
tc.myTank.setLive(true);
tc.myTank.setLife(100);
}
break;
}
locateDirection();
}
publicMissile fire() { //开火方法
int_x = this.x + Tank.WIDTH / 2- Missile.WIDTH / 2;
int_y = this.y + Tank.HEIGHT / 2- Missile.HEIGHT / 2; //使子弹从中心发出
Missile m = newMissile(_x, _y, good, ptDir, this.tc); //传递自身引用
this.tc.missiles.add(m);
returnm;
}
publicMissile 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 = newMissile(_x, _y, good, Missiledir, this.tc); //传递自身引用
this.tc.missiles.add(m);
returnm;
}
publicRectangle getRect() {
returnnewRectangle(x, y, WIDTH, HEIGHT);
}
publicbooleancoollideWithWall(Wall w) { //判断坦克撞墙
if(this.isLive() && this.getRect().intersects(w.getRect())) {
this.dir = Direction.STOP;
this.stay();
returntrue;
}
returnfalse;
}
privatevoidstay(){ //回溯到上一次的位置
this.x=this.oldx;
this.y=this.oldy;
}
publicbooleancoollideWithTank(Tank t){ //与单辆坦克碰撞
if(this!=t&&this.isLive() &&t.isLive() && this.getRect().intersects(t.getRect())) {
this.stay();
t.stay();
returntrue;
}
returnfalse;
}
publicbooleancoollideWithTanks(ArrayList tanks){ //与多辆坦克碰撞
booleanIscoollideWithTanks=false;
for(inti = 0;i
爆炸类
packageTankClient;
importjava.awt.*;
/**
* Created by lewis on 2016/10/5.
*/
publicclassExplode {
intx,y;
privatebooleanLive=true;
intstep=0; //数组下标,记录爆炸的状态
TankClient tc=null;
int[] diameter={4,7,12,18,26,32,49,30,14,6}; //爆炸直径大小
publicbooleanisLive() {
returnLive;
}
publicvoidsetLive(booleanlive) {
Live = live;
}
publicExplode(int_x,int_y,TankClient _tc){
x=_x;
y=_y;
tc=_tc;
}
publicvoiddraw(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++;
}
}
墙类
packageWall;
importTankClient.TankClient;
importjava.awt.*;
/**
* Created by lewis on 2016/10/6.
*/
publicclassWall{
intx,y,w,h;
TankClient tc;
publicWall(intx, inty, intw, inth, TankClient tc) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.tc = tc;
}
publicvoiddraw(Graphics g){
g.fillRect(x,y,w,h);
}
publicRectangle getRect(){
returnnewRectangle(x,y,w,h);
}
}
加血血块类
packageBlood;
importTankClient.TankClient;
importjava.awt.*;
/**
* Created by lewis on 2016/10/6.
* 加血模块
*
*/
publicclassBlood {
intx,y,w,h,step=0;
TankClient tc;
privatebooleanLive=true;
privateint[][] pos={ //血块 轨迹
{350,300},{360,300},{375,275},{400,200},{360,270},{340,280}
};
publicBlood(intx, inty, intw, inth, TankClient tc) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.tc = tc;
}
publicBlood() {
x=pos[0][0];
y=pos[0][1];
w=h=15;
step=0;
}
publicvoiddraw(Graphics g){
if(!this.isLive())return;
Color c = g.getColor();
g.setColor( Color.MAGENTA);
g.fillRect(x,y,w,h);
g.setColor(c);
move();
}
privatevoidmove(){
step++;
if(step==pos.length) {step=0;}
x=pos[step][0];
y=pos[step][1];
}
publicRectangle getRect(){
returnnewRectangle(x,y,w,h);
}
publicbooleanisLive() {
returnLive;
}
publicvoidsetLive(booleanlive) {
Live = live;
}
}
子弹类
packageMissile;
importTankClient.Tank;
importTankClient.TankClient;
importTankClient.Explode;
importWall.Wall;
importjava.awt.*;
importjava.util.ArrayList;
publicclassMissile {
publicstaticfinalintXSPEED = 10;
publicstaticfinalintYSPEED = 10;
publicstaticfinalintWIDTH = 10;
publicstaticfinalintHEIGHT = 10;
intx, y;
privateTankClient tc;
privatebooleangood;
privatebooleanLive=true; //判断炮弹是否存活
Tank.Direction dir;
publicbooleanisLive() {
returnLive;
}
publicvoidsetLive(booleanlive) {
Live = live;
}
publicMissile(intx, inty ,Tank.Direction dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
publicMissile(intx, inty,boolean_good, Tank.Direction dir,TankClient _tc) {
this(x,y,dir);
this.good=_good;
this.tc=_tc;
}
publicvoiddraw(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();
}
privatevoidmove() {
switch(dir) {
caseL:
x -= XSPEED;
break;
caseLU:
x -= XSPEED;
y -= YSPEED;
break;
caseU:
y -= YSPEED;
break;
caseRU:
x += XSPEED;
y -= YSPEED;
break;
caseR:
x += XSPEED;
break;
caseRD:
x += XSPEED;
y += YSPEED;
break;
caseD:
y += YSPEED;
break;
caseLD:
x -= XSPEED;
y += YSPEED;
break;
}
if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT) { //判断炮弹是否跑出边界
Live=false;
tc.missiles.remove(this); //若炮弹跑出边界则从集合中移除
}
}
publicRectangle getRect(){
returnnewRectangle(x,y,WIDTH, HEIGHT);
}
publicbooleanhitTank(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 = newExplode(x,y,tc);
tc.expelodes.add(e);
returntrue;
}
returnfalse;
}
publicbooleanhitTanks(ArrayList tanks) { //攻击多个坦克
for(inti = 0; i < tanks.size(); i++){
if(hitTank(tanks.get(i))){
returntrue;
}
}
returnfalse;
}
publicbooleanhitWall(Wall w){ //判断子弹撞墙
if(this.isLive()&&this.getRect().intersects(w.getRect())){
this.setLive(false); //撞上墙则设为死亡
returntrue;
}
returnfalse;
}
}