JavaScript小游戏--2048(PC端)
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端)的更多相关文章
- JavaScript小游戏--2048(移动端)
HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...
- JavaScript小游戏--2048(程序流程图)
- 制作一个 JavaScript 小游戏
简评: 作者学习了编程两个月,边学边做了一个 JavaScript 小游戏,在文中总结了自己在这个过程中的一些体会,希望能给其他初学者一些帮助. 对于很多想学编程但一直没下定决心的同学来说,最大的问题 ...
- javascript小实例,移动端页面中的拖拽
上文说到,想将移动端的拖拽说一说,那现在趁有时间,就将这个福利文带来了,哈哈! 在我还不知道怎么做移动端的手势操作的时候,我觉得这TM实在是太难了,这是多么高深的学问啊,手势操作耶,上滑下滑左滑右滑的 ...
- c语言----<项目>_小游戏<2048>
2048 小游戏 主要是针对逻辑思维的一个训练. 主要学习方面:1.随机数产生的概率.2.行与列在进行移动的时候几种情况.3.MessageBox的使用 #include <iostream&g ...
- 喜大普奔 | 微信小程序支持PC端打开了
微信小程序可以在PC端打开啦 微信PC版发布了v2.7.0测试版,其中一个重磅的功能就是:支持打开聊天中分享的小程序 咖啡君这么喜欢尝鲜的人自然是在第一时间下载进行了体验 安装成功,会有功能更新说明 ...
- C语言小游戏: 2048.c
概要:2048.c是一个C语言编写的2048游戏,本文将详细分析它的源码和实现.C语言是一种经典实用的编程语言,本身也不复杂,但是学会C语言和能够编写实用的程序还是有一道鸿沟的.本文试图通过一个例子展 ...
- JavaScript小游戏实例:统一着色
设计如下的简单小游戏. 在面板(画布)中放置10行10列共100个小方块,每个小方块随机在5种颜色中选一种颜色进行着色,在面板的下方,放置对应的5种颜色色块,如图1所示. 图1 “统一着色”游戏界面 ...
- JavaScript小游戏实例:简单的键盘练习
键盘是一种常用的输入设备,灵活熟练地使用键盘进行输入是计算机用户需掌握的一门基本功.下面我们编写一个简单的键盘练习游戏. 1.刺破气泡交互式小动画 在编写简单的键盘练习游戏之前,先设计一个简单地刺破气 ...
随机推荐
- php mktime()函数
PHP提供一个很好用的函数mktime().你只要按顺序传送给mktime()你希望表示的小时,分钟,秒数,月份,日期,及年份,mktime()就会返回该日期自1970年1月1日的总秒数.获取2000 ...
- struts2随笔
1.struts.properties配置常量等同于struts.xml中配置(置于类加载路径下面)struts.multipart.maxSize文件上传最大大小struts.action.exte ...
- Java基础(六)包装类
一.包装类 JAVA是一种面向对象语言,java中的类把方法与数据连接在一起,但在JAVA中不能定义基本类型对象,为了能将基本类型视为对象进行处理,java为每个基本类型都提供了包装类. 对应关系如下 ...
- bash的常用功能呢
一.tab键可以自动补齐命令 二.命令历史 1.history 查看之前敲过的所有命令 2.!历史命令编号 调用历史的某一个命令 三.命令别名 1.设置别名 alias 别名=‘命令’ 2.移除 ...
- Spring系列之Alias标签的解析与使用
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Java序列话和反序列化理解(New)
public interface Serializable {} 该接口没有任何实现方法,是一种标志,instance of Serializable 会判断object类型 一.序列化和反序列化的 ...
- java下double相乘精度丢失问题
比如 System.out.println(0.14*100); 输出: 14.000000000000002 解决方法: BigDecimal b = new BigDecimal(String.v ...
- php字符集转换
PHP通过iconv将字符串从GBK转换为UTF8字符集. 1. iconv()介绍 iconv函数可以将一种已知的字符集文件转换成另一种已知的字符集文件.例如:从GB2312转换为UTF-8. ic ...
- iview中关于table组件内放入Input会失去焦点
table里面的数据是一个数组,父组件传入的.子组件是截图的内容.当每个input框数据发生变化时,把数据传给父组件.在父组件做表单的提交. github内已经提到过这个问题(https://gith ...
- vue.js与angular.js的区别(个人)
刚进入实训 讲师就要发一些什么比较高大上的东西,本人才疏学浅 浅浅的分享一下angularjs 和vue.js的区别.只是简单的理解一下 大神勿喷. 生实训之前学习的angular.js 只是理解了 ...