ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript を使用して Web ゲームを作成しましょう。it_javascript スキルを見てみましょう。

JavaScript を使用して Web ゲームを作成しましょう。it_javascript スキルを見てみましょう。

WBOY
WBOYオリジナル
2016-05-16 19:06:411321ブラウズ

最終的なプロダクト コードは、フォールト トレランスがなく、無理なカプセル化が行われていて、コア部分のみが実装され、他の部分は古いものを好みで追加したものでした。

チュートリアルを始めましょう (チュートリアルと呼びましょう。時間がないので急いで書きますが、ご容赦ください)

最高難易度での分析ゲームの。
最初のステップ、一般的な分析
ゲームの主な要素を見て、いくつかの絵ブロックのペア、絵ブロックを入れることができる四角いコンテナ、および 2 つのブロックを接続できる線の 3 つの部分を見つけます。 。

第 2 ステップ、要素分析
絵ブロック: 合計 32 の異なるパターンがあり、各パターンは 4 つあります。タイルはマウスのクリックに応じて消えます。タイルには高さと幅があります。 。
正方形プレート: 128 個のタイル、2 次元ベアリングを保持できます。正方形プレートはタイルを保持し、既存のタイルの順序を混乱させることができます。
接続: ゲームの中心となる、2 つのタイルを接続して中心点を取得します。最大 2 回しか折りたたむことができず、接続は正方形のプレートの外側を通過できます。

3 番目。 step, abstract
上記の分析により、3 つの要素が 3 つのオブジェクトに抽象化されます。これを抽象化する方法は、自分の頭を使うことができます。

パート 4、コア アルゴリズム

1、シャッフル アルゴリズム (非常に単純なアルゴリズム)
2 次元配列のデータを 1 次元配列にプッシュし、位置属性を交換しますデータを位置に応じて置き換えます


2. パスを見つける:
実際、Lianliankan で最も重要なことは、最大 2 つのタイル間のパスを見つける方法です。頂点、ここで実装する方法はたくさんあります。ここで実装するのは、最短パスや最適パスではなく、見つかったメソッドです。
研究によると、接続は 2 つの部分に分割できることがわかります。1 つの部分は法線であり、もう 1 つの部分はブロックによって法線に投影された光線です。そして、この関係を使用できます。道を見つけるために。
JavaScript を使用して Web ゲームを作成しましょう。it_javascript スキルを見てみましょう。
まず、2 つのブロック A と B があるとします。各ブロックには X 方向と Y 方向の 2 本の線があり、AB の X 線共通に Y 方向の法線があるとします。領域間、または AB の Y 線共通領域間に X 方向の法線がある場合、パスが見つかります。

実装されていない箇所:(基本的には関係ありません。パスはシャッフル方法に応じて簡単に変更できます。興味があれば実装してください)
タイミング、得点、プロンプト、パッセージ


