JavaScript【趣味】做一个网页版2048

简介: JavaScript【趣味】做一个网页版2048 .

🌟前言

哈喽小伙伴们,从这篇文章开始,我会开始新的专栏JavaScript【趣味JS七十二变】;这个专栏里边会收录一些JavaScript的趣味玩法和一些小游戏,目的是为了大家在娱乐的过程中也可以去学习到很多知识点,喜欢的话希望大家可以订阅并持续关注;今天我们开始这个专栏的第一篇文章,使用Jquery 来做一个网页版的 2048 ;让我们一起来看看吧🤘

🌟先看效果(粉丝特权哈哈)

9556ff973ae04270b8acbecb60458d71.png

JS实现一个网页版2048小游戏

🌟代码实现

🌟页面布局 【index.html】

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>2048</title>
  <link rel="stylesheet" href="css/2048.css">
  <script src="js/jquery.min.js"></script>
  <script src="js/util.js"></script>
  <script src="js/2048.js"></script>
</head>
<body>
  <header>
    <h3>2048</h3>
    <div class="score hscore" style="line-height: 40px;">最高分数:<span>0</span></div>
    <div class="score" style="line-height: 10px;">分数:<span>0</span></div>
  </header>
  <div class="btn-group">
    <div class="newgame" onclick="newGame()" onmousedown="return false">新游戏</div>
  </div>
  <!-- 棋盘区域 -->
  <div class="grid">
  </div>
</body>
</html>

🌟样式文件【2048.css】

body,ul,li,h3{
  margin: 0;
  padding: 0;
  list-style: none;
}
body{
  background: #fcfad3;
}
a{
  text-decoration: none;
}
header{
  width: 500px;
  margin: 0 auto;
  text-align: center;
  font-family: arial;
  height: 60px;
}
header .score{
  float: right;
  width: 50%;
  height: 30px;
  line-height: 30px;
  font-size: 14px;
  text-align: right;
  color:#666;
}
header .score span{
  display: inline-block;
  width: 40px;
  padding:0 10px;
  color:#ff6529;
}
header h3{
  width: 40%;
  height: 60px;
  font-size: 44px;
  line-height: 60px;
  text-align: left;
  font-family:"arial";
  color:#ff6529;
  float: left;
}
.grid{
  width: 500px;
  height: 500px;
  background: #c4b6ab;
  margin: 10px auto 0px;
  border-radius: 20px;
  position: relative;
}
.grid-cell{
  width: 100px;
  height: 100px;
  border-radius: 10px;
  position: absolute;
  background: #d2c8be;
}
.number-cell{
  font-family: arial;
  font-size: 60px;
  font-weight: bold;
  text-align: center;
  line-height: 100px;
  position: absolute;
  border-radius: 10px;
}
.btn-group{
  margin:0 2%;
  text-align: center;
}
.newgame{
  display: inline-block;
  padding: 4px 12px;
  background: #ff6529;
  color: #fff;
  font-size: 18px;
  margin-top: 10px;
  border-radius: 0.5rem;
}
.newgame:active{
  opacity: 0.6;
}

🌟index.html 里用到的JS文件

🌟jquery.min.js

这个文件就不给大家输出了,如果小伙伴没有的话,我这里给大家推介一个CDN网站,大家可以自行去下载

BootCDN

稳定、快速、免费的前端开源项目 CDN 加速服务;共收录了 4381 个前端开源项目



8b601a90257147889fa44aa439aa68bd.png


🌟util.js

这个是封装了一个工具类,里边包含了一些相关的函数,封装起来也是为了方便复用

//工具类
var util ={
  pos:function(n){//获取x y位置
    return n*120+20;
  },
  //检测界面中是否有空间
  space:function(d){
    for(var i=0;i<4;i++){
      for(var j=0;j<4;j++){
        if(d[i][j]==0){
          return false;
        }
      }
    }
    return true;
  },
  //动画显示一个numbercell + 数字
  showNumber:function(x,y,num){
    var numberCell = $('#n'+x+y);
    numberCell.css({
      backgroundColor:bgColor[num],
      color:fontColor(num)
    }).text(num).animate({width:100,height:100,left:util.pos(y),top:util.pos(x)},50);
  },
  //消除动画
  moveAnimate:function (fi,fj,ti,tj){
    $('#n'+fi+fj).animate({
      left:util.pos(tj),
      top:util.pos(ti)
    },100)
  },
  //更新分数
  updateScore:function(){
    $('.score span').text(score);
    this.hightScore()
  },
  //最高分数
  hightScore:function(){
    if(!localStorage.getItem('hscore')){
      localStorage.setItem('hscore',0);
    }
    var oldH = localStorage.getItem('hscore');
    if(oldH<score){
      localStorage.setItem('hscore',score);
      $('.hscore span').text(score);
    }else{
      $('.hscore span').text(oldH);
    }
  }
}

