按照教程寫了一個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);??????? //將本身的引用傳遞過去,實現(xiàn)獲取Missile的數(shù)據(jù)
????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("炮彈數(shù)量:"+missiles.size(),50,50);
????????g.drawString("爆炸數(shù)量:"+expelodes.size(),50,70);
????????g.drawString("敵人數(shù)量:"+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的引用實現(xiàn)數(shù)據(jù)傳輸
????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 引用傳遞,實現(xiàn)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() {?????????????? //運動函數(shù)
????????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) {????????????????????????????? //隨機產(chǎn)生方向
????????????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;???? //使子彈從中心發(fā)出
????????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;???? //使子彈從中心發(fā)出
????????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;???????????????????????????????????????????? //數(shù)組下標,記錄爆炸的狀態(tài)
????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()){???????????????????????????????? //區(qū)分坦克對待
????????????????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);??????????????????? //撞上墻則設(shè)為死亡
????????????returntrue;
????????}
????????returnfalse;
????}
}