一、前言
以上是一段导语,话不扯远,对《三国志曹操传》熟悉的玩家知道,《三国志曹操传》的地图是由小地图块拼成的,那要实现它就和导语说得一样:很麻烦。不过即使麻烦也是一门技术,因此在此分享给大家,希望大家喜欢。
二、代码讲解
今天我要换换讲解方式,先不给代码,我们先来想想原理。现在,假如你有一幅图片,把它裁开成若干份,并打乱。现在如果让你用js把他们组织起来,如何做呢?先不说图的顺序,首先来看把它们弄在一起就很难了。这时我减少难度,给你几个选择:A.用margin慢慢调 B.用数组把它们排列好 C.放弃
在这道题中,选A是很不明智的,选C就代表你也拿不定主意。看来选B是最好的。既然都告诉大家用数组,那就先上代码吧。免得消磨大家兴致。
js代码:
复制代码 代码如下:
/* 
*Prompt: 
*If you want to add hurdle, find string: "{{Add hurdle above." and "{{After add hurdle, add the hurdle to the vector above." please. 
*If you want to add or change type of grid, find string: "{{Add new grid above.". 
*If you want to change position of map, please find string: "{{Change map margin above.". 
*If the icon of crid is changed, you have to change the size of icon. Find "{{Change icon size above." to change size. 
*/ 
//Map of hurdle or military or resource. 
var vView = []; 
/*Remarks: 
*L: land *S: sea *R: river *W: swamp *A: lawn *B: bridge *H: house *h: hospital *w: warehouse *b: bourse *M: military academy *m: military factories 
*r: research Center *P: port *D: dock *s: Shipyard 
*/ 
var mScene = { 
'L': ['./land.png', '陆地'] 
, 'S': ['./sea.png', '河流'] 
, 'T': ['./tree.png', '树木'] 
, 'B': ['./bridge.png', '桥'] 
, 'C': ['./beach.png', '沙滩'] 
}; 
//{{Add new grid above. 
var mCurrent = { 
Margin: { 
left: -1 
, top: -1 
, right: -1 
, bottom: -1 
} 
, Position: { 
X: -1 
, Y: -1 
} 
, Type: 'NONE' 
}; 
var mTitle = {}; 
var sHurdleONE = 
'S,S,S,S,S,S,S,S,S,S,S' 
+ ';T,L,T,T,T,T,S,S,S,S,T' 
+ ';T,L,L,T,S,S,S,S,S,L,T' 
+ ';T,L,L,L,C,C,C,S,S,T,S' 
+ ';T,L,L,L,C,C,C,B,B,L,T' 
+ ';T,L,L,C,C,C,C,S,S,L,T' 
+ ';T,L,L,C,C,T,S,S,L,L,T' 
//{{Add hurdle above. 
var vHurdles = [sHurdleONE]; 
//{{After add hurdle, add the hurdle to the vector above. 
function _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin) 
{ 
var mCoordMember = { 
left: nWidthBasic 
, top: nHeightBasic 
, right: nWidthBasic + nPicWidth 
, bottom: nHeightBasic + nPicHeight 
}; 
var mPositionMember = { 
X: (mCoordMember.left - mMargin.x) / nPicWidth 
, Y: (mCoordMember.top - mMargin.y) / nPicHeight 
}; 
var mItem = { 
Coord: mCoordMember 
, Position: mPositionMember 
, Type: cType 
}; 
return mItem; 
} 
function _loadHurdle(sHurdle) 
{ 
var nBasic = 0; 
var nWidthBasic = nBasic; //margin-left. 
var nHeightBasic = 0; //margin-top. 
//{{Change map margin above. 
var nPicWidth = 45; //Picture width is nBasic. 
var nPicHeight = 45; //Picturn height is nHeightBasic. 
//{{Change icon size above. 
var nSub; 
var nRow; 
var nCol; 
var v = sHurdle.split(';'); 
var vRec = []; 
for(nSub = 0; nSub < v.length; nSub++){ 
var vCrid = v[nSub].split(','); 
vRec[vRec.length] = vCrid; 
} 
for(nRow = 0; nRow < vRec.length; nRow++){ 
var vCol = vRec[nRow]; 
for(nCol = 0; nCol < vCol.length; nCol++){ 
var cType = vCol[nCol]; 
var mMargin = {x: nBasic, y: nBasic}; 
vView[vView.length] = _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin); 
nWidthBasic += nPicWidth; 
} 
nHeightBasic += nPicHeight; 
nWidthBasic = nBasic; 
} 
} 
//Show map with vector 'vView'. 
function _showMap(sID) 
{ 
var xDiv=document.getElementById(sID); 
var xGrid; 
var xImg; 
var nTop = 0; 
var nSub; 
var sIdPrefix = 'ID_IMG_NUM_'; 
var sIdGrid = 'ID_A_NUM_'; 
for(nSub = 0; nSub < vView.length; nSub++){ 
var mGrid = vView[nSub]; 
if(mGrid){ 
var xMargin = mGrid.Coord; 
var cType = mGrid.Type; 
var xProper = mScene[cType]; 
if(xProper){ 
xGrid = document.createElement('a'); 
xImg = document.createElement('img'); 
xImg.style.position = 'absolute'; 
xImg.style.marginLeft = xMargin.left; 
xImg.style.marginTop = xMargin.top; 
xImg.src = xProper[0]; 
xImg.style.border = '0px solid #000000'; 
xImg.id = sIdPrefix + nSub; 
xImg.style.width = 45; 
xImg.style.height = 45; 
xImg.style.display = 'block'; 
xGrid.onclick = function(e){ 
var xCurrentGrid = e.target; 
var sId = xCurrentGrid.id; 
var nIdAsSub = parseInt(sId.substring(sIdPrefix.length, sId.length)); 
mCurrent = vView[nIdAsSub]; 
if(!mCurrent){ 
alert("Error 0004."); 
} 
}; 
xGrid.title = xProper[1] + '(' + parseInt(mGrid.Position.X) + ', ' + parseInt(mGrid.Position.Y+2) + ')'; 
xGrid.id = sIdGrid + nSub; 
xGrid.appendChild(xImg); 
xDiv.appendChild(xGrid); 
}else{ 
alert("Error: 0003."); 
} 
}else{ 
alert("Error: 0002."); 
} 
} 
} 
//Show map of hurdle. 
function _showHurdle(nHurdle) 
{ 
if(vHurdles[nHurdle - 1]){ 
_loadHurdle(vHurdles[nHurdle - 1]); 
_showMap('ID_DIV_BATTLEFIELD'); 
}else{ 
alert("Error: 0001."); 
} 
}
看看,这点程序就用了195行,而且这还是一张地图,看来还很有点麻烦哦。没关系,慢慢解释。
首先还是把素材放在这里:





