> 웹 프론트엔드 > JS 튜토리얼 > JavaScript는 단순하고 탐욕스럽고 기본적인 객체 지향적입니다.

JavaScript는 단순하고 탐욕스럽고 기본적인 객체 지향적입니다.

高洛峰
풀어 주다: 2016-11-25 11:46:40
원래의
1168명이 탐색했습니다.

没有写博客的习惯,这篇算心血来潮,算篇近几天编写的小程序纪实.

      以编写此程序的方式结束Javascript的本阶段的学习.编写的目的在于熟悉javascript的编程方式,包括代码风格,面向对象的运用等.

      回到程序,说说Snake的移动的实现方法.其实很简单,向头部添加Unit,然后删除尾部.其他,参见注释.

 

程序包括一个html文件:snake.html和一个js文件:snake.js

 

     snake.html:

 

JavaScript简单贪吃蛇

   

snake.js:

/*

* JavaScript는 기본 객체 지향입니다.

* 규칙:

* 1. 벽이 없습니다. 바로연결, 상하연결.

* 2. 뱀머리가 스스로 충돌하면 사망.

* 호환성:

* 파이어폭스, 크롬 완벽지원

* IE 기본 지원(디버깅 부분 제외)

*

* 작성자: pcenshao

* 전재할 경우 출처를 밝혀주세요:

* http: //blog.csdn.net/pywepe

* http://pcenshao.taobao.com

*/

