续上一小节,我们回到newgame()这个函数,我们之前只做了init()内函数,相当于一个初始化操作
现在,我们需要再随机两个两个生成数字。
随机生成数字在这个游戏里会经常出现,用户移动一步,也会产生一个随机数字。
我们在newgame()函数里,声明一个generateOneNumber()函数,来随机在16个格子里找出没有数字的格子,随机生成一个数字2或4。
因为newgame()函数里,起始时,生成了2个随机数字,于是我们要调用2次。
function newgame(){
//初始化棋盘格
init();
//在随机两个格子生成数字
generateOneNumber(); //第一次
generateOneNumber(); //第二次
}
在main2048.js里,我们再去定义这个函数。我们先判断什么时候还能生成数字,就是4×4这16个格子里还有空间,就可以。
我们定义一个nospace()函数,传入当前board的值,表示16个格子里已经没有空间了,返回false,否则返回true.
function generateOneNumber(){
if(nospace(board)){
return false;
}
return true;
}
我们将nospace(board)函数放在【support2048.js】里
先遍历board数组,如果board[i][j]存在为0的元素,则还有空间,返回false。否则返回true。
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;
}
下面我们回到generateOneNumber(),如果有空间的话,我们怎么生成数呢?
1. 需要寻找一个空位
我们使用Math里面的random()函数,Math.random() 是算法中常用的函数,其作用是返回0~1之间浮点数,而我们的位置 i 和 j 都是0123,我们如何转换成0到4之间的随机数呢?
很简单,我们把生成的0~1之间的浮点数×4,这样就能产生0到4之间的浮点数。
为了能获得0到4之间的整数,我们使用Math.floor()函数,其作用是返回小于或等于一个给定数字的最大整数,比如1.4就返回整数1, 0.693就返回0。这样我们就能生成0123这四个随机数。
但是这样我们得到的数仍是一个浮点类型的,我们需要把随机数用作坐标,所以必须是整形的,我们再嵌套一个parseInt()函数来将生成的随机数强制转换成整形。
var randx = parseInt(Math.floor(Math.random()*4));
var randy = parseInt(Math.floor(Math.random()*4));
但此时这个数字我们仍不能用,因为如果这个位置原本有数字,我们不能使用,我们还需要判断该位置是否为0。
我们可以使用一个死循环,找每一个位置上的randx和randy是不是为0。为0我们就可以break结束循环,找到该坐标。
while(true){
if(board[randx][randy]==0) break;
randx = parseInt(Math.floor(Math.random()*4));
randy = parseInt(Math.floor(Math.random()*4));
}
2. 需要随机一个数字
下面我们随机生成一个数字,我们可以巧妙利用Math.random(),50%生成2, 50%生成4,我们可以判断生成的数与0.5比大小,生成2或4
var randNumber = Math.random() > 0.5?2:4;
3. 在随机位置显示随机数字
board[randx][randy] = randNumber;
然后我们需要通知前端显示这个randNumber,在2048游戏中,显示这一步是有一个动画效果的,我们新声明一个函数showNumberWithAnimation(randx,randy,randNumber)
在【showanimation2048.js】里,我们需要调用numberCell。
numberCell 从0到有数字, 那文字颜色和背景颜色都要根据数字来决定。之前已经写过 getNumberBackgroundColor() 和getNumberColor(),需要在这里调用。
var numberCell = $('#number-cell-'+i+'-'+j);
numberCell.css('background-color',getNumberBackgroundColor(randNumber));
numberCell.css('color',getNumberColor(randNumber));
numberCell.text(randNumber);
动画部分,我们使用jquery的animate()函数来完成。
numberCell.animate({
width:'100px',
height:'100px',
top:getPosTop(i,j),
left:getPosLeft(i,j)
},50);
第二个参数50,是指50ms完成该动画。
至此 showNumberWithAnimation()函数已经完成。
此时我们可以测试一下我们的代码,可以发现初始时生成了随机两个数,点击New Game,又生成了不同的两个数
这一小节结束,放上我们目前为止所有的代码检查一下!
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2048title>
<script type="text/javascript" src="jquery-3.4.1.min.js">script>
<script type="text/javascript" src="main2048.js">script>
<script type="text/javascript" src="showanimation2048.js">script>
<script type="text/javascript" src="support2048.js">script>
<link rel="stylesheet" type="text/css" href="2048.css">
head>
<body>
<header>
<h1>2048h1>
<a href="javascript:newgame();" id="newgamebutton">New Gamea>
<p>score:<span id="score">0span>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>
body{
font-family: Arial;
}
header{
display: block;
margin: 0 auto;
width: 500px;
text-align: center;
}
header h1{
font-size: 60px;
font-weight: bold;
}
header #newgamebutton{
display: block;
margin: 20px auto;
width: 100px;
padding: 10px 10px;
background-color: #8f7a66;
color: #fff;
border-radius: 10px;
text-decoration: none;
}
header #newgamebutton:hover{
background-color: #9f8b77;
}
header p{
font-size: 25px;
margin: 20px auto;
}
#grid-container{
width: 460px;
height: 460px;
padding: 20px;
margin: 50px auto;
background-color: #bbada0;
border-radius: 10px;
position: relative;
left: 0;
top:0;
}
.grid-cell{
width: 100px;
height: 100px;
border-radius: 6px;
background: #ccc0b3;
position: absolute;
}
.number-cell{
border-radius: 6px;
font-weight: bold;
font-size: 60px;
line-height: 100px;
text-align: center;
position: absolute;
}
var board = new Array();
var score = 0;
$(document).ready(function() {
newgame();
});
function newgame() {
// 1.初始化棋盘
init();
// 2.随机两个格子生成数字
generateOneNumber();
generateOneNumber();
}
function init() {
for(var i = 0; i < 4; i++)
for(var j = 0; j < 4; j++)
{
var gridCell = $("#grid-cell-"+i+"-"+j);
gridCell.css('top', getPosTop(i,j));
gridCell.css('left', getPosLeft(i,j));
}
for(var i = 0; i < 4; i++){
board[i] = new Array();
for(var j = 0; j < 4; j++){
board[i][j] = 0;
}
}
updateBoardView();
}
function updateBoardView() {
$(".number-cell").remove();
for(var i = 0; i < 4; i++)
for(var j = 0; j < 4; j++){
$("#grid-container").append("");
var theNumberCell = $('#number-cell-'+i+'-'+j);
if(board[i][j] == 0){
theNumberCell.css('width','0px');
theNumberCell.css('height','0px');
theNumberCell.css('top',getPosTop(i,j)+50);
theNumberCell.css('left',getPosLeft(i,j)+50);
}
else{
theNumberCell.css('width','100px');
theNumberCell.css('height','100px');
theNumberCell.css('top',getPosTop(i,j));
theNumberCell.css('top',getPosTop(i,j));
theNumberCell.css('background-color',getNumberBackgroundColor(board[i][j]));
theNumberCell.css('color',getNumberColor(board[i][j]));
theNumberCell.text(board[i][j]);
}
}
}
function generateOneNumber(){
if(nospace(board))
return false;
//随机一个位置
var randx = parseInt(Math.floor(Math.random()*4));
var randy = parseInt(Math.floor(Math.random()*4));
while(true){
if(board[randx][randy]==0) break;
randx = parseInt(Math.floor(Math.random()*4));
randy = parseInt(Math.floor(Math.random()*4));
}
//随机一个数字
var randNumber = Math.random() > 0.5?2:4;
//在随机位置显示随机数字
board[randx][randy] = randNumber;
showNumberWithAnimation(randx,randy,randNumber);
return true;
}
function getPosTop(i,j){
return 20 + i*120;
}
function getPosLeft(i,j){
return 20 + j*120;
}
function getNumberBackgroundColor(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 28192:return "#93c"; break;
}
return "black";
}
function getNumberColor(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;
}
function showNumberWithAnimation(i, j, randNumber){
var numberCell = $('#number-cell-'+i+'-'+j);
numberCell.css('background-color',getNumberBackgroundColor(randNumber));
numberCell.css('color',getNumberColor(randNumber));
numberCell.text(randNumber);
numberCell.animate({
width:'100px',
height:'100px',
top:getPosTop(i,j),
left:getPosLeft(i,j)
},50);
}
直接跳转下一小节:
html+css+js适合前端小白的实战全解(超详细)——2048小游戏(四)