您好,欢迎访问一九零五行业门户网

javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图_javascript技巧

小时候我们玩过拼图游戏,是用自己的手去拼的。今天我们来研究研究用javascript来拼图。同样是拼图,但用js拼图要比用手拼图麻烦多了,因此以后我要把它优化成引擎。
一、前言
以上是一段导语,话不扯远,对《三国志曹操传》熟悉的玩家知道,《三国志曹操传》的地图是由小地图块拼成的,那要实现它就和导语说得一样:很麻烦。不过即使麻烦也是一门技术,因此在此分享给大家,希望大家喜欢。
二、代码讲解
今天我要换换讲解方式,先不给代码,我们先来想想原理。现在,假如你有一幅图片,把它裁开成若干份,并打乱。现在如果让你用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 var vcrid = v[nsub].split(',');
vrec[vrec.length] = vcrid;
}
for(nrow = 0; nrow var vcol = vrec[nrow];
for(ncol = 0; 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 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 var vcrid = v[nsub].split(',');
vrec[vrec.length] = vcrid;
}
for(nrow = 0; nrow var vcol = vrec[nrow];
for(ncol = 0; 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 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代码里写上:几可以把拼的图一下子画出来。nhurdle就是地图在数组vhurdles里的对应下标,最低是1,而不是0,也就是说要用第一张地图,那nhurdle就该赋值为1,调用是写为:。 源代码下载
三、演示效果
演示图在下:
由于是静态的,所以就不给demo了。这种方法虽然很麻烦,而且地图块多了就很慢,但是毕竟是种技术,如果大家有什么好的方法也可以来告诉我。
希望大家多支持。谢谢。
其它类似信息

推荐信息