(function(){

$s = function(){

if(arguments.length == 1){

if(typeof 인수[0] == "string "){

                        return document.getElementById(arguments[0]);                                           0];

                                                             🎜>

$s.UNIT_HEIGHT = 10;

$s .PANEL_WIDTH = 30; // 논리적 너비

$s.PANEL_HEIGHT = 20; // 논리적 높이

$s.STEP = 250; // 각 단계의 시간

$s.HEAD_COLOR = "빨간색"; // 뱀 머리 색상

$s.BODY_COLOR = "검은색" / / 뱀 몸 색상

/*

* 식용 색소

*/

$s.COLORS = ["파란색","녹색"," #494e8f","#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 메소드를 강제 호출, 매개변수 오류 방지

위 : {},

아래 : {},

왼쪽 : {},

오른쪽 : {},

없음 : {}

};

$s.State = { // 상태를 나타냅니다.

STOP : {},

RUNNGIN : {},

PAUSE : {}

};

$s.Unit = function(){ // 셀, 조회 MVC 관점에서 보면 Unit은 모델이고 UnitView는 뷰

this.x = 0;

this.y = 0;

this.view = new $s.UnitView();

this.view.unit = this;

this.color = $s.BODY_COLOR;

};

$s.Unit.prototype.repaint = function(){

if(this.view != null){

this.view.repaint(); // 다시 그리기 알림

}                                                     🎜>

}

$s.Snake.prototype.init = function(dir,count){

var x = 5;

var y = 5;

for(var i = 0 ; i < 개수 ; i ++){

var u = new $s.Unit();

u.x = x ;

u.y = y ++;

this.units.push(u);

if(i == (count - 1 )){

u.color = $s.HEAD_COLOR ;

}

u.repaint();

}

};

$s. Snake.prototype.crash = function(x,y){ // 머리 위치를 전달하고 true를 반환하여 자신과의 충돌을 나타냅니다

for(var i = this.units.length - 2; i >= 0 ; i --){ // 헤더 자체 제외

var u = this.units[i];

if(u.x == x && u.y == y) {

                                            ; 🎜>

$s.Snake.prototype.go = function(){

// 앞에 음식이 있는지 확인

/ / 벽에 부딪힐지 여부

var _x = 0, _y = 0 ;

var head = this.units[this.units.length - 1];

_x = head.x;

_y = head.y;

var dir = $s.SnakeContext.dir;

$s.SnakeContext.stop();

> 왼쪽){

_x --

}else if(dir == $ s.Dir.RIGHT){

_x ++;

}else if(dir == $s.Dir.UP){

_y --;

}else if (dir == $s.Dir.DOWN){

_y ++;

}

🎜>

if(_x >= $s.PANEL_WIDTH){

_x = 0;

}

if(_x < 0){

_x = $s .PANEL_WIDTH - 1;

}

if(_y >= $s.PANEL_HEIGHT){

_y = 0;

}

if(_y < 0){

_y = $s.PANEL_HEIGHT - 1;

}

         

var h = new $ s.Unit(); // 새 헤더

If($s.SnakeContext.hasFood(_x,_y)){ // 다음 단계는 음식을 만나는 것

this.eat(_x,_y);

head = this .units[this.units.length - 1]; // eat 메소드로 헤드를 변경할 수 있으므로 다시 획득

_x = head.x;

_y = head.y;

                                                                                               ~

_y --;

                                                                                                                            COLOR;

head.repaint();

var oldHead = this.units[this.units.length - 2 ];

oldHead.color = $s.BODY_COLOR;

oldHead.repaint();

return;

}

var tail = this.units.shift() ;

$s.NodePool.releaseNode(tail);

This.units.push (h);

                                      ~                                                                                             ​ 단위[i];

If(i == (this.units.length - 1)){ // 머리

u.color = $s.HEAD_COLOR;

                                                                                                                                 🎜>

}

 

 };

 

 $s.Snake.prototype.eat = function(x,y){

    var food = $s.SnakeContext.food;

if(food != null){

food.alive = false;

this.units .push(food.unit);

                                                                        ~ >

임의번호 : 함수(하위,상위) { // [lower,upper] 범위의 정수를 반환합니다.

varChoices = upper - lower + 1;

               return Math.floor(Math.random() *Choices + lower) // value = Math.floor(Math.random() * 가능한 값의 개수 + 첫 번째 가능한 값)

},

randomLocation : function(maxX,maxY){

var x = $s.Random.randomNumber(0,maxX);

var y = $s. Random.randomNumber (0,maxY); 🎜>

This.unit = new $s.Unit();

this.unit.x = x;

this.unit. y = y;

var color = $s.COLORS[$s.Random.randomNumber(0,$s.COLORS.length - 1)];

this.unit.color = color;

this.alive = true;

this.unit.repaint( );

};

$s.Food.prototype.locateOn = function(x,y){

return this.unit.x == x && this.unit.y == y;

};

/*

* HTML 노드 풀, 효율성 향상이 주목적

* 꼬리 노드를 삭제하고 머리 노드를 추가하여 뱀의 움직임을 구현하기 때문에

* 이 과정에서 다수의 노드 생성 작업이 발생하게 됩니다. 작업 효율을 위해 노드를 모아서 관리합니다.

* 테일 노드는 삭제되지 않지만, 노드가 필요할 때 재사용할 수 있습니다.

*/

$s.NodePool = {

노드 : []

};

$s.NodePool._findHideNode = function(){ // 숨겨진 div 노드 찾기

for(var i = 0 ; i < this.nodes.length ; i ++){

var n = this.nodes[i];

if(n.style.display == "none"){

return n; }

return null;

};

$s.NodePool.createNode = function(){

var pooledNode = this._findHideNode();

if(pooledNode != null){

return pooledNode;

}else{

var newNode = document.createElement("div");

this.nodes.push(newNode);

return newNode;

}

};

$s.NodePool. releaseNode = function(node){

if(node ​​​​!= undefine && node , >

var div = view.node;

div.style.display = "none" ;

}

                                                                                

        }   

    }

   

    $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.borderColor = "흰색";       

            tag.style.margintLeft = "1px";

            tag.style.marginRight = "1px";

            tag.style.marginTop = "1px";

            tag.style.marginBottom = "1px";

            tag.style.BackgroundColor =  this.unit.color; // 颜color由模型Unit指정

            tag.style.position = "absolute"; //기준 위치는 상대 위치, 상대 위치는 절대 위치, 절대 위치, 表示孩子 상대 위치는

          

            tag.style.display = " 차단"; // 큼, 因为从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 태그 = 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 panel = 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";

        panel.style.borderColor = "red";

        panel.style.borderWidth = "1px ";

        panel.style.marginLeft = "자동";

        panel.style.marginRight = "자동";

panel.style.marginTop = "50px";

panel.style.position = "relative"; //컨테이너의 위치를 ​​상대값으로 지정하고, 자식의 위치를 ​​지정한 경우 절대적이라는 것은 자식이 컨테이너에 상대적이라는 것을 의미합니다. 절대 위치 지정.

panel.style.marginBottom = "auto";

this.node = panel;

document.body.appendChild(panel);

                                                        ";

len.style.marginBottom = "20 px";

len.style.color = "회색";

len.style.fontSize = "12px";

len.innerHTML = "길이:";

document.body.appendChild(len);

$s.SnakeContext._len = len;

  

   var startBn = document.createElement("button");

    startBn.innerHTML = "시작";

    startBn.style.marginLeft = "10px";

startBn.onclick = function(){

$s.SnakeContext.run();

} ;

$s.SnakeContext._startBn = startB n ;

document.body.appendChild(startBn);

"일시 중지";

PauseBn. style.marginLeft = "10px";

PauseBn.onclick = function(){

$s.SnakeContext.pause()

};

$s.SnakeContext._pauseBn = PauseBn;

document.body.appendChild(pauseBn);

🎜> / *

var stopBn = document.createElement("button ");

stopBn.innerHTML = "중지";

stopBn.style.marginLeft = "10px";

stopBn.onclick = function(){

$s.SnakeContext.stop();

};

$s.SnakeContext._stopBn = stopBn ; >

restartBn.innerHTML = "다시 시작";

restartBn.style.marginLeft = "10px";

restartBn.onclick = function(){

window .location.href = window.location.href;

};

}; $s.SnakeContext._restartBn = restartBn;

document.body.appendChild(restartBn);

                           ~                  (줄);

                                                                                                                                    

       span.style.color = "회색";

       span.style.fontSize = "12px";

       span.innerHTML = "调试";

        문서 .body.appendChild(span);

       

        var debug = document.createElement("input");

        debug.type = "checkbox";       

        debug.checked = $s.DEBUG;

        debug.onchange = function(){

            $s.SnakeContext.setDebug(debug.checked);

        };       

        document.body.appendChild(debug);

       

    };

    $s.PanelView.prototype.append = function(unitView){

        시도{

            this.node.appendChild(unitView.node);

        }catch(e){

            경고(e);   

        }       

    };

   

    /*

     *  

     * 约결정以_开头的成员为私有成员

     * 启动程序적 방법:

     * window.onload = function(){

     *     $s.SnakeContext.init() ;

     * }

     */

    $s.SnakeContext = {   

       dir : $s.Dir.NONE,

상태 : $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( );

                                              $s.SnakeContext.snake.go();        

                                            },$s.STEP);

            }

          

        },

        중지: function(){

            this._setState($s.State.STOP);

       },

        일시 중지: function(){

            this._setState($s.State.PAUSE);

        },

        _setState : 함수{

            if (this.state != s && this.goTimer != null){

               window.clearInterval(this.goTimer);

               this.goTimer = null;

              this.state = s;

            }    

        } ,

        getFood : function(x,y){

            for(var f in this.foods){

               if(f.x == x && f.y == y) {

                    return f;   

              }   

           }   

            null 반환;

        },

        init : function(){   

            이 .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;

          

            문서 ... .이벤트 .keyCode;

               }else{

                 코드 =     e.keyCode;

               }

                var str = "";

                var oldDir = $s.SnakeContext.dir;

                스위치(코드){

                  사례 37: // 왼쪽

                      if($s .SnakeContext.dir != $s .Dir.RIGHT){

                           $s.SnakeContext.dir = $s.Dir.LEFT;   

                      }   

                    str = "왼쪽";

                      브레이크;

                   사례 38 : // up

                     if($s. SnakeContext.dir != $s.Dir.DOWN){

                           $s.SnakeContext.dir = $s.Dir.UP;   

                     }           

                     str = "up";

                        휴식;

                   사례 39: // 맞음

                      if($s.SnakeContext.dir != $s.Dir.LEFT){

                          $s.SnakeContext.dir = $s.Dir.RIGHT;   

                      }           

                    str = "맞아";

                      break;

                    사례 40: // down

                      if($s. SnakeContext.dir != $s.Dir.UP){

                          $s.SnakeContext.dir = $s.Dir.DOWN;   

                      }              

                    str = "아래로";

                      휴식;

               }

                if($s.SnakeContext.dir != oldDir){

                   if($s.DEBUG){

                     var v = $s($s.KEY_UP_DIR_ID);

                        if(v){

                          v.innerHTML = "方向键:" + str;

                    }                     

                   }

                 

                   if($s.SnakeContext.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.SnakeContext.snake.go();        > 🎜>          

            var loc = $s.Random.randomLocation($s.PANEL_WIDTH - 1, $s.PANEL_HEIGHT - 1);

            this.food = new $s.Food(loc .x,loc.y);

           

        },

        뱀 : null,

        음식 : [],

        panelView : null,

        food : null,

        updateFood : function(){

           if(this.food.alive){ // 当前Food还存活

                반품;   

            }

            var loc = null;

            do{

 

               //随机产生一个点,直到不Snake중叠   

               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);

           

        },

        중첩: 기능(loc ){ // 检查是否与Snake중대,当중중叠时返回true

            var x = loc.x;

            var y = loc.y;

            for(var i = 0 ; i < this.snake.units.length ; i ++ ){

              var u = this.snake.units[i];

              if(u.x == x && u.y == y){

                    true를 반환합니다.   

               }

           }

            false 반환,

       },

        hasF ood : 함수(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 : 함수( 활성화){

            if(활성화 != $s.DEBUG){

               $s.DEBUG = 활성화;

               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 : 함수(태그){

            if(태그){

                태그. style.display = "블록";   

           }   

        },

        _hide : 기능(태그){

            if(태그){

                tag.style.display = "없음";   

           }   

        },

        ondead : function(){ // Snake死亡时回调

            if(this._start 대){

               this._startBn.disabled = true;

            }

           if(this._pauseBn){

               this._ PauseBn.disabled = true;   

            }

            if(this._stopBn){

               this._stopBn.disabled = true;   

            }

           경고("걸림");                                                                                                                                  "길이:" + this.snake.units.length;

},

_startBn : null,

_pauseBn : null ,

_stopBn : null ,

_restartBn : null,

_len : null

};

})();

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