🔥花了3天空余时间写了个纯前端游戏《卡片天才》

📌前言

后端平均一天一个接口 , 每天在岗位上闲的蛋疼。

在摸鱼的过程中玩了一款网页的文字沙盒游戏 ,玩了小一会枯燥乏味 ,满眼的文字非常抗拒 , 所以突发奇想为何不改造成有动画 , 有图片 ,有属性的卡片游戏呢?

思之而作 , 《卡片天才》应运而生 , 这是一款纯前端vue实现的卡片小游戏。

注意:游戏素材来源于网络 , 并未商用。

🍉玩法

  • 堆叠卡片产生不同的效应

没错 , 到这就介绍完了🥰 , 游戏主打的就是简单而不可思议 , 欢迎大家摸鱼时游玩并私信博主

相较游戏而言是非常简单的

但是作为纯使用前端vue实现来说是非常困难的

博主好几次都想不过来 , 需要大量的效应算法 , 以及阻断效应 , 和移动堆叠卡片重新匹配效应。

游戏画面

2024-04-25 17-38-37.gif

🍓技术

项目使用了帝莎编程 https://pc.dishait.cn/ , 这是一款vue3的开箱即用模板 , 不是打广告哈, 我并不是贡献者 , 我也是最近才发现的 , 模板中各种配置使用重复工作都写好了 , 可以直接上手。

  • 大致描述一下 vite5 + vue3.4 + ts + vueuse + pinia + router + unocss + icones 等等
  • 支持国际化以及暗黑模式

🍈开发思路

  1. 使用vueuse中的useDraggable实现拖拽以及拖拽前后的判读。
  2. 使用pinia并开启persist将游戏数据缓存起来
  3. 鼠标选中卡片时提高卡片层级,保证后选中的卡片在前选中的卡片高
  4. 卡片移动前解除卡片的效应,并编写算法根据移动卡片在卡组的位置,产生不同情况下的效应
  5. 卡片移动后与满足距离且最近的卡片组合,暂停卡组效应并根据最近卡片的组合情况产生新的效应。

🎉部分代码

移动前监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
ts复制代码onStart: (position, e) => {
// 移动者
let changeCards = props.card
// 更新卡片层级
data.updateZIndex(changeCards.id)
// 移动者组装项
let group =[...changeCards.group]
// 移动者在组中的位置
let groupIndex = group.findIndex(item=>item==changeCards.id)
// 移动者直接解除组装
changeCards.group = []
// 移动前后卡片组
let groupAll:number[][] = [[],[]]
// 卡片解除组装
if (group.length != 0) {
data.cards.forEach((item,index)=>{
// 属于卡片组&&不是本身
if (group.includes(item.id) && changeCards.id != item.id) {
// 组中卡
let card = data.cards[index]
// 组中卡在组中的位置
let cardIndex = group.findIndex(item=>item==card.id)
// 顶层卡片解除效应
if (card.id==group[0]) {
clearInterval(card.setInt)
card.percentage = 0
}
// 组中卡在移动卡前
if (cardIndex < groupIndex) {
// 少于两张卡
if (groupIndex <= 1) {
card.group = []
}else{
card.group = group.slice(0,groupIndex)
groupAll[0]=card.group
}
// 组中卡在移动卡后
}else{
// 少于两张卡
if (group.length - groupIndex <= 2) {
card.group = []
}else{
card.group = group.slice(groupIndex+1)
groupAll[1]=card.group
}
}
}
})
}
// 执行移动前后卡片组效应
groupAll.forEach((item)=>{
if (item.length!==0) {
groupEffect(item)
}
})
}

移动后监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
ts复制代码onEnd: (position, e) => {
// 移动者
let changeCards = props.card
// 记忆卡片最新位置
changeCards.x = x.value
changeCards.y = y.value
// 移动结束坐标
const endX = position.x
const endY = position.y
// 移动范围
const maxWidth: number = e.view?.innerWidth as number - 100
const maxHeight: number = e.view?.innerHeight as number - 100

// 卡片超出边界复位
x.value = Math.max(0, Math.min(endX, maxWidth))
y.value = Math.max(0, Math.min(endY, maxHeight))

// 符合距离条件卡片
let cardsAll:Card[] = []
// 卡片距离
let distance:number[] = []
// 给上述变量赋值
data.cards.forEach((item,index)=>{
// 去掉本身 , 隐藏 , 正在动画 , 末尾卡片非自身的卡片
if (item.id == changeCards.id || !item.show || item.animation!='' || ( item.group.length!=0 && item.group[item.group.length-1]!=item.id)) {
return
}
const xDistance = Math.abs(x.value - item.x)
const yDistance = Math.abs(y.value - item.y)
// 找到同时满足X , Y 坐标接近的卡片
if ( xDistance <= data.len.x && yDistance <= data.len.y ) {
distance.push(xDistance + yDistance)
cardsAll.push(item)
}
})
// 具有符合组合条件的卡片才进行组合
if (distance.length!=0) {
// 最近卡片索引
let minIndex = distance.findIndex(item => item == Math.min(...distance))
// 最近的卡片
let groupCard = cardsAll[minIndex]
// 记录组合 父级组合存在加入
let newGroup =groupCard.group.length!=0?[...groupCard.group,changeCards.id]:[groupCard.id,changeCards.id]

// 给新组合卡片重新赋值卡片组
data.cards.forEach((item,index)=>{
let card = data.cards[index]
// 解除原卡组效应
if (newGroup[0]==item.id) {
clearInterval(card.setInt)
card.percentage = 0
}
if (newGroup.includes(item.id)) {
card.group = newGroup
}
})
// 将卡片组合
x.value = groupCard.x
y.value = groupCard.y + 30

// 产生效应
groupEffect(newGroup)
}

// 记忆卡片最新位置
changeCards.x = x.value
changeCards.y = y.value

}

🍇后续思路

  • 除了更新更多卡片外 , 还将更新每张卡片的独特属性 ( 例如: 人类性别 – 年龄)
  • 金币系统以及战斗系统 (例如: 使用金币购买物品扩展卡片)
  • 繁殖系统以及继承系统 (例如: 将不同性别的人类产生效应)
  • 哥布林 ( 直接用博主照片 )

📚总结

发布这篇文章时只有两种效应和3张卡片 , 后续会更新创作。

可以查看更新日志和博主一起成长

欢迎各位留言以及私信。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%