JavaScript实现2048小游戏,我终于赢了一把
Posted 编程界明世隐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript实现2048小游戏,我终于赢了一把相关的知识,希望对你有一定的参考价值。
javascript实现2048小游戏
作者简介
作者名:编程界明世隐
简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞!
系列目录
1. JavaScript 贪吃蛇游戏
2. JavaScript 俄罗斯方块
3. JavaScript 扫雷小游戏
4. JavaScript 网红太空人表盘
效果图
实现思路
- 编写页面和画布代码。
- 绘制背景。
- 绘制好全部卡片。
- 随机生成一个卡片(2或者4)。
- 键盘事件监听(上、下、左、右键监听)。
- 根据键盘的方向,处理数字的移动合并。
- 加入成功、失败判定。
- 处理其他收尾工作。
代码实现
编写页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2048</title>
<style>
#box{
width:370px;
height:370px;
position:absolute;
margin:0 auto;
left:0;
right:0;
top:1px;
bottom:0;
}
.rebutton{
position: absolute;
top:370px;
left:38%;
}
</style>
</head>
<body>
<div id='box'></div>
<button onclick="restart()" class='rebutton'>重开</button>
</body>
<script src="js/util.js"></script>
<script src="js/2048.js"></script>
<script type="text/javascript">
</script>
</html>
添加画布
在2048.js编写代码
- 创建函数
function G2048(){
this.renderArr=[];//渲染数组
this.cards=initCardArray();
//游戏标记
this.flag='start';
}
//初始化数组
function initCardArray(){
var cards = new Array();
for (var i = 0; i < 4; i++) {
cards[i] = new Array();
for (var j = 0; j < 4; j++) {
//cards[i][j]=null;
}
}
return cards;
}
- 初始化和绘制背景代码(在2048.js中编写)
//初始化
G2048.prototype.init=function(el,musicObj){
if(!el) return ;
this.el=el;
var canvas = document.createElement('canvas');//创建画布
canvas.style.cssText="background:white;";
var W = canvas.width = 370; //设置宽度
var H = canvas.height = 370;//设置高度
el.appendChild(canvas);//添加到指定的dom对象中
this.ctx = canvas.getContext('2d');
this.draw();
}
//绘制入口
G2048.prototype.draw=function(){
//创建背景
this.drawGB();
//渲染到页面上
this.render();
}
//创建背景
G2048.prototype.drawGB=function(){
var bg = new _.Rect({x:0,y:0,width:364,height:364,fill:true,fillStyle:'#428853'});
this.renderArr.push(bg);
}
//渲染图形
G2048.prototype.render=function(){
var context=this.ctx;
this.clearCanvas();
_.each(this.renderArr,function(item){
item && item.render(context);
});
}
//清洗画布
G2048.prototype.clearCanvas=function() {
this.ctx.clearRect(0,0,parseInt(this.w),parseInt(this.h));
}
- 在页面代码中加入以下 js 代码
var box = document.getElementById('box');
g2048.init(box);
运行效果:
绘制好全部卡片
- 创建Card
//定义Card
function Card(i,j){
this.i=i;//下标i
this.j=j;//下标j
this.x=0;// x坐标
this.y=0;// y坐标
this.h=80;//高
this.w=80;//宽
this.start=10;//偏移量(固定值)
this.num=0;//显示数字
this.merge=false;//当前是否被合并过,如果合并了,则不能继续合并,针对当前轮
//初始化创建
this.obj = this.init();
//创建显示数字对象
this.numText = this.initNumText();
}
//初始创建
Card.prototype.init=function(){
return new _.Rect({x:this.x,y:this.y,width:this.w,height:this.h,fill:true});
}
//根据i j计算x y坐标
Card.prototype.cal=function(){
this.x = this.start + this.j*this.w + (this.j+1)*5;
this.y = this.start + this.i*this.h + (this.i+1)*5;
//更新给obj
this.obj.x=this.x;
this.obj.y=this.y;
//设置填充颜色
this.obj.fillStyle=this.getColor();
//更新文字的位置
this.numText.x = this.x+40;
this.numText.y = this.y+55;
this.numText.text=this.num;
}
//初始化显示数字对象
Card.prototype.initNumText=function(){
var font = "34px 思源宋体";
var fillStyle = "#7D4E33";
return new _.Text({x:this.x,y:this.y+50,text:this.num,fill:true,textAlign:'center',font:font,fillStyle:fillStyle});
}
//获取color
Card.prototype.getColor=function(){
var color;
//根据num设定颜色
switch (this.num) {
case 2:
color = "#EEF4EA";
break;
case 4:
color = "#DEECC8";
break;
case 8:
color = "#AED582";
break;
case 16:
color = "#8EC94B";
break;
case 32:
color = "#6F9430";
break;
case 64:
color = "#4CAE7C";
break;
case 128:
color = "#3CB490";
break;
case 256:
color = "#2D8278";
break;
case 512:
color = "#09611A";
break;
case 1024:
color = "#F2B179";
break;
case 2048:
color = "#DFB900";
break;
default://默认颜色
color = "#5C9775";
break;
}
return color;
}
Card.prototype.render=function(context){
//计算坐标等
this.cal();
//执行绘制
this.obj.render(context);
//是否绘制文字的处理
if(this.num!=0){
this.numText.render(context);
}
}
}
- 创建卡片
//创建卡片
G2048.prototype.drawCard=function(){
var that=this;
var card;
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
card = new Card(i,j);
that.cards[i][j]=card;
that.renderArr.push(card);
}
}
}
- 调用绘制代码
运行效果:
- 修改一下卡片的默认数字
随机生成一个卡片,2或者4
- 先把Card中 num 默认改成0
- 因为2跟4出现的比例是1:4,所以采用随机出1-5的数字,当是1的时候就表示,当得到2、3、4、5的时候就表示要出现数字2.
- 随机获取i,j 就可以得到卡片的位置,割接i,j取到card实例,如果卡片没有数字,就表示可以,否则就递归继续取,取到为止。
- 把刚才取到的数字,设置到card实例对象中就好了。
代码如下:
//随机创建一个卡片
G2048.prototype.createRandomNumber=function(){
var num = 0;
var index = _.getRandom(1,6);//这样取出来的就是1-5 之间的随机数
//因为2和4出现的概率是1比4,所以如果index是1,则创建数字4,否则创建数字2(1被随机出来的概率就是1/5,而其他就是4/5 就是1:4的关系)
console.log('index==='+index)
if(index==1){
num = 4;
}else {
num = 2;
}
//判断如果格子已经满了,则不再获取,退出
if(this.cardFull()){
return ;
}
//获取随机卡片,不为空的
var card = this.getRandomCard();
//给card对象设置数字
if(card!=null){
card.num=num;
}
}
//获取随机卡片,不为空的
G2048.prototype.getRandomCard=function(){
var i = _.getRandom(0,4);
var j = _.getRandom(0,4);
var card = this.cards[i][j];
if(card.num==0){//如果是空白的卡片,则找到了,直接返回
return card;
}
//没找到空白的,就递归,继续寻找
return this.getRandomCard();
}
//判断格子满了
G2048.prototype.cardFull=function() {
var card;
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
card = this.cards[i][j];
if(card.num==0){//有一个为空,则没满
return false;
}
}
}
return true;
}
draw方法中调用,表示打开游戏默认一个数字
运行效果:
加入键盘事件
同样要在draw方法中调用哦
//按键的控制
G2048.prototype.control=function(){
var that=this;
global.addEventListener('keydown',function(e){
console.log(that.flag)
if(that.flag!='start') return ;
var dir;
switch (e.keyCode){
case 87://w
case 38://上
dir=1;//上移动
break;
case 68://d
case 39://右
dir=2;//右移动
break;
case 83://s
case 40://下
dir=3;//下移动
break;
case 65://a
case 37://左
dir=4;//左移动
break;
}
//卡片移动的方法
that.moveCard(dir);
});
}
- 加入移动逻辑处理代码
//卡片移动的方法
G2048.prototype.moveCard=function(dir) {
//将卡片清理一遍,因为每轮移动会设定合并标记,需重置
this.clearCard();
if(dir==1){//向上移动
this.moveCardTop(true);
}else if(dir==2){//向右移动
this.moveCardRight(true);
}else if(dir==3){//向下移动
this.moveCardBottom(true);
}else if(dir==4){//向左移动
this.moveCardLeft(true);
}
//移动后要创建新的卡片
this.createRandomNumber();
//重绘
this.render();
//判断游戏是否结束
this.gameOverOrNot();
}
//将卡片清理一遍,因为每轮移动会设定合并标记,需重置
G2048.prototype.clearCard=function() {
var card;
for (var i = 0; i < 4; i++) {//i从1开始,因为i=0不需要移动
for (var j = 0; j < 4; j++) {
card = this.cards[i][j];
card.merge=false;
}
}
}
- 加入上下左右处理逻辑
//以上是关于JavaScript实现2048小游戏,我终于赢了一把的主要内容,如果未能解决你的问题,请参考以下文章