|
@@ -1,6 +1,6 @@
|
|
<template>
|
|
<template>
|
|
<div class="app">
|
|
<div class="app">
|
|
- <div class="container" @dragover="allowDrop" @drop="cancelHeroSelected">
|
|
|
|
|
|
+ <div class="container">
|
|
<div class="title" ></div>
|
|
<div class="title" ></div>
|
|
<div class="guide">
|
|
<div class="guide">
|
|
<a href="http://lol.duowan.com/1908/429554416930.html" target="_blank">>>使用指南<<</a>
|
|
<a href="http://lol.duowan.com/1908/429554416930.html" target="_blank">>>使用指南<<</a>
|
|
@@ -68,20 +68,18 @@
|
|
@addHero="addHero"/>
|
|
@addHero="addHero"/>
|
|
</div>
|
|
</div>
|
|
<div class="element-box">
|
|
<div class="element-box">
|
|
- <div class="element-wrapper" title="火" draggable="true" @dragstart="selectElement($event, 'fire')" >
|
|
|
|
|
|
+ <div :class="['element-wrapper', currentElement === 'fire' ? 'active' : '']" title="火" @click="currentElement = 'fire'">
|
|
<div class="element fire"></div>
|
|
<div class="element fire"></div>
|
|
</div>
|
|
</div>
|
|
- <div class="element-wrapper" title="水" draggable="true" @dragstart="selectElement($event, 'water')" >
|
|
|
|
|
|
+ <div :class="['element-wrapper', currentElement === 'water' ? 'active' : '']" title="水" @click="currentElement = 'water'">
|
|
<div class="element water"></div>
|
|
<div class="element water"></div>
|
|
</div>
|
|
</div>
|
|
- <div class="element-wrapper" title="风" draggable="true" @dragstart="selectElement($event, 'wind')" >
|
|
|
|
|
|
+ <div :class="['element-wrapper', currentElement === 'wind' ? 'active' : '']" title="风" @click="currentElement = 'wind'">
|
|
<div class="element wind"></div>
|
|
<div class="element wind"></div>
|
|
</div>
|
|
</div>
|
|
- <div class="element-wrapper" title="土" draggable="true" @dragstart="selectElement($event, 'earth')" >
|
|
|
|
|
|
+ <div :class="['element-wrapper', currentElement === 'earth' ? 'active' : '']" title="土" @click="currentElement = 'earth'">
|
|
<div class="element earth"></div>
|
|
<div class="element earth"></div>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
-
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -144,6 +142,7 @@
|
|
@heroSelectEquipment="handleHeroSelectEquipment"
|
|
@heroSelectEquipment="handleHeroSelectEquipment"
|
|
@deleteHero="handleDeleteHero"
|
|
@deleteHero="handleDeleteHero"
|
|
/>
|
|
/>
|
|
|
|
+ <div :class="['element-bg', currentElement]" v-if="memoElementsIndexes.includes(index)" draggable="true" @dragstart="handleDragElementStart"></div>
|
|
</div>
|
|
</div>
|
|
<transition name="slide-fade">
|
|
<transition name="slide-fade">
|
|
<div
|
|
<div
|
|
@@ -336,6 +335,8 @@ const MAX_HEROES_COUNT = 28 // 棋盘所能容纳的最大英雄上限
|
|
const MAX_PLAYER_LEVEL = 9 // 玩家最大等级
|
|
const MAX_PLAYER_LEVEL = 9 // 玩家最大等级
|
|
const MIN_PLAYER_LEVEL = 1 // 玩家最小等级
|
|
const MIN_PLAYER_LEVEL = 1 // 玩家最小等级
|
|
const LOCALSTORAGE_KEY = '__ydzySimulatorUserInfo'
|
|
const LOCALSTORAGE_KEY = '__ydzySimulatorUserInfo'
|
|
|
|
+const elements = ['fire', 'water', 'wind', 'earth'] // 元素属性
|
|
|
|
+const elementEquipmentsMap = {} // 元素属性与元素装备的映射
|
|
|
|
|
|
let fetters
|
|
let fetters
|
|
const original = {}
|
|
const original = {}
|
|
@@ -349,6 +350,15 @@ function duplicateHeroes(heroes) {
|
|
return Object.values(map)
|
|
return Object.values(map)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function initElementsIndexes (){
|
|
|
|
+ const ret = []
|
|
|
|
+ while(ret.length < 2) {
|
|
|
|
+ let n = genRandomInteger(0, MAX_HEROES_COUNT - 1)
|
|
|
|
+ !ret.includes(n) && ret.push(n)
|
|
|
|
+ }
|
|
|
|
+ return ret
|
|
|
|
+}
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
@@ -361,7 +371,8 @@ export default {
|
|
goals: [], // 待激活的羁绊
|
|
goals: [], // 待激活的羁绊
|
|
extra_population: 0, // 通过装备额外增加的人口
|
|
extra_population: 0, // 通过装备额外增加的人口
|
|
level: 1, // 当前玩家等级
|
|
level: 1, // 当前玩家等级
|
|
- currentElement: '', // 当前格子元素
|
|
|
|
|
|
+ currentElement: elements[genRandomInteger(0, elements.length - 1)], // 当前格子元素
|
|
|
|
+ memoElementsIndexes: initElementsIndexes(), // 记录带元素格子的索引
|
|
starSelectorVisiable: false, // 控制小小英雄选星级的对话框的显隐
|
|
starSelectorVisiable: false, // 控制小小英雄选星级的对话框的显隐
|
|
littleHeroSelectorVisiable: false, // 小小英雄选择框的显隐
|
|
littleHeroSelectorVisiable: false, // 小小英雄选择框的显隐
|
|
sharingPopupVisiable: false, // 分享对话框显隐
|
|
sharingPopupVisiable: false, // 分享对话框显隐
|
|
@@ -402,48 +413,7 @@ export default {
|
|
}
|
|
}
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
- // 拖拽取消英雄选择 / 移动棋盘内英雄
|
|
|
|
- cancelHeroSelected(ev) {
|
|
|
|
- const classList = ev.target.classList
|
|
|
|
- if (classList.contains('board-grid')) {
|
|
|
|
- // 此时用户为想从棋盘上移动该英雄
|
|
|
|
- const heroIndex = ev.dataTransfer.getData('heroIndex')
|
|
|
|
-
|
|
|
|
- if (heroIndex !== '') {
|
|
|
|
- const targetIndex = Array.from(document.querySelectorAll('.board-grid')).indexOf(ev.target)
|
|
|
|
- const hero = JSON.parse(ev.dataTransfer.getData('moveHero'))
|
|
|
|
- this.selectedHeroes.splice(Number(heroIndex), 1, null)
|
|
|
|
- this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
|
|
- }
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (classList.contains('hero') || classList.contains('item-hero') || classList.contains('equipment')) {
|
|
|
|
- // 此时代表棋盘上有英雄, 用户想要交换两英雄位置
|
|
|
|
- const heroIndex = ev.dataTransfer.getData('heroIndex')
|
|
|
|
- if (heroIndex) {
|
|
|
|
- // 对用户拖拽时的容错处理
|
|
|
|
- const targetNode = ev.target.parentNode.classList.contains('board-grid') ? ev.target.parentNode :
|
|
|
|
- ev.target.parentNode.parentNode.classList.contains('board-grid') ? ev.target.parentNode.parentNode : null
|
|
|
|
- if(!targetNode) { return }
|
|
|
|
-
|
|
|
|
- const targetIndex = Array.from(
|
|
|
|
- document.querySelectorAll('.board-grid')
|
|
|
|
- ).indexOf(targetNode)
|
|
|
|
-
|
|
|
|
- const hero = JSON.parse(ev.dataTransfer.getData('moveHero'))
|
|
|
|
- this.selectedHeroes.splice(Number(heroIndex),1,this.selectedHeroes[targetIndex])
|
|
|
|
- this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
|
|
- }
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
|
|
- // 此时用户为想从棋盘上删除该英雄
|
|
|
|
- const heroIndex = ev.dataTransfer.getData('heroIndex')
|
|
|
|
- if (heroIndex !== '') {
|
|
|
|
- this.selectedHeroes.splice(Number(heroIndex), 1, null)
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
// 点击取消英雄选择
|
|
// 点击取消英雄选择
|
|
handleDeleteHero(heroIndex) {
|
|
handleDeleteHero(heroIndex) {
|
|
this.selectedHeroes.splice(heroIndex, 1, null)
|
|
this.selectedHeroes.splice(heroIndex, 1, null)
|
|
@@ -491,28 +461,66 @@ export default {
|
|
this.extra_population = 0
|
|
this.extra_population = 0
|
|
this.level = 1
|
|
this.level = 1
|
|
},
|
|
},
|
|
- selectElement(ev, element){
|
|
|
|
- this.currentElement = element
|
|
|
|
- ev.dataTransfer.setData('element', element)
|
|
|
|
|
|
+ handleDragElementStart(ev){
|
|
|
|
+ const parentNode = ev.target.parentNode
|
|
|
|
+ const targetIndex = Array.from(document.querySelectorAll('.board-grid')).indexOf(parentNode)
|
|
|
|
+ ev.dataTransfer.setData('elementIndex', targetIndex)
|
|
},
|
|
},
|
|
- // 拖拽添加英雄到阵容中 或者 拖拽元素到格子里
|
|
|
|
- handleDrop(ev, heroIndex) {
|
|
|
|
|
|
+ // 拖拽添加英雄到阵容中
|
|
|
|
+ handleDrop(ev, targetIndex) {
|
|
ev.preventDefault()
|
|
ev.preventDefault()
|
|
|
|
+ ev.stopPropagation()
|
|
|
|
+ const classList = ev.target.classList
|
|
|
|
+ const elementIndex = ev.dataTransfer.getData('elementIndex') ? Number(ev.dataTransfer.getData('elementIndex')) : -1
|
|
|
|
+ const heroIndex = ev.dataTransfer.getData('heroIndex') ? Number(ev.dataTransfer.getData('heroIndex')) : -1
|
|
|
|
+ const hero = this.selectedHeroes[heroIndex]
|
|
// 拖拽添加英雄
|
|
// 拖拽添加英雄
|
|
if (ev.dataTransfer.getData('hero')) {
|
|
if (ev.dataTransfer.getData('hero')) {
|
|
if (this.currentPopulation < this.currentMaxHero) {
|
|
if (this.currentPopulation < this.currentMaxHero) {
|
|
const hero = JSON.parse(ev.dataTransfer.getData('hero'))
|
|
const hero = JSON.parse(ev.dataTransfer.getData('hero'))
|
|
- this.selectedHeroes.splice(heroIndex, 1, hero)
|
|
|
|
|
|
+ this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
} else {
|
|
} else {
|
|
alert('你该升级啦~点击小小英雄下方的升级按钮提升你的等级吧~')
|
|
alert('你该升级啦~点击小小英雄下方的升级按钮提升你的等级吧~')
|
|
}
|
|
}
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (classList.contains('board-grid')) {
|
|
|
|
+ if(elementIndex > -1) {
|
|
|
|
+ // 此时为用户将元素移动到空棋子上
|
|
|
|
+ this.memoElementsIndexes.splice(this.memoElementsIndexes.indexOf(elementIndex), 1, targetIndex)
|
|
|
|
+ } else {
|
|
|
|
+ // 此时用户为想从棋盘上移动该英雄
|
|
|
|
+ if (heroIndex > -1 && hero) {
|
|
|
|
+ this.selectedHeroes.splice(heroIndex, 1, null)
|
|
|
|
+ this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (classList.contains('hero') || classList.contains('item-hero') || classList.contains('equipment')) {
|
|
|
|
+ if(elementIndex > -1) {
|
|
|
|
+ // 此时为用户将元素移动到有英雄棋子的位置上
|
|
|
|
+ this.memoElementsIndexes.splice(this.memoElementsIndexes.indexOf(elementIndex), 1, targetIndex)
|
|
|
|
+ } else {
|
|
|
|
+ // 此时为用户想要交换棋子位置
|
|
|
|
+ if (heroIndex > -1 && hero) {
|
|
|
|
+ this.selectedHeroes.splice(heroIndex,1,this.selectedHeroes[targetIndex])
|
|
|
|
+ this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
|
|
- // 拖拽添加元素
|
|
|
|
- if(ev.dataTransfer.getData('element')) {
|
|
|
|
- if(!this.selectedHeroes[heroIndex]) {
|
|
|
|
- console.log('空格子')
|
|
|
|
|
|
+ if(classList.contains('element-bg')){
|
|
|
|
+ // 此时为用户想要将英雄棋子移动到有元素的空位上
|
|
|
|
+ if(elementIndex === -1) {
|
|
|
|
+ this.selectedHeroes.splice(heroIndex, 1, null)
|
|
|
|
+ this.selectedHeroes.splice(targetIndex, 1, hero)
|
|
}
|
|
}
|
|
|
|
+ // 另外一种情况为用户将带有元素的棋子拖拽到另一带有元素的棋子,这种情况不需要处理。
|
|
}
|
|
}
|
|
},
|
|
},
|
|
// 选择小小英雄星级
|
|
// 选择小小英雄星级
|
|
@@ -538,6 +546,9 @@ export default {
|
|
},
|
|
},
|
|
// 点击添加英雄到阵容中
|
|
// 点击添加英雄到阵容中
|
|
addHero(_hero){
|
|
addHero(_hero){
|
|
|
|
+ if(_hero.name === '大元素使 拉克丝' && this.selectedHeroes.find(h => h && h.name === '大元素使 拉克丝')) {
|
|
|
|
+ return alert('场上只能存在一个拉克丝。')
|
|
|
|
+ }
|
|
if (this.currentPopulation < this.currentMaxHero) {
|
|
if (this.currentPopulation < this.currentMaxHero) {
|
|
const positon = this.selectedHeroes.findIndex(el => !el)
|
|
const positon = this.selectedHeroes.findIndex(el => !el)
|
|
this.selectedHeroes.splice(positon, 1, JSON.parse(JSON.stringify(_hero)))
|
|
this.selectedHeroes.splice(positon, 1, JSON.parse(JSON.stringify(_hero)))
|
|
@@ -671,19 +682,38 @@ export default {
|
|
let duplicatedHeroes = duplicateHeroes(filteredHero)
|
|
let duplicatedHeroes = duplicateHeroes(filteredHero)
|
|
|
|
|
|
duplicatedHeroes.forEach(hero => {
|
|
duplicatedHeroes.forEach(hero => {
|
|
- // 拉克丝特殊处理一下
|
|
|
|
|
|
+ // 拉克丝特殊处理
|
|
if (hero.name === '大元素使 拉克丝') {
|
|
if (hero.name === '大元素使 拉克丝') {
|
|
hero.sort.forEach(job => {
|
|
hero.sort.forEach(job => {
|
|
heroCount[job] += 2
|
|
heroCount[job] += 2
|
|
})
|
|
})
|
|
- } else {
|
|
|
|
- hero.sort.forEach(job => {
|
|
|
|
|
|
+ hero.job.forEach(job => {
|
|
|
|
+ heroCount[job]++
|
|
|
|
+ })
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 元素女皇特殊处理
|
|
|
|
+ if(hero.name === '元素女皇 琪亚娜') {
|
|
|
|
+ const elementToFetter = {
|
|
|
|
+ water: 'heroSort7',
|
|
|
|
+ fire: 'heroSort5',
|
|
|
|
+ wind: 'heroSort2',
|
|
|
|
+ earth: 'heroSort11'
|
|
|
|
+ }
|
|
|
|
+ heroCount[ elementToFetter[this.currentElement] ]++
|
|
|
|
+ hero.job.forEach(job => {
|
|
heroCount[job]++
|
|
heroCount[job]++
|
|
})
|
|
})
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
+ hero.sort.forEach(job => {
|
|
|
|
+ heroCount[job] ++
|
|
|
|
+ })
|
|
hero.job.forEach(job => {
|
|
hero.job.forEach(job => {
|
|
heroCount[job]++
|
|
heroCount[job]++
|
|
})
|
|
})
|
|
|
|
+
|
|
})
|
|
})
|
|
|
|
|
|
// 重复的英雄带的装备只有自然之力不是唯一被动
|
|
// 重复的英雄带的装备只有自然之力不是唯一被动
|
|
@@ -788,6 +818,19 @@ export default {
|
|
this.$off('selectEquipment')
|
|
this.$off('selectEquipment')
|
|
this.$off('cancelEquipmentSelected')
|
|
this.$off('cancelEquipmentSelected')
|
|
}
|
|
}
|
|
|
|
+ },
|
|
|
|
+ currentElement(newVal){
|
|
|
|
+ // 这里的逻辑针对琪亚娜这个英雄做特殊处理
|
|
|
|
+ const heroIndex = this.selectedHeroes.findIndex(h => h.name === '元素女皇 琪亚娜')
|
|
|
|
+ if(heroIndex !== -1) {
|
|
|
|
+ const elementToFetter = {
|
|
|
|
+ water: 'heroSort7',
|
|
|
|
+ fire: 'heroSort5',
|
|
|
|
+ wind: 'heroSort2',
|
|
|
|
+ earth: 'heroSort11'
|
|
|
|
+ }
|
|
|
|
+ this.selectedHeroes[heroIndex].sort = [elementToFetter[newVal]]
|
|
|
|
+ }
|
|
}
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
@@ -815,8 +858,14 @@ export default {
|
|
|
|
|
|
initData()
|
|
initData()
|
|
|
|
|
|
|
|
+ const simulatorEquipment = []
|
|
|
|
+
|
|
|
|
+ data.simulatorEquipment.forEach(eq => {
|
|
|
|
+ eq.effectType !== 'element' ? simulatorEquipment.push(eq) : elementEquipmentsMap[eq.effectJob] = eq
|
|
|
|
+ })
|
|
|
|
+
|
|
fetters = data.fetters
|
|
fetters = data.fetters
|
|
- this.simulatorEquipment = data.simulatorEquipment
|
|
|
|
|
|
+ this.simulatorEquipment = simulatorEquipment
|
|
this.heroes = data.hero.data
|
|
this.heroes = data.hero.data
|
|
this.littleHeroes = data.littleHero.data
|
|
this.littleHeroes = data.littleHero.data
|
|
})
|
|
})
|
|
@@ -968,6 +1017,42 @@ export default {
|
|
&.filled {
|
|
&.filled {
|
|
background: none;
|
|
background: none;
|
|
}
|
|
}
|
|
|
|
+ // &.withElement{
|
|
|
|
+ // background-color: red;
|
|
|
|
+ // }
|
|
|
|
+ .element-bg{
|
|
|
|
+ width: 81px;
|
|
|
|
+ height: 92px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 2px;
|
|
|
|
+ top: 2px;
|
|
|
|
+ opacity: 0.6;
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
+ z-index: -1;
|
|
|
|
+ clip-path: polygon(
|
|
|
|
+ 50% 0%,
|
|
|
|
+ 100% 25%,
|
|
|
|
+ 100% 75%,
|
|
|
|
+ 50% 100%,
|
|
|
|
+ 0% 75%,
|
|
|
|
+ 0% 25%
|
|
|
|
+ );
|
|
|
|
+ &.fire{
|
|
|
|
+ background: url('../assets/images/fire.png') no-repeat 100% / 100%;
|
|
|
|
+ }
|
|
|
|
+ &.water{
|
|
|
|
+ background: url('../assets/images/water.png') no-repeat 100% / 100%;
|
|
|
|
+ }
|
|
|
|
+ &.earth{
|
|
|
|
+ background: url('../assets/images/earth.png') no-repeat 100% / 100%;
|
|
|
|
+ }
|
|
|
|
+ &.wind{
|
|
|
|
+ background: url('../assets/images/wind.png') no-repeat 100% / 100%;
|
|
|
|
+ }
|
|
|
|
+ &:hover{
|
|
|
|
+ opacity: 0.8;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
&.small {
|
|
&.small {
|
|
&:nth-child(n + 4) {
|
|
&:nth-child(n + 4) {
|
|
@@ -1295,6 +1380,8 @@ export default {
|
|
.element-box {
|
|
.element-box {
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
justify-content: space-evenly;
|
|
|
|
+ border: 1px solid #635d60;
|
|
|
|
+ padding: 10px 0;
|
|
.element-wrapper{
|
|
.element-wrapper{
|
|
width: 70px;
|
|
width: 70px;
|
|
height: 81px;
|
|
height: 81px;
|
|
@@ -1303,6 +1390,12 @@ export default {
|
|
background: url("../assets/images/icon-colorful.png") no-repeat 100% / 100%;
|
|
background: url("../assets/images/icon-colorful.png") no-repeat 100% / 100%;
|
|
position: relative;
|
|
position: relative;
|
|
z-index: 1;
|
|
z-index: 1;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ transition: all 0.3s cubic-bezier(.06,1.45,.46,1.6);
|
|
|
|
+ &.active{
|
|
|
|
+ transform: translateY(-10px);
|
|
|
|
+ filter: brightness(1.3);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
.element {
|
|
.element {
|
|
position: absolute;
|
|
position: absolute;
|