`

【纯JAVA语言做RPG游戏】1.做个瓷砖地图生成器

阅读更多

开个坑,想做个JAVA游戏。

虽然现在有着各种游戏引擎,使得做游戏的效率提高了很多,但是用着别人的代码来做感觉对自己也没啥提升,而且在游戏的模式上也不得不去迎合别人的思维,所以露珠准备应用前面学到的所有JAVA知识,来完成这个不用引擎的游戏项目,也算是一个对前面知识的总结与复习吧 O(∩_∩)O~

嗯,下面开始正题。

 

    说到RPG游戏,首先想到的是现在市面上各种各类的3D巨作,可这些是我这种菜鸟暂时无法企及的,所以呢,目标就定为2D的RPG游戏了.

    一想到2D的RPG游戏,立马回想起了一系列的以前电子词典上面的《金庸群侠传》《侠客行》之类的,这种游戏的共同点便是,所有的游戏元素都是一个一个的小方块,而游戏画面也就是由这一个一个的小方块构成。

    这些不同的小方块组成了游戏的地图,因为他们的上下左右都是对齐的,这样我们自然的就想到了用一种熟悉的数据结构来在游戏内部表示和储存它,那便是二维数组。我们用二维数组的位置i,j来确定小方块在地图中的坐标位置,而二维数组中元素的值便用来代表这一格元素的类型,例如用0来代表草地,用1来代表石头等等...

    这样选择好游戏的基本数据结构之后,我们首先想象我们的游戏已经完成,打开游戏程序后要进行的第一件事便是出现游戏的窗体,也就是说第一件事就是得载入游戏的地图,所以做这个游戏第一步便是在游戏开始之前就要编辑好一个二维数组,这个二维数组就是游戏的地图。

    这个数组我们不可能凭空去给他赋值,所以就需要一个图形化界面来让我们方便的去设置数组中的值:

    这便是这次的任务,做一个瓷砖地图编辑器,编辑完之后保存一个二维数组到一个文件中,以后写的游戏程序就能直接调用那个保存好的地图文件来载入地图了。

    由于是自己写的编辑器,就可以按自己的需求来配置这个地图编辑器的内容了

 

------------------------------------------------------------------------------------------------------------------------

 

1.首先写一个Mapconfig的接口,用来设置我们生成的地图的一些基本配置。(用接口来做配置文件是因为其他的类)

public interface MapConfig {
	//素材的大小
	int eleWidth = 50;
	int eleHeight = 50;
	//地图的大小
	int MapWidth = 2000;
	int MapHeight= 2000;
	//地图保存的位置
	String path = "D:\\mygame\\map\\map1.map";
	
	//用到的图片素材
	ImageIcon icon0 = new ImageIcon("000草地.png");
	ImageIcon icon100 = new ImageIcon("100红树.png");
	ImageIcon icon101 = new ImageIcon("101绿树.png");
	ImageIcon icon102 = new ImageIcon("102绿竹.png");
	//将所有的图片素材对象放入一个数组中,便于窗体上的下拉列表添加所有的图片素材
	ImageIcon[] allicons = {icon0,icon100,icon101,icon102}; 
}

 2.接下来便是写一个窗口类来实现上面那个地图配置接口,用来作为我们设置地图的窗口。(这里又有了一个问题,一个地图中有一些地形是可以通过的,而有一些地形是不能过的。这里我采用的区别方式是一个地图用三个二维数组表示,这三个数组分别代表【人物脚下的素材】,和【人物同一平面的素材】,以及【人物头上的素材】,这样分层定义地图,规定同一个层面的素材都是互斥不能通过的,就很好的解决了这个问题)

/**
 * 图形化设置地图数组
 * @author yy
 *
 */
public class SetMap extends JFrame implements MapConfig{
	//用来选择素材的下拉表(前面)
	JComboBox<ImageIcon> box;
	//用来选择素材层数的下拉表
	JComboBox<Integer> boxtype;
	//用来储存建立的地图数组的二维数组   (map1脚下素材   map2地表素材   map3上层素材)
	static int[][] map1 = new int[40][40];
	static int[][] map2 = new int[40][40];
	static int[][] map3 = new int[40][40];
	//用来存储对应的图片的二维数组 (这里的icon数组,只是用来将我们设置好的数组在界面上显示出来,不用保存进文件)
	static ImageIcon[][] icons1 = new ImageIcon[40][40];
	static ImageIcon[][] icons2 = new ImageIcon[40][40];
	static ImageIcon[][] icons3 = new ImageIcon[40][40];
	//编辑中的地图显示的面板
	static JPanel panel;
	/**
	 * 程序入口主函数
	 * @param args
	 */
	public static void main(String[] args) {
		SetMap sm = new SetMap();
		sm.init();
	}
	/**
	 * 设置窗体的方法
	 */
	public void init(){
		this.setTitle("地图数组生成");
		this.setSize(1000, 700);
		this.setDefaultCloseOperation(3);
		this.setLayout(new FlowLayout());
		//设置面板类
		panel = new MySetPanel();
		panel.setPreferredSize(new Dimension(MapWidth, MapHeight));
		JScrollPane jsp = new JScrollPane(panel);
		jsp.setPreferredSize(new Dimension(600, 600));
		jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		
		//创建选择素材层的下拉列表 (这里选择1表示当前编辑的是第一层的元素,2表示的当前编辑第二层元素,3同前面)
		boxtype = new JComboBox<Integer>();
		boxtype.addItem(1);
		boxtype.addItem(2);
		boxtype.addItem(3);
		
		//创建选择素材的下拉列表
		box = new JComboBox<ImageIcon>();
		//将我们前面配置文件中的所有图片素材放入下拉表的方法
		setBox(box);
		
		//创建按钮
		JButton create = new JButton("创建");
		create.setActionCommand("create");
		
		
		this.add(jsp);
		this.add(boxtype);
		this.add(box);
		this.add(create);
		this.setVisible(true);
		
		//给面板安装鼠标监听器
		PanelListenner plis = new PanelListenner();
		panel.addMouseListener(plis);
		//给按钮安装事件监听器
		Buttonlistenner blis = new Buttonlistenner();
		create.addActionListener(blis);
	}
	
	//设置地图中的素材下拉表
	public void setBox(JComboBox box){
		for(int i=0;i<allicons.length;i++){
			box.addItem(allicons[i]);
		}
	}
	
	/**
	 * 临时地图面板类
	 * @author yy
	 *
	 */
	class MySetPanel extends JPanel{
		
		@Override
		public void paint(Graphics g) {
			super.paint(g);
			for(int i=0;i<MapHeight/eleHeight;i++){
				for(int j=0;j<MapWidth/eleWidth;j++){
					//画第一层元素
					if(icons1[i][j]!=null){
						g.drawImage(icons1[i][j].getImage(), getDrawX(j), getDrawY(i), eleWidth, eleHeight, null);
					}
					//画第二层元素
					if(icons2[i][j]!=null){
						g.drawImage(icons2[i][j].getImage(), getDrawX(j), getDrawY(i), eleWidth, eleHeight, null);
					}
					//画第三层元素
					if(icons3[i][j]!=null){
						g.drawImage(icons3[i][j].getImage(), getDrawX(j), getDrawY(i), eleWidth, eleHeight, null);
					}
				}
			}
		}
		
		//将数组下标转化成对应的图片左上角坐标
		public int getDrawX(int j){
			int x = j*50;
			return x;
		}
		//将数组下标转化成对应的图片左上角坐标
		public int getDrawY(int i){
			int y = i*50; 	
			return y;
		}
	}
	
	/**
	 * 按键监听类
	 * @author yy
	 *
	 */
	class Buttonlistenner implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			//如果按下了创建按钮,就保存当前设置好的3个二维数组
			if(e.getActionCommand().equals("create")){
				try{
				System.out.println("开始保存");
				//得到文件输出流
				FileOutputStream fos = new FileOutputStream(path);
				//将文件输出流包装成基本数据输出流
				DataOutputStream dos = new DataOutputStream(fos);
				//从配置的接口中得到二维数组的大小(由于本类已经实现了上面的Mapconfig接口,所以可以直接用里面的数据)
				int i = MapHeight/eleHeight;
				int j = MapWidth/eleWidth;
				//先数组的大小写入文件
				dos.writeInt(i);
				dos.writeInt(j);
				//按顺序将三个二维数组写入文件,记住这里的写入方式,后面游戏读取地图的时候也要按这种顺序读回来
				for(int ii=0;ii<i;ii++){
					for(int jj=0;jj<j;jj++){
						dos.writeInt(map1[ii][jj]);
						dos.writeInt(map2[ii][jj]);
						dos.writeInt(map3[ii][jj]);
					}
				}
				//强制流中的数据完全输出完
				dos.flush();
				//关闭输出流
				dos.close();
				System.out.println("保存完成");
				
				}catch(Exception ef){
					ef.printStackTrace();
				}
			}
		}
	}
	
	
	
	/**
	 * 面板监听类
	 * @author yy
	 *
	 */
	class PanelListenner extends MouseAdapter{
		public void mouseClicked(MouseEvent e) {
			//得到该位置对应的数组下标
			int j = e.getX()/eleWidth;
			int i = e.getY()/eleHeight;
			System.out.println(i+"<>"+j);
			//得到选择框中的图片
			ImageIcon icon = (ImageIcon)box.getSelectedItem();
			//得到该图片的编号,此处默认取名字的前三位数字   PS:这里也可以用其它的处理方式,楼主只是想复习一下string
			int num = str2int(icon.toString().substring(0, 3));
			//修改数组中的值
			if((int)boxtype.getSelectedItem()==1){
				map1[i][j] = num;
				icons1[i][j] = icon;
			}else if((int)boxtype.getSelectedItem()==2){
				map2[i][j] = num;
				icons2[i][j] = icon;
			}else if((int)boxtype.getSelectedItem()==3){
				map3[i][j] = num;
				icons3[i][j] = icon;
			}
			System.out.println((int)boxtype.getSelectedItem());
			
			panel.repaint();
		}
		
		/**
		 * 将一个三位的字符串,转为一个int
		 * @param numstr
		 * @return
		 */
		public int str2int(String numstr){
			for(int i=0;i<3;i++){
				if(numstr.charAt(i)!=0){
					numstr = numstr.substring(i);
					int num = Integer.parseInt(numstr);
					return num;
				}
			}
			numstr = numstr.substring(2);
			int num = Integer.parseInt(numstr);
			return num;
		}
		
	}
}

 3.程序启动如下

 

 这样就可以通过控制两个下拉列表选择素材的层,和素材的类型,然后通过鼠标点击面板中来该表相应数组中元素的值了,完了之后点击【创建】按钮来将编辑好的地图存入文件。

这只是一个初步的模版,以后要加入什么NPC或者是什么传送门,还是野怪之类的,就换不同的素材就行了,以后的地图就可以用这个模式来创建了,游戏的第一步地图的生成也算是基本上完成了...

写这么一篇没什么内容的博客比码几个小时的代码都累,o(︶︿︶)o 唉,对程序员来说表达能力是大问题啊

 

 

 

  • 大小: 76.6 KB
15
4
分享到:
评论
6 楼 kotoko 2017-01-30  
还有,想请问一下,我用自己的图片,事先已调成50*50,为什么画图时会报错呢?图片还有什么其他要求吗?弄得我还以为是PanelListenner的问题。
5 楼 kotoko 2017-01-30  
你的PanelListenner 没有实现吧
4 楼 Y_1746119035 2014-10-24  
单身旅行 写道
用FX吧,感觉比用swing强点儿。。。

目前只学了Swing,就顺便拿来当个复习了..
3 楼 Y_1746119035 2014-10-24  
Night舞夜 写道
不知道楼主想做个什么样的游戏。

就是那种像RPG Maker做出来的那种类型的吧...
2 楼 单身旅行 2014-10-24  
用FX吧,感觉比用swing强点儿。。。
1 楼 Night舞夜 2014-10-24  
不知道楼主想做个什么样的游戏。

相关推荐

    【纯JAVA语言做RPG游戏】3.地图碰撞检测和角色行走的实现

    这个主题将探讨如何使用纯Java语言来处理这些问题。在本文中,我们将深入理解地图的构建、碰撞检测算法以及角色在游戏世界中的移动机制。 首先,地图在RPG游戏中通常由多个格子组成,每个格子代表一个可行走或不可...

    【纯java语言做RPG游戏】4.用XML导入NPC并与NPC对话

    在本教程中,我们将深入探讨如何使用纯Java语言制作角色扮演游戏(RPG)并利用XML文件导入非玩家角色(NPC)以及实现与NPC的交互。这个项目不仅涵盖了基础的Java编程,还涉及到游戏开发中的重要概念,如数据结构、...

    【纯JAVA语言做个RPG游戏】2.游戏界面及角色移动的基本实现

    在本项目中,我们将探讨如何使用纯Java语言创建一个简单的角色扮演游戏(RPG)游戏界面以及实现角色的移动功能。这个教程将引导我们逐步构建一个基础的2D游戏框架,涉及核心的游戏逻辑、用户交互以及图形渲染。 ...

    c#游戏开发基于unity3d的回合制RPG游戏源码.zip

    c#游戏开发基于unity3d的回合制RPG游戏源码.zipc#游戏开发基于unity3d的回合制RPG游戏源码.zipc#游戏开发基于unity3d的回合制RPG游戏源码.zipc#游戏开发基于unity3d的回合制RPG游戏源码.zipc#游戏开发基于unity3d的...

    Github基于Java的Rpg游戏

    【标题】:“Github基于Java的Rpg游戏”指的是在GitHub上可以找到的一种使用Java编程语言开发的角色扮演游戏(Role-Playing Game,简称RPG)。这种类型的游戏通常包含丰富的剧情、角色发展和互动元素,而通过使用...

    纯java开发的一个RPG游戏,亲测可用

    这个标题揭示了一个基于Java编程语言的RPG(角色扮演游戏)项目,表明该游戏是完全使用Java语言编写的,没有依赖其他非Java技术。"纯Java开发"通常意味着游戏的所有核心逻辑、图形渲染和用户界面都是用Java Swing...

    java文字RPG小游戏

    Java编程语言是开发“java文字RPG小游戏”的基础工具,这是一种基于文本的角色扮演游戏,玩家通过输入指令来控制角色行动,探索虚拟世界,与各种怪物战斗,例如描述中的哥布林。在这样的游戏中,核心功能包括游戏...

    基于java语言的RPG游戏源代码+说明书

    《基于Java语言的RPG游戏源代码解析及开发指南》 在编程世界中,Java以其跨平台、面向对象和高效性等特性,成为了许多开发者首选的编程语言之一。特别是对于游戏开发,Java也有着广泛的应用,例如我们今天要讨论的...

    javaRPG游戏.zip

    Java RPG游戏是一款基于Java编程语言开发的角色扮演游戏。Java作为一种跨平台的编程语言,因其高效、稳定和可移植性,常被用于开发各种类型的游戏,包括RPG(角色扮演游戏)。RPG游戏通常包含丰富的剧情、角色养成、...

    unity 3D多人在线RPG网络游戏源码.rar

    unity 3D多人在线RPG网络游戏源码.rarunity 3D多人在线RPG网络游戏源码.rarunity 3D多人在线RPG网络游戏源码.rarunity 3D多人在线RPG网络游戏源码.rarunity 3D多人在线RPG网络游戏源码.rarunity 3D多人在线RPG网络...

    JavaRPG-游戏

    《JavaRPG-游戏》是一款基于Java编程语言开发的角色扮演游戏,体现了Java在游戏开发领域的应用。游戏虽然简单,但包含了游戏设计的基本要素,如角色、环境、交互等,展现了Java在构建复杂逻辑和实时交互系统方面的...

    JavaRPG游戏-地图编辑器

    "JavaRPG游戏-地图编辑器"正是这样一个专为Java RPG游戏设计的地图编辑软件。 该编辑器的主要功能可能包括以下几点: 1. **图形化界面**:地图编辑器通常配备了一个用户友好的图形界面,使得开发者可以通过拖拽、...

    Unity 3D的Ultimate MMO RPG Kit 在线 mmo rpg 游戏开发.zip

    "Ultimate MMO RPG Kit" 是一个专为开发在线MMO RPG游戏设计的工具包,它包含了各种预设、脚本、系统和资源,旨在帮助开发者快速构建大规模多人在线的角色扮演游戏。 该工具包的核心知识点包括: 1. **网络同步**...

    RPG游戏实例.rar

    在这个名为“RPG游戏实例.rar”的压缩包中,包含了C++编程语言开发的一款角色扮演游戏(Role-Playing Game,简称RPG)的源代码。RPG游戏是一种深受玩家喜爱的游戏类型,通常包含丰富的剧情、角色发展和策略元素。...

    java写的RPG小游戏

    Java编写的RPG小游戏是一款基于Java编程语言开发的角色扮演游戏(Role-Playing Game,简称RPG)。这类游戏通常包含丰富的故事情节、角色设定、任务系统和战斗机制,为玩家提供沉浸式的游戏体验。在Java环境下,...

    jianhun.rar_Java游戏_RPG_java rpg_jianhun_rpg游戏

    这款"jianhun.rar"是一个Java游戏的实例,特别是一款角色扮演游戏(RPG)。 【RPG】 RPG,全称Role-Playing Game,即角色扮演游戏。玩家在游戏中扮演一个或多个角色,通过与游戏世界的互动,推进故事发展,完成任务...

Global site tag (gtag.js) - Google Analytics