1.初始化棋局

$(document).ready(function() {
prepare_for_mobile(); //适配移动端
new_game();
});

2.开始新游戏

function new_game() {
back = [];
//初始化棋盘
init();
//在随机两个格子生成数字
generate_one_number();
generate_one_number();
}

3.初始化

function init() {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var grid_cell = $('#grid_cell_' + i + '_' + j);
grid_cell.css('top', get_pos_top(i, j) + 'rem');//每个格子距离顶部和左边的距离;
grid_cell.css('left', get_pos_left(i, j) + 'rem');
}
}
for (var i = 0; i < 4; i++) {
board[i] = new Array();
has_conflicted[i] = new Array();
for (var j =0; j < 4; j++) {
board[i][j] = 0;//生成二维数组,每个格子的数字初始化为0;
has_conflicted[i][j] = false;
}
} update_board_view();
score = 0;
update_score(score);
}

4.更新棋局(改数字大小、数字背景、设置数字宽度、高度、位置)

数字为0、 数字大于100、数字大于1024获取不同的数字大小及背景;

function update_board_view() {
$('.number_cell').remove();//??number_cell
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$('#grid_container').append('<div class="number_cell" id="number_cell_' + i + '_' + j + '"></div>');
var number_cell = $('#number_cell_' + i + '_' + j);
if (board[i][j] == 0) {
number_cell.css({
'width': '0',//宽度、高度为0
'height': '0',
'top': get_pos_top(i, j) + 2.5 + 'rem',//这是每个数字的位置,其相对于每个格子的位置还要加2.5rem(每个格子高度、宽度为5rem)
'left': get_pos_left(i, j) + 2.5 +'rem',
'line-height': '5rem',
'font-size': '3rem'
}); }else if(board[i][j] >= 1024){
console.log(board[i][j]);
number_cell.css({
'width': '5rem',
'height': '5rem',
'top': get_pos_top(i, j) + 'rem',
'left': get_pos_left(i, j) + 'rem',
'background-color': get_number_background_color(board[i][j]),//改变背景颜色
'color': get_number_color(board[i][j]),//改变数字颜色
'line-height': '5rem',
'font-size': '2rem'//字体变小
});
number_cell.text(board[i][j]);
}else if(board[i][j] >= 100){
number_cell.css({
'width': '5rem',
'height': '5rem',
'top': get_pos_top(i, j) + 'rem',
'left': get_pos_left(i, j) + 'rem',
'background-color': get_number_background_color(board[i][j]),
'color': get_number_color(board[i][j]),
'line-height': '5rem',
'font-size': '2.5rem'
});
number_cell.text(board[i][j]);
}else {//小于100
number_cell.css({
'width': '5rem',
'height': '5rem',
'top': get_pos_top(i, j) + 'rem',
'left': get_pos_left(i, j) + 'rem',
'background-color': get_number_background_color(board[i][j]),
'color': get_number_color(board[i][j]),
'line-height': '5rem',
'font-size': '3rem'
});
number_cell.text(board[i][j]);//.text()方法设置或返回被选元素的文本内容
}
has_conflicted[i][j] = false;
}
} }

5.随机在一个格子生成数字

function generate_one_number() {
if (nospace(board)) {//若nospace(board)返回true,说明没有空格子;
return false;
}
//随机一个位置
var randx = parseInt(Math.floor(Math.random() * 4));
var randy = parseInt(Math.floor(Math.random() * 4));//在124行调用
var time = 0;
while (time < 50) {//time??50??
if (board[randx][randy] == 0) {//看看随机选的位置上数字是否为0,为0则可用,跳出循环,不为0,则重新找位置。
break;
}
randx = parseInt(Math.floor(Math.random() * 4));//当board[randx][randy]不为0,则重新选位置。
randy = parseInt(Math.floor(Math.random() * 4));
time++;
}
if (time == 50) {//如果连续找了50次都没找到数字为0的位置,则按二维数组挨个去找,直到找到第一个数字为0的格子;
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (board[i][j] == 0) {
randx = i;
randy = j;
}
}
}
}
//随机一个数字
var rand_number = Math.random() < 0.5 ? 2 : 4;
//在随机位置显示随机数字
board[randx][randy] = rand_number;
show_number_with_animation(randx, randy, rand_number);//动画显示数字格子
save_status(board); //每生产一个数字,保存状态(以便撤回),模拟快照,每一步生成一个对象,调用support.js中函数
return true;
}

