博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Javascript开发《三国志曹操传》-零部件开发(四)-用地图块拼成大地图
阅读量:5741 次
发布时间:2019-06-18

本文共 13614 字,大约阅读时间需要 45 分钟。

小时候我们玩过拼图游戏,是用自己的手去拼的。今天我们来研究研究用javascript来拼图。同样是拼图,但用js拼图要比用手拼图麻烦多了,因此以后我要把它优化成引擎。

 

一、前言

以上是一段导语,话不扯远,对《三国志曹操传》熟悉的玩家知道,《三国志曹操传》的地图是由小地图块拼成的,那要实现它就和导语说得一样:很麻烦。不过即使麻烦也是一门技术,因此在此分享给大家,希望大家喜欢。

前几章的位置:

用Javascript开发《三国志曹操传》-零部件开发(三)-人物对话中,仿打字机输出文字

用Javascript开发《三国志曹操传》-零部件开发(二)-让目标人物移动

用Javascript开发《三国志曹操传》-零部件开发(一)-让静态人物动起来

 

二、代码讲解

今天我要换换讲解方式,先不给代码,我们先来想想原理。现在,假如你有一幅图片,把它裁开成若干份,并打乱。现在如果让你用js把他们组织起来,如何做呢?先不说图的顺序,首先来看把它们弄在一起就很难了。这时我减少难度,给你几个选择:

A.用margin慢慢调        B.用数组把它们排列好        C.放弃

在这道题中,选A是很不明智的,选C就代表你也拿不定主意。看来选B是最好的。既然都告诉大家用数组,那就先上代码吧。免得消磨大家兴致。

js代码:

