JQuery实现1024小游戏
最近用Jqery写了一个1024小游戏,由于是第一次写小游戏,所以就选了一个基础的没什么难度游戏。具体实现如下:
首先在开发时将整个游戏分成两层(自认为),底层是游戏的数据结构以及对数据的操作,上层是显示出来的用户界面。底层选择使用一个4x4的二维数组,整个游戏的数据操作都围绕着这个二维数组进行。
【一】游戏基础界面
<div id="game">
<div id="header">
<h1>1024</h1>
<button id="newGame">开始新的游戏</button>
<p>分数:<span id="score">0</span> 最高分:<span id="maxScore">0</span></p>
<div id="movescore"><p>+16</p></div>
</div>
<div id="container">
<div class="cell" id="cell-0-0"></div>
<div class="cell" id="cell-0-1"></div>
<div class="cell" id="cell-0-2"></div>
<div class="cell" id="cell-0-3"></div>
<div class="cell" id="cell-1-0"></div>
<div class="cell" id="cell-1-1"></div>
<div class="cell" id="cell-1-2"></div>
<div class="cell" id="cell-1-3"></div>
<div class="cell" id="cell-2-0"></div>
<div class="cell" id="cell-2-1"></div>
<div class="cell" id="cell-2-2"></div>
<div class="cell" id="cell-2-3"></div>
<div class="cell" id="cell-3-0"></div>
<div class="cell" id="cell-3-1"></div>
<div class="cell" id="cell-3-2"></div>
<div class="cell" id="cell-3-3"></div>
</div>
<div class="gameover">
<div id="gameoverText">
<p></p>
</div>
<p id="gameoverScore"></p>
<div id="reStart">
<button id="reStartBtn">再玩一次</button>
</div>
</div>
</div>
CSS:
*{
margin:;
padding:;
}
#game{
font-family: Arial;
margin: 0 auto;
text-align: center;
}
#header{
margin: 20px;
}
#header a{
font-family: Arial;
text-decoration: none;/*设置 h1、h2、h3、h4 元素的文本修饰*/
display: block;
color: white;
margin: 20px auto;
width: 125px;
height: 35px;
text-align: center;
line-height: 40px;
background-color: #8f7a66;
border-radius: 10px;
font-size: 15px;
}
#header p{
font-family: Arial;
font-size: 20px;
}
#container{
width: 460px;
height: 460px;
background-color: #bbada0;
margin: 0 auto;
border-radius: 10px;
position: relative;
padding: 20px;
}
.cell{
width: 100px;
height: 100px;
border-radius: 6px;
background-color: #ccc0b3;
position: absolute;
font-size: 3.5em;
font-weight:;
text-align: center;
line-height:100px;
}
#newGame{
width: 120px;
height: 30px;
border-radius: 5px;
border: 1px solid rgb(143,122,102);
background-color: rgb(143,122,102);
color: white;
margin-top: 10px;
margin-bottom: 10px;
}
.gameover{
width: 100%;
height: 500px;
background-color: rgba(255,255,255,0.5);
position: absolute;
top:153px;
display: none;
}
#gameoverText{
font-size: 4em;
font-weight:;
color: #363636;
text-align: center;
opacity:;
padding-top: 10%;
}
#reStartBtn{
width: 100px;
height: 40px;
border-radius: 5px;
border: 1px solid rgb(143,122,102);
background-color: rgb(143,122,102);
color: white;
margin-top: 3%;
}
#gameoverScore{
font-size: 1.5em;
}
#movescore{
position: absolute;
text-align: center;
padding-left: 45%;
top:110px;
font-weight:;
display: none;
}
此时界面的16个格子是重叠在一起的,给每个格子写css比较麻烦,所以通过js循环进行设置:
//初始化绘制表格
function printTab(){
for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
var cell=$('#cell-'+i+'-'+j);
cell.css({top:(20+i*120),left:(20+j*120)});
}
}
}
不同的数字显示不同的背景颜色与文字颜色:
function getBackgroundColor(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;
}
}
// 设置相应数字的文字颜色
function getColor(number){
if (number <= 4) {
return "#776e65"
}
return "white";
}
每次操作后根据当前二维数组进行重绘画面:
//根据二维数组绘制画面
function rePrint(checkerboard){
for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
if(checkerboard[i][j]!=0){
var printCell=$('#cell-'+i+'-'+j);
printCell.css('background-color',getBackgroundColor(checkerboard[i][j]));
printCell.css('color',getColor(checkerboard[i][j]));
printCell.text(checkerboard[i][j]);
if(checkerboard[i][j]>=1024){
printCell.css('font-size','2.5em');
printCell.css('font-weight','500');
}
}else{
var printCell=$('#cell-'+i+'-'+j);
printCell.css('background-color','#ccc0b3');
printCell.css('color','black');
printCell.text('');
}
}
}
}
【二】游戏逻辑
除了需要定义一个二维数组checkerboard,还需要定义一个存总分的变量score,一个存每次操作得分的变量addScore,一个记录键盘是否可以操作的变量ableKeyDown,0可以响应键盘操作,1禁止键盘操作。
①游戏初始化
初始化封装成一个函数方便后续的【开始新的游戏】以及【再玩一次】功能。
//初始化游戏
function newgame(){
ableKeyDown=0;
score=0;
checkerboard=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
$('#score').text('0');
$('#maxScore').text(window.localStorage.getItem("maxScore"));
rePrint(checkerboard);
randNum(checkerboard);
randNum(checkerboard);
}
②在随即位置生成2或4
根据游戏规则,在游戏刚开始时会在两个随即位置分别生成2或4,在每次操作后若游戏没结束,会在一个空的位置随机生成一个2或4,将这一功能封装成一个函数,Math.random()生成的随机数范围是[0,1),由于二维数组范围是[0,3],所以通过Math.floor(Math.random()*4)将得到0-3的随机数。另外需要随机得到2或4,定义一个数组initRandNum=[2,4],只需随机得到initRandNum[0]或initRandNum[1]即可,所以同理使用Math.floor(Math.random()*2)随机得到1或2即可。
function randNum(checkerboard){//在随机位置随机产生2或4
var randX = Math.floor(Math.random()*4);
var randY = Math.floor(Math.random()*4);
var initRandNum=[2,4];
var randNum=Math.floor(Math.random()*2);
var randVal=initRandNum[randNum];
while(true){
if(checkerboard[randX][randY]==0){
break;
}else{
var randX = Math.floor(Math.random()*4);
var randY = Math.floor(Math.random()*4);
}
}
checkerboard[randX][randY]=randVal;
printRandNum(randX,randY,randVal);//将randNum()绘制出来
}
在得到上述随即位置的2或4后需要将其绘制出来:
function printRandNum(randX,randY,randVal){
var printRandCell=$('#cell-'+randX+'-'+randY);
printRandCell.css('background-color',getBackgroundColor(randVal));
printRandCell.css('color',getColor(randVal));
printRandCell.text(randVal);
}
③游戏中最重要的两个函数
即判断当前能否移动的函数以及如何移动合并的函数。
1)--------判断能否移动,以左移为例
根据对游戏的观察发现在两中情况下可以移动,一是存在某个不为零的方块,该数字左边为空,即其左边的数组值为0;二是存在某个不为零的方块,,该数字左边与其相同,即其左边的数组值与其相等。对二维数组进行循环,若满足上述条件就返回1,即可以移动。
function canMoveLeft(checkerboard){
for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
if(checkerboard[i][j]!=0){
if(j!=0){
if(checkerboard[i][j-1]==0||checkerboard[i][j-1]==checkerboard[i][j]){
return 1;
break;
}
}
}
}
}
}
2)--------移动合并函数,以左移为例
这个应该是游戏中最重要的函数,根据游戏规则,1)若一个非零方块左边全部为空,它将移动到最左边,若左边的某个不为0,它将移动到这个不为0方块的右边;2)若一个非零方块与左边的数字相同,它将移动到左边并与之合并相加;3)若一个非零方块与左边的数字相同,他与左边合并后的值恰巧与再左边的数相同,此时应该只进行第一次合并,不进行第二次合并。例如当前一排是4,2,2,0,其移动后结果应该是4,4,0,0,而不是8,0,0,0。
第三点尤为重要,最开始由于忽略了这点写出来后结果是不对的。我真对3)的解决办法是,在每次循环一行时初始化一个长度为4的数组var tag=[0,0,0,0],若某个数在此次循环制相加过一次,就在tag相应位置置为1,再然后在每次合并前做一次判断,若该tag为1,则不进行相加。
function moveLeft(checkerboard){
addscore=0;
for(var i=0;i<4;i++){
var tag=[0,0,0,0];
for(var j=1;j<4;j++){ if(checkerboard[i][j]!=0){
if(checkerboard[i][j-1]==0){//左边为空时
for(k=j-1;k>=0;k--){
if(checkerboard[i][k]!=0){
checkerboard[i][k+1]=checkerboard[i][j];
checkerboard[i][j]=0;
if(checkerboard[i][k+1]==checkerboard[i][k]){//移动后与左边相等
if(tag[k]==0&&tag[k+1]==0){
checkerboard[i][k]+=checkerboard[i][k+1];
score += checkerboard[i][k];
addscore+=checkerboard[i][k];
tag[k]=1; checkerboard[i][k+1]=0;
}
}
break;
}else if(k==0){//左边全空
checkerboard[i][0]=checkerboard[i][j];
checkerboard[i][j]=0;
break;
}
}
}else if(checkerboard[i][j-1]==checkerboard[i][j]){//左边相等时
if(tag[j-1]==0&&tag[j]==0){
checkerboard[i][j-1]+=checkerboard[i][j];
score += checkerboard[i][j-1];
addscore+=checkerboard[i][j-1];
tag[j-i]=1; checkerboard[i][j]=0;
}
}
}
}
}
rePrint(checkerboard);//停止移动后重绘画面
}
值得注意的是,为了计算游戏的总分以及每次操作的得分,需要在每次合并后对addScore和score进行计算。
右移、上移、下移与左移逻辑基本相同,只需对左移代码稍作修改即可。
④关于分数
//更新分数
function updateScore(num){
$('#score').text(num);
}
在每次得分后会在总分位置产生一个加分动画
//分数动画
function movescore(score){
if(score>0){
$('#movescore p').text('+'+score);
$('#movescore').css('top','110px');
$('#movescore').show();
var top;
var topVal=110;
var opacityVal=1;
var timer=null;
timer=setInterval(function(){
topVal-=5;
opacityVal-=0.1;
top=topVal+'px';
$('#movescore').css('top',top);
$('#movescore').css('opacity',opacityVal);
if(topVal<50){
clearInterval(timer);
$('#movescore').hide();
}
},40);
}
}
⑤游戏结束
若二维数组中某一项等于1024游戏结束,显示最终得分,并设置键盘不可继续操作;或者当前无法继续移动游戏结束,显示最终得分。
//游戏结束函数
function gameOver(checkerboard){
if(canMoveLeft(checkerboard)!=1&&canMoveRight(checkerboard)!=1&&canMoveUp(checkerboard)!=1&&canMoveDown(checkerboard)!=1){
$('.gameover').show();
$('#gameoverText p').text('Game Over !');
$('#gameoverScore').text('最终得分'+score);
if(score>window.localStorage.getItem("maxScore")){
window.localStorage.setItem("maxScore",score);
$('#maxScore').text(window.localStorage.getItem("maxScore"));
}
}
for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
if(checkerboard[i][j]==1024){
ableKeyDown=1;//键盘不可操作
$('.gameover').show();
$('#gameoverText p').text('Congratulations!');
$('#gameoverScore').text('最终得分'+score);
if(score>window.localStorage.getItem("maxScore")){
window.localStorage.setItem("maxScore",score);
$('#maxScore').text(window.localStorage.getItem("maxScore"));
}
break;
}
}
}
}
⑥开始新游戏&再玩一次
//开始新游戏
$('#newGame').click(function(){
newgame();
});
//再玩一次
$('#reStartBtn').click(function(){
$('.gameover').hide();
newgame();
});
JQuery实现1024小游戏的更多相关文章
- js、jQuery实现2048小游戏
2048小游戏 一.游戏简介: 2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...
- jQuery实现拼图小游戏
小熊维尼拼图 2017-07-23 ...
- jQuery 打气球小游戏 点击气球爆炸效果
最近在学习前端,看到偶尔看到前端小游戏,就想自己写一个小游戏,奈何水平有限,只能写打气球这种简单的,所有的气球都是动态生成的,气球的颜色也是随机的 html部分 <div class=" ...
- 基于jQuery的2048小游戏设计(网页版)
上周模仿一个2048小游戏,总结一下自己在编写代码的时候遇到的一些坑. 游戏规则:省略,我想大部分人都玩过,不写了 源码地址:https://github.com/xinhua6/2048game.g ...
- jquery实现抽奖小游戏
在很多网站或游戏活动中我们都会看到有关抽奖的活动或界面: 下面我将给大家介绍下如何通过javascript来实现这样的一个抽奖功能,主要从下面三个步骤入手(文中着重介绍第三部分有关功能的实现): 1. ...
- jQuery之-拼图小游戏
在线实例:http://lgy.1zwq.com/puzzleGame/ 源代码思路分析: [一]如何生成图片网格,我想到两种方法: (1)把这张大图切成16张小图,然后用img标签的src (2)只 ...
- 在HTML页面中有jQuery实现实现拼图小游戏
1.用jQuery实现拼图小游戏 2.首先获得td的点击事件.再进行交换位置 3.下面这种仅供参考 4.下面这些是HTMl标签 当这个世界变得越来越复杂的时候,内心最需保持一份简单一份纯真:
- jQuery实践-网页版2048小游戏
▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...
- JQuery&原生js ——实现剪刀石头布小游戏
前言 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库( 或JavaScript框架).jQuery设计的宗旨是“write L ...
随机推荐
- 经济学人使用Golang构建微服务历程回顾
关键点 经济学人内容分发系统需要更大的灵活性,将内容传递给日益多样化的数字渠道.为了实现这一灵活性目标并保持高水平的性能和可靠性,平台从一个单体结构过渡到微服务体系结构. 用Go编写的服务是新系统的一 ...
- 在Android项目中使用AspectJ
版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/8888459.html 什么是AOP AOP是 Aspec ...
- Angular2入门:TypeScript的类型 - 对象解构
- #8 Python数学方法
前言 前几节了解了Python的不同数据类型,有小伙伴会问,不同的数据类型之间是否可以相互转换?肯定是可以的,本篇博文主要记录数字类型的转换,其他类型的相互转换会在下几节记录,Here we go! ...
- FFmpeg流媒体处理-收流与推流
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10623968.html 1. 简介 流媒体是使用了流式传输的多媒体应用技术.如下是维基百 ...
- Python和Java分别实现冒泡排序
1.基本思想 冒泡排序的基本思想是对比相邻的元素值.相邻元素值比较,如果满足条件两者就交换,把较小的移动到前面,把较大的移动到后面,这样较小的元素就像气泡一样浮上来了.可以看出,冒泡排序的每一次循环都 ...
- [CF833B] The Bakery
Description 将一个长度为n的序列分为k段 使得总价值最大一段区间的价值表示为区间内不同数字的个数 \(n\leq 35000,k\leq 50,1\leq a_i\leq n\) Solu ...
- Extjs4.2+webAPI+EF实现分页以及webapi的数据传值
由于不明白分页的总数是怎么计算,不知道他的分页方式所以花费了好多功夫,现在弄出来了与大家分享下 1.首先是EF的简历,想必大家都清楚:添加-〉新建项-〉数据-〉Ado.net实体数据模型 2.就是后台 ...
- eclipse + maven搭建SSM框架
0.系统环境 1)Windows 10 企业版 2)JDK 1.8.0_131 3)Eclipse Java EE IDE for Web Developers Version: Neon.3 Re ...
- FireFox升级后FireBug不能使用
今天发现,火狐浏览器从49.0.2升级到50.0.2之后,firebug的js调试被禁用了,果断去找49.0.2的版本. 链接: https://ftp.mozilla.org/pub/firefox ...