> 웹 프론트엔드 > JS 튜토리얼 > JavaScript로 Snake 위젯을 구현하는 예제 코드

JavaScript로 Snake 위젯을 구현하는 예제 코드

黄舟
풀어 주다: 2017-08-20 09:48:23
원래의
2009명이 탐색했습니다.

1 이전에 작성됨

"JavsScript Advanced 프로그래밍"이 내 기술을 연습하기 위해 작은 데모를 만들고 싶어했던 것 같아서 Snake 게임을 선택했습니다. 예전에는 모두 C#으로 작성했기 때문에 Snake를 클래스로 작성한 뒤 작은 메소드들로 하나씩 나누어서 제공해야 하는 메소드들만 제공했습니다. 이런 식으로 Snake는 모듈로 사용될 수 있으며 어디에서나 재사용이 가능합니다. 그러나 js로 작성하는 경우에는 js 언어의 특성을 모듈식 프로그래밍에 잘 활용하지 못하기 때문에 첫 번째 구현 버전에서는 완전히 프로세스 지향적 접근 방식을 채택하고 함수에 필요한 모든 변수를 전역 변수로 선언합니다. 이는 기능을 수행할 수도 있지만 재사용할 수 없으며 많은 최상위 변수가 정의되어 전역 변수를 오염시킵니다. 글을 쓴 후에는 꼭 제공해야 하는 변수나 함수형 인터페이스만 외부에 제공되도록 항상 제가 작성한 내용을 다시 캡슐화하고 싶습니다. 많은 정보를 확인한 결과 클로저를 사용하여 js 캡슐화를 구현할 수 있음이 밝혀졌습니다. 함수 내부의 지역 변수와 클로저 함수를 해당 타입의 프라이빗 변수와 함수로 선언함으로써 이를 통해 개발해야 할 인터페이스를 객체에 제공합니다.

2 Snake 컴포넌트 사용법

2.1 기본 예제

샘플 코드 1은 다음과 같습니다.


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>贪吃蛇组件</title>
</head>
<body>
 <canvas width="600" height="600" id="gameScense"></canvas>
</body>
<script src="SnakeGame.js"></script>
<script>
 var snakeGame = new SnakeGame("gameScense",{
 });
 snakeGame.startGame();
</script>
</html>
로그인 후 복사

먼저 SnakeGame.js 컴포넌트를 도입한 후 SnakeGame 객체를 인스턴스화하여 전송합니다. SnakeGame에 생성자는 두 개의 매개변수를 전달합니다. 첫 번째 매개변수는 캔버스의 ID이고 두 번째 매개변수는 게임 구성 개체입니다. 비어 있으면 기본 구성이 사용됩니다. 마지막으로 개체의 startGame() 메서드를 호출하여 뱀의 논리를 구현합니다. 기본 방향 제어 키는 위, 아래, 왼쪽 및 오른쪽 키이며 일시 중지는 스페이스입니다. 효과는 다음과 같습니다.

JavaScript로 Snake 위젯을 구현하는 예제 코드인스턴스화 중에 전달된 구성 개체를 변경하여 게임을 더 효과적으로 제어할 수 있습니다. </p><p> 샘플 코드 2: </p><p class=

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>贪吃蛇组件</title>
</head>
<body>
 <canvas width="600" height="600" id="gameScense"></canvas>
</body>
<script src="SnakeGame.js"></script>
<script>
 var snakeGame = new SnakeGame("gameScense",{
  snakeColor:"red",
  foodColor:"green",
  scenseColor:"blue",
  directionKey:[68,83,65,87],
 });
 snakeGame.startGame();
</script>
</html>
로그인 후 복사

매개변수의 이름으로 알 수 있으며, 뱀의 색상, 음식, 게임 배경, 게임을 제어하는 ​​방향 키를 구성할 수 있습니다. 구성 방향 순서는 [왼쪽, 아래, 오른쪽, 위]입니다. 효과는 다음과 같습니다.

