Java版飞机游戏 游戏Java飞机编程语言
先贴游戏图。
......................................跳过.........................................
时间加起来也算是用了一天的时间,碰碰撞撞,修修补补终于是把这个游戏给做完了,虽然不完美,也还有bug,不过对自己而言,也算是不错的了。
在之前,自己一直觉得这游戏真的挺麻烦的,所以在动手自己开始做前,还一直在网上找相关视频借鉴借鉴,然而却没有,所以没办法只能自己动手。真正的开始敲下第一行代码时,思路却都已经出现在脑海中,然后一发不可收拾,用一个下午的时间把基本功能都给做完了,然后晚上边玩,边修复一些小的bug,第二天早上把排行榜给做了。
现在回过头来看,不扯这个小游戏,我发现我一直都在小看自己,总是在做某件事前,就给自己打上了有可能不成功的标签,又觉得事情很难。在真正开始做时,好多时候事情真的很简单,只是自己对这一方面的内容不熟悉而已。
自己害怕失败吧...真的,一个年轻人还没开始做事之前就退却了,真是不可理喻啊。慢慢来吧,现在还有时间,趁自己还有可以犯错的资本时,多尝试尝试总是好事。
.......................................分割线......................................
我把所有的图都画在了JLabel上,然后再在面板上显示,看起来很方便,但缺点也是很明显,就是不管是我方飞机,还是敌方飞机,还是子弹,在移动起来,总是一卡一卡的,不流畅,可自己又想不出好的法子了,只能这样做下去。
讲一些重要的代码,不然会显得很繁琐,例如继承了JLabel的MyPlane类,Bullet类就不贴了,一些没必要的注释或者调试的输出就不删了。
GameFrame类实现了KeyListener接口,为的是可以直接操作我方飞机的移动,因为我方飞机的JLabel是直接加载这个上面的。移动键为WSAD,然后对活动范围也加了一些限制,总不能移动到可见界面外去了是吧。
@Override public void keyTyped(KeyEvent e) { //获得飞机位置 int x = myplane.getX(); int y = myplane.getY(); //每次移动大小 int speed = 10; //根据不同指令执行命令 if (e.getKeyChar() == 'W' || e.getKeyChar() == 'w') { // 上移 y -= speed; } else if (e.getKeyChar() == 'S' || e.getKeyChar() == 's') { // 下移 y += speed; } else if (e.getKeyChar() == 'A' || e.getKeyChar() == 'a') { // 左移 x -= speed; } else if (e.getKeyChar() == 'D' || e.getKeyChar() == 'd') { // 右移 x += speed; } //设置活动范围 if (x > -5 && x < Constant.WIDTH - 65 && y > 0 && y < Constant.HEIGHT - 110) { myplane.setLocation(x, y); } // repaint(); }
而对于子弹而言,肯定是伴随着飞机发射的,所以出现的位置肯定是跟飞机位置相关,并且是自动发射,不要用户控制,直接开启个线程,可能因为图片的原因,所以需要对位置稍微进行小的偏移修改。
// 开启子弹线程 private void launch() { new Thread() { @Override public void run() { //如果为true,则启动线程,否则关闭 while (flagBullet) { // 给出现时的坐标加上一个值,调整位置 //以飞机坐标为参数,生成一个子弹对象 Bullet bullet = new Bullet(myplane.getX() + 30, myplane.getY() + 30, GameFrame.this); // 将子弹加入面板 panel.add(bullet); // 添加进子弹列表 GameList.bulletList.add(bullet); // 开始行动 new Thread(bullet).start(); // 每隔300毫秒发射一颗子弹 try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace(); } } } }.start(); }
而对于敌机,则是随机出现的,当然,也不是可以出现在任意位置,而是固定了几个位置,然后随机的。也给限制了数量,面板最多一次可见多少个,然后没隔10秒增加一个,如果达到上限,则不会新出现飞机。
/* * 启动敌机线程 */ private void otherPlane() { new Thread() { @Override public void run() { //获得第一次出现敌机的时间 long firstTime = System.currentTimeMillis(); //一次最多存在number数量的敌机 int number = 5; while (flagPlane) { //获得当前时间 long currentTime = System.currentTimeMillis(); //每10秒多增加一架可以在界面上显示的敌机 if(currentTime - firstTime > 10000){ number ++; //交换数据 firstTime = currentTime; } // System.out.println("OtherPlane's number is : " // + GameList.planeList.size()); int size = GameList.planeList.size(); //如果list中的敌机数量小于总共可以在界面上显示的,则创建对象 if (size <= number) { OtherPlane otherPlane = new OtherPlane(GameFrame.this); //需要把该对象放到面板中去显示 panel.add(otherPlane); //加入list GameList.planeList.add(otherPlane); //启动,可以活动 new Thread(otherPlane).start(); //没500毫秒生成一个 try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } } }.start(); }
从上面的代码中可以都可以看到一个GameList类,这个类我是为了操作方便而写的,其实肯定是不符合规范的。在里面实现了一些方法,例如子弹打到了敌机,或者敌机与我方飞机碰到了等等。
下面这个方法就是子弹打到了敌机,然后子弹和敌机都消失,但当时在写这个的时候,出现了很多问题,其中最严重的是当子弹和敌机都消失后,我方飞机还是会被本该消失的飞机碰到,调试了好久才发现,虽然敌机从面板上和list中都移除了,但他的线程仍然存在,也就是说我们只是看不到他了,但还是活着的,所以需要把对应的线程结束掉才行。
//停止相碰的子弹和敌机的线程 op.setFlag(false); bullet.setFlag(false);
// 判断子弹是否与敌机有接触 public static void intersectsBullet(Bullet bullet, GameFrame gameFrame) { // 创建子弹的矩形 Rectangle bulletRect = new Rectangle(bullet.getX(), bullet.getY(), bullet.getWidth(), bullet.getHeight()); for (int i = 0; i < planeList.size(); i++) { // 创建每一个敌机的矩形,逐一进行判断 OtherPlane op = planeList.get(i); Rectangle planeRect = new Rectangle(op.getX(), op.getY(), op.getWidth(), op.getHeight()); // 如果两个矩形相交 if (bulletRect.intersects(planeRect)) { //分数+1 Score.score ++; //停止相碰的子弹和敌机的线程 op.setFlag(false); bullet.setFlag(false); // 从面板中移除掉敌机和子弹 gameFrame.remove(op); gameFrame.remove(bullet); // 从list中移除两个对象 bulletList.remove(bullet); planeList.remove(op); // 刷新界面 gameFrame.repaint(); } } }
从上面的代码可以看出,我判断是否产生接触用的是Rectangle类中的intersects方法,这个方法的意思是判断两个矩形是否相交,所以需要把需要判断的两个对象提取相应的位置,宽,高出来。但问题是,他们的宽和高都是根据图片设置的,所以在碰撞这个问题是,会有点小bug。
结束游戏有两种方式,一种是地方飞机与我方飞机发生了碰撞
//判断敌机和我方飞机是否相撞 public static void intersectsPlane(OtherPlane op, GameFrame gameFrame) { //创建我方飞机矩形 MyPlane myplane = gameFrame.getMyPlane(); Rectangle myRect = new Rectangle(myplane.getX(), myplane.getY(), myplane.getWidth(), myplane.getHeight()); //敌方飞机矩形 Rectangle opRect = new Rectangle(op.getX(), op.getY(), op.getWidth(), op.getHeight()); //如果矩形相交,则发生碰撞,游戏结束 if (opRect.intersects(myRect)) { gameFrame.remove(op); gameFrame.remove(myplane); op.setFlag(false); //游戏结束 gameOver(gameFrame); } }
例外一种是时间到了,在另外一个类中,就是判断倒计时是否归0了。他们都需要共同的代码,需要提取出来,封装成一个方法了。
结束掉所有的线程,并且清除所有的数据,注意的是,也要把我方飞机的数据置null才行。
public static void gameOver(GameFrame gameFrame){ //清除我方飞机数据 gameFrame.setMyPlane(null); // 终止生成子弹和生成敌机的循环 gameFrame.setFlagBullet(false); gameFrame.setFlagPlane(false); //停止时间分数线程 Score.flag = false; // 清空list bulletList.clear(); planeList.clear(); //对话框要出现在清理数据之后 String name = JOptionPane.showInputDialog("游戏结束,请输入你的大名:"); Recorder recorder = new Recorder(); recorder.write(name, Score.score); // 关闭界面 gameFrame.dispose(); // 打开主界面 new MainFrame(); }
因为也同时写了排行榜,所以在游戏结束时,会弹出一个对话框,提示游戏结束,并且输入自己的姓名。而数据会写入到xml文件中,xml文件解析用的是dom方法,很惭愧的是,才学了没多久,竟然就忘了差不多了,还需要翻看笔记才能想起。
写起来没逻辑,整个程序放在了附件,有需要的朋友可以下载,如果有什么好的建议或不足,谢谢在评论中提出。
推荐阅读
-
免费java游戏代码大全(编程一个最简单游戏代码)
-
免费java游戏代码大全(编程一个最简单游戏代码)
-
C#飞机打字游戏的代码示例(winform版)
-
利用java开发简易版扫雷游戏
-
Pygame实现小游戏飞机大战,不用精灵版
-
【响应式编程的思维艺术】 (4)从打飞机游戏理解并发与流的融合
-
java版游戏辅助,自动化程序。
-
java写游戏脚本(编程一个最简单游戏代码)
-
笔试编程题 数字游戏 Java题解 牛牛举办了一场数字游戏,有n个玩家参加这个游戏,游戏开始每个玩家选定一个数,然后将这个数写在纸上(十进制数,无前缀零),然后接下来对于每一个数字将其数位按照非递减
-
飞机大战 雷霆战机 打字小游戏 java小游戏设计(提供源代码下载)