1 /*  2  *Prompt:  3  *If you want to add hurdle, find string: "{
{Add hurdle above." and "{
{After add hurdle, add the hurdle to the vector above." please. 4 *If you want to add or change type of grid, find string: "{
{Add new grid above.". 5 *If you want to change position of map, please find string: "{
{Change map margin above.". 6 *If the icon of crid is changed, you have to change the size of icon. Find "{
{Change icon size above." to change size. 7 */ 8 9 //Map of hurdle or military or resource. 10 var vView = []; 11 12 /*Remarks: 13 *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 14 *r: research Center *P: port *D: dock *s: Shipyard 15 */ 16 var mScene = { 17 'L': ['./land.png', '陆地'] 18 , 'S': ['./sea.png', '河流'] 19 , 'T': ['./tree.png', '树木'] 20 , 'B': ['./bridge.png', '桥'] 21 , 'C': ['./beach.png', '沙滩'] 22 }; 23 //{
{Add new grid above. 24 25 var mCurrent = { 26 Margin: { 27 left: -1 28 , top: -1 29 , right: -1 30 , bottom: -1 31 } 32 , Position: { 33 X: -1 34 , Y: -1 35 } 36 , Type: 'NONE' 37 38 }; 39 var mTitle = {}; 40 41 var sHurdleONE = 42 'S,S,S,S,S,S,S,S,S,S,S' 43 + ';T,L,T,T,T,T,S,S,S,S,T' 44 + ';T,L,L,T,S,S,S,S,S,L,T' 45 + ';T,L,L,L,C,C,C,S,S,T,S' 46 + ';T,L,L,L,C,C,C,B,B,L,T' 47 + ';T,L,L,C,C,C,C,S,S,L,T' 48 + ';T,L,L,C,C,T,S,S,L,L,T' 49 ; 50 //{
{Add hurdle above. 51 52 var vHurdles = [sHurdleONE]; 53 //{
{After add hurdle, add the hurdle to the vector above. 54 55 function _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin) 56 { 57 var mCoordMember = { 58 left: nWidthBasic 59 , top: nHeightBasic 60 , right: nWidthBasic + nPicWidth 61 , bottom: nHeightBasic + nPicHeight 62 }; 63 var mPositionMember = { 64 X: (mCoordMember.left - mMargin.x) / nPicWidth 65 , Y: (mCoordMember.top - mMargin.y) / nPicHeight 66 }; 67 var mItem = { 68 Coord: mCoordMember 69 , Position: mPositionMember 70 , Type: cType 71 }; 72 73 return mItem; 74 } 75 76 function _loadHurdle(sHurdle) 77 { 78 var nBasic = 0; 79 var nWidthBasic = nBasic; //margin-left. 80 var nHeightBasic = 0; //margin-top. 81 82 //{
{Change map margin above. 83 84 var nPicWidth = 45; //Picture width is nBasic. 85 var nPicHeight = 45; //Picturn height is nHeightBasic. 86 //{
{Change icon size above. 87 88 var nSub; 89 var nRow; 90 var nCol; 91 92 var v = sHurdle.split(';'); 93 var vRec = []; 94 95 for(nSub = 0; nSub < v.length; nSub++){ 96 var vCrid = v[nSub].split(','); 97 vRec[vRec.length] = vCrid; 98 } 99 100 for(nRow = 0; nRow < vRec.length; nRow++){101 var vCol = vRec[nRow];102 103 for(nCol = 0; nCol < vCol.length; nCol++){104 var cType = vCol[nCol];105 var mMargin = {x: nBasic, y: nBasic};106 107 vView[vView.length] = _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin);108 109 nWidthBasic += nPicWidth;110 }111 112 nHeightBasic += nPicHeight;113 nWidthBasic = nBasic;114 }115 }116 117 118 119 //Show map with vector 'vView'.120 function _showMap(sID)121 {122 var xDiv=document.getElementById(sID);123 124 var xGrid;125 var xImg;126 127 128 var nTop = 0;129 130 var nSub;131 var sIdPrefix = 'ID_IMG_NUM_';132 var sIdGrid = 'ID_A_NUM_';133 for(nSub = 0; nSub < vView.length; nSub++){134 var mGrid = vView[nSub];135 136 if(mGrid){137 var xMargin = mGrid.Coord;138 var cType = mGrid.Type;139 var xProper = mScene[cType];140 141 if(xProper){142 xGrid = document.createElement('a');143 xImg = document.createElement('img');144 145 xImg.style.position = 'absolute';146 xImg.style.marginLeft = xMargin.left;147 xImg.style.marginTop = xMargin.top;148 149 xImg.src = xProper[0];150 151 xImg.style.border = '0px solid #000000';152 xImg.id = sIdPrefix + nSub;153 154 xImg.style.width = 45;155 xImg.style.height = 45;156 157 xImg.style.display = 'block';158 159 xGrid.onclick = function(e){160 var xCurrentGrid = e.target;161 var sId = xCurrentGrid.id;162 var nIdAsSub = parseInt(sId.substring(sIdPrefix.length, sId.length));163 164 mCurrent = vView[nIdAsSub];165 if(!mCurrent){166 alert("Error 0004.");167 }168 };169 xGrid.title = xProper[1] + '(' + parseInt(mGrid.Position.X) + ', ' + parseInt(mGrid.Position.Y+2) + ')';170 xGrid.id = sIdGrid + nSub;171 172 xGrid.appendChild(xImg);173 174 xDiv.appendChild(xGrid);175 }else{176 alert("Error: 0003.");177 }178 }else{179 alert("Error: 0002.");180 }181 }182 }183 184 //Show map of hurdle.185 function _showHurdle(nHurdle)186 {187 if(vHurdles[nHurdle - 1]){188 _loadHurdle(vHurdles[nHurdle - 1]);189 _showMap('ID_DIV_BATTLEFIELD');190 }else{191 alert("Error: 0001.");192 }193 }194 195

看看,这点程序就用了195行,而且这还是一张地图,看来还很有点麻烦哦。没关系,慢慢解释。

首先还是把素材放在这里,当然也可以去我的相册下载下来。

tree.png land.png sea.png bridge.png beach.png

素材不是来自《三国志曹操传》,因为没整理好《三国志曹操传》的地图素材,所以就随便找了些。不过也照样可以用。希望大家不要介意。

 

麻烦的代码最容易弄得乱七八糟,因此在此时要良好的区分开样式设置和拼图核心。

拼图核心在哪里呢???在这里:

1 var mScene = { 2                 'L': ['./land.png', '陆地'] 3                 , 'S': ['./sea.png', '河流'] 4                 , 'T': ['./tree.png', '树木'] 5                 , 'B': ['./bridge.png', '桥'] 6                 , 'C': ['./beach.png', '沙滩'] 7             }; 8 //{
{Add new grid above. 9 10 var mCurrent = {11 Margin: {12 left: -113 , top: -114 , right: -115 , bottom: -116 }17 , Position: {18 X: -119 , Y: -120 }21 , Type: 'NONE'22 23 };24 var mTitle = {};25 26 var sHurdleONE = 27 'S,S,S,S,S,S,S,S,S,S,S'28 + ';T,L,T,T,T,T,S,S,S,S,T'29 + ';T,L,L,T,S,S,S,S,S,L,T'30 + ';T,L,L,L,C,C,C,S,S,T,S'31 + ';T,L,L,L,C,C,C,B,B,L,T'32 + ';T,L,L,C,C,C,C,S,S,L,T'33 + ';T,L,L,C,C,T,S,S,L,L,T'34 ;35 //{
{Add hurdle above.36 37 var vHurdles = [sHurdleONE];38 //{
{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的,所以也不解释了。关键是在下:

1 var sHurdleONE = 2         'S,S,S,S,S,S,S,S,S,S,S'3         + ';T,L,T,T,T,T,S,S,S,S,T'4         + ';T,L,L,T,S,S,S,S,S,L,T'5         + ';T,L,L,L,C,C,C,S,S,T,S'6         + ';T,L,L,L,C,C,C,B,B,L,T'7         + ';T,L,L,C,C,C,C,S,S,L,T'8         + ';T,L,L,C,C,T,S,S,L,L,T'9         ;

这段代码就是把定义好的S,T,B,C,L连在一起的核心。后面只用定义S,T,B,C,L的宽度高度定义就能把它们连成一块。并且只要把它们在数组里的位置调一调就能改变样式。

接下来为了能切换地图,我们把第一张地图放进了数组:

1 var vHurdles = [sHurdleONE];2 //{
{After add hurdle, add the hurdle to the vector above.

如果以后加了地图,只用把地图所属的数组名加到vHurdles数组就可以了,调用是就可以直接写对应下标。

样式设置在下:

1 function _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin)  2 {  3     var mCoordMember = {  4                             left: nWidthBasic  5                             , top: nHeightBasic  6                             , right: nWidthBasic + nPicWidth  7                             , bottom: nHeightBasic + nPicHeight  8                         };  9     var mPositionMember = { 10                             X: (mCoordMember.left - mMargin.x) / nPicWidth 11                             , Y: (mCoordMember.top - mMargin.y) / nPicHeight 12                         }; 13     var mItem = { 14                     Coord: mCoordMember 15                     , Position: mPositionMember 16                     , Type: cType 17                 }; 18  19     return mItem; 20 } 21  22 function _loadHurdle(sHurdle) 23 { 24     var nBasic = 0; 25     var nWidthBasic = nBasic;            //margin-left. 26     var nHeightBasic = 0;                //margin-top. 27      28     //{
{Change map margin above. 29 30 var nPicWidth = 45; //Picture width is nBasic. 31 var nPicHeight = 45; //Picturn height is nHeightBasic. 32 //{
{Change icon size above. 33 34 var nSub; 35 var nRow; 36 var nCol; 37 38 var v = sHurdle.split(';'); 39 var vRec = []; 40 41 for(nSub = 0; nSub < v.length; nSub++){ 42 var vCrid = v[nSub].split(','); 43 vRec[vRec.length] = vCrid; 44 } 45 46 for(nRow = 0; nRow < vRec.length; nRow++){ 47 var vCol = vRec[nRow]; 48 49 for(nCol = 0; nCol < vCol.length; nCol++){ 50 var cType = vCol[nCol]; 51 var mMargin = {x: nBasic, y: nBasic}; 52 53 vView[vView.length] = _createGrid(nWidthBasic, nHeightBasic, nPicWidth, nPicHeight, cType, mMargin); 54 55 nWidthBasic += nPicWidth; 56 } 57 58 nHeightBasic += nPicHeight; 59 nWidthBasic = nBasic; 60 } 61 } 62 63 64 65 //Show map with vector 'vView'. 66 function _showMap(sID) 67 { 68 var xDiv=document.getElementById(sID); 69 70 var xGrid; 71 var xImg; 72 73 74 var nTop = 0; 75 76 var nSub; 77 var sIdPrefix = 'ID_IMG_NUM_'; 78 var sIdGrid = 'ID_A_NUM_'; 79 for(nSub = 0; nSub < vView.length; nSub++){ 80 var mGrid = vView[nSub]; 81 82 if(mGrid){ 83 var xMargin = mGrid.Coord; 84 var cType = mGrid.Type; 85 var xProper = mScene[cType]; 86 87 if(xProper){ 88 xGrid = document.createElement('a'); 89 xImg = document.createElement('img'); 90 91 xImg.style.position = 'absolute'; 92 xImg.style.marginLeft = xMargin.left; 93 xImg.style.marginTop = xMargin.top; 94 95 xImg.src = xProper[0]; 96 97 xImg.style.border = '0px solid #000000'; 98 xImg.id = sIdPrefix + nSub; 99 100 xImg.style.width = 45;101 xImg.style.height = 45;102 103 xImg.style.display = 'block';104 105 xGrid.onclick = function(e){106 var xCurrentGrid = e.target;107 var sId = xCurrentGrid.id;108 var nIdAsSub = parseInt(sId.substring(sIdPrefix.length, sId.length));109 110 mCurrent = vView[nIdAsSub];111 if(!mCurrent){112 alert("Error 0004.");113 }114 };115 xGrid.title = xProper[1] + '(' + parseInt(mGrid.Position.X) + ', ' + parseInt(mGrid.Position.Y+2) + ')';116 xGrid.id = sIdGrid + nSub;117 118 xGrid.appendChild(xImg);119 120 xDiv.appendChild(xGrid);121 }else{122 alert("Error: 0003.");123 }124 }else{125 alert("Error: 0002.");126 }127 }128 }

以上的代码很简单,自己可以看看,提示一下:当你在自己开发的过程中如果弹出一个Error: 0002, Error: 0003, Error: 0001什么之类的,就代表出了错,需要马上去检查。这是为了在麻烦的程序开发中有一点提醒而设计的。值得注意的是:这里的图片全是createElement弄出来的,所以请不要猜疑html代码里有什么蹊跷。

接着看:

1 function _showHurdle(nHurdle)2 {3     if(vHurdles[nHurdle - 1]){4         _loadHurdle(vHurdles[nHurdle - 1]);5         _showMap('ID_DIV_BATTLEFIELD');6     }else{7         alert("Error: 0001.");8     }9 }

这是在你要弄出地图的调用函数,当你在html代码里写上:<body οnlοad="_showHurdle(nHurdle)">几可以把拼的图一下子画出来。nHurdle就是地图在数组vHurdles里的对应下标,最低是1,而不是0,也就是说要用第一张地图,那nHurdle就该赋值为1,调用是写为:<body οnlοad="_showHurdle(1)">。

源代码下载:

 

三、演示效果

演示图在下:

由于是静态的,所以就不给demo了。这种方法虽然很麻烦,而且地图块多了就很慢,但是毕竟是种技术,如果大家有什么好的方法也可以来告诉我。

 

希望大家多支持。谢谢。

转载于:https://www.cnblogs.com/ducle/archive/2012/09/23/2699066.html

你可能感兴趣的文章
JDBC--使用DatabaseMetaData获取数据库信息
查看>>
makefile(三)使用命令
查看>>
AC AP
查看>>
[日推荐] 『忆年共享相册』-照片鉴证一起走过的哪些年
查看>>
Tomcat Session 共享 方法
查看>>
从零开始写一个武侠冒险游戏-6-用GPU提升性能(3)
查看>>
2015年工作总结
查看>>
在64位win7上安装visual studio 6.0
查看>>
Smart 2.0 开发指南
查看>>
»Spring 之AOP AspectJ切入点语法详解(最全了,不需要再去其他地找了)
查看>>
有感于DELL官网的修正速度和服务态度
查看>>
金三银四铜五铁六,面试得做好这个准备
查看>>
算法之【插入排序法】
查看>>
为UILabel 添加圆角背景(转)
查看>>
Android修改和添加APN网络
查看>>
Android App监听软键盘按键的三种方式
查看>>
优化导入数据到MariaDB、Mysql(InnoDB)的速度
查看>>
脸皮!哈,要它做什么!
查看>>
每天40分钟家务
查看>>
Linux基础 -- 帮助命令
查看>>