实验楼项目学习笔记-网页2048

首先我们需要有一张4X4的表格:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
    <title>shiyanlou-2048</title>
    <link rel="stylesheet" href="style.css"/>
    <script type="text/javascript" src="http://libs.baidu.com/jquery/2.0.3/jquery.min.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <script type="text/javascript" src="showanimation.js"></script>
    <script type="text/javascript" src="support.js"></script>
</head>
<body>
    <header>
        <h1>shiyanlou-2048</h1>
        <a href="javascript:new_game();" id="new_game_button">New Game</a>
        <p>score: <span id="score">0</span></p>
    </header>
    <div id="grid_container">
        <div class="grid_cell" id="grid_cell_0_0"></div>
        <div class="grid_cell" id="grid_cell_0_1"></div>
        <div class="grid_cell" id="grid_cell_0_2"></div>
        <div class="grid_cell" id="grid_cell_0_3"></div>
 
        <div class="grid_cell" id="grid_cell_1_0"></div>
        <div class="grid_cell" id="grid_cell_1_1"></div>
        <div class="grid_cell" id="grid_cell_1_2"></div>
        <div class="grid_cell" id="grid_cell_1_3"></div>
 
        <div class="grid_cell" id="grid_cell_2_0"></div>
        <div class="grid_cell" id="grid_cell_2_1"></div>
        <div class="grid_cell" id="grid_cell_2_2"></div>
        <div class="grid_cell" id="grid_cell_2_3"></div>
 
        <div class="grid_cell" id="grid_cell_3_0"></div>
        <div class="grid_cell" id="grid_cell_3_1"></div>
        <div class="grid_cell" id="grid_cell_3_2"></div>
        <div class="grid_cell" id="grid_cell_3_3"></div>
    </div>
</body>
</html>
然后需要给页面和每个格子,加上样式:
//style.css
header {
    display: block;
    margin: 0 auto;
    width: 100%;
    text-align: center;
}
 
header h1 {
    font-family: Arial;
    font-size: 60px;
    font-weight: bold;
    margin: 0 auto;
}
 
header #new_game_button {
    display: block;
    margin: 0px auto;
    width: 100px;
    padding: 10px 10px;
    background-color: #8f7a66;
    font-family: Arial;
    color: white;
    border-radius: 10px;
    text-decoration: none;
}
 
header #new_game_button:hover {
    background-color: #9f8b77;
}
 
header p {
    font-family: Arial;
    font-size: 25px;
    margin: 5px auto;
}
 
#grid_container {
    width: 460px;
    height: 460px;
    padding: 20px;
    margin: 0px auto;
    background-color: #bbada0;
    border-radius: 10px;
    position: relative;
}
 
.grid_cell {
    width: 100px;
    height: 100px;
    border-radius: 6px;
    background-color: #ccc0b3;
    position: absolute;
}
 
.number_cell {
    border-radius: 6px;
    font-family: Arial;
    font-weight: bold;
    font-size: 60px;
    line-height: 100px;
    text-align: center;
    position: absolute;
}

//在main.js中

var board = new Array();    //每个格子的数字
var score = 0;  //分数
var has_conflicted = new Array();   //解决连续消除的标记
var startx = 0; //移动端触摸屏幕时开始点的x坐标
var starty = 0; //移动端触摸屏幕时开始点的y坐标
var endx = 0;   //移动端触摸屏幕时结束点的x坐标
var endy = 0;   //移动端触摸屏幕时结束点的y坐标
var success_string = ‘Success‘;
var gameover_string = ‘GameOver‘;
 
//HTML文档加载完成后,初始化棋局
$(document).ready(function() {
    //做自适应处理
    prepare_for_mobile();
    new_game();
});
 
//开始新游戏
function new_game() {
    //初始化棋盘
    init();
    //在随机两个格子生成数字
    generate_one_number();
    generate_one_number();
}
 
//初始化
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));
            grid_cell.css(‘left‘, get_pos_left(i, j));
        }
    }
    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;
            has_conflicted[i][j] = false;
        }
    }
    update_board_view();
    score = 0;
    update_score(score);
}
 