JavaScript로 Snake 위젯을 구현하는 예제 코드 물론 더 많은 구성이 있습니다. 점수 변경에 대한 콜백 함수, 게임 종료 시 콜백 함수 등을 정의할 수도 있습니다. 다음은 SnakeGame 객체에 공통적인 구성 매개변수와 메소드를 소개합니다. </p><p><strong>2.2 공개 메소드</strong></p><p>•startGame(): 게임을 시작합니다. 이 방법에서는 다양한 설정이 초기화됩니다. 예를 들어 점수, 뱀 몸, 속도 등을 재설정합니다. </p><p>•changeGameStatus(): 게임 상태, 즉 일시 중지 및 시작을 변경합니다. SnakeGame 개체에는 게임 상태 변수로 개인 변수가 있습니다. </p><p><strong>2.3 게임 매개변수 구성을 위한 객체 gameConfigObj 속성, </strong></p><p>gameConfigObj 객체에는 총 10개의 속성, 3개의 콜백 함수가 있어야 합니다. </p><p>attributes</p><p>•size: 뱀 블록과 음식의 크기, 기본값은 20<br/>•rowCount : 행, 기본 30개 행<br/>•colCount: 열, 기본 30개 열<br/>•snakeColor: 뱀 몸체 색상, 기본 녹색<br/>•foodColor: 음식 색상, 기본 노란색<br/>•scenseColor: 게임 장면 배경 색상, 기본 검정색<br/>•directionKey: 방향 키, 기본값 [39, 40, 37, 38] 위, 아래, 왼쪽 및 오른쪽<br/>•pasueKey: 일시 정지 키, 기본값 32, 스페이스 키<br/>•levelCount: 속도 레벨 제어, 기본값 10.<br/>•curSpeed: 초기 속도, 기본값 200ms</p><p>콜백 함수</p> <p>•onCountChange: 이벤트, 모든 음식, 점수 변경, 이 메소드가 매개변수(count)와 함께 호출됩니다. </p><p>•onGamePause: 이벤트, 게임 상태가 변경될 때 이 메소드가 호출됩니다. 일시 중지를 나타내는 매개 변수 1, 0은 게임이 진행 중임을 의미합니다. </p><p>•onGameOver: 이벤트, 게임이 종료되면 이 메서드가 호출됩니다. </p><p><strong>2.4고급 기능 사용 </strong></p><p>위의 속성을 사용하면 보다 대화형 프로그램을 설계할 수 있습니다. 코드는 다음과 같습니다. </p><p>예제 3</p><p class=

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>贪吃蛇组件</title>
 <style type="text/css">
  *{
   margin:0px;
   padding:0px;
  }
  #gamebd{
   width:850px;
   margin:50px auto;
  }
  #gameScense{
   background-color:green;
   float:left;
  }
  #gameSet{
   margin-left:10px;
   float:left;
  }
  .gameBoxStyle{
   margin-bottom:7px;
   padding:5px 10px;
  }
  .gameBoxStyle h3{
   margin-bottom:7px;
  }
  .gameBoxStyle p{
   line-height: 1.7em;
  }
  .gameBoxStyle input{
   margin-top:7px;
   background-color: white;
   border:1px gray solid;
   padding:3px 9px;
   margin-right:9px;
  }
  .gameBoxStyle input[type=text]{
   width:90px;
  }
  .gameBoxStyle input:hover{
   background-color: #e2fff2;
  }
  .gameBoxStyle #txtValue{
   color:red;
  }
 </style>
</head>
<body>
<p id="gamebd">
 <canvas id="gameScense" width="600" height="600">
 </canvas>
 <p id="gameSet">
  <p id="gameControl" class="gameBoxStyle">
   <h3>游戏控制</h3>
   <p>方向键:上,下,左,右</p>
   <p>开始/暂停:空格</p>
  </p>
  <p id="gameStatus" class="gameBoxStyle">
   <h3>游戏状态</h3>
   <p>用户名:<input type="text" placeholder="输入用户名:" id="txtUserName" value="游客123"/> </p>
   <p>当前用户1得分:<span id="txtValue">0</span></p>
   <input type="button" value="开始游戏" id="btnStart"/>
   <input type="button" value="暂停" id="btnPause"/>
  </p>
  <p id="game" class="gameBoxStyle">
   <h3>游戏记录</h3>
   <a href="#" rel="external nofollow" rel="external nofollow" >查看历史记录</a>
  </p>
 </p>
</p>
<script src="js/SnakeGame.js"></script>
</body>
<script src="SnakeGame.js"></script>
<script>
 var btnStart=document.getElementById("btnStart");
 var btnPasue=document.getElementById("btnPause");
 var gameSnake = new SnakeGame("gameScense",{
  snakeColor:"red",
  onCountChange:function(count){
   var txtScore=document.getElementById("txtValue");
   txtScore.innerText=count.toString( );
   txtScore=null;
  },
  onGamePause:function(status){
   if(status){
    btnPasue.value = "开始";
   }else {
    btnPasue.value = "暂停"
   }
  },
  onGameOver:function (status) {
   alert("游戏结束");
  }
 });
 btnStart.onclick=function(event){
  if(checkUserName()){
   gameSnake.startGame();
   btnStart.blur();
  }
 }
 btnPasue.onclick=function(event) {
  gameSnake.changeGameStatus();
  btnStart.blur();
 }
 function checkUserName(){
  var txtUserName = document.getElementById("txtUserName");
  if(txtUserName.value.length==0){
   alert("用户名不能为空");
   return false;
  }else {
   return true;
  }
 }