🌟2048.js

核心JS文件,处理游戏的大部分逻辑

/*
  2048游戏逻辑
  # 变量组
  data 存放数据
  score 存放分数
  1. 绘制界面  4*4 双层 for 计算left top
*/
var data = [];//数据
var score = 0; //分数
var flag = true;
var bgColor = {//不同数字单元格背景颜色
  2:'#eee4da',
  4:'#ede0c8',
  8:'#f2b179',
  16:'#f59563',
  32:'#f67c5f',
  64:'#f65e3b',
  128:'#edcf72',
  256:'#edcc61',
  512:'#9c0',
  1024:'#33b5e5',
  2048:'#09c',
  4096:'#a6c',
  8192:'#93c'
}
var fontColor=function(num){//数字颜色
  if(num<=4){
    return "#776e65";
  }
  return "#fff";
}
$(function(){
  newGame()
})
// 新游戏
function newGame(){
  //绘制界面
  drawSence();
  score =0;
  util.updateScore();
  util.hightScore();
  //随机生成2个数字
  getNumber();
  getNumber();
  flag=true;
}
//绘制界面函数
function drawSence(){
  var grid=$('.grid');
  grid.empty();
  for (var i = 0; i < 4; i++) {
    for(var j = 0; j < 4; j++){
      $('<div>').attr({
        class:'grid-cell',
        id:'g'+i+j
      }).css({
        top:util.pos(i),
        left:util.pos(j)
      }).appendTo(grid)
    }
  }
  //初始化数据
  for(var i=0;i<4;i++){
    data[i]=[];
    for(var j=0;j<4;j++){
      data[i][j]=0;
    }
  }
  //创建number-cell
  showdata()
  console.log(data)
}
function showdata(){
  var grid=$('.grid');
  $('.number-cell').remove(); //清除所有number-cell元素
  for(var i=0;i<4;i++){
    for(var j=0;j<4;j++){
      var numberCell = $('<div>');
      numberCell.attr({
        class:'number-cell',
        id:'n'+i+j
      }).appendTo(grid);
      if(data[i][j]==0){
        numberCell.css({
          width:0,
          height:0,
          left:util.pos(j)+50,
          top:util.pos(i)+50
        })
      }else{
        numberCell.css({
          width:100,
          height:100,
          left:util.pos(j),
          top:util.pos(i)
        })
        numberCell.css({
          backgroundColor:bgColor[data[i][j]],
          color:fontColor(data[i][j]),
        }).text(data[i][j]);
      }
    }
  }
}
function getNumber(){
  if(util.space(data)){
    return true;
  }
  //随机单元格 位置
  var x = Math.floor(Math.random()*4);
  var y = Math.floor(Math.random()*4);
  while(data[x][y]!=0){
    x = Math.floor(Math.random()*4);
    y = Math.floor(Math.random()*4);
  }
  //随机数字
  var num = Math.random()<0.5?2:4;
  data[x][y] = num;
  util.showNumber(x,y,num);
  console.log(data)
  return false;
}
// 监听键盘按键
$(document).keydown(function(e){
  if(!flag){return;}
  switch(e.keyCode){
    case 37:
    moveLeft();
    break;
    case 38:
    moveTop();
    break;
    case 39:
    moveRight();
    break;
    case 40:
    moveBottom();
    break;
    default:
    break;
  }
})
// 键盘左键
function moveLeft(){
  isGameOver();
  if(!canMoveLeft()){
    return false;
  }
  for(var i=0;i<4;i++){
    for(var j=1;j<4;j++){
      if(data[i][j]!=0){
        for(var k=0;k<j;k++){
          if(data[i][k]==0&&noBlockH(i,k,j,data)){
            //move()
            util.moveAnimate(i,j,i,k);
            data[i][k]=data[i][j];
            data[i][j]=0;
            continue;
          }else if(data[i][k]==data[i][j]&&noBlockH(i,k,j,data)){
            //move()
            util.moveAnimate(i,j,i,k);
            //add
            data[i][k]+=data[i][j];
            data[i][j]=0;
            score+=data[i][k];//增加分数
            util.updateScore();//更新分数
            continue;
          }
        }
      }
    }
  }
  setTimeout(getNumber,100);
  setTimeout(showdata,100);
}
// 键盘上键
function moveTop(){
  isGameOver();
  if(!canMoveTop()){
    return false;
  }
  for(var i=1;i<4;i++){
    for(var j=0;j<4;j++){
      if(data[i][j]!=0){
        for(var k=0;k<i;k++){
          if(data[k][j]==0&&noBlockV(j,k,i,data)){
            //move()
            util.moveAnimate(i,j,k,j);
            data[k][j]=data[i][j];
            data[i][j]=0;
            continue;
          }else if(data[k][j]==data[i][j]&&noBlockV(j,k,i,data)){
            //move()
            util.moveAnimate(i,j,k,j);
            //add
            data[k][j]+=data[i][j];
            data[i][j]=0;
            score+=data[k][j];//增加分数
            util.updateScore();//更新分数
            continue;
          }
        }
      }
    }
  }
  setTimeout(getNumber,100);
  setTimeout(showdata,100);
}
// 键盘下键
function moveBottom(){
  isGameOver();
  if(!canMoveBottom()){
    return false;
  }
  for(var i=2;i>=0;i--){
    for(var j=0;j<4;j++){
      if(data[i][j]!=0){
        for(var k=3;k>i;k--){
          if(data[k][j]==0&&noBlockV(j,i,k,data)){
            //move()
            util.moveAnimate(i,j,k,j);
            data[k][j]=data[i][j];
            data[i][j]=0;
            continue;
          }else if(data[k][j]==data[i][j]&&noBlockV(j,i,k,data)){
            //move()
            util.moveAnimate(i,j,k,j);
            //add
            data[k][j]+=data[i][j];
            data[i][j]=0;
            score+=data[k][j];//增加分数
            util.updateScore();//更新分数
            continue;
          }
        }
      }
    }
  }
  setTimeout(getNumber,100);
  setTimeout(showdata,100);
}
// 键盘右键
function moveRight(){
  isGameOver();
  if(!canMoveRight()){
    return false;
  }
  for(var i=0;i<4;i++){
    for(var j=2;j>=0;j--){
      if(data[i][j]!=0){
        for(var k=3;k>j;k--){
          if(data[i][k]==0&&noBlockH(i,j,k,data)){
            //move()
            util.moveAnimate(i,j,i,k);
            data[i][k]=data[i][j];
            data[i][j]=0;
            continue;
          }else if(data[i][k]==data[i][j]&&noBlockH(i,j,k,data)){
            //move()
            util.moveAnimate(i,j,i,k);
            //add
            data[i][k]+=data[i][j];
            data[i][j]=0;
            score+=data[i][k];//增加分数
            util.updateScore();//更新分数
            continue;
          }
        }
      }
    }
  }
  setTimeout(getNumber,100);
  setTimeout(showdata,100);
}
function canMoveLeft(){
  for(var i=0;i<4;i++){
    for(var j=1;j<4;j++){
      if(data[i][j]!=0){
        if(data[i][j-1]==0||data[i][j-1]==data[i][j]){
          return true;
        }
      }
    }
  }
  return false;
}
function canMoveTop(){
  for(var i=1;i<4;i++){
    for(var j=0;j<4;j++){
      if(data[i][j]!=0){
        if(data[i-1][j]==0||data[i-1][j]==data[i][j]){
          return true;
        }
      }
    }
  }
  return false;
}
function canMoveRight(){
  for(var i=0;i<4;i++){
    for(var j=0;j<3;j++){
      if(data[i][j]!=0){
        if(data[i][j+1]==0||data[i][j+1]==data[i][j]){
          return true;
        }
      }
    }
  }
  return false;
}
function canMoveBottom(){
  for(var i=0;i<3;i++){
    for(var j=0;j<4;j++){
      if(data[i][j]!=0){
        if(data[i+1][j]==0||data[i+1][j]==data[i][j]){
          return true;
        }
      }
    }
  }
  return false;
}
function noBlockH(row,col1,col2,data){
  for(var i=col1+1;i<col2;i++){
    if(data[row][i]!=0){
      return false;
    }
  }
  return true;
}
function noBlockV(col,row1,row2,data){
  for(var i=row1+1;i<row2;i++){
    if(data[i][col]!=0){
      return false;
    }
  }
  return true;
}
// 游戏结束
function isGameOver(){
  if(!canMoveTop()&&!canMoveBottom()&&!canMoveLeft()&&!canMoveRight()){
    alert('GameOver');
    flag=false;
  }
}

