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. show_space

    create or replace procedure show_space( p_segname_1 in varchar2,p_space in varchar2 default 'AUTO',p ...

  2. Layer UI 模块化的用法(转)

    此文章适合入门的同学查看,之前因为项目的原因,在网上找了一套Layer UI做的后台管理系统模板,完全不懂LayUI里面的JS用法,看了官方文档和其它资料后才明白怎么去实现模块化这个例子,但是还是感觉 ...

  3. golang学习之win7下go环境搭建

    以下均采用windows64环境,首先是go的下载,go有msi安装安装和zip解压安装两种安装方式,使用msi安装后go环境会自动配置,zip解压后需手动配置各种环境变量. 首先是下载,网上一搜一大 ...

  4. isPrototypeOf、instanceof、hasOwnProperty函数整理

    isPrototypeOf 作用:检测一个对象是否是另一个对象的原型.或者说一个对象是否被包含在另一个对象的原型链中 var p = {x:1};//定义一个原型对象 var o = Object.c ...

  5. linux修改用户名和密码

    linux修改用户名和密码 修改root密码:sudo passwd root 修改用户密码(如hadoop) sudo passwd hadoop 修改主机名:sudo vi /etc/hostna ...

  6. https如何工作

    一.http 网络协议基于分层架构构建了七层模型,是ISO建立的用于计算机或者通信系统之间的互联的标准体系.下图展示了其中的五层: http被称为超文本传输协议,是互联网上应用最为广泛的一种网络协议, ...

  7. 第2章 css边框属性

    圆角效果 border-radius border-radius是向元素添加圆角边框. 使用方法: border-radius:10px; /* 所有角都使用半径为10px的圆角 */ border- ...

  8. MySQL聚合函数在计算时,不会自动匹配与之相对应的数据

    学习mysql过程中遇到了一个困惑,纠结了我半天时间,刚刚又重新复习了一下,终于知道问题所在 以下是一个需求: 取得平均薪水最高的部门的部门编号 代码如下: select deptno, avg(sa ...

  9. 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...

  10. Java 监听器,国际化

    1. 监听器 1.1 概述 监听器: 主要是用来监听特定对象的创建或销毁.属性的变化的! 是一个实现特定接口的普通java类! 对象: 自己创建自己用 (不用监听) 别人创建自己用 (需要监听) Se ...