赞
踩
这一块没什么好说的,就是给游戏提供入口,由于想照顾兼容更多情况引入了vue-router。
我用到了SCSS主要是为了让css写起来简洁一点,为了好看点,个人习惯用到了苹方字体,可以不必在意。
<template> <div id="app"> <router-view /> </div> </template> <style lang="scss"> @import "./assets/font/font.css"; body { margin: 0; font-family: "PingFang-RE", "Montserrat-RE", "Microsoft YaHei"; button, input { font-family: "PingFang-RE"; } } #app { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } </style>
这一块没什么好说的,主要是把组件引入进来应用到App里面的router-view
import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from '../views/Home.vue'; Vue.use(VueRouter); const routes = [ { path: '/', name: 'Home', component: Home, }, ]; const router = new VueRouter({ routes, }); export default router;
这里我用一个v-for循环把16个格子展现出来
background就是用的Grid布局,分成四行四列
<template> <div class="background"> <div v-for="i of 16" :key="i" class="grid-cell"></div> </div> </template> <script> export default { }; </script> <style lang="scss" scoped> .background { width: 365px; height: 365px; padding: 20px; background-color: #bbada0; border-radius: 10px; display: grid; grid-row-gap: 15px; grid-column-gap: 15px; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(4, 80px); .grid-cell { width: 80px; height: 80px; border-radius: 5px; background-color: #ccc0b3; } } </style>
这里也相当简单,我用一个header标签包裹
<header>
<h1>2048</h1>
<button @click="init" class="init-button">New Game</button>
<p>
Score: <span>{
{ score }}</span>
</p>
</header>
header { h1 { margin: 0; font-size: 32px; } p { margin: 0; margin-top: 10px; font-size: 16px; span { font-weight: bold; } } } .init-button { width: 110px; padding: 10px; background-color: #8f7a66; color: #fff; border: none; border-radius: 8px; cursor: pointer; outline: none; font-size: 16px; font-weight: bold; &:hover { background-color: #9f8a77; } }
用一个container包裹
mask是游戏通关或失败的遮罩
Background是背景以组件形式引入了的标签
number-cells是游戏的数字格子,transition-group是为了给这些格子加过渡动画,数字格我以数组形式存起来然后v-for逐个展示出来
<div class="container"> <div class="mask" v-if="success"> <h1>You win!</h1> <button @click="init" class="init-button">Try again</button> </div> <div class="mask" v-if="gameover"> <h1>Game over!</h1> <button @click="init" class="init-button">Try again</button> </div> <Background /> <div class="number-cells"> <transition-group name="appear"> <div class="number-cell" v-for="cell of numberCells" :id="`c${cell.id}`" :key="cell.id" :style=" ` width: 80px; height: 80px; border-radius: 5px; font-size: 32px; font-weight: bold; line-height: 80px; color: #776e65; position: absolute; z-index: ${ cell.num}; backgroundColor: ${ cell.color}; top: ${ getTop(cell)}; left: ${ getLeft(cell)}; ` " > { { cell.num }} </div> </transition-group> </div> </div>
container包裹了background,然后整个容器用margin来做水平居中
mask以container为基准做绝对定位,用top…等定位来拉伸展开
number-cell(数字格子)也是以container为基准做绝对定位,top和left的数值通过格子的数据结构计算出。
因为合并时可能会存在大数值的格子需要覆盖小数值的格子,所以以数值来作为z-index
然后就是用到了vue的transition以及CSS3的transition,前者是用来在DOM生成时的一个从无到有的动画,后者是数字格的滑动
.container { width: 405px; height: 405px; margin: 20px auto; position: relative; .mask { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 9999; background: rgba(238, 228, 218, 0.5); text-align: center; h1 { font-size: 60px; font-weight: 700; height: 60px; line-height: 60px; margin-top: 120px; color: #776e65; } button { margin-top: 30px; } } .number-cells { .number-cell { transition: $transitionTime top, $transitionTime left; // animation-fill-mode: backwards; // animation: appear 200ms ease-in-out; } } } .appear-enter-active { animation: appear 100ms ease-in-out; } .appear-leave-active { transition: $transitionTime top, $transitionTime left; } @keyframes appear { 0% { opacity: 0; transform: scale(0); } 50% { opacity: 0; transform: scale(0.5); } 100% { opacity: 1; transform: scale(1); } }
getTop(cell) {
return `${
20 + cell.y * 95}px`;
},
getLeft(cell) {
return `${
20 + cell.x * 95}px`;
},
score记录游戏分数
numberCells是一个存放数字格的数组,在上面提到数字格是由这个数组生成的
color就是为了后续获得数字格对应的背景色而定义的
auxId是一个用来辅助唯一标记数字格的id的,后续会介绍
success是标记游戏是否通关
gameover标记游戏是否结束
canMove后面介绍,是一个辅助判断的变量
data() { return { score: 0, numberCells: [], color: { 2: '#eee4da', 4: '#ede0c8', 8: '#f2b179', 16: '#f59563', 32: '#f67c5f', 64: '#f65e3b', 128: '#edcf72', 256: '#edcc61', 512
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。