tank java_tankwar(从零开始的java)

这篇博客详细介绍了使用Java编程实现坦克大战游戏中的坦克类,包括坦克的生命值、位置、移动方向、状态变化以及与墙和炮弹的碰撞检测。通过内部类Bloodbar实现了坦克血量的图形化展示,并提供了键盘事件处理,使坦克能根据用户输入进行移动和射击。
摘要由CSDN通过智能技术生成

1 packagetankwar;    //tank类2 import java.awt.*;3 import java.awt.event.*;4 importjava.util.List;5 import java.util.*;6

7 public classtank {8

9 Frame1 tc;10 private int life=100; //声明变量life表示我方坦克生命值

11

12 private intx,y;13 public static final int Width=30;14 public static final int High=30;15 private boolean bl=false,br=false,bu=false,bd=false;16 private Random r=new Random(); //声明一个随机数产生器(源自java.util.*)实现让坦克随机地动起来

17 private int step=r.nextInt(12)+3;//记录敌方坦克步数,以保证地方坦克不会原地乱晃,而是到达一定步数才变换方向

18 boolean good; //分辨敌我的变量

19 private boolean live=true; //决定坦克生死的变量

20 enumdirection{L,R,U,D,LU,LD,RU,RD,Stop};21 private Bloodbar bb=new Bloodbar(); //声明一个我方坦克HP的图形化对象bb

22 private intoldx,oldy;23

24 direction dir=direction.Stop;25 direction ptdir=direction.D; //为解决坦克静止时炮弹无法正常发射的问题新建一个表示炮桶的变量

26

27 public tank(int x, int y,booleangood) {28 super();29 this.x =x;30 this.y =y;31 this.good=good;32 System.out.println("Initalization.........");33 }34

35 public booleanisGood() {36 returngood;37 }38

39 public intgetLife() {40 returnlife;41 }42

43 public void setLife(intlife) {44 this.life =life;45 }46

47 private class Bloodbar{ //声明一个tank类的内部类Bloodbar 来实现我方坦克HP的图形化;

48 public voiddraw(Graphics g){49 Color c=g.getColor();50 g.drawRect(x, y-10, Width, 10);51 g.setColor(Color.RED);52 int w=Width*life/100;53 g.fillRect(x, y-10, w, 10);54 g.setColor(c);55 }56 }57

58 public tank(int x,int y,booleangood,direction dir,Frame tc){59 this(x,y,good); //??

60 this.dir=dir;61 this.tc=(Frame1) tc;//??

62 }63

64 public voiddraw(Graphics g){65 if(!live){ //若变量live值为false,则该坦克为死,不需要画出

66 if(!good){67 tc.tanks.remove(this);68 }69 }70 Color c=g.getColor();71 if(good==true)72 g.setColor(Color.RED);73 else

74 g.setColor(Color.YELLOW);75 g.fillOval(x, y, Width, High);76 g.setColor(c);77 switch(ptdir){78 caseL:79 g.drawLine(x+tank.Width/2,y+tank.High/2, x, y+tank.High/2);80 break;81 caseR:82 g.drawLine(x+tank.Width/2,y+tank.High/2, x+tank.Width, y+tank.High/2);83 break;84 caseRU:85 g.drawLine(x+tank.Width/2,y+tank.High/2, x+tank.Width, y);86 break;87 caseLU:88 g.drawLine(x+tank.Width/2,y+tank.High/2, x, y);89 break;90 caseU:91 g.drawLine(x+tank.Width/2,y+tank.High/2, x+tank.Width/2, y);92 break;93 caseD:94 g.drawLine(x+tank.Width/2,y+tank.High/2, x+tank.Width/2, y+tank.High);95 break;96 caseLD:97 g.drawLine(x+tank.Width/2,y+tank.High/2, x,y+tank.High);98 break;99 caseRD:100 g.drawLine(x+tank.Width/2,y+tank.High/2, x+tank.Width, y+tank.High);101 break;102 }103 if(this.dir!=direction.Stop){104 this.ptdir=this.dir; //坦克只要不静止坦克当前移动方向等于炮桶方向

105 }106 if(x<0)107 x=0;108 if(y<0)109 y=0;110 if(x+tank.Width>Frame1.GameWidth)111 x=Frame1.GameWidth-tank.Width;112 if(y+tank.High>Frame1.GameHeigh)113 y=Frame1.GameHeigh-tank.High;114 if(good) //只为我方坦克显示hp条

115 bb.draw(g);116 tankmove(); //在每次进行"重画"是根据当前赋予枚举变量dir的值对坦克的状态进行对于的改变(或不变)

117 }118

119 public booleanisLive() {120 returnlive;121 }122

123 public void setLive(booleanlive) {124 this.live =live;125 }126

127 public voidkeypress(KeyEvent e){128

129 int key=e.getKeyCode();130 System.out.println(live);131 if(this.good){132 switch(key){133 caseKeyEvent.VK_F2:134 if(!this.live){135 this.live=true;136 this.life=100;137 }138 break;139 case KeyEvent.VK_CONTROL://如果不希望一下子发射太密集的炮弹,可以不在keypress中加ctrl选项,只需将一下ctrl的内容剪切到kepreleased即可

140 tc.misl.add(fire());//按下ctrl往容器添加炮弹:方法1 添加fire方法的炮弹返回值

141 break;142 caseKeyEvent.VK_LEFT:143 bl=true;144 break;145 caseKeyEvent.VK_RIGHT:146 br=true;147 break;148 caseKeyEvent.VK_UP:149 bu=true;150 break;151 caseKeyEvent.VK_DOWN:152 bd=true;153 break;154 default:break;155 }156 directl(); //在每次按下按键的时候调用状态变更函数

157 }158 }159

160 public voidkeyReleased(KeyEvent e) {161

162 int key=e.getKeyCode();163 System.out.println("TestUp:.........." + this.good + " " + this.live);164 switch(key){165 caseKeyEvent.VK_LEFT:166 bl=false;167 break;168 caseKeyEvent.VK_RIGHT:169 br=false;170 break;171 caseKeyEvent.VK_UP:172 bu=false;173 break;174 caseKeyEvent.VK_DOWN:175 bd=false;176 break;177 caseKeyEvent.VK_A:178 superfire();179 break;180 default:181 break;182 }183 directl();184 }185

186 public voidtankmove(){187 if(!live)188 return;189 oldx=x;190 oldy=y;191 switch(dir){192 caseL:193 x-=3;194 break;195 caseR:196 x+=3;197 break;198 caseRU:199 x+=3;200 y-=3;201 break;202 caseLU:203 x-=3;204 y-=3;205 break;206 caseU:207 y-=3;208 break;209 caseD:210 y+=3;211 break;212 caseLD:213 x-=3;214 y+=3;215 break;216 caseRD:217 x+=3;218 y+=3;219 break;220 caseStop:221 break;222 default:223 break;224 }225 if(!good){226 direction[] dirs=direction.values(); //枚举类型含有方法.values可以将其内容转化为数组

227 if(step==0){ //当移动坦克可移动步数为0时,对可移动步数step重新进行

228 step=r.nextInt(12)+3;//范围3-14的随机赋值,且dir也重新复制并转换方向

229 int rn=r.nextInt(dirs.length); //随机数r的方法nextint来实现在dirs范围内随机去一个值这一操作

230 this.dir=dirs[rn]; //赋予敌方坦克随机方向

231

232 }233 step--;234 if(r.nextInt(40)>38)235 tc.misl.add(fire());236 }237 }238

239 private voiddirectl(){240

241 System.out.println(bu + " " + bd +" " + bl+" "+br);242 if(bu&&!bd&&!bl&&!br)243 dir=direction.U;244 if(!bu&&bd&&!bl&&!br)245 dir=direction.D;246 if(!bu&&!bd&&bl&&!br)247 dir=direction.L;248 if(!bu&&!bd&&!bl&&br)249 dir=direction.R;250 if(bu&&!bd&&bl&&!br)251 dir=direction.LU;252 if(!bu&&bd&&bl&&!br)253 dir=direction.LD;254 if(bu&&!bd&&!bl&&br)255 dir=direction.RU;256 if(!bu&&bd&&!bl&&br)257 dir=direction.RD;258 if(!bu&&!bd&&!bl&&!br)259 dir=direction.Stop;260 }261

262 publicmissile fire(){263 if(!live)264 return null;265 int x=this.x+tank.Width/2-missile.Width/2;266 int y=this.y+tank.High/2-missile.High/2;267 missile m=new missile(x,y,this.good,ptdir,this.tc); //炮弹发射是根据炮桶方向而不是坦克方向,且因为if(this.dir!=direction.Stop)268 //tc.misl.add(m); 按下ctrl往容器中添加炮弹:方法2 当keypress中按下ctrl时会调用fire方法,直接在fire方法内将炮弹对象m添加进容器即可(返回值可有可无),也就是说当使用这种写法时switch中的ctrl选项只需写fire

269 return m; //所以传过来的方向只能是静止状态之前最近的一个非静止状态方向

270 }271

272 publicmissile fire(direction dir){273 if(!live)274 return null;275 int x=this.x+tank.Width/2-missile.Width/2;276 int y=this.y+tank.High/2-missile.High/2;277 missile m=new missile(x,y,this.good,dir,this.tc);278 returnm;279 }280

281 publicRectangle getrect(){282 return new Rectangle(x,y,Width,High); //获取坦克的长宽

283 }284

285 public booleancollidewithwall(wall w){286 if(this.live&&this.getrect().intersects(w.getrect())){287 x=oldx;288 y=oldy;289 tc.misl.remove(this);290 return true;291 }292 return false;293 }294

295 public boolean collidewithtank(java.util.Listtanks){296 for(int i=0;i

309 public void superfire(){//发射超级炮弹

310 direction[] dirs=direction.values();311 for(int i=0;i<8;i++){312 tc.misl.add(fire(dirs[i]));313 }314 }315

316 public booleaneat(bloodpakage b){317 if(this.getrect().intersects(b.getrect())&&live&&b.isLive()){318 this.life=100;319 b.setLive(false);320 return true;321 }322 return false;323 }324 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值