//更新棋局
function update_board_view() {
    $(‘.number_cell‘).remove();
    for (var i = 0; i < 4; i++) {
        for (var j = 0; j < 4; j++) {
            $(‘#grid_container‘).append(‘<div id="number_cell_‘ + i + ‘_‘ + j + ‘"></div>‘);
            var number_cell = $(‘#number_cell_‘ + i + ‘_‘ + j);
            if (board[i][j] == 0) {
                number_cell.css(‘width‘, ‘0px‘);
                number_cell.css(‘height‘, ‘0px‘);
                number_cell.css(‘top‘, get_pos_top(i, j) + cell_side_length / 2);
                number_cell.css(‘left‘, get_pos_left(i, j) + cell_side_length / 2);
            } else {
                number_cell.css(‘width‘, cell_side_length);
                number_cell.css(‘height‘, cell_side_length);
                number_cell.css(‘top‘, get_pos_top(i, j));
                number_cell.css(‘left‘, get_pos_left(i, j));
                number_cell.css(‘background-color‘, get_number_background_color(board[i][j]));
                number_cell.css(‘color‘, get_number_color(board[i][j]));
                number_cell.text(board[i][j]);
            }
            has_conflicted[i][j] = false;
        }
    }
    $(‘.number_cell‘).css(‘line-height‘, cell_side_length + ‘px‘);
    $(‘.number_cell‘).css(‘font-size‘, 0.6 * cell_side_length + ‘px‘);
}
 
//随机在一个格子生成数字
function generate_one_number() {
    if (nospace(board)) {
        return false;
    }
    //随机一个位置
    var randx = parseInt(Math.floor(Math.random() * 4));
    var randy = parseInt(Math.floor(Math.random() * 4));
    var time = 0;
    while (time < 50) {
        if (board[randx][randy] == 0) {
            break;
        }
        randx = parseInt(Math.floor(Math.random() * 4));
        randy = parseInt(Math.floor(Math.random() * 4));
        time++;
    }
    if (time == 50) {
        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);
    return true;
}
 
//自适应处理
function prepare_for_mobile() {
    if (document_width > 500) {
        grid_container_width = 500;
        cell_side_length = 100;
        cell_space = 20;
    }
    $(‘#grid_container‘).css(‘width‘, grid_container_width - 2 * cell_space);
    $(‘#grid_container‘).css(‘height‘, grid_container_width - 2 * cell_space);
    $(‘#grid_container‘).css(‘padding‘, cell_space);
    $(‘#grid_container‘).css(‘border-radius‘, 0.02 * grid_container_width);
    $(‘.grid_cell‘).css(‘width‘, cell_side_length);
    $(‘.grid_cell‘).css(‘height‘, cell_side_length);
    $(‘.grid_cell‘).css(‘border-radius‘, 0.02 * grid_container_width);
}
//在support.js中
document_width = window.screen.availWidth;  //屏幕宽度
grid_container_width = 0.92 * document_width;   //期盘宽度
cell_side_length = 0.18 * document_width;   //格子的大小
cell_space = 0.04 * document_width; //格子之间的间隔
 
//获得相应格子距离期盘顶部的距离
function get_pos_top(i, j) {
    return cell_space + i * (cell_space + cell_side_length);
}
 
//获得相应格子距离棋盘左边的距离
function get_pos_left(i, j) {
    return cell_space + j * (cell_space + cell_side_length);
}
 
//获得相应数字的背景色
function get_number_background_color(number) {
    switch (number) {
        case 2: return ‘#eee4da‘; break;
        case 4: return ‘#ede0c8‘; break;
        case 8: return ‘#f2b179‘; break;
        case 16: return ‘#f59563‘; break;
        case 32: return ‘#f67c5f‘; break;
        case 64: return ‘#f65e3b‘; break;
        case 128: return ‘#edcf72‘; break;
        case 256: return ‘#edcc61‘; break;
        case 512: return ‘#9c0‘; break;
        case 1024: return ‘#33b5e5‘; break;
        case 2048: return ‘#09c‘; break;
        case 4096: return ‘#a6c‘; break;
        case 8192: return ‘#93c‘; break;
    }
    return ‘black‘;
}
 
//获得相应数字的颜色
function get_number_color(number) {
    if (number <= 4)
        return ‘#776e65‘;
    return ‘white‘;
}
 
//判断棋盘上是否还有空格子
function nospace(board) {
    for (var i = 0; i < 4; i++) {
        for (var j = 0; j < 4; j++) {
            if (board[i][j] == 0) {
                return false;
            }
        }
    }
    return true;
}

//在showanimation.js中

//动画显示数字格子

function show_number_with_animation(i, j, rand_number) {
    var number_cell = $(‘#number_cell_‘ + i + ‘_‘ + j);
    number_cell.css(‘background-color‘, get_number_background_color(rand_number));
    number_cell.css(‘color‘, get_number_color(rand_number));
    number_cell.text(rand_number);
    number_cell.animate({
        width: cell_side_length,
        height: cell_side_length,
        top: get_pos_top(i, j),
        left: get_pos_left(i, j)
    }, 50);
}
 
//更新分数
function update_score(score) {
    $(‘#score‘).text(score);
}
上面我们完成了布局和初始化,最后我们就要实现让它能移动,并能够消除,直至游戏成功或失败:
//在main.js中加入
//监听键盘的上下左右移动
$(document).keydown(function(event) {
    if ($(‘#score‘).text() == success_string) {
        new_game();
        return;
    }
    switch (event.keyCode) {
        case 37: //left
            event.preventDefault();
            if (move_left()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
            break;
        case 38: //up
            event.preventDefault();
            if (move_up()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
            break;
        case 39: //right
            event.preventDefault();
            if (move_right()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
            break;
        case 40: //down
            event.preventDefault();
            if (move_down()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
            break;
        default:
            break;
    }
});
 
//监听移动设备的触摸开始
document.addEventListener(‘touchstart‘, function(event) {
    startx = event.touches[0].pageX;
    starty = event.touches[0].pageY;
});
 
//监听移动设备的触摸移动
document.addEventListener(‘touchmove‘, function(event) {
    event.preventDefault();
});
 
//监听移动设备的触摸结束
document.addEventListener(‘touchend‘, function(event) {
    endx = event.changedTouches[0].pageX;
    endy = event.changedTouches[0].pageY;
 
    var deltax = endx - startx;
    var deltay = endy - starty;
    if (Math.abs(deltax) < 0.3 * document_width && Math.abs(deltay) < 0.3 * document_width) {
        return;
    }
    if ($(‘#score‘).text() == success_string) {
        new_game();
        return;
    }
    //x
    if (Math.abs(deltax) >= Math.abs(deltay)) {
        if (deltax > 0) {
            //move right
            if (move_right()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
        } else {
            //move left
            if (move_left()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
        }
    } else {    //y
        if (deltay > 0) {
            //move down
            if (move_down()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
        } else {
            //move up
            if (move_up()) {
                setTimeout(‘generate_one_number()‘, 210);
                setTimeout(‘is_gameover()‘, 300);
            }
        }
    }
});
 
//向左移动
function move_left() {
    if (!can_move_left(board)) {
        return false;
    }
    //move left
    for (var i = 0; i < 4; i++) {
        for (var j = 1; j < 4; j++) {
            if (board[i][j] != 0) {
                for (var k = 0; k < j; k++) {
                    if (board[i][k] == 0 && no_block_horizontal(i, k, j, board)) {
                        show_move_animation(i, j, i, k);
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        break;
                    } else if (board[i][k] == board[i][j] && no_block_horizontal(i, k, j, board) && !has_conflicted[i][k]) {
                        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;
}
 
//向右移动
function move_right() {
    if (!can_move_right(board)) {
        return false;
    }
    //move right
    for (var i = 0; i < 4; i++) {
        for (var j = 2; j >= 0; j--) {
            if (board[i][j] != 0) {
                for (var k = 3; k > j; k--) {
                    if (board[i][k] == 0 && no_block_horizontal(i, j, k, board)) {
                        show_move_animation(i, j, i, k);
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        break;
                    } else if (board[i][k] == board[i][j] && no_block_horizontal(i, j, k, board) && !has_conflicted[i][k]) {
                        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;
}
 
//向上移动
function move_up() {
    if (!can_move_up(board)) {
        return false;
    }
    //move up
    for (var j = 0; j < 4; j++) {
        for (var i = 1; i < 4; i++) {
            if (board[i][j] != 0) {
                for (var k = 0; k < i; k++) {
                    if (board[k][j] == 0 && no_block_vertical(j, k, i, board)) {
                        show_move_animation(i, j, k, j);
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        break;
                    } else if (board[k][j] == board[i][j] && no_block_vertical(j, k, i, board) && !has_conflicted[k][j]) {
                        show_move_animation(i, j, k, j);
                        board[k][j] += board[i][j];
                        board[i][j] = 0;
                        //add score
                        score += board[k][j];
                        update_score(score);
                        has_conflicted[k][j] = true;
                        break;
                    }
                }
            }
        }
    }
    setTimeout(‘update_board_view()‘, 200);
    return true;
}
 
//向下移动
function move_down() {
    if (!can_move_down(board)) {
        return false;
    }
    //move down
    for (var j = 0; j < 4; j++) {
        for (var i = 2; i >= 0; i--) {
            if (board[i][j] != 0) {
                for (var k = 3; k > i; k--) {
                    if (board[k][j] == 0 && no_block_vertical(j, i, k, board)) {
                        show_move_animation(i, j, k, j);
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        break;
                    } else if (board[k][j] == board[i][j] && no_block_vertical(j, i, k, board) && !has_conflicted[k][j]) {
                        show_move_animation(i, j, k, j);
                        board[k][j] += board[i][j];
                        board[i][j] = 0;
                        //add score
                        score += board[k][j];
                        update_score(score);
                        has_conflicted[k][j] = true;
                        break;
                    }
                }
            }
        }
    }
    setTimeout(‘update_board_view()‘, 200);
    return true;    
}
 
//判断游戏成功或失败
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() {
    update_score(gameover_string);
}
//在support.js中加入
//判断是否能向左移动
function can_move_left(board) {
    for (var i = 0; i < 4; i++) {
        for (var j = 1; j < 4; j++) {
            if (board[i][j] != 0) {
                if (board[i][j - 1] == 0 || board[i][j] == board[i][j - 1]) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
//判断是否能向右移动
function can_move_right(board) {
    for (var i = 0; i < 4; i++) {
        for (var j = 2; j >= 0; j--) {
            if (board[i][j] != 0) {
                if (board[i][j + 1] == 0 || board[i][j] == board[i][j + 1]) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
//判断是否能向上移动
function can_move_up(board) {
    for (var j = 0; j < 4; j++) {
        for (var i = 1; i < 4; i++) {
            if (board[i][j] != 0) {
                if (board[i - 1][j] == 0 || board[i - 1][j] == board[i][j]) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
//判断是否能向下移动
function can_move_down(board) {
    for (var j = 0; j < 4; j++) {
        for (var i = 2; i >= 0; i--) {
            if (board[i][j] != 0) {
                if (board[i + 1][j] == 0 || board[i + 1][j] == board[i][j]) {
                    return true;
                }
            }
        }
    }
    return false;
}
 
//判断水平方向上时候是否有空格子
function no_block_horizontal(row, col1, col2, board) {
    for (var i = col1 + 1; i < col2; i++) {
        if (board[row][i] != 0) {
            return false;
        }
    }
    return true;
}
 
//判断垂直方向上时候是否有空格子
function no_block_vertical(col, row1, row2, board) {
    for (var i = row1 + 1; i < row2; i++) {
        if (board[i][col] != 0) {
            return false;
        }
    }
    return true;
}
 
//判断是否还能移动
function nomove(board) {
    if (can_move_down(board) || can_move_up(board) || can_move_right(board) || can_move_left(board)) {
        return false;
    }
    return true;
}
//在showanimation.js中加入
//格子移动时有动画效果
function show_move_animation(fromx, fromy, tox, toy) {
    var number_cell = $(‘#number_cell_‘ + fromx + ‘_‘ + fromy);
    number_cell.animate({
        top: get_pos_top(tox, toy),
        left: get_pos_left(tox, toy)
    }, 200);
}

到此我们的网页版2048就完成了。

时间: 2024-08-30 06:36:53

实验楼项目学习笔记-网页2048的相关文章

六自由度机械臂项目学习笔记

由于课程要做一个控制六自由度机械臂的项目,主要是学习舵机和舵机控制的知识,在这里做一下学习笔记. 使用的舵机为2个DS3115MG数字舵机+4个MG996R模拟舵机. 1.舵机基本构造 2.舵机控制原理 控制电路板接受来自信号线的控制信号,控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘.舵机的输出轴和位置反馈电位计是相连的,舵盘转动的同时,带动位置反馈电位计,电位计将输出一个电压信号到控制电路板,进行反馈,然后控制电路板根据所在位置决定电机转动的方向和速度,从而达到目标停止.其工作流程

bootstrap学习笔记(网页开发小知识)

这是我在学习Boostrap网页开发时遇到的主要知识点: 1.导航条navbar 添加.navbar-fixed-top类可以让导航条固定在顶部,固定的导航条会遮住页面上的其他内容,除非给<body>元素设置了padding. 导航条的默认高度是50px,比如设置:body{ padding-top:70px} 2.下拉菜单 注意:可以通过data属性API就能使用所有的Bootstrap插件,无需写一行JavaScript代码.这是Bootstrap中的一等API,也应该是你的首选方式. &

CentOS7的安装及部署javaweb项目 - 学习笔记

一, 概述: 这两天在捣鼓linux的东西,安装及配置网络环境,共享设置,以及安装jdk , tomcat环境,并将自己开发的javaweb系统部署到上述环境中.经过周末熬到深夜,终于搞掂,现在整理一下笔记,分享出来,以后也可以回顾. 二, 安装CentOS7: 我这里是基于VirtualBox的安装,安装的是无桌面版本CentOS 1, 下载virtualbox并安装 此处省略100字.... 2, 下载CentOS最小安装版本 官网: https://www.centos.org/downl

Unity3d - RPG项目学习笔记(二十)

前期工程将装备信息导入到了工程中,且实现了在背包内鼠标移动显示物品提示信息,本次工程开始构建装备穿戴功能. 项目需求: 右键点击背包内的装备,使其穿戴在身上. 需求分析: 右键点击背包内的装备,注意,此时的装备还是背包内的一个物品,即是工程所定义的id为2001-2010的InventoryItem而已:需求可以抽象为右键点击背包内的一个物品,如果该物品是装备类,则在角色的EquipmentUI相应的位置生成一个与之图标相同的EquipmentItem,则视为“装备”了该物品. 具体实现: ①右

网上图书商城项目学习笔记-003系统功能模块分析

1. itcastgoods文件夹介绍2. 项目导入演示 * 导入数据库 * 导入项目,发布,运行3. 项目原型导入演示 * 导入项目原型,发布,运行4. 小工具介绍5. jQuery介绍 6. 项目前台功能介绍 * User模块 > 注册 > 激活 > 登录 > 修改密码 > 退出 * Category模块 > 显示所有分类 * Book模块 > 按分类查询(分页) > 按图名查询(模糊)(分页) > 按作者查询(分页) > 按出版社查询(分页

网上图书商城项目学习笔记-031图书管理模块介绍及添加图书

一.流程分析 1.图书管理模块介绍 2. 3. 4.添加图书第一步 5.添加图书第二步 二.代码 1.view层 (1)body.jsp 1 <body> 2 <h1 align="center">图书管理</h1> 3 <p align="center"> 4 <a href="<c:url value='/admin/AdminBookServlet?method=addPre'/>&q

网上图书商城项目学习笔记-010显示所有分类

一.流程分析 二.代码 1.view层 1)main.jsp 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 4 5 <!DOCTYPE HTML

IDCM项目学习笔记

项目介绍: IDCM:Internet Data center monitoring 网络数据中心监控平台 IRP:Information Resource planing 信息资源规划 1.设置表中公共字段 在业务逻辑的表中,都有五个公共字段,如下: `gmt_create` datetime NOT NULL COMMENT '数据新增时间', `creator` varchar(128) NOT NULL DEFAULT '0' COMMENT '创建者', `gmt_modified`

开源中国社区 iPhone 客户端项目学习笔记

注:本文假设你已经有xcode4或以上的开发环境 (建议 Xcode 4.3) 直接用双击 oschina.xcodeproj 文件启动 xcode 即可 本项目采用 GPL 授权协议,欢迎大家在这个基础上进行改进,并与大家分享. 下面将简单的解析下项目: 1.AFNetwork --- 通用网络库2.GCDiscreetNotificationView --- 顶部弹出并会自动消失的通知栏3.Thread --- 后台线程对象,处理后台发送带图片的动弹4.SoftwareGroup --- 所