扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
小游戏地图一般都是各种图片的拼接,然后保存到2维数组里面
我们提供的服务有:网站设计制作、成都网站设计、微信公众号开发、网站优化、网站认证、耀州ssl等。为上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的耀州网站制作公司
比如
//数值常量
public static final int EMPTY=0;//空地什么也没有
public static final int BRICK=1;//土墙
public static final int STONE=2;//石头
public static final int SEA=3;//海洋
public static final int GREENS=4;//草地
public static final int SNOW=5;//雪地
//对应的图片
.....
public static final Image IMG_STONE=new ImageIcon(MapValues.class.getResource("/resource/imgs/stone.png")).getImage();//石头图片
......
那么保存一副地图就可以用类似于下面的二维数组表示
002405100
145111123
132131001
使用的时候, 加载二维数组,然后把对应的图片显示在地图上就可以了.
不过这样做也存在一定的问题.
1:图片太多,对应的数字太多, 那么地图编辑起来很麻烦, 需要有强大的记忆力,和想象力
2:不能一边编辑,一边就显示出效果来, 出错后,排查麻烦. 效率太低
所以,我们还需要写点代码,做一个简单的地图编辑器,添加辅助线,擦除工具等, 这样的话, 编辑地图就非常方便了,所见即所得.并且一键可以保存为地图数据(二维数组)
学习swing的时候,写过一个简单的地图编辑器,效果图如下
为了熟悉不同的图形界面API, 游戏界面使用的不是swing,而是JavaFX
用java写一个地图编辑器
记得媒体在采访c++之父的时候,他说作为程序员,要相信自己能够解决已经理解的任何事情.
换句话说:您可以解决任何问题,只要想得明白
现实问题:开发一个基于地砖的二维游戏的地图编辑器,要求生成两个binary文件,各包含一个二维数组,*.map存放地砖,花花草草什么的.*.item放道具,比如某个点可能会触发一个事件.很简单,随便写.看到这里您已经大致明白程序的整体结构.
计算机语言:java.
要理解事件必须分析
初步来看,地图编辑器:生成某种形式的若干数组,无论是哪种形式的数组,你的目的:
生成数组.地图是实际是一个(x,y)的二维坐标系,这很容易让人联系到:亦无论
我准备把设置两个程序界面(主界面/map界面),java的布局管理器不好摆弄,不如分开两个class,主界面用jbuilder自动创建的application模块(带菜单).map界面自己写,也是jframe,类之间相互传递消息,map界面将在程序开始时被初始化,也可以在程序从主界面中初始化(有问题)
构建程序
以下内容为程序代码:
basepanel.setlayout(new gridlayout(5, 5));
for (byte i = 0; i 9; i++) {
basemapbutton[i] = new
((icon) pic.getimageicon(i, 0));
basemapbutton[i].setbuttontitle(i);
basemapbutton[i].addactionlistener(buttonlistener);
basepanel.add(basemapbutton[i]);
}
itempanel.setlayout(new gridlayout(5, 5));
for (byte i = 0; i 3; i++) {
itemmapbutton[i] = new mapbutton((icon) pic.getimageicon(i, 1));
itemmapbutton[i].setbuttontitle(i);
itemmapbutton[i].addactionlistener(buttonlistener1);
itempanel.add(itemmapbutton[i]);
}
tabbedpane.addtab("bases", basepanel);
tabbedpane.addtab("items", itempanel);
contentpane.add(tabbedpane, borderlayout.center);
有两个地方要解释:
mapbutton:自己写的一个类
以下内容为程序代码:
import javax.swing.icon;
import javax.swing.jbutton;
public class mapbutton extends jbutton {
public mapbutton() {
super();
}
public mapbutton(string arg0) {
super(arg0);
}
public mapbutton(action arg0) {
super(arg0);
}
public mapbutton(icon arg0) {
super(arg0);
}
public mapbutton(string arg0, icon arg1) {
super(arg0, arg1);
}
public byte width, height;
//public pic_w, pic_y;
public void setbuttontitle(byte w, byte h) {
width = w;
height = h;
}
public void setbuttontitle(byte w){
width =w;
}
public byte getbuttonwidth() {
return width;
}
public byte getbuttonheight() {
return height;
}
}
pic:自己写的mappic类的intance:
以下内容为程序代码:
package com.nenghe.mapeditor;
import javax.swing.imageicon;
public class mappic {
imageicon[] baseimages;
imageicon[] itemimages;
imageicon image1;
public mappic() {
init();
}
public void init() {
baseimages = new imageicon[9];
baseimages[0] = new imageicon(mappic.class.getresource("m1.png"/images/wink.gif[/img]);
baseimages[1] = new imageicon(mappic.class.getresource("m2.png"/images/wink.gif[/img]);
baseimages[2] = new imageicon(mappic.class.getresource("m3.png"/images/wink.gif[/img]);
baseimages[3] = new imageicon(mappic.class.getresource("m4.png"/images/wink.gif[/img]);
baseimages[4] = new imageicon(mappic.class.getresource("m5.png"/images/wink.gif[/img]);
baseimages[5] = new imageicon(mappic.class.getresource("m6.png"/images/wink.gif[/img]);
baseimages[6] = new imageicon(mappic.class.getresource("m7.png"/images/wink.gif[/img]);
baseimages[7] = new imageicon(mappic.class.getresource("m8.png"/images/wink.gif[/img]);
baseimages[8] = new imageicon(mappic.class.getresource("m9.png"/images/wink.gif[/img]);
itemimages = new imageicon[3];
itemimages[0] = new imageicon(mappic.class.getresource("error.png"/images/wink.gif[/img]);
itemimages[1] = new imageicon(mappic.class.getresource("i1.png"/images/wink.gif[/img]);
itemimages[2] = new imageicon(mappic.class.getresource("i2.png"/images/wink.gif[/img]);
}
public imageicon getimageicon(int x, int flags) {
if (flags == 0) {
return baseimages[x];
} else if (flags == 1) {
return itemimages[x];
}
return null;
}
}
写mapbutton在于处理事件的时候可以准确的获得按钮的坐标,忘了说了,map界面中我是用按钮代替地图方格的.这是很容易想到的,最笨也是最省力的办法
pic单独写好改,什么时候内容改变了,很容易改,硬要合写没有也随便.
下面就是事件了
有两个事件要处理,第一个是按钮事件,第二个菜单事件
按钮事件我套用这样的结构
以下内容为程序代码:
actionlistener buttonlistener = new actionlistener() {
public void actionperformed(actionevent e) {
//system.out.println(e.tostring());
mapbutton pressedbutton = (mapbutton) e.getsource();
mapdraw.temp_x = pressedbutton.getbuttonwidth();
mapdraw.temp_y = 0;
//system.out.println(mapdraw.temp_x+" "+mapdraw.temp_y);
}
};
....
basemapbutton[i].addactionlistener(buttonlistener);
jbuilder中把按钮事件事件单独生成一个类,我不明白,看不懂.真的很高深.
菜单事件模型jbuilder自己加的.overwrite
以下内容为程序代码:
public void *_actionperformed(actionevent e) {...}
用两个中间值从主界面向map界面传递按了什么:
这里是map界面中的按钮的事件处理程序
以下内容为程序代码:
actionlistener buttonlistener = new actionlistener() {
public void actionperformed(actionevent e) {
mapbutton pressedbutton = (mapbutton) e.getsource();
pressedwidth = pressedbutton.getbuttonwidth();
pressedheight = pressedbutton.getbuttonheight();
if (temp_y == 0) {
if (item[pressedwidth][pressedheight] != 0) {
item[pressedwidth][pressedheight] = 0;
jfm.showmessage("这里的道具已被置空!\nthe item has been null!"/images/wink.gif[/img];
}
map[pressedwidth][pressedheight] = temp_x;
pressedbutton.seticon((icon) pic.getimageicon(temp_x,
temp_y));
} else {
if (map[pressedwidth][pressedheight] == 0) {
jfm.showmessage("道具不能放在这!\nnot put item at this point!"/images/wink.gif[/img];
} else {
if (temp_x == 0) {
byte value = map[pressedwidth][pressedheight];
item[pressedwidth][pressedheight] = 0;
pressedbutton.seticon((icon) pic.getimageicon(
value, 0));
} else {
pressedbutton.seticon((icon) pic.getimageicon(
temp_x, temp_y));
item[pressedwidth][pressedheight] = temp_x;
}
}
}
}
};
请问两个中间值是什么呢?一目了然哦
最后是生成map
以下内容为程序代码:
public void createmap() throws ioexception {
try {
dataoutputstream mapbinaryfile = new dataoutputstream(
new fileoutputstream(mapeditor.filename + "map"/images/wink.gif[/img]);
dataoutputstream itembinaryfile = new dataoutputstream(
new fileoutputstream(mapeditor.filename + "item"/images/wink.gif[/img]);
mapbinaryfile.writebyte(width);
mapbinaryfile.writebyte(height);
for (byte i = 0; i height; i++)
for (byte j = 0; j width; j++) {
//system.out.println(i+" "+j);
byte mapvalue = map[i][j];
byte itemvalue = item[i][j];
if (mapvalue != 0) {
system.out.println(i+" "+j+" "+ mapvalue);
mapbinaryfile.writebyte(j);
mapbinaryfile.writebyte(i);
mapbinaryfile.writebyte(mapvalue);
}
if (itemvalue != 0) {
itembinaryfile.writebyte(j);//x
itembinaryfile.writebyte(i);//y
itembinaryfile.writebyte(itemvalue);
}
}
mapbinaryfile.close();
itembinaryfile.close();
} catch (eofexception e) {
system.err.println("error"/images/wink.gif[/img];
}
}
地图拥用个二维数组,A,B的逻辑分别判断,Aif(i(数组高度)= 0,j != 0 )(j--),if(j = 0,i = 0)(i ++),if(i != 0,j == 0)(j ++)if(i == 10, j == 10)(i --)B的逻辑与A反下,就可以了
地图编辑器思路如下:
这个小地图是3x3的,我们用汉字对它进行描述:
石头 空白 雪地
空白 砖墙 空白
水面 空白 草地
这像什么? 像不像二维数组.! 所以我们可以使用二维数组来存储一副地图.
当然了使用汉字来描述地图, 还是太麻烦...
我们使用数字来存储更好.把数字和对应的图片做好一一对应的关系.比如0代表空白 1代表石头 ... 绘制地图的时候,循环二维数组,如果是1就在此处画石头,循环到0就什么也不画直接跳过..
拓展,如果还想有稍微立体点的效果, 就是比如有薄雾什么的, 那么你可以建立另外一个天气图层的二维数组, 这个数组就是绘制薄雾等天气的, 这个要最后绘制, 这样才能起到薄雾对下面地图的遮挡..
编辑地图的时候 ,先点击一个图片,表示等下需要绘制的图片是哪一个.然后在编辑地图的时候按下鼠标代表开始开始绘制, 然后鼠标拖动到哪里就绘制到哪里, 最后松开鼠标松开, 完成绘制
地图的保存: 二维数组可以直接把每个元素写入到文本文件里, 当然了也可以直接把整个二维数组对象都写入到文件里,使用的时候,直接读取还原即可
大思路挺简单的。就是处理图片,在数据库中存放一张大图(完整的大地图)。根据页面请求,在服务端用Java处理后,向客户端发送不同的大图部分。
你说不用API,这是不可能的,你写System.out.println("");就是在用API。只不过是Java标准配置,用起来方便。我想你的意思是不用第三方类库(如GoogleAPI)吧。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流