坦克大战2.0向3.0版本的实现——2
昨天没写完的今天接着写
我们确定了 子弹应该是一个独立的类,下面就要分析分析他拥有的属性和实现的细节了
1.子弹应该有的属性:
1.子弹的坐标
2.子弹的方向
2.让子弹不停的运动:
实现Runnable接口,创建并启动线程,j接收传入进来的坐标和坦克的朝向,根据朝向 持续修改x或y坐标
实现如下:
//子弹类 class Shot implements Runnable{ int x; int y; int direct; int speed=1; 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(this.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); } } }
我知道现在 while(true){......} 是一个无限循环,这会在后面改进的,先不用管
还有,关于 己方坦克的类昨天没有写清楚,如下:
己方坦克有上下左右移动和发射子弹的功能,具体只说发射子弹的功能 shotEnmpy()方法
说白了就是,这个类用来发射子弹,就是创建Shot类的实例,并且传如方向和坐标,就这个作用,实现如下:
public void ShotEnmpy() { switch(this.direct) { case 0: s=new Shot(x,y-15,0); break; case 1: s=new Shot(x+20,y,1); break; case 2: s=new Shot(x,y+15,2); break; case 3: s=new Shot(x-20,y,3); break; } //启动子弹线程 Thread t=new Thread(s); t.start(); }
还有什么呢?还有的就是在频幕中显示出我的发射出来的子弹了,这没什么好说的,就是在 paint()中绘制就是了
//画出自己坦克的子弹 if(this.hero.s!= null) { g.draw3DRect(hero.s.x, hero.s.y, 2, 2, false); }
现在子弹的坐标就已经啊在动了,可是测试你会发现坐标在动但子弹没动,
当然了,因为没刷新页面啊。我们能看到屏幕上有东西在动是因为屏幕在快速刷新,因为刷新速度太快
超过了某个频率,眼睛就分辨不出来,产生运动的效果了。
所以我要做的就是每隔一段时间让屏幕重绘.因为要自动的不停的重绘,所以面板就要实现Runnable接口了
重写run()方法:
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(); } this.repaint(); } }
别忘了启动面版MyPanel的实例mp的线程:
mp=new MyPanel(); //启动线程 Thread t=new Thread(mp); t.start();
还有上面的无限循环的问题:子弹何时死亡?
1.打到敌方坦克时:先不考虑,这不是3.0版实现的,后面版本才能实现
2.当子弹飞到屏幕或者说面板的边界时,撞上了墙。这是我们考虑的,也很简单
因为我们设定的平面区域时800*600,此段放到Shot类中的run()方法中。如下:
//子弹何时死亡? //判断子弹是否碰到墙壁边缘 if(x<-2||x>800||y<-2||y>600) { this.isLive=false; break; }
就这样!!