ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript はシンプルかつ貪欲な、基本的なオブジェクト指向です
没有写博客的习惯,这篇算心血来潮,算篇近几天编写的小程序纪实.
以编写此程序的方式结束Javascript的本阶段的学习.编写的目的在于熟悉javascript的编程方式,包括代码风格,面向对象的运用等.
回到程序,说说Snake的移动的实现方法.其实很简单,向头部添加Unit,然后删除尾部.其他,参见注释.
程序包括一个html文件:snake.html和一个js文件:snake.js
snake.html:
$s(function(){
$s.SnakeContext.init();
});
snake.js:
/*
* JavaScript は基本的なオブジェクト指向です
* ルール:
* 1. 壁はなく、左右は接続されており、上下は接続されています
* 2. ヘビは頭が衝突すると死にます
* Firefox、Chrome を完全にサポートします。
* IEの基本サポート(デバッグ部分を除く)
*
* 著者: pcenshao
* 転載する場合は出典を明記してください:
* http://blog.csdn.net/pywepe
* http://pcenshao.taobao.com
*/(function(){ $ s = function(){document.getelementbyid(arguments [0]);; $ s.unit_width = 10; // $ s.unit_height = 10; S.Step = 250; $ s.Step = 250; "#905d1d","#845538","#77ac98","#8552a1 "];
/*
* デバッグ関連
* $s.DEBUG デバッグ情報表示スイッチ
* $s.KEY_UP_DIR_ID方向キーのノードIDを監視します 存在しない場合は表示されません
* $s.HEAD_LOCATION_ID スネークヘッドの位置のノードIDを監視します * 存在しない場合は表示されません。 /
$s.DEBUG = false;
$s.KEY_UP_DIR_ID = "keyup";
$s.HEAD_LOCATION_ID = "headLocation";
$s.Dir = { // 方向を表し、強制的に呼び出されますパラメーターエラーを回避する $s.Dir.UP メソッド
UP: {},
DOWN: {},
LEFT : {},
RIGHT : {},
NONE : {}
};
$s.State = { // 状態を表します
STOP : {},
RUNNGIN: {},
PAUSE: {}}}; $ s.Unit = Function () {/ / セル、MVC の目で見てください、ユニットはモデル、unitView はビューです this.x = 0this.y = 0; this.view = new $s.UnitView();
this.view.unit = this; this.color = $s.BODY_COLOR; }; $s .Unit.prototype.repaint = function(){ $ s.スネーク= function(){ This.units = []; };
$s.Snake.prototype.init = function(dir,count){
var x = 5;
var y = 5;
for(var i = 0; i var u = new $s.Unit(); u. $s.Snake.prototype.crash = function(x,y) ) { / / 頭の位置を渡し、それ自体との衝突を示す場合は true を返します for(var i = this.units.length - 2 ; i >= 0 ; i --){ // 頭自体を除外します var u = this.units [i]; / それ自体と衝突するかどうかを判断します $s.SnakeContext.stop(); SnakeContext。 s.Dir.LEFT){ ir == $s.Dir. Up) { -_y -; else if (dir == $ s.dir.down) { _y ++ } (_x > 1; } if(_y) > = $ s.panel_height) { _y = 0; } if (_y & lt; 0) { _y = $ s.panel_height -1;}} var h = new $ s.Unit() ; // 新しいヘッダー I} else if (dir == $ s.dir.down) { _y ++; } head.color = $ s.head_color; head.repaint () .units[this.units.length - 2]; (h); .units.length - 1 ; i >= 0; i --){ var u = this.units[i]; 頭 u.color = $s.HEAD_COLOR; u.repaint(); .Snake.prototype.eat = function(x,y){ var food = $s.SnakeContext.food; if(food != null){ food.alive = false; this.units。 Push(food.unit); "); } } } /* * 簡単なメソッドを提供する乱数生成器 */ $s.Random = { randomNumber: function( lower,upper){ // [ lower, upper ] の範囲の整数を返します var Choices = upper - lower + 1; }} null を返します。 var pooledNode=this._findHideNode(); div "); this.nodes.push(newnode); } } $s.UnitView = function(){ // ユニットの映像 this.unit = null; this.node = null; }; $s.UnitView. prototype.repaint = function(){ if(this.node == null){ // 初初期化 var tag = $s.NodePool.createNode(); tag.style.width = $s.UNIT_WIDTH + "px"; tag.style.height = $s.UNIT_HEIGHT + "px"; tag.style.borderStyle = "点線"; tag.style.borderWidth = "1px"; tag.style .borderColor = "白"; tag.style.margintLeft = "1px"; tag.style.marginRight = "1px"; tag.style.marginTop = "1px"; tag.style. marginBottom = "1px"; tag.style.backgroundColor = this.unit.color; // 颜色由モデルユニット指定 tag.style.position = "absolute"; // コンテナの位置は相対的に指定され、子の位置は絶対時間に指定され、孩子相对コンテナ绝对定位を表示します。 tag.style.display = "block"; // 重要なため、NodePool 取得のポイントは隐藏状態です var x = this.unit.x * $s.UNIT_WIDTH; var y = this.unit. y * $s.UNIT_HEIGHT; tag.style.top = y + "px"; tag.style.left = x + "px"; this.node = tag; $s.SnakeContext.panelView.append(this) ; }else{ var tag = this.node; var x = this.unit.x * $s.UNIT_WIDTH; var y = this.unit.y * $s.UNIT_HEIGHT; tag.style.top = y + "px"; tag.style.left = x + "px"; tag.style.backgroundColor = this.unit.color; } }; $s.PanelView = function(){ // 按钮区を含む整个游戏領域 var pane = document.createElement("div"); panel.style.width = ($s.PANEL_WIDTH * $s.UNIT_WIDTH ) + "px"; panel.style.height = ($s.PANEL_HEIGHT * $s.UNIT_HEIGHT ) + "px"; panel.style.borderStyle = "dotted"; パネル。 style.borderColor = "red"; panel.style.borderWidth = "1px"; panel.style.marginLeft = "auto"; panel.style.marginRight = "auto"; panel.style.marginTop = "50px"; use using using out through through using ‐ ‐ ‐ ‐ ‐‐ ‐‐panel.style.position = "50px"; .style .marginBottom = "自動"; this.node = パネル; marginleft = "自動"; len.style.marginbottom = "20px"; span.style.color = "gray"; span.style.fontSize = "12px"; span.innerHTML = "调试"; document.body.appendChild(span); var デバッグ= document.createElement("input"); debug.type = "チェックボックス"; debug.checked = $s.DEBUG; debug.onchange = function(){ $s.SnakeContext.setDebug(debug.checked); }; document.body.appendChild(debug); }; $s.PanelView.prototype.append = function(unitView){ try{ this.node.appendChild(unitView.node); }キャッチ(e){ アラート(e); } }; /* * 全局环境类、代表应用 * 约定以_开头的成员は私有成员 * 启アニメーション程序的方法: * window.onload = function (){ * $s.SnakeContext.init(); * } */ $s.SnakeContext = { dir :状態 : $s.State .STOP, goTimer : null, run : function(){ if(this.state != $s.State.RUNNGIN){ this.state = $s.State.RUNNGIN; this .gotimer = window.setInterval(function(){ $ s.snakecontext.updatefood(); }, stop : function(){ this._setState($s.State.STOP); }, stop : function(){ this._setState($s.State.PAUSE ); }, _setState : function(s){ if(this.state != s && this.goTimer != null){ window.clearInterval(this.goTimer); this.goTimer = null; this.state = s; } }, getFood : function(x,y){ for(var f this.foods){ if(f.x == x && f.y == y){ return f; } } return null; }, init : function(){ this.panelView = new $s.PanelView(); this.snake = new $s.Snake() ; this.dir = $s.Dir.DOWN; this.snake.init($s.Dir.UP,3); this._len.innerHTML = "长度:" + 3; document.body.onkeyup = function(e){ var code = null; if(window.event){ // クソIE コード= window.event.keyCode; }else{ code = e.keyCode; } var str = ""; var oldDir = $s.SnakeContext.dir; switch(code){ case 37: // left if($s .SnakeContext.dir != $s.Dir.RIGHT){ $s.SnakeContext.dir = $s.Dir.LEFT; } str = "left"; ブレーク; case 38 : // up if($s.SnakeContext.dir != $s.Dir.DOWN){ $s.SnakeContext。 dir = $s.Dir.UP; } str = "up"; 休憩; case 39: // right if($s.SnakeContext.dir != $s.Dir.LEFT){ $s.SnakeContext .dir = $s.Dir.RIGHT; }} str = "right"; dir = $s.Dir.DOWN; }} str = "down"; ($s.KEY_UP_DIR_ID); if(v){ v.innerHTML = "方向键:" + } } if($s.Sn akeContext.goTimer != null) { window.clearInterval($s.SnakeContext.goTimer); $s.SnakeContext.goTimer = null; } $s.SnakeContext.snake.go(); $s.SnakeContext.goTimer = window.setInterval(function(){ $s.SnakeContext.updateFood(); $s.Snake Context.snake.go (); },$s.STEP); } }; var loc = $s.Random.randomLocation($s.PANEL_WIDTH - 1, $s.PANEL_HEIGHT - 1); this.food = new $s.Food(loc.x,loc.y); }, ヘビ : null, 食べ物 : [], パネルビュー : null, 食べ物 : null , updateFood : function(){ if(this.food.alive){ //現在の食品は存続 return; } var loc = null; do{ // 随机生一个点、不不蛇重叠 loc = $s.Random.randomLocation($s.PANEL_WIDTH - 1,$s. PANEL_HEIGHT - 1); }while(this.overlap(loc)); this.food = new $s.Food(loc.x,loc.y); }, overlap : function(loc){ // 检查は蛇重叠、当重叠回真に戻ります var x = loc.x; var y = loc.y; for(var i = 0 ; i var u = this.snake .units[i]; if(u.x == x && u.y == y){ trueを返します。 } } return false; }, hasFood : function(x,y){ if($s.DEBUG){ var xt = $s($s.HEAD_LOCATION_ID); if(xt){ xt.innerHTML = "头部の位置:(" + x + "," + y + ")"; } } return this.food.locateOn(x,y); }, setDebug : function(enable){ if(enable != $s.DEBUG){ $s .DEBUG = enable; if($s.DEBUG){ // 显示 var i = $s($s.KEY_UP_DIR_ID); $ s.SnakeContext._show(i); i = $s ($s.HEAD_LOCATION_ID); $s.SnakeContext._show(i); }else{// 隐藏 var i = $s($s.KEY_UP_DIR_ID); $s.SnakeContext._hide( i); i = $s($s.HEAD_LOCATION_ID); $s.SnakeContext._hide(i); } } }, _show : function(tag){ if (タグ){ tag.style.display = "ブロック"; } }, _hide : function(tag){ if(tag){ tag.style.display = "なし」; } }, ondead : function(){ // スネーク死亡時回调 if(this._startBn){ this._startBn.disabled = true; } if(this._pauseBn ){ this._pauseBn.disabled = true; } if(this._stopBn){ this._stopBn.disabled = true; } _len : null }; })();