[Ctrl A すべて選択 注: 外部 Js を導入する必要がある場合は、
を実行するために更新する必要があります]<script> /************************************************************************ 设计:tot 时间:2007-12-29 MSN:xiaotot@msn.com ************************************************************************/ //记录被选择图块的信息 var selectImg = ""; var selectX = 0; var selectY = 0; //图块宽度和高度,用来计算画线的位置 var stepX = 41; var stepY = 50; //初始化棋盘,只能以oGrid命名 var oGrid = new objGrid(16,8); /*****************************功能函数*******************************************/ //数组元素随机排序,tot设计,修改请保留 function rndArray(arr){ var le = arr.length; for(var i=0; i < le; i++){ var s = Math.floor(Math.random()*le); var zx = arr[i].x; var zy = arr[i].y;//这里不能写成z=arr[i],因为object是引用 arr[i].x = arr[s].x; arr[i].y = arr[s].y; arr[s].x = zx; arr[s].y = zy; } } //数组元素随机排序 function ArrayRnd(arr,times){ for(i = 0; i < times; i++)rndArray(arr) } //获取Html元素的绝对位置 function GetAbsoluteLocation(element){ if ( arguments.length != 1 || element == null ) return null; var offsetTop = element.offsetTop; var offsetLeft = element.offsetLeft; var offsetWidth = element.offsetWidth; var offsetHeight = element.offsetHeight; while( element = element.offsetParent ) { offsetTop += element.offsetTop; offsetLeft += element.offsetLeft; } return { absoluteTop: offsetTop, absoluteLeft: offsetLeft, offsetWidth: offsetWidth, offsetHeight: offsetHeight }; } /*****************************封装对象*******************************************/ //方盘对象,用来放置图块,tot设计,修改请保留 function objGrid(width,height){ var imgNum = 32; //图块样式个数 var gridNum = width * height; //初始化图块所用的图片名 var arrImg = new Array(imgNum); for(i = 0;i < imgNum; i++) arrImg[i] = "llk_" + i; //初始化图块数组 var arrImgBlock = new Array(gridNum); for(i = 0; i< gridNum; i++){ arrImgBlock[i] = new objImgBlock(arrImg[Math.floor(i /4)]); arrImgBlock[i].x = Math.floor(i / height); arrImgBlock[i].y = i % height; } //打乱次序 ArrayRnd(arrImgBlock,5); //生成方盘对象 var obj = new Object(); obj.backGround = "back.gif";//方盘的背景图片 obj.arrGrid = new Array(width); //初始化方盘二维数组 for(i = 0; i < width; i++) obj.arrGrid[i] = new Array(height); //向放盘中放置图块 obj.init = function (arrBlock){ for(i = 0; i < width; i++) for(j = 0; j < height; j++){ this.arrGrid[i][j] = ""; } grid = arrBlock.length; for(i = 0; i < grid; i++) this.arrGrid[arrBlock[i].x][arrBlock[i].y] = arrBlock[i]; this.drawGrid() this.setGridBackground(this.backGround) } //洗牌 obj.shuffle = function (){ var arrIBlock = new Array(); for(i = 0; i < width; i++) for(j = 0; j < height; j++) if(this.arrGrid[i][j] != "")arrIBlock.push(this.arrGrid[i][j]); ArrayRnd(arrIBlock,5); this.init(arrIBlock); } //查找最远射点 obj.findRadial = function (point){ var minX = -1, minY = -1, maxX = width, maxY = height; //水平查找最远射点 for(i = 0; i < width; i++){ if(i < point.X){ if(this.arrGrid[i][point.Y] != "") minX = point.X; else{ if(minX == point.X) minX = i; } }else if(i > point.X){ if(this.arrGrid[i][point.Y] != ""){ maxX = i - 1; break; } } } //垂直查找最远射点 for(i = 0; i < height; i++){ if(i < point.Y){ if(this.arrGrid[point.X][i] != "") minY = point.Y; else{ if(minY == point.Y) minY = i; } }else if(i > point.Y){ if(this.arrGrid[point.X][i] != ""){ maxY = i - 1; break; } } } return { MinX : minX, MinY : minY, MaxX : maxX, MaxY : maxY } } //查找法线 obj.findNormal = function(sPoint,ePoint){ var startPoint, endPoint var sRadial = this.findRadial(sPoint); var eRadial = this.findRadial(ePoint); var pass;//是否可以通过标志 maxSX = Math.max(sRadial.MinX,eRadial.MinX) minEX = Math.min(sRadial.MaxX,eRadial.MaxX); maxSY = Math.max(sRadial.MinY,eRadial.MinY); minEY = Math.min(sRadial.MaxY,eRadial.MaxY) //查找横法线 if( maxSY <= minEY){ if(maxSY == -1){ startPoint = new objPoint(sPoint.X,-1); endPoint = new objPoint(ePoint.X,-1); }else if(minEY == height){ startPoint = new objPoint(sPoint.X,height); endPoint = new objPoint(ePoint.X,height); } else{ for(j = maxSY; j <= minEY; j++){ pass = true; for(i = Math.min(sPoint.X,ePoint.X) + 1; i < Math.max(sPoint.X,ePoint.X); i++){ if(this.arrGrid[i][j] != "") pass = false; } if(pass){ startPoint = new objPoint(sPoint.X,j); endPoint = new objPoint(ePoint.X,j); } } } }//查找竖法线 else if( maxSX <= minEX){ if(maxSX == -1){ startPoint = new objPoint(-1,sPoint.Y); endPoint = new objPoint(-1,ePoint.Y); }else if(minEX == width){ startPoint = new objPoint(width,sPoint.Y); endPoint = new objPoint(width,ePoint.Y); } else{ for(i = maxSX; i <= minEX; i++){ pass = true; for(j = Math.min(sPoint.Y,ePoint.Y) + 1; j < Math.max(sPoint.Y,ePoint.Y); j++){ if(this.arrGrid[i][j] != "") pass = false; } if(pass){ startPoint = new objPoint(i,sPoint.Y); endPoint = new objPoint(i,ePoint.Y); } } } } //返回法线端点 if(startPoint){ return{sP : startPoint, eP : endPoint} } else {return false}; } //画方盘 obj.drawGrid = function (){ var gDiv = document.getElementById("gridDiv"); var tempHtml = "<table id=gridTalbe border=0 cellpadding=0 cellspacing=0 align=center>"; for(i = 0; i < height; i++){ tempHtml += ""; for(j = 0; j < width; j++){ tempHtml += "<td>"; if(this.arrGrid[j][i] != "") tempHtml += this.arrGrid[j][i].toHtml(); tempHtml += ""; } tempHtml += ""; } tempHtml += ""; gDiv.innerHTML = tempHtml; } //设置背景 obj.setGridBackground = function(img){ var gTable = document.getElementById("gridTalbe"); gTable.style.backgroundImage = "url(images/" + img + ")"; this.backGround = img; } //执行初始化 obj.init(arrImgBlock); return obj; } //图块对象 function objImgBlock(pic){ var obj = new Object(); obj.picName = pic; obj.x = 0; obj.y = 0; obj.toHtml = function(){ return "<img name=" + this.picName + " onclick=clickImg(" + this.x + "," + this.y + ") src=images/" + this.picName + ".gif>" } return obj; } //坐标点对象,对应于承载图块的二元数组下标 function objPoint(x,y){ return{ X : x, Y : y }} //点击图块的动作 function clickImg(x,y){ eObj = event.srcElement; if((selectImg.name == eObj.name) && (selectImg !== eObj)){ if(Line(new objPoint(selectX,selectY),new objPoint(x,y))){ selectImg.style.display = "none"; eObj.style.display = "none"; selectImg = ""; selectX = 0; selectY = 0; }else changeSelect(eObj,x,y) }else{ changeSelect(eObj,x,y) } } //更换选择的图块 function changeSelect(o,x,y){ selectImg.className = ""; selectImg = o; selectImg.className = "select"; selectX = x; selectY = y; } //画线 function Line(sPoint,ePoint){ var nLine = oGrid.findNormal(sPoint,ePoint); if(nLine){ oGrid.arrGrid[sPoint.X][sPoint.Y] = ""; oGrid.arrGrid[ePoint.X][ePoint.Y] = ""; drawLine(sPoint,nLine.sP); drawLine(nLine.sP,nLine.eP); drawLine(ePoint,nLine.eP); setTimeout(clearLine,500); return true; }else{ return false } } //连接两点的画线函数 function drawLine(sPoint,ePoint){ var startPoint, endPoint, lineType = true;//默认画横线 var lineLen;//画线长度 var linDiv = document.getElementById("lineDiv"); var O = document.getElementById("gridTalbe"); //原点的绝对坐标 var oPoint = new objPoint(GetAbsoluteLocation(O).absoluteLeft - 25, GetAbsoluteLocation(O).absoluteTop - 30); if(sPoint.X == ePoint.X){ //画竖线 if(sPoint.Y > ePoint.Y){//判断起始点 startPoint = ePoint; endPoint = sPoint; }else{ startPoint = sPoint; endPoint = ePoint; } lineLen = endPoint.Y - startPoint.Y + 1; lineType = false; }else{//画横线 if(sPoint.X > ePoint.X){//判断起始点 startPoint = ePoint; endPoint = sPoint; }else{ startPoint = sPoint; endPoint = ePoint; } lineLen = endPoint.X - startPoint.X + 1; } for(i = 1; i <= lineLen; i++){ var lineDot = document.createElement("<div class=lineDot>"); lineDot.style.left = lineType ? (oPoint.X + stepX * (startPoint.X + i) + "px") : (oPoint.X + stepX * (startPoint.X + 1) + "px"); lineDot.style.top = lineType ? (oPoint.Y + stepY * (startPoint.Y + 1) + "px") : (oPoint.Y + stepY * (startPoint.Y + i) + "px"); linDiv.insertBefore(lineDot); } } //清除画线 function clearLine(){ var linDiv = document.getElementById("lineDiv"); linDiv.innerHTML = ""; } //调试用 function debug(str){ var linDiv = document.getElementById("debug"); linDiv.innerHTML = str + " " + linDiv.innerHTML; } function odebug(obj,oname){ var linDiv = document.getElementById("debug"); for(o in obj){ if(typeof(obj[o]) == "object"){ odebug(obj[o],oname + o + ".") } else linDiv.innerHTML = oname + o + "=" + obj[o] + " " + linDiv.innerHTML; } } </script>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。