</script>
</html>
로그인 후 복사

위 코드는 OnChangeCount, onGamePause 및 onGameOver의 세 가지 콜백 함수를 설정하여 인터페이스와 구성 요소 간의 상호 작용을 구현합니다. 효과는 다음과 같습니다.

JavaScript로 Snake 위젯을 구현하는 예제 코드

예제 4

먼저 html 파일을 생성합니다


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Jaume&#39;s贪吃蛇</title>
 <link rel="stylesheet" href="css/gameStyle.css" rel="external nofollow" >
</head>
<body>
<p id="gamebd">
 <canvas id="gameScense" width="600" height="600">
 </canvas>
 <canvas id="gameScense1" width="600" height="600" style="background-color: black">
 </canvas>
 <p id="gameSet">
  <p id="gameControl" class="gameBoxStyle">
   <h3>游戏控制</h3>
   <p>方向键:上,下,左,右</p>
   <p>开始/暂停:空格</p>
  </p>
  <p id="gameStatus" class="gameBoxStyle">
   <h3>游戏状态</h3>
   <p>当前用户1得分:<span id="txtValue">0</span></p>
   <p>当前用户2得分:<span id="txtValue1">0</span></p>
   <input type="button" value="开始游戏" id="btnStart"/>
  </p>
  <p id="game" class="gameBoxStyle">
   <h3>游戏记录</h3>
   <a href="#" rel="external nofollow" rel="external nofollow" >查看历史记录</a>
  </p>
 </p>
</p>
<script src="js/SnakeGame.js"></script>
<script src="js/UIScript.js"></script>
</body>
</html>
로그인 후 복사

样式文件如下:


*{
 margin:0px;
 padding:0px;
}
#gamebd{
 /*width:850px;*/
 /*margin:50px auto;*/
 width:100%;
}
#gameScense{
 background-color:green;
 float:left;
}
#gameSet{
 margin-left:10px;
 float:left;
}
.gameBoxStyle{
 margin-bottom:7px;
 padding:5px 10px;
}
.gameBoxStyle h3{
 margin-bottom:7px;
}
.gameBoxStyle p{
 line-height: 1.7em;
}
.gameBoxStyle input{
 margin-top:7px;
 background-color: white;
 border:1px gray solid;
 padding:3px 9px;
 margin-right:9px;
}
.gameBoxStyle input[type=text]{
 width:90px;
}
.gameBoxStyle input:hover{
 background-color: #e2fff2;
}
.gameBoxStyle #txtValue{
 color:red;
}
로그인 후 복사

在html中拖入了两个文件,一个是贪吃蛇组件,另一个是UIScript.js,其中的代码如下:


/**
 * Created by tjm on 8/16/2017.
 */
var btnStart=document.getElementById("btnStart");
var gameSnake = new SnakeGame("gameScense",{
 snakeColor:"red",
 directionKey:[68,83,65,87],
 pauseKey:81,
 onCountChange:function(count){
  var txtScore=document.getElementById("txtValue");
  txtScore.innerText=count.toString( );
  txtScore=null;
 },
 onGameOver:function (status) {
  alert("游戏结束");
 }
});
var gameSnake1 = new SnakeGame("gameScense1",{
 snakeColor:"green",
 size:20,
 onCountChange:function(count){
  var txtScore=document.getElementById("txtValue1");
  txtScore.innerText=count.toString();
  txtScore=null;
 },
 onGameOver:function (status) {
  alert("游戏结束");
 }
});
btnStart.onclick=function(event){
  gameSnake.startGame();
  gameSnake1.startGame();
  btnStart.blur();
}
로그인 후 복사

实例化两个SnakeGame对象,一个对象使用默认的上下左右键和空格键作为方向键和暂停键,而另一个使用了,W、A、S、D 以及 Q 作为方向键和暂停键。效果如下:

JavaScript로 Snake 위젯을 구현하는 예제 코드嗯哼,没错,完美实现了。使用SnakeGame这个组件,创建贪吃蛇游戏就是如此的简单。下面简单介绍一下,组件的实现方式。</p><p><span   style=3贪吃蛇组件实现方式

在上一节中就提到过,没有采用过道哥拉斯的设计模式,下面给出贪吃蛇设计结构。具体的源代码,可以在后面的链接中进行下载。代码如下:


/**
 * Created by tjm on 8/18/2017.
 */
