坦克大战--这款游戏,相信大家小时候都玩过,想当年还在读小学的时候,我和我表哥整个暑假拿着一台小霸王游戏机接上电视,就开始玩坦克大战,通关根本停不下来,
简直打遍天下无敌手。现在我上了大学,学的是软件工程专业,学了java,现在我自己用java做了这款小游戏,和大家分享一下,也说一下我在做这个游戏过程中遇到的一些问题,
希望对大家起到一定的帮助。源代码在附件里,大家可以下载
首先简略的说下整个坦克大战的大致流程、要实现的功能和最后的效果图
主要有以下这些类:
效果图:
大致流程如下
1、首先得有一个面板
2、加入一辆坦克
3、让坦克移动
4、加入子弹
5、加入敌人的坦克
6、让敌人的坦克动起来,并且能发子弹
7、子弹能够消灭坦克
实现功能:能够四处移动
能够打击敌人
敌人能够移动
能够模拟爆炸
能够产生障碍
能够增长生命
1,如何给游戏加上坦克等图片?
下面使用到了ClassLoader类装载器获取系统资源
ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。
ClassLoader提供了两个方法用于从装载的类路径中取得资源:
public URL getResource(String name);
public InputStream getResourceAsStream(String name);
这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
然而,程序中调用的通常并不是ClassLoader的这两个方法,而是Class的getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或YourClass.getClass()),
而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,但根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,
所以只需要使用Class对象的这两个方法就可以了。
从文件中装入图像,使用类装载器的public URL getResource(String name);方法打开文件
这个要用到类的反射的相关知识,大家还有不懂的可以去查API文档或者百度
具体实现代码(大家可以在Tank类中找到这段代码):
private static Toolkit tk = Toolkit.getDefaultToolkit(); private static Image[] tankImages = null; private static Map<String,Image> imgs = new HashMap<String,Image>(); //静态代码区 static{ tankImages=new Image[]{ tk.getImage(Tank.class.getClassLoader().getResource("image/tankL.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankLU.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankU.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankRU.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankR.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankRD.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankD.gif")), tk.getImage(Tank.class.getClassLoader().getResource("image/tankLD.gif")) }; imgs.put("L",tankImages[0]); imgs.put("LU",tankImages[1]); imgs.put("U",tankImages[2]); imgs.put("RU",tankImages[3]); imgs.put("R",tankImages[4]); imgs.put("RD",tankImages[5]); imgs.put("D",tankImages[6]); imgs.put("LD",tankImages[7]); }
加入爆炸、子弹的图片和加入坦克的图片一样,这里就不做详细说明了
2,打第一颗子弹打出时没有爆炸产生
当我们照上面的方法加上爆照的图片后,发现第一发子弹打到敌人坦克时没有爆炸产生,从第二发开始都有爆炸产生
打一颗子弹时爆炸图片还木有到内存中来,第二次画爆照图片时已经到内存中里。我们定义的图片数组是static的,在类加载的时候,首先执行的就是static,这个时候还没有执行draw()方法,那么肯定不是这个原因
原因:getResource()执行时只拿到了图片的虚框(很多软件显示比较大的图片时也会出现这种情况),当调用draw()方法,还没有拿到数据
解决方案:
在Explode类中加入boolean类型 init变量
private static boolean init = false;
在Explode类draw()方法里面第一行加入以下代码
if(!init){ for (int i = 0; i < imgs.length; i++) { g.drawImage(imgs[i], -100, -100, null); } init=true; }
3、解决炮弹不消亡的问题
步骤:
加入控制子弹生死的量bLive(Missle)
当子弹已经死去就不需要对其重画
当子弹飞出边界就死亡
当子弹死亡就从容器中去除
package com.zkx.tank; import java.awt.*; import java.util.HashMap; import java.util.List; import java.util.Map; public class Missile { public static final int XSPEED=10; public static final int YSPEED=10; public static final int WIDTH=10; public static final int HEIGHT=10; int x,y; Direction dir; private boolean good; private boolean live=true; private TankClient tc; private static Toolkit tk = Toolkit.getDefaultToolkit(); private static Image[] missileImages = null; private static Map<String,Image> imgs = new HashMap<String,Image>(); //静态代码区 static{ missileImages=new Image[]{ tk.getImage(Missile.class.getClassLoader().getResource("image/missileL.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileLU.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileU.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileRU.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileR.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileRD.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileD.gif")), tk.getImage(Missile.class.getClassLoader().getResource("image/missileLD.gif")) }; imgs.put("L",missileImages[0]); imgs.put("LU",missileImages[1]); imgs.put("U",missileImages[2]); imgs.put("RU",missileImages[3]); imgs.put("R",missileImages[4]); imgs.put("RD",missileImages[5]); imgs.put("D",missileImages[6]); imgs.put("LD",missileImages[7]); } public boolean isLive() { return live; } public Missile(int x, int y,Direction dir) { this.x = x; this.y = y; this.dir = dir; } public Missile(int x,int y,boolean good,Direction dir,TankClient tc){ this(x,y,dir); this.good=good; this.tc=tc; } public void draw(Graphics g){ if(!live){ tc.missiles.remove(this); return; } switch(dir){ case L: g.drawImage(imgs.get("L"), x, y, null); break; case LU: g.drawImage(imgs.get("LU"), x, y, null); break; case U: g.drawImage(imgs.get("U"), x, y, null); break; case RU: g.drawImage(imgs.get("RU"), x, y, null); break; case R: g.drawImage(imgs.get("R"), x, y, null); break; case RD: g.drawImage(imgs.get("RD"), x, y, null); break; case D: g.drawImage(imgs.get("D"), x, y, null); break; case LD: g.drawImage(imgs.get("LD"), x, y, null); break; case STOP: break; } } private void move() { switch(dir){ case L: x-=XSPEED; break; case LU: x-=XSPEED; y-=YSPEED; break; case U: y-=YSPEED; break; case RU: x+=XSPEED; y-=YSPEED; break; case R: x+=XSPEED; break; case RD: x+=XSPEED; y+=YSPEED; break; case D: y+=YSPEED; break; case LD: x-=XSPEED; y+=YSPEED; break; case STOP: break; } if(x<0 || y<0 || x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGHT){ live=false; } } public Rectangle getRect(){ return new Rectangle(x,y,WIDTH,HEIGHT); } public boolean hitTank(Tank t){ if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive() && this.good!=t.isGood()){ if(t.isGood()){ t.setLife(t.getLife()-20); if(t.getLife()<=0) t.setLive(false); }else{ t.setLive(false); } this.live=false; Explode e=new Explode(x,y,tc); tc.explodes.add(e); return true; } return false; } public boolean hitTanks(List<Tank> tanks){ for(int i=0;i<tanks.size();i++){ if(hitTank(tanks.get(i))){ return true; } } return false; } public boolean hitWall(Wall w){ if(this.live&&this.getRect().intersects(w.getRect())){ this.live=false; return true; } return false; } }
4、如何让坦克向8个方向行走?
步骤:
添加记录按键状态的布尔量
添加代表方向的量(使用枚举)
根据按键状态确定Tank方向
根据方向进行下一步的移动(move)
void move(){ this.oldX=x; this.oldY=y; switch(dir){ case L: x-=XSPEED; break; case LU: x-=XSPEED; y-=YSPEED; break; case U: y-=YSPEED; break; case RU: x+=XSPEED; y-=YSPEED; break; case R: x+=XSPEED; break; case RD: x+=XSPEED; y+=YSPEED; break; case D: y+=YSPEED; break; case LD: x-=XSPEED; y+=YSPEED; break; case STOP: break; }
相关推荐
本文将围绕“Java多线程实现坦克大战游戏带声音图片”这一主题,深入探讨如何利用Java的多线程技术来构建一个包含声音和图形的坦克战斗游戏。 首先,我们要理解Java中的线程。线程是程序执行的最小单元,每个线程都...
"JAVA(坦克大战,多线程管理).rar"这个压缩包可能包含了一个基于Java实现的坦克大战游戏,其中涉及了多线程的概念来模拟游戏中的各种动态元素,如坦克、子弹、障碍物等的独立运动和交互。下面我们将深入探讨Java多...
7. **多线程与并发**:在高级版本的坦克大战中,可能会引入多线程技术,让玩家间的交互更加实时。比如,两个玩家的操作可以分别在不同的线程中处理,提高游戏体验。 总结,C++实现的坦克大战游戏涉及了键盘事件处理...
功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡...
从给定的文件信息来看,这是一段C++代码,用于实现一个基于控制台的多线程坦克大战游戏。下面将详细解析其中的关键知识点。 ### C++多线程编程 在C++中,多线程是指在一个程序中同时运行多个线程的能力。这可以...
总结,Java游戏之坦克大战不仅展示了Java语言的强大功能,还涵盖了游戏开发的多个重要方面,包括图形界面设计、多线程控制、事件处理、碰撞检测、游戏循环以及数据结构和算法的应用。通过学习和实践这个游戏的开发,...
坦克大战是一款经典的双人对战游戏,最初在FC游戏机上流行。在Android平台上开发坦克大战,开发者需要掌握基本的游戏编程原理,包括游戏循环、碰撞检测、物体移动与旋转、射击逻辑等。此外,还需要熟悉Android的图形...
在Android平台上实现一...总的来说,实现Android版的坦克大战游戏,开发者需要掌握Android应用开发、2D图形编程、网络编程、多线程技术、UI设计、性能优化等多个领域的知识,这是一个既能锻炼技能又能带来乐趣的项目。
《坦克大战游戏源码+素材+文档》是一个适合初学者的项目,旨在帮助他们实践Java面向对象编程思想,提升编程技能。在这个项目中,你将深入理解如何利用Java语言来开发一个完整的游戏,同时,通过实际操作,巩固并应用...
总之,Android坦克大战源码涵盖了Android开发的多个重要领域,包括绘图与自定义控件、音频处理、数据库操作、多线程编程、碰撞检测以及动画制作。通过对这些知识点的学习和理解,开发者不仅可以掌握Android游戏开发...
3. **多线程**:在坦克大战中,游戏逻辑和用户交互需要同时进行,这就需要用到Java的多线程技术。通过创建多个线程,游戏可以一边处理玩家的操作,一边更新游戏状态,确保游戏流畅运行。 4. **事件监听**:为了响应...
7. **多线程**:在高级版本的坦克大战中,可能会引入多线程技术,使得游戏逻辑(如AI控制的坦克)和用户交互能在不同的线程中并发执行,提高游戏响应速度。 通过分析这个C++实现的坦克大战源码,我们可以学习到如何...
通过研究坦克大战游戏的源码,开发者可以学习到Android游戏开发的基础知识,包括UI设计、游戏逻辑构建、动画实现、事件处理、资源管理、多线程编程以及性能优化等,这些都将对今后的Android开发工作大有裨益。
4. **多线程**:为了实现游戏的实时性和流畅性,坦克大战可能会使用到多线程。例如,一个线程负责游戏逻辑的更新,另一个线程负责渲染图形,这样可以避免UI线程阻塞,提高游戏性能。 5. **图像处理**:游戏中图片的...
"Java版的坦克大战小游戏源码"就是一个极佳的实践项目,它不仅让我们有机会重温Java的基础知识,还能够深入理解多线程、内部类、图形绘制以及泛型等高级特性。下面,我们将详细探讨这个项目中的关键知识点。 首先,...
多线程在坦克大战中起着至关重要的作用。游戏通常需要同时处理多个任务,例如玩家控制的坦克移动、敌方坦克的行为、炮弹的轨迹等。这些任务如果都在同一个线程中执行,会导致程序阻塞,影响游戏体验。因此,使用多...
2. 多线程:游戏通常需要同时处理用户输入、渲染和游戏逻辑,多线程技术在这里至关重要。 3. 文件I/O操作:读取和写入游戏数据,如地图、配置、存档等。 4. 算法和数据结构:如路径查找、碰撞检测等,涉及到搜索算法...
【Java小游戏坦克大战程序设计】是一个使用Java编程语言开发的经典坦克战斗游戏项目。这个项目旨在帮助开发者提升在游戏编程、网络通信以及图形用户界面设计等方面的技能。以下将详细阐述涉及的知识点: 1. **Java...
【基于Java坦克大战游戏源码】的项目是一个用于学习和实践Java编程的优秀实例,尤其适合深入理解Java的多线程技术。在这个项目中,开发者使用Java语言在Eclipse集成开发环境中构建了一款经典的游戏——坦克大战。...