add page of gameplay
BIN
src/assets/202202/gameplay/cell-bg.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
src/assets/202202/gameplay/icon-upgrade.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/202202/gameplay/icon_play.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
src/assets/202202/gameplay/icon_pve.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/202202/gameplay/icon_pvp.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/202202/gameplay/icon_social.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/202202/gameplay/img_pve.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
src/assets/202202/gameplay/img_pvp.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
src/assets/202202/gameplay/img_social.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
src/assets/202202/gameplay/img_upgrade.png
Normal file
After Width: | Height: | Size: 36 KiB |
79
src/components/gameplay/DataCell.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div class="data-cell" :class="{'right': data.type === 1}" >
|
||||||
|
<div class="left-part" >
|
||||||
|
<div class="icon">
|
||||||
|
<img :src="data.icon" alt=""/>
|
||||||
|
</div>
|
||||||
|
<div class="title">{{data.title}}</div>
|
||||||
|
<div class="desc">
|
||||||
|
<p v-for="(s, i) in data.desc" :key="i">{{s}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right-part">
|
||||||
|
<img :src="data.mainImg" alt=""/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'DataCell',
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
props: ['data']
|
||||||
|
})
|
||||||
|
export default class extends Vue {
|
||||||
|
get isRight() {
|
||||||
|
return this.data.type === 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.data-cell{
|
||||||
|
width: 1348px;
|
||||||
|
height: 432px;
|
||||||
|
background-image: url('../../assets/202202/gameplay/cell-bg.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
&.right{
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
.right-part{
|
||||||
|
width: 410px;
|
||||||
|
height: 227px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.left-part {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 660px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 140px;
|
||||||
|
.icon{
|
||||||
|
height: 35px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
color: white;
|
||||||
|
font-weight: blod;
|
||||||
|
font-size: 32px;
|
||||||
|
line-height: 38px;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<div class="video-section">
|
||||||
|
<div class="video-cover">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'VideoSection',
|
||||||
|
components: {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default class extends Vue {}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.video-section{
|
||||||
|
.video-cover{
|
||||||
|
width: 1280px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -29,6 +29,7 @@ import { Component, Vue } from 'vue-property-decorator'
|
|||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
import { AppModule } from '@/store/modules/app'
|
import { AppModule } from '@/store/modules/app'
|
||||||
import { BlockChain } from '@/utils/blockchain'
|
import { BlockChain } from '@/utils/blockchain'
|
||||||
|
import { loginWithSign } from '@/utils/login'
|
||||||
|
|
||||||
declare module 'vue/types/vue' {
|
declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
@ -59,7 +60,8 @@ export default class extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async collectToWallet() {
|
async collectToWallet() {
|
||||||
return this.bc.connect()
|
await this.bc.connect()
|
||||||
|
await loginWithSign(this.bc, AppModule.accountId, AppModule.chainId)
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDrop() {
|
toggleDrop() {
|
||||||
|
@ -17,7 +17,7 @@ export interface ICellData {
|
|||||||
|
|
||||||
declare module 'vue/types/vue' {
|
declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
cellData: ICellData
|
cellData?: ICellData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tab-bar">
|
<div class="tab-bar" ref="bar">
|
||||||
<div class="tab" @click="tabChange('cec')" :class="{'active': selectTab==='cec'}">CEC</div>
|
<div
|
||||||
<div class="tab" @click="tabChange('ceg')" :class="{'active': selectTab==='ceg'}">CEG</div>
|
class="tab"
|
||||||
<div class="tab" @click="tabChange('allocation')" :class="{'active': selectTab==='allocation'}">Release & Allocation</div>
|
v-for="d in tabDatas"
|
||||||
|
@click="tabChange(d.id)"
|
||||||
|
:key="d.id"
|
||||||
|
:style="tabStyleObj"
|
||||||
|
:class="{'active': selectTab===d.id}"
|
||||||
|
>{{d.name}}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
export interface ITabData{
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
declare module 'vue/types/vue' {
|
declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
selectTab?: string
|
selectTab?: string
|
||||||
|
tabDatas?: ITabData[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,9 +29,17 @@ declare module 'vue/types/vue' {
|
|||||||
name: 'TabBar',
|
name: 'TabBar',
|
||||||
components: {
|
components: {
|
||||||
},
|
},
|
||||||
props: ['selectTab']
|
props: ['selectTab', 'tabDatas']
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
$refs!: {
|
||||||
|
bar: HTMLFormElement
|
||||||
|
}
|
||||||
|
|
||||||
|
get tabStyleObj() {
|
||||||
|
return { width: `${(1 / (this.tabDatas?.length || 1)) * 100}%` }
|
||||||
|
}
|
||||||
|
|
||||||
tabChange(val: string) {
|
tabChange(val: string) {
|
||||||
if (val !== this.selectTab) {
|
if (val !== this.selectTab) {
|
||||||
this.$emit('tab-change', val)
|
this.$emit('tab-change', val)
|
||||||
@ -30,7 +49,6 @@ export default class extends Vue {
|
|||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tab-bar{
|
.tab-bar{
|
||||||
width: 1271px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -42,9 +60,6 @@ export default class extends Vue {
|
|||||||
color: #D3D3D3;
|
color: #D3D3D3;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 410px;
|
|
||||||
height: 64px;
|
|
||||||
line-height: 64px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
&.active {
|
&.active {
|
||||||
@ -52,6 +67,8 @@ export default class extends Vue {
|
|||||||
background-image: url('../../assets/202202/tokennomic/tab-active.png');
|
background-image: url('../../assets/202202/tokennomic/tab-active.png');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top;
|
background-position: top;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
border-radius: 32px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container" :style="cstyle">
|
<div class="container" :style="cstyle">
|
||||||
<desktop-header current-section="gameplay"></desktop-header>
|
<desktop-header current-section="gameplay"></desktop-header>
|
||||||
|
<video-section></video-section>
|
||||||
|
<tab-bar
|
||||||
|
:select-tab="activeTab"
|
||||||
|
:tab-datas="tabs"
|
||||||
|
@tab-change="tabChange"
|
||||||
|
></tab-bar>
|
||||||
|
<data-cell v-for="data in currentCell" :key="data.title" :data="data"></data-cell>
|
||||||
<desktop-footer></desktop-footer>
|
<desktop-footer></desktop-footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -9,17 +16,103 @@
|
|||||||
import { Component, Vue } from 'vue-property-decorator'
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
import DesktopHeader from '@/components/index/DesktopHeader.vue'
|
import DesktopHeader from '@/components/index/DesktopHeader.vue'
|
||||||
import DesktopFooter from '@/components/index/DesktopFooter.vue'
|
import DesktopFooter from '@/components/index/DesktopFooter.vue'
|
||||||
|
import VideoSection from '@/components/gameplay/VideoSection.vue'
|
||||||
|
import TabBar, { ITabData } from '@/components/tokennomic/TabBar.vue'
|
||||||
|
import DataCell from '@/components/gameplay/DataCell.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'Gameplay',
|
name: 'Gameplay',
|
||||||
components: {
|
components: {
|
||||||
|
DataCell,
|
||||||
|
VideoSection,
|
||||||
DesktopFooter,
|
DesktopFooter,
|
||||||
DesktopHeader
|
DesktopHeader,
|
||||||
|
TabBar
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
private scale = 1.0
|
private scale = 1.0
|
||||||
private initWidth = 1920
|
private initWidth = 1920
|
||||||
|
private activeTab = ''
|
||||||
|
|
||||||
|
private tabs: ITabData[] = [
|
||||||
|
{
|
||||||
|
id: 'pvp',
|
||||||
|
name: 'PvP'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'pve',
|
||||||
|
name: 'PvE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'upgrade',
|
||||||
|
name: 'Upgrade'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'social',
|
||||||
|
name: 'Social'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
private cells: any[] = [
|
||||||
|
{
|
||||||
|
title: 'BATTLE ROYALE',
|
||||||
|
type: 0,
|
||||||
|
icon: require('@/assets/202202/gameplay/icon_pvp.png'),
|
||||||
|
mainImg: require('@/assets/202202/gameplay/img_pvp.png'),
|
||||||
|
desc: ['Quick play and Rank supported, ranked match has season ranking. ',
|
||||||
|
'Up to 40 players parachute onto an island and scavenge for weapons',
|
||||||
|
'and equipment to kill others while avoiding getting killed',
|
||||||
|
'themselves. The last player or team standing wins the round.']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Quest-AFK earning',
|
||||||
|
type: 1,
|
||||||
|
icon: require('@/assets/202202/gameplay/icon_pve.png'),
|
||||||
|
mainImg: require('@/assets/202202/gameplay/img_pve.png'),
|
||||||
|
desc: ['No operation needed, automatic battle',
|
||||||
|
'Players can go AFK after entering PVE, battle last a certain of time',
|
||||||
|
'Tokens will be rewarded for winning the battle while failure leads no rewards'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Upgrade NFT to increase reward',
|
||||||
|
type: 0,
|
||||||
|
icon: require('@/assets/202202/gameplay/icon-upgrade.png'),
|
||||||
|
mainImg: require('@/assets/202202/gameplay/img_upgrade.png'),
|
||||||
|
desc: ['·Higher level NFT leads to higher level matches that have higher rewards',
|
||||||
|
'·Higher level heros and weapons lead to higher win rate',
|
||||||
|
'·Higher level heros have higher daily maximum token cap'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: 'Play with your friends',
|
||||||
|
type: 1,
|
||||||
|
icon: require('@/assets/202202/gameplay/icon_social.png'),
|
||||||
|
mainImg: require('@/assets/202202/gameplay/img_social.png'),
|
||||||
|
desc: ['Team up with friends in PvP.',
|
||||||
|
'Support real-time voice in battle, friend follows, chat room, private',
|
||||||
|
'message, live streaming and other funcions'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
get currentCell() {
|
||||||
|
if (this.activeTab) {
|
||||||
|
const idx = this.tabs.findIndex(o => o.id === this.activeTab)
|
||||||
|
console.log(idx)
|
||||||
|
return [this.cells[idx]]
|
||||||
|
} else {
|
||||||
|
return this.cells
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tabChange(val:string) {
|
||||||
|
console.log('tag change: ', val)
|
||||||
|
this.activeTab = val
|
||||||
|
}
|
||||||
|
|
||||||
get cstyle() {
|
get cstyle() {
|
||||||
return {
|
return {
|
||||||
// transform: `scale(${this.scale})`
|
// transform: `scale(${this.scale})`
|
||||||
@ -56,4 +149,9 @@ export default class extends Vue {
|
|||||||
background-color: #171717;
|
background-color: #171717;
|
||||||
transform-origin: top;
|
transform-origin: top;
|
||||||
}
|
}
|
||||||
|
.tab-bar{
|
||||||
|
width: 960px;
|
||||||
|
height: 64px;
|
||||||
|
line-height: 64px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,7 +2,12 @@
|
|||||||
<div class="container" :style="cstyle">
|
<div class="container" :style="cstyle">
|
||||||
<desktop-header current-section="tokennomic"></desktop-header>
|
<desktop-header current-section="tokennomic"></desktop-header>
|
||||||
<img class="top-bg" src="@/assets/202202/tokennomic/tokennomic_bg.png" alt="top bg"/>
|
<img class="top-bg" src="@/assets/202202/tokennomic/tokennomic_bg.png" alt="top bg"/>
|
||||||
<tab-bar :select-tab="activeTab" @tab-change="tabChange"></tab-bar>
|
<tab-bar
|
||||||
|
:select-tab="activeTab"
|
||||||
|
:tab-datas="tabs"
|
||||||
|
style="width: 1280px"
|
||||||
|
@tab-change="tabChange"
|
||||||
|
></tab-bar>
|
||||||
<tab-cec v-show="activeTab==='cec'"></tab-cec>
|
<tab-cec v-show="activeTab==='cec'"></tab-cec>
|
||||||
<tab-ceg v-show="activeTab==='ceg'"></tab-ceg>
|
<tab-ceg v-show="activeTab==='ceg'"></tab-ceg>
|
||||||
<tab-allocation v-show="activeTab==='allocation'" ></tab-allocation>
|
<tab-allocation v-show="activeTab==='allocation'" ></tab-allocation>
|
||||||
@ -16,7 +21,7 @@ import DesktopHeader from '@/components/index/DesktopHeader.vue'
|
|||||||
import DesktopFooter from '@/components/index/DesktopFooter.vue'
|
import DesktopFooter from '@/components/index/DesktopFooter.vue'
|
||||||
import TabCec from '@/components/tokennomic/TabCec.vue'
|
import TabCec from '@/components/tokennomic/TabCec.vue'
|
||||||
import TabCeg from '@/components/tokennomic/TabCeg.vue'
|
import TabCeg from '@/components/tokennomic/TabCeg.vue'
|
||||||
import TabBar from '@/components/tokennomic/TabBar.vue'
|
import TabBar, { ITabData } from '@/components/tokennomic/TabBar.vue'
|
||||||
import TabAllocation from '@/components/tokennomic/TabAllocation.vue'
|
import TabAllocation from '@/components/tokennomic/TabAllocation.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -36,6 +41,21 @@ export default class extends Vue {
|
|||||||
|
|
||||||
private activeTab = 'cec'
|
private activeTab = 'cec'
|
||||||
|
|
||||||
|
private tabs: ITabData[] = [
|
||||||
|
{
|
||||||
|
id: 'cec',
|
||||||
|
name: 'CEC'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ceg',
|
||||||
|
name: 'CEG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'allocation',
|
||||||
|
name: 'Release & Allocation'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
get cstyle() {
|
get cstyle() {
|
||||||
return {
|
return {
|
||||||
// transform: `scale(${this.scale})`
|
// transform: `scale(${this.scale})`
|
||||||
@ -81,5 +101,10 @@ export default class extends Vue {
|
|||||||
margin-bottom: 100px;
|
margin-bottom: 100px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.tab-bar{
|
||||||
|
width: 1280px;
|
||||||
|
height: 64px;
|
||||||
|
line-height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|