var SnakeGame = function () {
 /*蛇块和食物组件类*/
 function SnakeBlock(row,col){
  this.row=row;
  this.col=col;
 }
 SnakeBlock.prototype.draw = function(graphic,color,size){
  graphic.fillStyle=color;
  graphic.fillRect(size*this.col,size*this.row,size-2,size-2);
 }
 SnakeBlock.prototype.clearDraw = function(graphic,color,size){
  graphic.fillStyle=color;
  graphic.fillRect(size*this.col,size*this.row,size,size);
 }
 SnakeBlock.prototype.equal = function(snakeBlock){
  if(snakeBlock.row==this.row && snakeBlock.col==this.col){
   return true;
  }else{
   return false;
  }
 }
 /*贪吃蛇组件类*/
 function SnakeGame(gameScenseId, gameConfigObj) {
  // 私有属性
  var gameScense = document.getElementById(gameScenseId);
  var graphic = gameScense.getContext("2d");
  var count = 0;
  var snake;
  var curFood;
  var runId;
  var isMoved = false;//方向改变后,如果没有移动则方向键暂时失效。
  var gameStatus = false;
  var curDirection = 1;
  var size = gameConfigObj.size || 20;
  var rowCount = gameConfigObj.rowCount || 30;
  var colCount = gameConfigObj.colCount || 30;
  var snakeColor = gameConfigObj.snakeColor || "green";
  var foodColor = gameConfigObj.foodColor || "yellow";
  var scenseColor = gameConfigObj.scenseColor || "black";
  var directionKey = gameConfigObj.directionKey || [39, 40, 37, 38];
  var pauseKey = gameConfigObj.pauseKey || 32;
  var levelCount = gameConfigObj.levelCount || 10;
  var curSpeed = gameConfigObj.curSpeed || 200;
  //公开事件
  var onCountChange = gameConfigObj.onCountChange || null; //带有一个参数
  var onGamePause = gameConfigObj.onGamePause || null; //带有一个参数
  var onGameOver = gameConfigObj.onGameOver || null;
  //判断
  if(gameScense.width != size*rowCount || gameScense.height != size*colCount){
   throw "场景大小不等于行列大小*蛇块大小";
  }
  //特权方法
  this.startGame = startGame;
  this.changeGameStatus = changeGameStatus;
  //注册 dom 键盘事件
  var preFunc = document.onkeydown;
  document.onkeydown = function (e) {
   var key = (e || event).keyCode;
   handleKeyInput(key);
   if (typeof preFunc == "function") {
    preFunc(e);
   }
  }
  //私有方法
  /*初始化蛇身*/
  function initSnake(){
   ···
  }
  /*绘制场景背景色*/
  function initScense(){
   ···
  }
  /*产生食物*/
  function genFood(){
   ···
  }
  /*吃食物*/
  function eatFood(snakeHead){
   ···
  }
  /*判断游戏是否结束*/
  function gameOver(){
   ···
  }
  /*蛇移动*/
  function snakeMove(){
   ···
  }
  function changeSpeed(){
   ···
  }
  function handleKeyInput(key){
   ···
  }
  function initGame(){
   ···
  }
  function triggerEvent(callback,argument){
   ···
  }
  function runGame(){
   ···
  }
  function pauseGame() {
   ···
  }
  function changeGameStatus(){
   ···
  }
  function startGame(){
   ···
  }
 }
 return SnakeGame; //最后返回一个组件构造函数
}();
로그인 후 복사

上面有一个很重要的地方,就是键盘注册的代码,单独列出来分析一下。


var preFunc = document.onkeydown;
  document.onkeydown = function (e) {
   var key = (e || event).keyCode;
   handleKeyInput(key);
   if (typeof preFunc == "function") {
    preFunc(e);
   }
  }
로그인 후 복사

该段代码的逻辑是,首先判断在 document 上是否注册了onkeydown 事件,如果注册了该事件,则保存所引用的事件处理程序,然后重置onkeydown事件程序,然后在新的事件处理程序中,调用先前的事件处理程序,这样就实现了事件触发后,调用所有监听该事件处理程序,而不是直接覆盖。

另外关于贪吃蛇的设计逻辑,可以参看我另外一篇文章,个人觉得讲的非常详细了,文章:基于控制台实现贪吃蛇游戏

3 小结

通过这次贪吃蛇组件的设计,对 js 的模块化设计稍微了解了一下,但是,我也不知道上文所实现的贪吃蛇模块有哪些缺陷,希望有大神看到这篇文章,能给一些指导。当然了,该组件还可以进行进一步的扩展,比如将游戏的方块,替换成图片。

위 내용은 JavaScript로 Snake 위젯을 구현하는 예제 코드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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