线程项目总结

 

线程项目——坦克大战总结

 

 

 

一.预计游戏实现功能

 

   1)两方坦克,电脑控制敌方坦克,由线程控制。玩家控制自己的坦克,通过添加键盘监听器实现。

   2)坦克发射子弹,并能判断敌我,判断输赢。通过建立子弹线程实现。

   3)坦克之间不能互撞。

   3)添加背景,有普通强(普通子弹课打破),白色墙(普通子弹无法打破),水(子弹可通过,坦克不能),草(子弹,坦克均能通过)。

   4)实现子弹,坦克碰到不同障碍物的不同执行方法。

   5)优化界面,添加音乐,判断输赢,实现重玩,升级等其他功能。


二.碰到的技术问题

 

其实,整个过程我们碰到了无数大大小小,奇奇怪怪的问题,以下只罗列出几个关键性问题供大家参考。

1)两方坦克,两方子弹图片,走法均不同,如何设计既能减少代码,又能实现该功能。      虽说玩家自己的坦克不是线程,但和其他坦克只是图片不同,创建一个坦克类,写一个设置名字的方法,在创建坦克对象时,区别敌我。此类中,写坦克行走,转向,碰到其他坦克和障碍物的方法。再单独写一个坦克线程类,利用人机算法,在run方法中,操作坦克运动。

大致如下:

坦克类

public class Tank {

    //构造器,传入初始坦克的位置

      public Tank(Graphics g, int x, int y) {}

      //设置不同方向坦克的图片对象

      public void setImage() {}

      // 坦克前进的方法

  public int  forward() {}

      //坦克攻击的方法

  public void attack() {}

     //得到坦克运动时方向的方法

     public String getDirection() {}

    //判断坦克是否和其他会坦克相撞

 public int isSeparate() {}

      //设置坦克名字的方法

    public void setName(String name) {}

   }


坦克线程类

 public class TankRunnable implements Runnable{

     //构造器,传入坦克对象

     public TankRunnable(Tank tank, Graphics g) {}

     //重写run方法

     public void run() {}

}


而子弹类则直接写成一个线程类,重写run方法时直接调用发射的方法。此类中,也有诸如根据坦克名字设置图片,判断敌我的方法。

大致如下:


子弹线程类


public class Bullet extends Thread{

      //构造器,传入此时要发射坦克的坐标和坦克对象

        public Bullet(Graphics g, int x, int y, String direction, String name,

                Tank tank) {}

      //发射子弹的方法

        public void shot() {}

     //判断是否撞到墙

       private void isHitWall() {}

     //设置子弹图片的方法

       public void setImage() {}

     //判断是否打到坦克

       public void isHitTank() {}

    //重写run方法

       public void run() { shot();}

}


此外,判断子弹打中坦克方法中,要把子弹和对方坦克一一进行判断,此时,可以用集合分别存储这些坦克对象,写在一个借口里,让子弹类实现接口即可。


2)墙的画法

      由于墙被子弹打到后,要爆炸消失,所有墙肯定不能用一张背景图代替,必须一块一块的画在画布上。在这个问题上,我们先用坐标循环画出墙,并把每个墙的对象都存入一个集合里,而此时却出现了很大的一个问题,子弹线程中,有判断子弹是否打到墙的方法,我们是让子弹与画面上所有墙进行比较判断,这无疑加大了子弹的压力。画面上一次会出现多个子弹,而每颗子弹没走一步就要执行这么多次,主程序就出现了最讨厌的问题——卡!

最后,我们决定像五子棋那样,用一个二维数组存储这些墙,子弹判断时只需要根据坐标判断与之相邻的一块砖即可,大大减少代码的执行。


3)边界

      这个问题,我们暂时还没有解决。

      由于在坦克类中,我们写了一个碰到边界即反向的方法,而此方法却不适合玩家自己的坦克,进而出现了玩家到边界自动转向,图片却没有转换过来,且还能继续走,甚至出边界。


4)

      这本属于项目优化,我们写的子弹线程中太多方法,子弹每走一步,要判断执行很多代码,必然导致运行速度慢,甚至卡,死机等问题。

     对此,我们先是用数组存储墙缓解这个问题,也进一步限制子弹颗数,即一颗子弹要么出边界,要么打到墙或坦克,才能发射另一颗子弹。


5)人机算法

若是智能的算法,电脑的坦克应该追随玩家的坦克,并在合适时机发射子弹,像五子棋一样,既要有防守,也要有进攻。而我们写的算法很简单,坦克其实在无序的行走,这个将慢慢完善。


三.几个重点技术实现方法


1)坦克运动方向和图片的匹配

public int  forward() {

// 坦克初始位置

g.drawImage(imagexyHighWidenull);

// 设置一个黑色矩形

g.setColor(Color.BLACK);

try {

// 如果是自己的坦克,线程不休眠,阻止键盘延迟

if (name.equals("Mytank")) {

sleep = 0;

}

Thread.sleep(sleep);// 线程休眠

g.fillRect(xyHighWide);// 覆盖原先坦克的图片

// 判断方向,改变相应坐标值

if (direction.equals("Right")) {

x += speed;

setDirection("Right");

}

if (direction.equals("Left")) {

x -= speed;

setDirection("Left");

}

if (direction.equals("Up")) {

y -= speed;

setDirection("Up");

}

if (direction.equals("Down")) {

y += speed;

setDirection("Down");

}

// 画出新位置,走一步

g.drawImage(imagexyHighWidenull);

}

catch (InterruptedException e) {

e.printStackTrace();

}

return 0;

}


2)坦克,子弹行走的动态效果

   上述代码已有介绍,即根据起始坐标先画出图,用黑色矩形框盖住原先图片,再画出新位置的图。这和画布重绘其实是一样的。

   当然也可以在重绘方法中实现。

   此外,重要的是要利用双缓冲清楚闪屏的情况。


3)判断子弹或坦克是否碰到障碍物

   这是一个技术难点,即使得到两者坐标,又如何判断。

   此刻,我们利用Rectangle中的intersect(Rectangle R)方法判断两者是否相撞。

   即,根据两者坐标创建两个矩形对象,用上述方法即可。


4)声效


File file = new File("music\\fire.wav");

URL rul;

try {

rul = file.toURL();

AudioClip ac = Applet.newAudioClip(rul);

ac.play();

catch (MalformedURLException e) {

e.printStackTrace();

}



四.自我体会


  这是第一个我们做的比较复杂的项目,加之我们选的题目复杂程度也高,中间碰到了很多问题,刚开始还比较积极,但后来些许有些烦躁。好在我们都坚持下来了,这里,我最想说的是以下几点;


1)团队合作很重要

   刚开始,想要一个人独立完成一个项目的确有点困难,而团队合作不仅在节省了时间,也保证了项目的质量性。三个人有三种想法,只要交流的好,面对问题,总能找出比较好的解决办法。当然,在找错时也很有帮助。


2)做项目要有全局思维

    一个完整的项目前前后后的联系是很紧密的,在初始做时,要对整个游戏,每个步骤有宏观的把握,即要想到后面的步骤。不然,很容易出现前面一直解决问题,最后发现思路完全错,最大的致命性问题无法解决。


3)遇到问题要积极及时与他人交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值