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);
}
}
}
- 调用绘制代码
运行效果:
- 修改一下卡片的默认数字
- 先把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;
}
}
}
- 加入上下左右处理逻辑
//向上移动
G2048.prototype.moveCardTop=function(bool) {
var res = false;
var card;
for (var i = 1; i < 4; i++) {//i从1开始,因为i=0不需要移动
for (var j = 0; j < 4; j++) {
card = this.cards[i][j];
if(card.num!=0){//只要卡片不为空,要移动
if(card.moveTop(this.cards,bool)){//向上移动
res = true;//有一个为移动或者合并了,则res为true
}
}
}
}
return res;
}
//向右移动
G2048.prototype.moveCardRight=function(bool) {
var res = false;
var card;
for (var i = 0; i < 4; i++) {
for (var j = 3; j >=0 ; j–) {//j从COLS-1开始,从最右边开始移动递减
card = this.cards[i][j];
if(card.num!=0){//只要卡片不为空,要移动
if(card.moveRight(this.cards,bool)){//向右移动
res = true;//有一个为移动或者合并了,则res为true
}
}
}
}
return res;
}
//向下移动
G2048.prototype.moveCardBottom=function(bool) {
var res = false;
var card;
for (var i = 3; i >=0; i–) {//i从ROWS-1开始,往下递减移动
for (var j = 0; j < 4; j++) {
card = this.cards[i][j];
if(card.num!=0){//只要卡片不为空,要移动
if(card.moveBottom(this.cards,bool)){//下移动
res = true;//有一个为移动或者合并了,则res为true
}
}
}
}
return res;
}
//向左移动
G2048.prototype.moveCardLeft=function(bool) {
var res = false;
var card;
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4 ; j++) {//j从1开始,从最左边开始移动
card = this.cards[i][j];
if(card.num!=0){//只要卡片不为空,要移动
if(card.moveLeft(this.cards,bool)){//向左移动
res = true;//有一个为移动或者合并了,则res为true
}
}
}
}
return res;
}
- 在Card中加入向上移动的处理逻辑
- 从第2行开始移动,因为第一行不需要移动。
- 只要卡片的数字不是0,就表示要移动。
- 根据 i-1 可以获取到上一个卡片,如果上一个卡片是空,则把当前卡片交换上去,并且递归,因为可能要继续往上移动。
- 如果当前卡片与上一个卡片是相同数字的,则要合并。
- 以上两种都不是,则不做操作。
//卡片向上移动
Card.prototype.moveTop=function(cards,bool) {
var i=this.i;
var j=this.j;
//设定退出条件
if(i==0){//已经是最上面了
return false;
}
//上面一个卡片
var prev = cards[i-1][j];
if(prev.num==0){//上一个卡片是空
//移动,本质就是设置数字
if(bool){//bool为true才执行,因为flase只是用来判断能否移动
prev.num=this.num;
this.num=0;
//递归操作(注意这里是要 prev 来 move了)
prev.moveTop(cards,bool);
}
return true;
}else if(prev.num==this.num && !prev.merge){//合并操作(如果已经合并了,则不运行再次合并,针对当然轮)
if(bool){bool为true才执行
prev.merge=true;
prev.num=this.num*2;
this.num=0;
}
return true;
}else {//上一个的num与当前num不同,无法移动,并退出
return false;
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
react和vue的比较
相同
1)vitual dom
2)组件化
3)props,单一数据流
不同点
1)react是jsx和模板;(jsx可以进行更多的js逻辑和操作)
2)状态管理(react)
3)对象属性(vue)
4)vue:view——medol之间双向绑定
5)vue:组件之间的通信(props,callback,emit)
09551)]
[外链图片转存中…(img-qBehruMq-1711748409552)]
[外链图片转存中…(img-Yvz1LUoz-1711748409552)]
[外链图片转存中…(img-ecEYwaIo-1711748409552)]
[外链图片转存中…(img-ncurnd4a-1711748409553)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-u6ErickA-1711748409553)]
react和vue的比较
相同
1)vitual dom
2)组件化
3)props,单一数据流
不同点
1)react是jsx和模板;(jsx可以进行更多的js逻辑和操作)
2)状态管理(react)
3)对象属性(vue)
4)vue:view——medol之间双向绑定
5)vue:组件之间的通信(props,callback,emit)
[外链图片转存中…(img-5cGdY9mW-1711748409554)]