`

多线程游戏坦克大战

 
阅读更多

坦克大战--这款游戏,相信大家小时候都玩过,想当年还在读小学的时候,我和我表哥整个暑假拿着一台小霸王游戏机接上电视,就开始玩坦克大战,通关根本停不下来,

简直打遍天下无敌手。现在我上了大学,学的是软件工程专业,学了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;	
	}

 

  • 大小: 13.6 KB
  • 大小: 22.7 KB
分享到:
评论

相关推荐

    java多线程实现坦克大战游戏带声音图片

    本文将围绕“Java多线程实现坦克大战游戏带声音图片”这一主题,深入探讨如何利用Java的多线程技术来构建一个包含声音和图形的坦克战斗游戏。 首先,我们要理解Java中的线程。线程是程序执行的最小单元,每个线程都...

    JAVA(坦克大战,多线程管理).rar

    "JAVA(坦克大战,多线程管理).rar"这个压缩包可能包含了一个基于Java实现的坦克大战游戏,其中涉及了多线程的概念来模拟游戏中的各种动态元素,如坦克、子弹、障碍物等的独立运动和交互。下面我们将深入探讨Java多...

    C++坦克大战完整代码.zip

    7. **多线程与并发**:在高级版本的坦克大战中,可能会引入多线程技术,让玩家间的交互更加实时。比如,两个玩家的操作可以分别在不同的线程中处理,提高游戏体验。 总结,C++实现的坦克大战游戏涉及了键盘事件处理...

    坦克大战——C++游戏代码

    功能方面,游戏参考于80年代任天堂红白机(FC/FamilyComputer)上的游戏坦克大战(Battle City),包括地图,游戏模式等等(当时的游戏直接烧在电路板上)。所以游戏平衡方面已经有了很好的参考,无需再花大量时间测试平衡...

    C++控制台多线程坦克大战源码

    从给定的文件信息来看,这是一段C++代码,用于实现一个基于控制台的多线程坦克大战游戏。下面将详细解析其中的关键知识点。 ### C++多线程编程 在C++中,多线程是指在一个程序中同时运行多个线程的能力。这可以...

    java游戏之坦克大战

    总结,Java游戏之坦克大战不仅展示了Java语言的强大功能,还涵盖了游戏开发的多个重要方面,包括图形界面设计、多线程控制、事件处理、碰撞检测、游戏循环以及数据结构和算法的应用。通过学习和实践这个游戏的开发,...

    基于Android studio编写的坦克大战游戏.zip

    坦克大战是一款经典的双人对战游戏,最初在FC游戏机上流行。在Android平台上开发坦克大战,开发者需要掌握基本的游戏编程原理,包括游戏循环、碰撞检测、物体移动与旋转、射击逻辑等。此外,还需要熟悉Android的图形...

    Android实现坦克大战游戏

    在Android平台上实现一...总的来说,实现Android版的坦克大战游戏,开发者需要掌握Android应用开发、2D图形编程、网络编程、多线程技术、UI设计、性能优化等多个领域的知识,这是一个既能锻炼技能又能带来乐趣的项目。

    坦克大战游戏源码+素材+文档

    《坦克大战游戏源码+素材+文档》是一个适合初学者的项目,旨在帮助他们实践Java面向对象编程思想,提升编程技能。在这个项目中,你将深入理解如何利用Java语言来开发一个完整的游戏,同时,通过实际操作,巩固并应用...

    Android 坦克大战源码

    总之,Android坦克大战源码涵盖了Android开发的多个重要领域,包括绘图与自定义控件、音频处理、数据库操作、多线程编程、碰撞检测以及动画制作。通过对这些知识点的学习和理解,开发者不仅可以掌握Android游戏开发...

    java做的坦克大战(带图片)

    3. **多线程**:在坦克大战中,游戏逻辑和用户交互需要同时进行,这就需要用到Java的多线程技术。通过创建多个线程,游戏可以一边处理玩家的操作,一边更新游戏状态,确保游戏流畅运行。 4. **事件监听**:为了响应...

    c++坦克大战源码_写的不错

    7. **多线程**:在高级版本的坦克大战中,可能会引入多线程技术,使得游戏逻辑(如AI控制的坦克)和用户交互能在不同的线程中并发执行,提高游戏响应速度。 通过分析这个C++实现的坦克大战源码,我们可以学习到如何...

    Android应用源码之坦克大战游戏源码.zip

    通过研究坦克大战游戏的源码,开发者可以学习到Android游戏开发的基础知识,包括UI设计、游戏逻辑构建、动画实现、事件处理、资源管理、多线程编程以及性能优化等,这些都将对今后的Android开发工作大有裨益。

    坦克大战图片+音效版

    4. **多线程**:为了实现游戏的实时性和流畅性,坦克大战可能会使用到多线程。例如,一个线程负责游戏逻辑的更新,另一个线程负责渲染图形,这样可以避免UI线程阻塞,提高游戏性能。 5. **图像处理**:游戏中图片的...

    java版的坦克大战小游戏源码

    "Java版的坦克大战小游戏源码"就是一个极佳的实践项目,它不仅让我们有机会重温Java的基础知识,还能够深入理解多线程、内部类、图形绘制以及泛型等高级特性。下面,我们将详细探讨这个项目中的关键知识点。 首先,...

    JAVA+Swing坦克大战

    多线程在坦克大战中起着至关重要的作用。游戏通常需要同时处理多个任务,例如玩家控制的坦克移动、敌方坦克的行为、炮弹的轨迹等。这些任务如果都在同一个线程中执行,会导致程序阻塞,影响游戏体验。因此,使用多...

    坦克大战游戏源码+素材 java

    2. 多线程:游戏通常需要同时处理用户输入、渲染和游戏逻辑,多线程技术在这里至关重要。 3. 文件I/O操作:读取和写入游戏数据,如地图、配置、存档等。 4. 算法和数据结构:如路径查找、碰撞检测等,涉及到搜索算法...

    Java小游戏坦克大战程序设计

    【Java小游戏坦克大战程序设计】是一个使用Java编程语言开发的经典坦克战斗游戏项目。这个项目旨在帮助开发者提升在游戏编程、网络通信以及图形用户界面设计等方面的技能。以下将详细阐述涉及的知识点: 1. **Java...

    基于java坦克大战游戏源码

    【基于Java坦克大战游戏源码】的项目是一个用于学习和实践Java编程的优秀实例,尤其适合深入理解Java的多线程技术。在这个项目中,开发者使用Java语言在Eclipse集成开发环境中构建了一款经典的游戏——坦克大战。...

Global site tag (gtag.js) - Google Analytics