坦克大战底层框架搭建并思路分析(二)=》让坦克动起来
好,继续昨天的,昨天我们已经包装好一个坦克类了,现在正式开始驱动坦克,动起来才是王道,文绉绉的一直扯蛋就没意思了,对吧?
定义一个TankClient.java (坦克的客户端类)
import java.awt.*; import java.awt.event.*; //引入事件
public class TankClient extends Frame { //直接继承 Frame类,比在在内容里: Frame f = new Frame();来创建窗体,有很大的便利,且易于调配 public static final int GAME_WIDTH = 800; //定义游戏窗体的宽度 public static final int GAME_HEIGHT = 600; //第一游戏窗体的宽度
Tank myTank = new Tank(40,40); //实例化一个坦克,然后坦克出现的坐标为 x=40,y=40;
下面我们就来好好的定义一下这个游戏窗体,使用一个方法来定义这个窗体
public void lauchFrame(){ this.setBounds(100,100,GAME_WIDTH,GAME_HEIGHT); //定义窗体的出现位置和大小 this.setTitle("tank激战!"); //给窗体起名 this.addWindowListener(new WindowAdapter(){ //使用匿名类的方式进行监听,使得窗口能够按 “×”后关闭 public void windowClosing(WindowEvent e) { //实现关闭窗体方法 System.exit(1); //输入1表示正常的退出 } }); //坦克类中我们定义的的四个方向键是要通过被监听到才能够被程序识别的,因此这里还是采用匿名类的方式来实现监听 this.addKeyListener(new KeyAdapter(){ //监听适配器 public void keyPressed(KeyEvent e){ myTank.keyPressed(e); //这样就监听了坦克类里的keyPressed()方法了 }
public void keyReleased(KeyEvent e){ //同上
myTank.keyReleased(e);
}
});
this.setResizable(false); //窗体不可拖拉改变大小
this.setBackground(Color.GREEN); //设置游戏窗体的背景颜色
setVisible(true); //窗体可见
new Thread(new PaintThread()).start(); //启动运行线程,下面将提到
}
//用paint()方法来调用tank类里的draw()画出来坦克来,但此若是单用此方法画出来的只是固定的,无法移动,因此下面使用线程来弥补这缺陷
public void paint(Graphics g){ myTank.draw(g); }
使用线程:
private class PaintThread implements Runnable{ public void run(){ while(true){ repaint(); //repaint()方法会调用update()方法【下讲中这方法用于解决闪烁问题】,update()再去调用paint()方法,这里没有update()的话会直接调用paint()方法 try{Thread.sleep(20);} //规定线程每 20毫秒画一次,就是每隔20毫秒你才能驱动一次坦克,这也是坦克能否灵活移动的关键,设置过大的话感觉老牛推车行走慢,不爽! catch(Exception e){e.printStackTrace();} } } }
最后我们使用主方法来调用lauchFrame()方法,从而产生坦克出来
public static void main(String[] args) { TankClient tc = new TankClient(); tc.lauchFrame(); }
}
运行之后可看到如下,方向控制非常灵敏,八个方向都正常运行,可自行感受一下这移动的原理,与坦克类中的方向定义是息息相关的!
至此底层框架的搭建完美收官,本人亲测 Tank类代码和TankClient类代码没有问题,只是复制时删除注释要注意不要删到括号,
下一步我们将进行三步完成坦克大战的第二步关于坦克发射子弹和敌方出现的情况!