素材不是来自《三国志曹操传》,因为没整理好《三国志曹操传》的地图素材,所以就随便找了些。不过也照样可以用。希望大家不要介意。
麻烦的代码最容易弄得乱七八糟,因此在此时要良好的区分开样式设置和拼图核心。
拼图核心在哪里呢?在这里:
复制代码 代码如下:
var mScene = { 
'L': ['./land.png', '陆地'] 
, 'S': ['./sea.png', '河流'] 
, 'T': ['./tree.png', '树木'] 
, 'B': ['./bridge.png', '桥'] 
, 'C': ['./beach.png', '沙滩'] 
}; 
//{{Add new grid above. 
var mCurrent = { 
Margin: { 
left: -1 
, top: -1 
, right: -1 
, bottom: -1 
} 
, Position: { 
X: -1 
, Y: -1 
} 
, Type: 'NONE' 
}; 
var mTitle = {}; 
var sHurdleONE = 
'S,S,S,S,S,S,S,S,S,S,S' 
+ ';T,L,T,T,T,T,S,S,S,S,T' 
+ ';T,L,L,T,S,S,S,S,S,L,T' 
+ ';T,L,L,L,C,C,C,S,S,T,S' 
+ ';T,L,L,L,C,C,C,B,B,L,T' 
+ ';T,L,L,C,C,C,C,S,S,L,T' 
+ ';T,L,L,C,C,T,S,S,L,L,T' 
//{{Add hurdle above. 
var vHurdles = [sHurdleONE]; 
//{{After add hurdle, add the hurdle to the vector above.
首先我把S,T,B,C,L定义好,使S代表河流,T代表树木,B代表桥,C代表沙滩,L代表陆地。var mCurrent后面有用,暂不解释。然后是var mTitle,这个专门是用来显示title的,所以也不解释了。关键是在下: 
复制代码 代码如下:
var sHurdleONE = 
'S,S,S,S,S,S,S,S,S,S,S' 
+ ';T,L,T,T,T,T,S,S,S,S,T' 
+ ';T,L,L,T,S,S,S,S,S,L,T' 
+ ';T,L,L,L,C,C,C,S,S,T,S' 
+ ';T,L,L,L,C,C,C,B,B,L,T' 
+ ';T,L,L,C,C,C,C,S,S,L,T' 
+ ';T,L,L,C,C,T,S,S,L,L,T' 
这段代码就是把定义好的S,T,B,C,L连在一起的核心。后面只用定义S,T,B,C,L的宽度高度定义就能把它们连成一块。并且只要把它们在数组里的位置调一调就能改变样式。
接下来为了能切换地图,我们把第一张地图放进了数组: 
复制代码 代码如下:
var vHurdles = [sHurdleONE]; 
//{{After add hurdle, add the hurdle to the vector above.
如果以后加了地图,只用把地图所属的数组名加到vHurdles数组就可以了,调用是就可以直接写对应下标。
样式设置在下: 
复制代码 代码如下:
function _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin) 
{ 
var mCoordMember = { 
left: nWidthBasic 
, top: nHeightBasic 
, right: nWidthBasic + nPicWidth 
, bottom: nHeightBasic + nPicHeight 
}; 
var mPositionMember = { 
X: (mCoordMember.left - mMargin.x) / nPicWidth 
, Y: (mCoordMember.top - mMargin.y) / nPicHeight 
}; 
var mItem = { 
Coord: mCoordMember 
, Position: mPositionMember 
, Type: cType 
}; 
return mItem; 
} 
function _loadHurdle(sHurdle) 
{ 
var nBasic = 0; 
var nWidthBasic = nBasic; //margin-left. 
var nHeightBasic = 0; //margin-top. 
//{{Change map margin above. 
var nPicWidth = 45; //Picture width is nBasic. 
var nPicHeight = 45; //Picturn height is nHeightBasic. 
//{{Change icon size above. 
var nSub; 
var nRow; 
var nCol; 
var v = sHurdle.split(';'); 
var vRec = []; 
for(nSub = 0; nSub < v.length; nSub++){ 
var vCrid = v[nSub].split(','); 
vRec[vRec.length] = vCrid; 
} 
for(nRow = 0; nRow < vRec.length; nRow++){ 
var vCol = vRec[nRow]; 
for(nCol = 0; nCol < vCol.length; nCol++){ 
var cType = vCol[nCol]; 
var mMargin = {x: nBasic, y: nBasic}; 
vView[vView.length] = _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin); 
nWidthBasic += nPicWidth; 
} 
nHeightBasic += nPicHeight; 
nWidthBasic = nBasic; 
} 
} 
//Show map with vector 'vView'. 
function _showMap(sID) 
{ 
var xDiv=document.getElementById(sID); 
var xGrid; 
var xImg; 
var nTop = 0; 
var nSub; 
var sIdPrefix = 'ID_IMG_NUM_'; 
var sIdGrid = 'ID_A_NUM_'; 
for(nSub = 0; nSub < vView.length; nSub++){ 
var mGrid = vView[nSub]; 
if(mGrid){ 
var xMargin = mGrid.Coord; 
var cType = mGrid.Type; 
var xProper = mScene[cType]; 
if(xProper){ 
xGrid = document.createElement('a'); 
xImg = document.createElement('img'); 
xImg.style.position = 'absolute'; 
xImg.style.marginLeft = xMargin.left; 
xImg.style.marginTop = xMargin.top; 
xImg.src = xProper[0]; 
xImg.style.border = '0px solid #000000'; 
xImg.id = sIdPrefix + nSub; 
xImg.style.width = 45; 
xImg.style.height = 45; 
xImg.style.display = 'block'; 
xGrid.onclick = function(e){ 
var xCurrentGrid = e.target; 
var sId = xCurrentGrid.id; 
var nIdAsSub = parseInt(sId.substring(sIdPrefix.length, sId.length)); 
mCurrent = vView[nIdAsSub]; 
if(!mCurrent){ 
alert("Error 0004."); 
} 
}; 
xGrid.title = xProper[1] + '(' + parseInt(mGrid.Position.X) + ', ' + parseInt(mGrid.Position.Y+2) + ')'; 
xGrid.id = sIdGrid + nSub; 
xGrid.appendChild(xImg); 
xDiv.appendChild(xGrid); 
}else{ 
alert("Error: 0003."); 
} 
}else{ 
alert("Error: 0002."); 
} 
} 
}
以上的代码很简单,自己可以看看,提示一下:当你在自己开发的过程中如果弹出一个Error: 0002, Error: 0003, Error: 0001什么之类的,就代表出了错,需要马上去检查。这是为了在麻烦的程序开发中有一点提醒而设计的。值得注意的是:这里的图片全是createElement弄出来的,所以请不要猜疑html代码里有什么蹊跷。
接着看: 
复制代码 代码如下:
function _showHurdle(nHurdle) 
{ 
if(vHurdles[nHurdle - 1]){ 
_loadHurdle(vHurdles[nHurdle - 1]); 
_showMap('ID_DIV_BATTLEFIELD'); 
}else{ 
alert("Error: 0001."); 
} 
}
这是在你要弄出地图的调用函数,当你在html代码里写上:<body onload="_showHurdle(nHurdle)">几可以把拼的图一下子画出来。nHurdle就是地图在数组vHurdles里的对应下标,最低是1,而不是0,也就是说要用第一张地图,那nHurdle就该赋值为1,调用是写为:<body onload="_showHurdle(1)">。 
源代码下载
三、演示效果

由于是静态的,所以就不给demo了。这种方法虽然很麻烦,而且地图块多了就很慢,但是毕竟是种技术,如果大家有什么好的方法也可以来告诉我。
希望大家多支持。谢谢。
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
 - 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
 - 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
 - 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
 - 群星《2024好听新歌42》AI调整音效【WAV分轨】
 - 王思雨-《思念陪着鸿雁飞》WAV
 - 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
 - 李健《无时无刻》[WAV+CUE][590M]
 - 陈奕迅《酝酿》[WAV分轨][502M]
 - 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
 - 群星《吉他王(黑胶CD)》[WAV+CUE]
 - 齐秦《穿乐(穿越)》[WAV+CUE]
 - 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
 - 邝美云《邝美云精装歌集》[DSF][1.6G]
 - 吕方《爱一回伤一回》[WAV+CUE][454M]