0%

仿羊了个羊游戏

一个多月没更新博客了,赶紧来更新一波

✨前言

前段时间,无论是微信朋友圈还是QQ空间几乎都被一款小游戏刷屏,那就是羊了个羊,一款技术力很低,纯靠拿捏人们心理而爆火的游戏。难度不高,热度爆表,这种游戏一下子就吸引了开发者的注意力,于是我就见到了很多羊了个羊的开发文章。彼时刚系统学习完Vue2的我正想着怎么去进阶学习Vue3,而且也正缺项目练手,于是这个简单的小游戏一下子就吸引了我的注意力。

🎇项目规划

做一个项目之前要看看需要做什么东西,有一个统筹规划。虽然我以前从未做过项目,但是这点常识还是有的。首先就是看大致的解决方案,由于羊了个羊是随机生成卡片的布局模式,而上一层相对下一层一般有偏移量,因此可考虑用棋盘布局解决。具体思路就是先定义棋盘格子的长和宽,设置棋盘格子为绝对定位,然后偏移长和宽,从而在棋盘上生成对应的格子。这段代码实现得比较幼稚,在源代码中的initTable中实现的。然后我的想法是让卡片随机在这些格子中生成出来,从而实现游戏中的随机生成算法。当然,羊了个羊的游戏没有管游戏是否能完成出来,但是这里我们肯定是要保证卡片是3的倍数的,并且要保证同一个src的卡片也是3的倍数。

🎃项目逻辑难点

一开始觉得就比较难解决的一个点就是覆盖逻辑

不过后来想到可以直接根据index值判断上下关系,然后直接比较两张卡片在X和Y上的偏移量差值是否小于卡片定义的长宽从而判断是否被覆盖,算是比较简单且方便的一个算法了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
isCovered(){
this.table.forEach((card)=>{
if(card.isExist && card.index < 4){
for (const cardKey in this.table){
if(this.table[cardKey].isExist && this.table[cardKey].index > card.index){
let width = this.table[cardKey].left - card.left;
width = width > 0 ? width : -width;
let height = this.table[cardKey].top - card.top;
height = height > 0 ? height : -height;
console.log(width,height)
if(width < CardWidth && height < CardHeight){
card.clickable = false;
break;
}else{
card.clickable = true;
}
}
}
}
})
}

然后是判断卡片点击后插入下面的位置的逻辑代码

采用的方法是判断下方的消除框是否有跟卡片src一样的src,如果有就接着看下一张,直到下一张不是相同的src,那就插在这张卡片的前面。如果消除框中没有出现相同的src,那就在最后面插入一张卡片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
insert(item){
let index;
/*这里的length是加入之前的length所以只-1不-2,还是挺坑的,逻辑陷阱吧算是*/
for(let i=0;i<this.store.selectedCards.length || this.store.selectedCards.length === 0;i++){
if(i === this.store.selectedCards.length - 1 || this.store.selectedCards.length === 0){
index = this.store.selectedCards.length - 2;
this.store.selectedCards.push(item);
break;
}
if(this.store.selectedCards[i].imgSrc === item.imgSrc && this.store.selectedCards[i+1].imgSrc !== item.imgSrc){
index = i-1;
this.store.selectedCards.splice(i+1,0,item);
break;
}
}
return index;
},

❓项目的几个问题

  • 首先就是关于浏览器的事件循环机制问题。我在写代码的过程中,发现有很多代码逻辑必须采用定时器触发,不然就会影响到游戏的整体逻辑,这是我觉得比较奇怪的一点。譬如判断方块是否消除的代码逻辑在判断游戏是否输掉的代码逻辑之前,但是当方块刚好七块但里面有可以消除的方块时,判断游戏是否输掉的逻辑仍会生效并判断游戏输掉,但是给其加一个100ms的定时器触发后就没有类似的问题了。

  • 还有关于静态资源打包的问题。Vite不支持使用require动态加载,那么难道所有的静态资源都只能一个一个import进来吗,这是一件很麻烦的事情,应该是有更好的解决方案的

  • 项目加载问题。我的项目用nginx部署上线之后,连接总是会出现静态资源加载很久的情况,即图片要加载半天,这肯定是极为影响页面浏览体验的,有什么加快静态资源的加载的方法吗?