🌟结语

喜欢的话大家一定要关注这篇专栏,后续也会不定期持续输出JS相关的趣味玩法。各位小伙伴让我们 let’s be prepared at all times!

目录
相关文章
|
21天前
|
存储 JavaScript 前端开发
使用JavaScript构建动态交互式网页:从基础到实践
【10月更文挑战第12天】使用JavaScript构建动态交互式网页:从基础到实践
55 1
|
2月前
|
编解码 前端开发 JavaScript
javascript检测网页缩放演示代码
javascript检测网页缩放演示代码
|
2月前
|
Web App开发 JavaScript 前端开发
添加浮动按钮点击滚动到网页底部的纯JavaScript演示代码 IE9、11,Maxthon 1.6.7,Firefox30、31,360极速浏览器7.5.3.308下测试正常
添加浮动按钮点击滚动到网页底部的纯JavaScript演示代码 IE9、11,Maxthon 1.6.7,Firefox30、31,360极速浏览器7.5.3.308下测试正常
|
2天前
|
JavaScript
js实现简洁实用的网页计算器功能源码
这是一款使用js实现简洁实用的网页计算器功能源码。可实现比较基本的加减乘除四则运算功能,界面简洁实用,是一款比较基本的js运算功能源码。该源码可兼容目前最新的各类主流浏览器。
9 2
|
25天前
|
存储 JavaScript 前端开发
【JavaScript】网页交互的灵魂舞者
本文介绍了 JavaScript 的三种引入方式(行内、内部、外部)和基础语法,包括变量、数据类型、运算符、数组、函数和对象等内容。同时,文章还详细讲解了 jQuery 的基本语法和常用方法,如 `text()`、`html()`、`val()`、`attr()` 和 `css()` 等,以及如何插入和删除元素。通过示例代码和图解,帮助读者更好地理解和应用这些知识。
13 1
【JavaScript】网页交互的灵魂舞者
用CSS+JavaScript打造网页中的选项卡
用CSS+JavaScript打造网页中的选项卡
|
1月前
|
Web App开发 缓存 前端开发
前端RAG:使用Transformers.js手搓纯网页版RAG(二)- 基于qwen1.5-0.5B
本文继续探讨了RAG的后半部分,通过在浏览器中运行qwen1.5-0.5B模型实现了增强搜索全流程。然而,由于浏览器与模型性能限制,该方案更适合研究、离线及高隐私场景。文章提供了完整的前端代码,让读者能够动手尝试。此外,详细介绍了代码框架、知识库准备、模型初始化及问答实现等步骤,并展示了实际运行效果。受限于当前技术,除非在离线或高隐私环境下,网页大模型的应用仍需进一步优化。
|
1月前
|
存储 自然语言处理 文字识别
纯前端RAG:使用Transformers.js实现纯网页版RAG(一)
本文将分两部分教大家如何在网页中实现一个RAG系统,本文聚焦于深度搜索功能。通过浏览器端本地执行模型,可实现文本相似度计算和问答匹配,无需依赖服务器。RAG搜索基于高维向量空间,即使不完全匹配也能找到意义相近的结果。文中详细介绍了如何构建知识库、初始化配置、向量存储及相似度计算,并展示了实际应用效果。适用于列表搜索、功能导航、文档查询及表单填写等多种场景。
111 0
|
2月前
|
Web App开发 前端开发 JavaScript
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
|
2月前
|
JavaScript 前端开发
用JavaScript编程控制网页上checkbox选择状态:全选、全部取消、反选
用JavaScript编程控制网页上checkbox选择状态:全选、全部取消、反选