Pro JavaScript List.11-11
//为实现各种现代浏览器的requestAnimationFrame()方法,创建一段简单的跨浏览器保障代码(polyfill),以实现流畅、高效的动画。由保罗•艾里什(Paul Irish)编写,网址为 http://bit.ly/req_anim_frame。
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback){
window.setTimeout(callback, 1000 / 60);
};
})(); // Define the game logic module which keeps track of the game state, the players's score,
// the number of lives remaining, handles collisions between the player's character and
// other obstacles and ensures the game graphics are drawn onto the <canvas> at the
// right moment. This module contains the brains behind the game play and instructs other
// code modules to do the heavy lifting through the use of the observer design pattern.
//定义游戏的逻辑模块。此模块保持追踪以下内容,包括有游戏状态、玩家的分数、剩余的生命条数。此模块还处理玩家角色和其他物体碰撞。此模块还确保游戏图形可以在正确的时刻绘制到<canvas>上。
(function(Frogger) { // Define a variable to hold the current player's score
//定一个变量来记录玩家当前的分数。
var _score = 0, // Define and initialize a variable to hold the high score achieved in the game
//定义并初始化一个变量来记录游戏中所获得的最高分。
_highScore = 1000, // Define the number of lives the player has remaining before the game is over
//定义游戏结束前玩家还剩余的生命条数。
_lives = 5, // Define the number of milliseconds the player has to get their character to
// the goal (60 seconds). If they take too long, they will lose a life
//定义玩家要将他们的角色送达目标位置的毫秒数(60秒)。如果玩家耗用时间过长,则他们将失去一条生命。
_timeTotal = 60000, // Define a variable to store the current time remaining for the player to reach
// the goal
//定义一个变量来保存玩家要到达目标位置的当前剩余时间。
_timeRemaining = _timeTotal, // Define the refresh rate of the graphics on the <canvas> element (one draw every
// 33⅓ milliseconds = 30 frames per second). Attempting to redraw too frequently
// can cause the browser to slow down so choose this value carefully to maintain a
// good balance between fluid animation and smooth playability
//定义<canvas>元素上的图形的刷新时间(每33⅓毫秒绘制一次 = 每秒30帧)。频率太快的重新绘制会引起浏览器响应缓慢。因此,选择使用这个值可以在流畅的动画与利索的可玩性之间取得平衡。
_refreshRate = 33.333, // Define a variable to store the number of times the player's character has
// reached the goal
//定义一个变量来保存玩家的角色已经到达目标位置的次数。
_timesAtGoal = 0, // Define a variable to indicate the number of times the player's character needs
// to reach the goal for the game to be won
//定义一个变量来记录玩家的角色为取得胜利还须到达目标位置的次数。
_maxTimesAtGoal = 5, // Define a Boolean variable to indicate whether the player's movement is currently
// frozen in place
//定义一个布尔变量来记录玩家当前的移动状态是否被冻结在原地。
_isPlayerFrozen = false, // Define a variable to store the last time the game loop ran - this helps keep
// the animation running smoothly at the defined refresh rate
//定义一个变量来保存上一次游戏主循环运行的时间——这有助于使动画以所定义的刷新频率下流通运行。
_lastTimeGameLoopRan = (new Date()).getTime(); // Define a function to be called to count down the time remaining for the player to
// reach the goal without forfeiting a life
//定义一个函数进行调用,用来对玩家到达目标而不至于失去一条生命的剩余时间进行倒计时。
function countDown() {
if (_timeRemaining > 0) { // This function will be called as frequently as the _refreshRate variable
// dictates so we reduce the number of milliseconds remaining by the
// _refreshRate value for accurate timing
//此函数将会根据_refreshRate变量值的频率进行调用。这样,我们就可以用剩余的毫秒数减去_refreshRate变量的值来实现精确的倒计时。
_timeRemaining -= _refreshRate; // Publish the fact that the remaining time has changed, passing along the
// new time remaining as a percentage - which will help when we come to display
// the remaining time on the game board itself
//发出通知,剩余时间已经发生改变,把新的剩余时间以百分比形式传入——有助于我们在游戏面板上显式剩余时间。
Frogger.observer.publish("time-remaining-change", _timeRemaining / _timeTotal);
} else { // If the remaining time reaches zero, we take one of the player's remaining
// lives
//如果剩余时间到达零,则将玩家的剩余生命条数减一。
loseLife();
}
} // Define a function to be called when all the player's lives have gone and the game
// is declared over
//定义一个函数,当玩家所有的生命已经失去时调用此函数,并宣布游戏结束。
function gameOver() { // Pause the player's movements as they are no longer in the game
//暂停玩家的移动,因为他们已经不能再继续进行游戏了。
freezePlayer(); // Inform other code modules in this application that the game is over
//通知这个应用程序中的其他代码模块,游戏已经结束。
Frogger.observer.publish("game-over");
} // Define a function to be called when the player has reached the goal
//定义一个函数,当玩家到达最终目标时调用此函数。
function gameWon() { // Inform other code modules that the game has been won
//通知其他代码模块,游戏取得胜利。
Frogger.observer.publish("game-won");
} // Define a function to be called when the player loses a life
//定义一个函数,当玩家失去一条生命时调用此函数。
function loseLife() { // Decrease the number of lives the player has remaining
//玩家的剩余生命条数减一。
_lives--; // Pause the player's movements
//暂停玩家的移动。
freezePlayer(); // Inform other code modules that the player has lost a life
//通知其他代码模块,玩家已经失去一条生命。
Frogger.observer.publish("player-lost-life"); if (_lives === 0) { // Declare the game to be over if the player has no lives remaining
//如果玩家没有剩余生命,则宣布游戏结束。
gameOver();
} else { // If there are lives remaining, wait 2000 milliseconds (2 seconds) before
// resetting the player's character and other obstacles to their initial
// positions on the game board
//如果还有剩余生命,则等待2000毫秒(2秒),再把玩家角色和其他物体重新设置至他们各自在游戏面板中的初始位置。
setTimeout(reset, 2000);
}
} // Define a function to be called when the player's character is required to be frozen
// in place, such as when the game is over or when the player has lost a life
//定义一个函数,当玩家角色需要被冻结在原地时进行调用。如游戏结束时,或当玩家失去一条生命时。
function freezePlayer() { // Set the local variable to indicate the frozen state
//将局部变量_isPlayerFrozen设为true来表示冻结状态。
_isPlayerFrozen = true; // Inform other code modules - including that which controls the player's
// character - that the player is now be frozen
//通知其他代码模块——包括控制玩家角色的模块——玩家现在被冻结了。
Frogger.observer.publish("player-freeze");
} // Define a function to be called when the player's character is free to move after
// being previously frozen in place
//定义一个函数,当玩家的角色从先前的冻结在原地状态恢复至自由移动状态时,调用此函数。
function unfreezePlayer() { // Set the local variable to indicate the new state
//将局部变量_isPlayerFrozen设为false来表示新状态。
_isPlayerFrozen = false; // Inform other code modules that the player's character is now free to move around
// the game board
//通知其他代码模块,玩家的角色现在可以在游戏面板上自由移动。
Frogger.observer.publish("player-unfreeze");
} // Define a function to increase the player's score by a specific amount and update
// the high score accordingly
//定义一个函数来以特定的分值增加玩家的分数,并相应地更新最高分数记录。
function increaseScore(increaseBy) { // Increase the score by the supplied amount (or by 0 if no value is provided)
//用参数所提供的分值加增加分数(如果没有分值提供,则以0作为增加分值)。
_score += increaseBy || 0; // Inform other code modules that the player's score has changed, passing along
// the new score
//通知其他代码模块,玩家的分数已经发生改变,把新的分数传入。
Frogger.observer.publish("score-change", _score); // If the player's new score beats the current high score then update the high
// score to reflect the player's new score and inform other code modules of a
// change to the high score, passing along the new high score value
//如果玩家的新分数高于当前的最高分数记录,则更新最高分数记录的值来对应出玩家的新分数,并通知其他代码模块最高分记录发生了改变,把新的最高分值传入。
if (_score > _highScore) {
_highScore = _score;
Frogger.observer.publish("high-score-change", _highScore);
}
} // Define a function to execute once the player reaches the designated goal
//定义一个函数,一旦玩家到达指定的目标位置后,执行此函数。
function playerAtGoal() { // When the player reaches the goal, increase their score by 1000 points
//当玩家到达目标位置,将玩家的分数增加1000分。
increaseScore(1000); // Increment the value indicating the total number of times the player's character
// has reached the goal
//增加表示玩家的角色已经到达目标位置总次数的值。
_timesAtGoal++; // Freeze the player's character movement temporarily to acknowledge they have
// reached the goal
//临时冻结玩家角色的移动来表示确认玩家已经到达目标位置。
freezePlayer(); if (_timesAtGoal < _maxTimesAtGoal) { // The player must enter the goal a total of 5 times, as indicated by the
// _maxTimesAtGoal value. If the player has not reached the goal this many
// times yet, then reset the player's character position and obstacles on the
// game board after a delay of 2000 milliseconds (2 seconds)
//玩家必须进入目标位置5次,如_maxTimesAtGoal的值所示。如果玩家还没有完成这个数量,则等待2000毫秒(2秒),在游戏面板上重新设置玩家角色位置以及各个其他物体。
setTimeout(reset, 2000);
} else { // If the player has reached the goal 5 times, the game has been won!
//如果玩家已经到达目标位置5次,则游戏胜利。
gameWon();
}
} // Define a function to execute when the player moves their character on the game
// board, increasing their score by 20 points when they do
//定义一个函数,当玩家把角色在游戏面板上移动时,执行此函数。当玩家移动角色时,分数增加20分。
function playerMoved() {
increaseScore(20);
} // Define a function to be called when the game board needs to be reset, such as when
// the player loses a life
//定义一个函数,当游戏面板需要重新设置时进行调用。如当玩家失去一条生命时。
function reset() { // Reset the variable storing the current time remaining to its initial value
//把保存当前剩余时间的变量重设为它的初始值。
_timeRemaining = _timeTotal; // Release the player's character if it has been frozen in place
//如果玩家的角色已经被冻结在原地,则解除冻结。
unfreezePlayer(); // Inform other code modules to reset themselves to their initial conditions
//通知其他代码模块,使它们本身重设至各自的初始状态。
Frogger.observer.publish("reset");
} // The game loop executes on an interval at a rate dictated by value of the
// _refreshRate variable (once every 50 milliseconds), in which the game board is
// redrawn with the character and obstacles drawn at their relevant positions on
// the board and any collisions between the player's character and any obstacles
// are detected
//游戏主循环以特定的频率按某时间间隔执行,该频率由变量_refreshRate的值指定(每50毫秒一次【注:这里应是每33.333毫秒一次】),
function gameLoop() { // Calculate how many milliseconds have passed since the last time the game loop
// was called
//计算自从上一次游戏主循环调用以来,所过去的毫秒数。
var currentTime = (new Date()).getTime(),
timeDifference = currentTime - _lastTimeGameLoopRan; // Execute this function again when the next animation frame is ready for use by
// the browser - keeps the game loop looping
//当下一动画帧准备好可供浏览器使用时执行此函数——保持游戏主循环持续进行。
window.requestAnimationFrame(gameLoop); // If the number of milliseconds passed exceeds the defined refresh rate, draw
// the obstacles in the updated position on the game board and check for collisions
//如果已经过去的毫秒时间超过了所定义的刷新频率时间,则在游戏面板上将各物体绘制在更新后的位置,并检测是否存在碰撞。
if (timeDifference >= _refreshRate) { // Clear the <canvas> element's drawing surface - erases everything on the
// game board so we can redraw the player's character and obstacles in their
// new positions
//清空<canvas>元素的绘制表面——擦除在游戏上的所有内容以便我们能将玩家的角色和各物体绘制在各自的新位置上。
Frogger.drawingSurface.clearRect(0, 0, Frogger.drawingSurfaceWidth, Frogger.drawingSurfaceHeight); if (!_isPlayerFrozen) { // As long as the player's character is not frozen in place, ensure the
// timer is counting down, putting pressure on the player to reach the
// goal in time
//只要玩家的角色没有被冻结在原地,就要确保进行倒计时,给玩家施加压力使其能在限时内到达目标地点。
countDown(); // Inform other code modules to check the player has not collided with an
// obstacle on the game board
//通知其他代码模块来检查玩家是否撞上游戏面板上的某个物体。
Frogger.observer.publish("check-collisions");
} // Now on our empty canvas we draw our game board and the obstacles upon it in
// their respective positions
//现在,我们在空白的canvas上绘制游戏面板,以及把各个物体绘制到各自位置上。
Frogger.observer.publish("render-base-layer"); // After the game board and obstacles, we draw the player's character so that
// it is always on top of anything else on the <canvas> drawing surface
//绘制完游戏面板和各个物体后,我们才绘制玩家的角色。这样,在<canvas>的绘制平面中,玩家角色就实现了置顶的效果。
Frogger.observer.publish("render-character"); // Store the current time for later comparisons to keep the frame rate smooth
//保存当前时间用于稍后进行对比,以保持帧频流畅。
_lastTimeGameLoopRan = currentTime;
}
} // Define a function to kick-start the application and run the game loop, which renders
// each frame of the game graphics and checks for collisions between the player's
// character and any obstacles on the game board
//定义一个函数来启动应用程序并运行游戏主循环。游戏主循环会渲染每一帧的游戏图像,并检测玩家角色与游戏面板中的其他物体之间的碰撞。
function start() { // Inform other code modules of the initial state of the game's high score
//把游戏最高分数的初始值通知其他代码模块。
Frogger.observer.publish("high-score-change", _highScore); // Start the game loop running
//使游戏主循环开始运行。
gameLoop();
} // Execute the start() function to kick off the game loop once the "game-load" event
// is fired. We'll trigger this event after we've configured the rest of our code
// modules for the game
//一旦“game-load”事件发生,执行start()函数来启动游戏主循环。在我们为游戏完成其余的代码模块配置后,我们将触发该事件。
Frogger.observer.subscribe("game-load", start); // Execute the playerAtGoal() function when another code module informs us that the
// player has reached the goal
//当其他代码模块通知我们玩家已经到达目标位置后,执行playerAtGoal()函数。
Frogger.observer.subscribe("player-at-goal", playerAtGoal); // Execute the playerMoved() function when we have been informed that the player has
// moved their character
//当我们接到通知说玩家已经移动他们的角色时,执行playerMoved()函数。
Frogger.observer.subscribe("player-moved", playerMoved); // Execute the loseLife() function when we are informed by another code base that the
// player's character has collided with an obstacle on the game board
//当我们被其他代码通知说玩家的角色和游戏面板中的某个物体发生碰撞时,执行loseLife()函数。
Frogger.observer.subscribe("collision", loseLife); // Pass the global Frogger variable into the module so it can be accessed locally,
// improving performance and making its dependency clear
//把全局Frogger变量传入模块中,这样它就可以局部变量方式被访问,有助于提高性能。
}(Frogger));
Pro JavaScript List.11-11的更多相关文章
- NOIp 11.11/12
最后一场比较正式的NOIp模拟赛,写一发小总结.题目没什么好说的,大部分很简单,先贴一下代码. 1111 T1 //string //by Cydiater //2016.11.11 #include ...
- 11.11光棍节工作心得——github/MVP
11.11光棍节工作心得 1.根据scrum meeting thirdday中前辈的指导进行学习 我在博客中贴了链接,竟然TrackBack引来了原博主,
- 下面程序的输出结果是____ A:11,10 B:11,11 C:10,10 D:10,11 int x=10; int y=x++; printf("%d,%d",(x++,y),y++);
下面程序的输出结果是____ A:11,10 B:11,11 C:10,10 D:10,11 int x=10; int y=x++; printf("%d,%d",(x++,y) ...
- Hadoop格式化 From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection exception: java.net.
192.168.11.12:8485: Call From hu-hadoop1/192.168.11.11 to hu-hadoop2:8485 failed on connection excep ...
- 〖Linux〗iptables端口转发(11.11.136.80:5552 <==> 10.10.136.1:8055/11.11.136.1:8055)
环境: pc1: 10.10.72.1 (network: 10.10.72.0/22) pc2: 地址1: 10.10.136.1 (nework: 10.10.136.0/22) 地址2: 11. ...
- 2017.11.11 B201 练习题思路及解题方法
2017.11.11 B201 练习题思路及解题方法 题目类型及涵盖知识点 本次总共有6道题目,都属于MISC分类的题目,涵盖的知识点有 信息隐藏 暴力破解 音轨,摩斯电码 gif修改,base64原 ...
- Notes of Daily Scrum Meeting(11.11)
Notes of Daily Scrum Meeting(11.11) 今天是11月11号光棍节,不知道大家的购物热情被点燃没有,有没有买到自己心仪的东西.额,今天我们的团队任务进度和昨天差不多, 每 ...
- TeamWork#3,Week5,Scrum Meeting 11.6, 11.7, 11.11, 11.12
11.6:到目前为止基本已完成相关知识的学习,各方面工作都开始进行,一开始进行比较慢. 11.7:项目遇到困难,需要补充相关知识,进度慢了下来. 11.11:各方面工作进展比较顺利,没有什么大问题. ...
- new Date("2018-01-01 11:11:11").valueOf() 在IE下会返回 NaN
原因是在ie下 new Date不能处理 小横线 这种时间格式,但是 替换成 斜线就可以正常获得毫秒数,像下面这样: new Date(('2018-01-01 11:11:11').replace( ...
- [18/11/11] java标识符及变量
一.标识符规范 1.必须以字母.下划线 .美元符号开头. 即数字不能作为开头,其它位随便 2.不可以是java关键字(即保留字), 如static .class.new 等 . 注:int 年 ...
随机推荐
- 解决docker容器开启端口映射后,会自动在防火墙上打开端口的问题
在docker中运行第三方服务时,通常需要绑定服务端口到本地主机.但使用 -p 参数进行的端口映射,会自动在iptables中建立规则,绕过firewalld,这对于端口级的黑白名单控制管理是很不利的 ...
- Linux系统上对其他用户隐藏进程的简单方法
mount -o remount,rw,hidepid=2 /proc 我使用的是多用户系统,大部分的用户通过ssh客户端访问他们的资源.我如何(怎么样)避免泄露进程信息给他们?如何(怎么样)在Deb ...
- dao层取值用List<map<String,Object>>接收有序map
发现一个好玩的Map, 当需要Map有序时用java.util.LinkedHashMap接收,是有序map resultType="java.util.LinkedHashMap" ...
- 修改 SQL SERVER 2008 編輯前200筆 資料表問題? 转载自:http://www.dotblogs.com.tw/easy1201/archive/2008/12/04/6179.aspx
小弟前幾天 下載安裝了 SQL SERVER 2008 感覺系統效能還不錯 但是要編輯 資料表卻出現 很苦惱 但經過一番波折 終於了解如何改善 先執行SQL Server Management Stu ...
- Java笔记(基础第二篇)
声明数组 数组元素类型 数组名字[]; 数组元素类型[] 数组名字; 分配内存空间 数组名字 = new 数组元素类型[数组元素的个数] 其中使用new关键字为数组分配内存时,数组中各个元素的初始化值 ...
- Appium Python核心API
adb命令模拟按键事件 :http://blog.sina.com.cn/s/blog_68f262210102vc1b.html
- CentOS6与7区别整理
(1)桌面系统 [CentOS6] GNOME 2.x [CentOS7] GNOME 3.x(GNOME Shell) (2)文件系统 [CentOS6] ext4 [CentOS7] xfs (3 ...
- AtCoder Beginner Contest 137 D题【贪心】
[题意]一共有N个任务和M天,一个人一天只能做一个任务,做完任务之后可以在这一天之后的(Ai-1)天拿到Bi的工资,问M天内最多可以拿到多少工资. 链接:https://atcoder.jp/cont ...
- 014_linuxC++之_不同类型的继承
#include <iostream> #include <string.h> #include <unistd.h> using namespace std; c ...
- printf:函数参数计算从右向左,从左向右?
造冰箱的大熊猫@cnblogs 2019/8/3 1.问题 某天写了如下代码: unsigned char ReadByteFromFile ( FILE * fp ) { unsigned char ...