6.监听键盘的上下左右移动

keyCode(键码),指定与引发事件的键关联的Unicode的键码。此属性旨在与所述的onkeydown,的onkeyup和onkeypress事件的事件中使用。

键盘上下左右 方向键的键码(keyCode)是38、40、37和39

$(document).keydown(function(event) {
if ($('#score').text() == success_string) {//一按下键盘首先判断是否成功。324行判断数字是否到达2048,若等于2048则调用showanimation.js中的更新分数函数;
new_game();
return;
}
switch (event.keyCode) {//键盘上下左右 方向键的键码(keyCode)是38、40、37和39
case 37: //left
event.preventDefault();
if (move_left()) {
setTimeout('generate_one_number()', 200);//在指定的毫秒数后调用函数或计算表达式,setTimeout() 只执行 code 一次;
setTimeout('is_gameover()', 300);
}
break;
case 38: //up
event.preventDefault();
if(move_up()){
setTimeout('generate_one_number()',200);
setTimeout('is_gameover()', 300);
}
break;
case 39: //right
event.preventDefault();
if(move_right()){
setTimeout('generate_one_number()',200);
setTimeout('is_gameover()', 300);
}
break;
case 40: //down
event.preventDefault();
if (move_down()){
setTimeout('generate_one_number()',200);
setTimeout('is_gameover()', 300);
}
break;
default:
break;
}
});

7.向左移动 (向右移动、向上移动、向下移动类似)

function move_left() {//判断能否左移,调用support.js
if (!can_move_left(board)) {
return false;
}
//move left
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) { //j=1
if (board[i][j] != 0) {
for (var k = 0; k < j; k++) {
if (board[i][k] == 0 && no_block_horizontal(i, k, j, board)) {//(i,k)为0且(i,k)到(i,j)之间都是0
show_move_animation(i, j, i, k);//格子移动时有动画效果,从(i,j)到(i,k)
board[i][k] = board[i][j];
board[i][j] = 0;
break;//跳出的只是199行的for循环,外面还有两层循环
} else if (board[i][k] == board[i][j] && no_block_horizontal(i, k, j, board) && !has_conflicted[i][k]) {//可合并的情况,(i,k)和(i,j)数字相等且(i,k)到(i,j)之间都是0
show_move_animation(i, j, i, k);
board[i][k] += board[i][j];
board[i][j] = 0;
//add score
score += board[i][k];
update_score(score);
has_conflicted[i][k] = true;//??
break;
}
}
}
}
}
setTimeout('update_board_view()', 200);
return true;
}

8.判断游戏是否成功

function is_gameover() {
for(var i=0; i<4; i++){
for(var j=0; j<4; j++){
if (board[i][j] == 2048){
update_score(success_string);
return;
}
}
}
if (nospace(board) && nomove(board)) {//没有空格子,且各个方向不能移动合并;
gameover();
}
}
function gameover() {
alert("走投无路啦");
}

9.保存状态

function save_status(board) {
var o = new Object();
var n = 1;
for(var i=0; i<4; i++){
for(var j=0; j<4; j++){
o[n] = score+ ',' + board[i][j];//每个o长度为16
n ++;
}
}
back.push(o); //调用一次save_status(board),back长度加1.
}

10.撤销状态(回退)

function come_back() {
if (back.length<=2){//back数组长度小于2
return;
}
var o = back[back.length-2];//结合support.js中保存状态的函数理解,back数组长度减2,back[]取减2后的位置上的值,(每生成一个数字会保存一次状态,back数组长度加1)
var n = 1;
//o[n]遍历对象
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {//把存的score和board[i][j]取出
board[i][j] = parseInt(o[n].substr(o[n].lastIndexOf(',')+1));//lastIndexOf从右向左出现某个字符或字符串的首个字符索引值,该索引值加1,即可去到,的后半部分
score = parseInt(o[n]);//逗号前面的
n++;
}
}
update_score(score);
back.pop();
setTimeout('update_board_view()',200);
}

