用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");
baseimages[1] = new ImageIcon(MapPic.class.getResource("m2.png");
baseimages[2] = new ImageIcon(MapPic.class.getResource("m3.png");
baseimages[3] = new ImageIcon(MapPic.class.getResource("m4.png");
baseimages[4] = new ImageIcon(MapPic.class.getResource("m5.png");
baseimages[5] = new ImageIcon(MapPic.class.getResource("m6.png");
baseimages[6] = new ImageIcon(MapPic.class.getResource("m7.png");
baseimages[7] = new ImageIcon(MapPic.class.getResource("m8.png");
baseimages[8] = new ImageIcon(MapPic.class.getResource("m9.png");
itemimages = new ImageIcon[3];
itemimages[0] = new ImageIcon(MapPic.class.getResource("error.png");
itemimages[1] = new ImageIcon(MapPic.class.getResource("i1.png");
itemimages[2] = new ImageIcon(MapPic.class.getResource("i2.png");
}
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!";
}
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!";
} 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");
DataOutputStream itembinaryfile = new DataOutputStream(
new FileOutputStream(MapEditor.filename + "item");
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";
}
}
结束!
就这么简单!但是问题很多很多.都不能叫程序,随便写的玩的哦
需要源代码的朋友请留下email,要指出bug哦
亦或者msn交流:chinuxmanhotmail.com
用Java写一个地图编辑器
80酷酷网 80kuku.com