- 浏览: 13102 次
- 性别:
- 来自: 成都
文章分类
最新评论
用Javascript开发《三国志曹操传》-开源讲座(四)-用地图块拼成大地图
小时候我们玩过拼图游戏,是用自己的手去拼的。今天我们来研究研究用javascript来拼图。同样是拼图,但用js拼图要比用手拼图麻烦多了,因此以后我要把它优化成引擎。
用Javascript开发《三国志曹操传》-开源讲座(二)-让目标人物移动
A.用margin慢慢调 B.用数组把它们排列好 C.放弃
素材不是来自《三国志曹操传》,因为没整理好《三国志曹操传》的地图素材,所以就随便找了些。不过也照样可以用。希望大家不要介意。
麻烦的代码最容易弄得乱七八糟,因此在此时要良好的区分开样式设置和拼图核心。
拼图核心在哪里呢???在这里:
接下来为了能切换地图,我们把第一张地图放进了数组:
样式设置在下:
接着看:
一、前言
以上是一段导语,话不扯远,对《三国志曹操传》熟悉的玩家知道,《三国志曹操传》的地图是由小地图块拼成的,那要实现它就和导语说得一样:很麻烦。不过即使麻烦也是一门技术,因此在此分享给大家,希望大家喜欢。
前几章的位置:
用Javascript开发《三国志曹操传》-开源讲座(三)-人物对话中,仿打字机输出文字
http://blog.csdn.net/yorhomwang/article/details/8008759
http://blog.csdn.net/yorhomwang/article/details/8007871
用Javascript开发《三国志曹操传》-开源讲座(一)-让静态人物动起来
http://blog.csdn.net/yorhomwang/article/details/7984576二、代码讲解
今天我要换换讲解方式,先不给代码,我们先来想想原理。现在,假如你有一幅图片,把它裁开成若干份,并打乱。现在如果让你用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行,而且这还是一张地图,看来还很有点麻烦哦。没关系,慢慢解释。
首先还是把素材放在这里:
tree.png |
land.png |
sea.png |
bridge.png |
beach.png |
麻烦的代码最容易弄得乱七八糟,因此在此时要良好的区分开样式设置和拼图核心。
拼图核心在哪里呢???在这里:
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)">。
源代码下载:http://files.cnblogs.com/ducle/map.rar
三、演示效果
演示图在下:
由于是静态的,所以就不给demo了。这种方法虽然很麻烦,而且地图块多了就很慢,但是毕竟是种技术,如果大家有什么好的方法也可以来告诉我。
希望大家多支持。谢谢。
----------------------------------------------------------------
欢迎大家转载我的文章。
转载请注明:转自Yorhom's Game Box
欢迎继续关注我的博客
相关推荐
以上是一段导语,话不扯远,对《三国志曹操传》熟悉的玩家知道,《三国志曹操传》的地图是由小地图块拼成的,那要实现它就和导语说得一样:很麻烦。不过即使麻烦也是一门技术,因此在此分享给大家,希望大家喜欢。 ...
16款最流行的JavaScript框架-开源中国社区.docx16款最流行的JavaScript框架-开源中国社区.docx16款最流行的JavaScript框架-开源中国社区.docx16款最流行的JavaScript框架-开源中国社区.docx16款最流行的JavaScript...
16款最流行的JavaScript框架-开源中国社区.pdf16款最流行的JavaScript框架-开源中国社区.pdf16款最流行的JavaScript框架-开源中国社区.pdf16款最流行的JavaScript框架-开源中国社区.pdf16款最流行的JavaScript框架-...
首先来说,我对游戏开发可以算是不怎么深入,因为现在的程序员爱用canvas,我却就只会拿几个div凑和。不过没关系,因为做出来的同样是游戏。哈!废话最近有点多,感兴趣的朋友可以了解下
本代码库是基于百度地图JSAPI GL版的JavaScript开源工具库,如果使用的是2D地图的话,参考旧的[2D开源库](https://github.com/huiyan-fe/BMap-JavaScript-library)。 ## 如何使用 我们在将GL版的开源工具库放到了...
fight01.pngfight02.pngfight03.pngfight04.png03.png02.png01.png首先,我找了一些出自经典游戏《三国志曹操传》里的素材(这些是魏将庞德的图片)。在下面我要用这些静态图片来演示如何化静为动。如果自己要演示...
文档包括了4个MapABC地图API Flash版-JavaScript版-Silverlight版-Flex版。用老版本开发地图系统,可以参数这4个文档来维护。
前两讲我告诉了大家如何使人物移动,那么今天我们就来看看如何实现仿《三国志曹操传》人物情景对话,感兴趣的朋友可以了解下,希望本文对你有所帮助
sa-sdk-javascript, 传感器分析 JavaScript SDK sa-sdk-javascript传感器分析 JavaScript SDK紧急招聘前端工程师,运维工程师,大数据工程师等,各种级别的都需要,求发送到我邮箱( shengyonggen@sensorsdata.cn
本书的以那些期望提高自己在设计模式方面的知识并将它们应用到javascript编程语言中的专业开发者为目标读者。
这些素材照样来自《三国志曹操传》,如果我没记错,应该是曹操的素材。接下来我要结合上一次的技术,来告诉大家如何使人物走动起来。不过今天我们着重在于如何使人物走动,因为我们上一讲已经讲了如何使人物化静态为...
开发指南--百度地图JavaScriptAPI大众版
SuperMap iClient for JavaScript
五子棋 - in html5是一款使用Javascript开发的开源小游戏
开源项目-pazams-go-for-javascript-developers.zip,pazams/go-for-javascript-developers
JavaScript-讲座.rar
ChakraCore 是微软开源的 Microsoft Edge 浏览器 Chakra JavaScript 引擎的核心部分,主要用于 Microsoft Edge 和 Windows 中 HTML/CSS/JavaScript 编写的应用。ChakraCore 支持 x86/x64/ARM 架构 JavaScript 的 ...
JSDK是一个JavaScript框架,具有一个小的核心文件和许多扩展库,具有以下功能:Lang-Extension,BOM,DOM,Event,Reflect,AOP,Thread,JS2D,JSGF和JSUI。 您可以使用JSDK来开发Web应用程序,JS游戏或Web小部件。