小游戲地圖一般都是各種圖片的拼接,然后保存到2維數(shù)組里面
我們提供的服務(wù)有:網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、耀州ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學管理、有技術(shù)的耀州網(wǎng)站制作公司
比如
//數(shù)值常量
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;//雪地
//對應(yīng)的圖片
.....
public?static?final?Image?IMG_STONE=new?ImageIcon(MapValues.class.getResource("/resource/imgs/stone.png")).getImage();//石頭圖片
......
那么保存一副地圖就可以用類似于下面的二維數(shù)組表示
002405100
145111123
132131001
使用的時候, 加載二維數(shù)組,然后把對應(yīng)的圖片顯示在地圖上就可以了.
不過這樣做也存在一定的問題.
1:圖片太多,對應(yīng)的數(shù)字太多, 那么地圖編輯起來很麻煩, 需要有強大的記憶力,和想象力
2:不能一邊編輯,一邊就顯示出效果來, 出錯后,排查麻煩. 效率太低
所以,我們還需要寫點代碼,做一個簡單的地圖編輯器,添加輔助線,擦除工具等, 這樣的話, 編輯地圖就非常方便了,所見即所得.并且一鍵可以保存為地圖數(shù)據(jù)(二維數(shù)組)
學習swing的時候,寫過一個簡單的地圖編輯器,效果圖如下
為了熟悉不同的圖形界面API, 游戲界面使用的不是swing,而是JavaFX
用java寫一個地圖編輯器
記得媒體在采訪c++之父的時候,他說作為程序員,要相信自己能夠解決已經(jīng)理解的任何事情.
換句話說:您可以解決任何問題,只要想得明白
現(xiàn)實問題:開發(fā)一個基于地磚的二維游戲的地圖編輯器,要求生成兩個binary文件,各包含一個二維數(shù)組,*.map存放地磚,花花草草什么的.*.item放道具,比如某個點可能會觸發(fā)一個事件.很簡單,隨便寫.看到這里您已經(jīng)大致明白程序的整體結(jié)構(gòu).
計算機語言:java.
要理解事件必須分析
初步來看,地圖編輯器:生成某種形式的若干數(shù)組,無論是哪種形式的數(shù)組,你的目的:
生成數(shù)組.地圖是實際是一個(x,y)的二維坐標系,這很容易讓人聯(lián)系到:亦無論
我準備把設(shè)置兩個程序界面(主界面/map界面),java的布局管理器不好擺弄,不如分開兩個class,主界面用jbuilder自動創(chuàng)建的application模塊(帶菜單).map界面自己寫,也是jframe,類之間相互傳遞消息,map界面將在程序開始時被初始化,也可以在程序從主界面中初始化(有問題)
構(gòu)建程序
以下內(nèi)容為程序代碼:
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:自己寫的一個類
以下內(nèi)容為程序代碼:
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:
以下內(nèi)容為程序代碼:
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單獨寫好改,什么時候內(nèi)容改變了,很容易改,硬要合寫沒有也隨便.
下面就是事件了
有兩個事件要處理,第一個是按鈕事件,第二個菜單事件
按鈕事件我套用這樣的結(jié)構(gòu)
以下內(nèi)容為程序代碼:
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
以下內(nèi)容為程序代碼:
public void *_actionperformed(actionevent e) {...}
用兩個中間值從主界面向map界面?zhèn)鬟f按了什么:
這里是map界面中的按鈕的事件處理程序
以下內(nèi)容為程序代碼:
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
以下內(nèi)容為程序代碼:
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];
}
}
地圖擁用個二維數(shù)組,A,B的邏輯分別判斷,Aif(i(數(shù)組高度)= 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的,我們用漢字對它進行描述:
石頭 空白 雪地
空白 磚墻 空白
水面 空白 草地
這像什么? 像不像二維數(shù)組.! 所以我們可以使用二維數(shù)組來存儲一副地圖.
當然了使用漢字來描述地圖, 還是太麻煩...
我們使用數(shù)字來存儲更好.把數(shù)字和對應(yīng)的圖片做好一一對應(yīng)的關(guān)系.比如0代表空白 1代表石頭 ... 繪制地圖的時候,循環(huán)二維數(shù)組,如果是1就在此處畫石頭,循環(huán)到0就什么也不畫直接跳過..
拓展,如果還想有稍微立體點的效果, 就是比如有薄霧什么的, 那么你可以建立另外一個天氣圖層的二維數(shù)組, 這個數(shù)組就是繪制薄霧等天氣的, 這個要最后繪制, 這樣才能起到薄霧對下面地圖的遮擋..
編輯地圖的時候 ,先點擊一個圖片,表示等下需要繪制的圖片是哪一個.然后在編輯地圖的時候按下鼠標代表開始開始繪制, 然后鼠標拖動到哪里就繪制到哪里, 最后松開鼠標松開, 完成繪制
地圖的保存: 二維數(shù)組可以直接把每個元素寫入到文本文件里, 當然了也可以直接把整個二維數(shù)組對象都寫入到文件里,使用的時候,直接讀取還原即可
大思路挺簡單的。就是處理圖片,在數(shù)據(jù)庫中存放一張大圖(完整的大地圖)。根據(jù)頁面請求,在服務(wù)端用Java處理后,向客戶端發(fā)送不同的大圖部分。
你說不用API,這是不可能的,你寫System.out.println("");就是在用API。只不過是Java標準配置,用起來方便。我想你的意思是不用第三方類庫(如GoogleAPI)吧。