JavaScript小游戏--2048(PC端)的更多相关文章

  1. JavaScript小游戏--2048(移动端)

    HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...

  2. JavaScript小游戏--2048(程序流程图)

  3. 制作一个 JavaScript 小游戏

    简评: 作者学习了编程两个月,边学边做了一个 JavaScript 小游戏,在文中总结了自己在这个过程中的一些体会,希望能给其他初学者一些帮助. 对于很多想学编程但一直没下定决心的同学来说,最大的问题 ...

  4. javascript小实例,移动端页面中的拖拽

    上文说到,想将移动端的拖拽说一说,那现在趁有时间,就将这个福利文带来了,哈哈! 在我还不知道怎么做移动端的手势操作的时候,我觉得这TM实在是太难了,这是多么高深的学问啊,手势操作耶,上滑下滑左滑右滑的 ...

  5. c语言----<项目>_小游戏<2048>

    2048 小游戏 主要是针对逻辑思维的一个训练. 主要学习方面:1.随机数产生的概率.2.行与列在进行移动的时候几种情况.3.MessageBox的使用 #include <iostream&g ...

  6. 喜大普奔 | 微信小程序支持PC端打开了

    微信小程序可以在PC端打开啦 微信PC版发布了v2.7.0测试版,其中一个重磅的功能就是:支持打开聊天中分享的小程序 咖啡君这么喜欢尝鲜的人自然是在第一时间下载进行了体验 安装成功,会有功能更新说明 ...

  7. C语言小游戏: 2048.c

    概要:2048.c是一个C语言编写的2048游戏,本文将详细分析它的源码和实现.C语言是一种经典实用的编程语言,本身也不复杂,但是学会C语言和能够编写实用的程序还是有一道鸿沟的.本文试图通过一个例子展 ...

  8. JavaScript小游戏实例:统一着色

    设计如下的简单小游戏. 在面板(画布)中放置10行10列共100个小方块,每个小方块随机在5种颜色中选一种颜色进行着色,在面板的下方,放置对应的5种颜色色块,如图1所示. 图1  “统一着色”游戏界面 ...

  9. JavaScript小游戏实例:简单的键盘练习

    键盘是一种常用的输入设备,灵活熟练地使用键盘进行输入是计算机用户需掌握的一门基本功.下面我们编写一个简单的键盘练习游戏. 1.刺破气泡交互式小动画 在编写简单的键盘练习游戏之前,先设计一个简单地刺破气 ...

随机推荐

  1. CentOS7部署.Net Core2.0站点(中)

    继续上篇的内容,本篇来学习下nginx的配置和守护进程supervisor的使用. 一.Nginx安装及配置 (1)安装nginx sudo yum install epel-release #添加源 ...

  2. Angular4 step by step.3

    1.Routes 路由模块 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angul ...

  3. openJDK的下载

    http://jdk7.java.net/source.html # 失效 http://download.java.net/openjdk/jdk7 # 无效,点击文件下载跳转错误页面 http:/ ...

  4. 十 DatagramChannel

    DatagramChannel是一个能收发UDP包的通道.因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入.它发送和接收的是数据包. 打开 DatagramChannel 下面是 Dat ...

  5. css text-shadow

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. Navicat工具、pymysql模块

    一 IDE工具介绍(Navicat) 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具,我们使用Navicat工具,这个工具本质上就是一个socket客户端,可视化的连接m ...

  7. for 循环的时候 append() 是移动不是复制

    使用for 的时候,append() 不是复制,而是移动,只有最后一个元素才真正的append() 到了 解决办法: 1. 使用字符串: 2.使用clone();

  8. OGC 的 WMS、WFS 及WCS服务(转)

    OGC——Open Geospatial Consortium——开放地理信息联盟,是一个非盈利的志愿的国际标准化组织,引领着空间地理信息标准及定位基本服务的发展目前在空间数据互操作领域,基于公共接口 ...

  9. 简单理解C#中的抽象工厂模式是什么概念!

    抽象工厂模式向客户端提供一个接口,使得客户端在不必指定具体类型的情况下,创建多个产品族中的对象.本文采取的仍然是接着以前的那个快餐店的例子.现在,快餐店经常良好,逐渐发展壮大,为了适合不同地方人的饮食 ...

  10. openlayers跨域设置后出现http status 500错误

    最近需要弄一下地理信息系统,用到openlayers和geoserver.在解决跨域的时候出现如下问题.求解决方案啊. 问题如下: 附:已经安装了python27,环境变量path中也添加了:c:\P ...