• 翻牌闯关游戏


    翻牌闯关游戏


    3关:关卡由少至多12格、20格、30格
    图案:12个
    玩法:点击两张卡牌,图案一到即可消除掉

    记忆时长(秒):memoryDurationTime:5
    可配置:默认5

    提示游戏玩法:showTipsFlag:1
    可配置:1:判断localStorage值,仅一次提示游戏玩法 2:每次游戏第一关(12格关卡)都提示游戏玩法

    在什么时候提示游戏玩法:showTipsFuncName:'goInGame'
    可配置:1:setTimeRun:牌面已经全部翻转反面未开始计时 2:goInGame:牌面未全部翻转反面时

    提示游戏玩法 时长(毫秒):showTipsTime:4100
    可配置:默认4100,注:设置的引导手势动画2s

    是否需要计时:ifNeedTime:2
    可配置:0:不需要计时; 1:正计时; 2:倒计时

    倒计时开始时间(秒):baseTime:[20,60,90]
    可配置:第N关卡(baseTime下标对应值)对应的秒数

    闯关失败重新闯关是否从第一关开始:ifFailResetLevelStartNum:true
    可配置:默认true

    开始游戏(根据闯关情况自动设置对应关卡):
    this.gameRun()

    当前关卡闯关游戏结束:
    this.gameOver()

    游戏组件页代码:

    1. <template>
    2. <div v-show="showGame" class="page game">
    3. <div class="game_body">
    4. <div v-if="memoryShow" class="game_time">
    5. <span>记忆倒计时:</span>
    6. <span>{{memoryTime}}s</span>
    7. </div>
    8. <div v-else class="game_time">
    9. <span>倒计时:</span>
    10. <span>{{curTime}}s</span>
    11. </div>
    12. <div v-if="isStartGame" class="game_box">
    13. <ul class="game_list" :class="{'first_level':levelStartNum == 0,'second_level':levelStartNum == 1,'third_level':levelStartNum == 2}">
    14. <li @click="chooseBrand(index)" v-for="item,index in currLevelData" :key="index">
    15. <img :class="clearBrandArr.indexOf(index) == -1 && inGame && (currBrandIndex1 !== index && currBrandIndex2 !== index) ? 'show' : 'hide'" src="@/assets/img/game_3.png" />
    16. <img :class="!inGame || (currBrandIndex1 === index || currBrandIndex2 === index) ? 'show' : 'hide'" :src="item" />
    17. </li>
    18. </ul>
    19. </div>
    20. </div>
    21. <!-- 提示游戏玩法 -->
    22. <div v-show="showTips" class="game_tips">
    23. <div class="game_tips_body">
    24. <img src="@/assets/img/game_5.png" />
    25. </div>
    26. </div>
    27. </div>
    28. </template>
    29. <script>
    30. export default {
    31. data(){
    32. return{
    33. // 翻牌对应的图片(12张)
    34. gameBrandList:[
    35. require('@/assets/img/game/1.png'),
    36. require('@/assets/img/game/2.png'),
    37. require('@/assets/img/game/3.png'),
    38. require('@/assets/img/game/4.png'),
    39. require('@/assets/img/game/5.png'),
    40. require('@/assets/img/game/6.png'),
    41. require('@/assets/img/game/7.png'),
    42. require('@/assets/img/game/8.png'),
    43. require('@/assets/img/game/9.png'),
    44. require('@/assets/img/game/10.png'),
    45. require('@/assets/img/game/11.png'),
    46. require('@/assets/img/game/12.png'),
    47. ],
    48. LevelNum:[12,20,30], // 第N关卡对应的格子数
    49. levelStartNum:0, // 第N关卡 从0开始
    50. currLevelData:[], //当前关卡 翻牌对应的图片
    51. showGame:false,
    52. inGame:false, //进入游戏页面后,是否用户可点击参与了
    53. isStartGame:false,
    54. currBrandIndex1:'', //每两次点击第1次选择的格子index
    55. currBrandIndex2:'', //每两次点击第2次选择的格子index
    56. clearBrandArr:[], //已清除的格子
    57. memoryDurationTime:5, //记忆时长(秒)
    58. memoryShow:false, //展示记忆时长倒计时
    59. memoryTime:0, //记忆时长倒计时
    60. showTips:false, //是否提示游戏玩法
    61. showTipsEnd:false, //是否提示游戏玩法 展示结束
    62. showTipsFlag:1, //1:判断localStorage值,仅一次提示游戏玩法 2:每次游戏第一关都提示游戏玩法
    63. // showTipsFuncName:'setTimeRun', //在什么时候提示游戏玩法 setTimeRun:牌面已经全部翻转反面未开始计时 goInGame:牌面未全部翻转反面时
    64. showTipsFuncName:'goInGame', //在什么时候提示游戏玩法 setTimeRun:牌面已经全部翻转反面未开始计时 goInGame:牌面未全部翻转反面时
    65. showTipsTime:4100, //提示游戏玩法 时长(毫秒)
    66. ifNeedTime:2, //0:不需要计时; 1:正计时; 2:倒计时
    67. baseTime:[20,60,90], //倒计时开始时间,秒 第N关卡(baseTime下标对应值)对应的秒数
    68. timer:null, //定时器
    69. curTime:'-', //当前 用时 或 倒计时
    70. timing:0,
    71. rafId:'',
    72. isClearAll:false, //清除完毕当前关卡闯关游戏结束 用于结束计时
    73. gameEnd:false, //倒计时结束,当前关卡闯关游戏结束
    74. ifFailResetLevelStartNum:true, //闯关失败重新闯关是否从第一关开始
    75. }
    76. },
    77. mounted() {
    78. // this.gameRun();
    79. this.$emit('flipBrandMounted');
    80. },
    81. watch:{
    82. showTipsEnd:function(newV,oldV){
    83. if(newV){
    84. if(this.showTipsFuncName == 'setTimeRun'){
    85. this.setTimeRun();
    86. }
    87. if(this.showTipsFuncName == 'goInGame'){
    88. this.goInGame();
    89. }
    90. }
    91. }
    92. },
    93. methods:{
    94. // 倒计时
    95. showTime(){
    96. this.curTime--;
    97. // 计时结束
    98. if(this.curTime == 0){
    99. clearInterval(this.timer);
    100. if(!this.isClearAll){
    101. this.gameEnd = true;
    102. this.gameOver();
    103. }
    104. }
    105. // 清除完毕当前关卡闯关游戏结束
    106. if(this.isClearAll == true){
    107. clearInterval(this.timer);
    108. }
    109. },
    110. // 计时
    111. changeTime(k){
    112. // console.log(k);
    113. if(!this.timing && k){
    114. this.timing = k
    115. }
    116. this.rafId = requestAnimationFrame(this.changeTime);
    117. this.curTime = ((k - this.timing) / 1000).toFixed(2);
    118. // console.log(this.curTime);
    119. this.$nextTick(()=>{
    120. // 清除完毕当前关卡闯关游戏结束
    121. if(this.isClearAll == true){
    122. cancelAnimationFrame(this.rafId);
    123. }
    124. })
    125. },
    126. // 开始计时
    127. setTimeRun(){
    128. this.showTipsDo('setTimeRun',(flag)=>{
    129. if(flag){
    130. if(this.ifNeedTime == 1){
    131. this.timing = 0;
    132. this.changeTime();
    133. }
    134. if(this.ifNeedTime == 2){
    135. this.curTime = this.baseTime[this.levelStartNum];
    136. this.timer ? clearInterval(this.timer) : '';
    137. this.timer = setInterval(this.showTime,1000);
    138. }
    139. }
    140. })
    141. },
    142. // 提示游戏玩法 逻辑处理
    143. showTipsDo(funcName,callback){
    144. // console.log(funcName , this.showTipsFuncName)
    145. // 初始化时间
    146. if(this.ifNeedTime == 1){
    147. this.curTime = 0;
    148. }
    149. if(this.ifNeedTime == 2){
    150. this.curTime = this.baseTime[this.levelStartNum];
    151. }
    152. if(funcName != this.showTipsFuncName){
    153. callback && callback(true);
    154. return;
    155. }
    156. // 游戏开始前 提示游戏玩法
    157. if((this.showTipsFlag == 1 && !localStorage.getItem('isShowTips')) || (this.showTipsFlag == 2 && this.levelStartNum == 0 && !this.showTipsEnd)){
    158. this.showTips = true;
    159. // 一轮手势引导动画2s
    160. setTimeout(()=>{
    161. this.showTips = false;
    162. this.showTipsEnd = true;
    163. if(this.showTipsFlag == 1) localStorage.setItem('isShowTips',1)
    164. },this.showTipsTime)
    165. callback && callback(false);
    166. }else{
    167. callback && callback(true);
    168. }
    169. },
    170. // 开始游戏
    171. gameRun(){
    172. // 闯关结束后再继续下一关
    173. if(this.gameEnd || this.isClearAll){
    174. if(this.isClearAll){
    175. // 闯关成功
    176. if(this.levelStartNum < this.LevelNum.length - 1){
    177. this.levelStartNum++;
    178. }else{
    179. // 全部关卡闯关成功,重新第1关再开始
    180. this.levelStartNum = 0;
    181. }
    182. }else{
    183. // 闯关失败
    184. if(this.ifFailResetLevelStartNum){
    185. this.levelStartNum = 0;
    186. }
    187. }
    188. }
    189. this.gameEnd = false;
    190. this.isClearAll = false;
    191. this.$nextTick(()=>{
    192. this.gameStart();
    193. })
    194. },
    195. // 当前关卡闯关游戏结束
    196. gameOver(){
    197. this.$emit('gameOver',this.isClearAll,this.gameEnd,this.levelStartNum);
    198. },
    199. // 初始化游戏 当前关卡 翻牌对应的图片
    200. gameStart(){
    201. this.isStartGame = false;
    202. this.inGame = false;
    203. this.currBrandIndex1 = '';
    204. this.currBrandIndex2 = '';
    205. this.clearBrandArr = [];
    206. this.currLevelData = [];
    207. let currBrandList = [].concat(this.gameBrandList).sort(function(a, b){
    208. return 0.5 - Math.random();
    209. });
    210. let currLevelLen = this.LevelNum[this.levelStartNum];
    211. let currLevelData = [];
    212. for(let i = 0; i < currLevelLen / 2; i++){
    213. if(i > this.gameBrandList.length - 1){
    214. // 12个牌子不够双倍匹配
    215. let randomKey = Math.floor(Math.random() * this.gameBrandList.length);
    216. currLevelData[i] = currBrandList[randomKey];
    217. currLevelData[currLevelLen - 1 - i] = currBrandList[randomKey];
    218. }else{
    219. currLevelData[i] = currBrandList[i];
    220. currLevelData[currLevelLen - 1 - i] = currBrandList[i];
    221. }
    222. }
    223. this.currLevelData = currLevelData.sort(function(a, b){
    224. return 0.5 - Math.random();
    225. });
    226. this.$nextTick(()=>{
    227. this.showGame = true;
    228. this.isStartGame = true;
    229. this.goInGame();
    230. })
    231. },
    232. // 用户可以去点击清除操作了
    233. goInGame(){
    234. this.showTipsDo('goInGame',(flag)=>{
    235. if(flag){
    236. this.memoryTime = this.memoryDurationTime;
    237. this.memoryDoing();
    238. }
    239. })
    240. },
    241. // 记忆时长倒计时
    242. memoryDoing(){
    243. if(this.memoryTime < 0){
    244. this.memoryShow = false;
    245. this.inGame = true;
    246. this.setTimeRun();
    247. return;
    248. }
    249. this.memoryShow = true;
    250. clearTimeout(this.timer);
    251. this.timer = setTimeout(()=>{
    252. this.memoryTime--
    253. this.memoryDoing();
    254. },1000)
    255. },
    256. // 点击格子
    257. chooseBrand(index){
    258. // 倒计时结束不可点击
    259. if(this.gameEnd){
    260. console.log('倒计时结束不可点击');
    261. return;
    262. }
    263. if(!this.inGame || this.currBrandIndex1 === index || (this.currBrandIndex1 && this.currBrandIndex2) || this.clearBrandArr.indexOf(index) !== -1){
    264. return;
    265. }
    266. if(this.currBrandIndex1 !== ''){
    267. this.currBrandIndex2 = index;
    268. if(this.currLevelData[index] == this.currLevelData[this.currBrandIndex1] && index != this.currBrandIndex1){
    269. // 两点击一样
    270. this.clearBrand(this.currBrandIndex1,index);
    271. }else{
    272. // 两点击不一样
    273. setTimeout(()=>{
    274. this.currBrandIndex1 = '';
    275. this.currBrandIndex2 = '';
    276. },300)
    277. }
    278. }else{
    279. this.currBrandIndex1 = index;
    280. }
    281. },
    282. // 两次点击相同清除格子
    283. clearBrand(index,index2){
    284. setTimeout(()=>{
    285. if(this.clearBrandArr.indexOf(index) !== -1 && this.clearBrandArr.indexOf(index2) !== -1){
    286. // 快速点击情况不记录
    287. }else{
    288. this.currBrandIndex1 = '';
    289. this.currBrandIndex2 = '';
    290. this.clearBrandArr.push(index,index2);
    291. this.$nextTick(()=>{
    292. if(this.clearBrandArr.length == this.LevelNum[this.levelStartNum]){
    293. // 清除完毕
    294. // this.gameRun();
    295. if(!this.gameEnd){
    296. this.isClearAll = true;
    297. this.gameOver();
    298. }
    299. }
    300. })
    301. }
    302. },300)
    303. },
    304. }
    305. }
    306. </script>
    307. <style scoped>
    308. .page{ width:100%; height:100%; position:absolute; left:0; top:0; overflow: hidden;}
    309. /* 游戏页 */
    310. .page.game{ background-color: #fff;}
    311. .game_body{ height: 1104px; padding-top: 60px; background: url(../assets/img/game_1.png) no-repeat center top; background-size: 100%; position: relative;}
    312. .game_body::after{ content: ""; width: 100%; min-height: calc(100vh - 1104px); height: 396px; background: url(../assets/img/game_2.png); background-size: 100% 100%; position: absolute; left: 0; top: 1102px;}
    313. .game_time{ height: 62px; line-height: 53px; color: #FFFDF4; font-size: 36px; font-weight: bold;
    314. display: flex; justify-content: center; align-items: center;
    315. text-shadow: 2px 2px 0 #895F41 , 2px 2px 0 #895F41 , -2px -2px 0 #895F41 , -2px -2px 0 #895F41 , 2px -2px 0 #895F41 , 2px -2px 0 #895F41 , -2px 2px 0 #895F41 , -2px 2px 0 #895F41;
    316. }
    317. .game_box{ height: 940px; margin-top: 42px;}
    318. .game_list{
    319. display: flex; flex-direction: row; flex-wrap: wrap; justify-content: flex-start; align-items: flex-start;
    320. }
    321. .game_list li img{ width: 100%; height: 100%; position: absolute; left: 0; top: 0;
    322. transition: all .2s linear;
    323. }
    324. .game_list li img.show{
    325. transform: scaleX(1);
    326. }
    327. .game_list li img.hide{ display: block !important;
    328. transform: scaleX(0);
    329. }
    330. /* 12*/
    331. .game_list.first_level{ padding: 0 98px;}
    332. .game_list.first_level li{ width: 168px; height: 222px; position: relative;
    333. animation: fadeToDown .5s linear both;
    334. }
    335. .game_list.first_level li:nth-child(3n + 2){ margin: 0 calc((100% - 168px * 3) / 2);}
    336. .game_list.first_level li:nth-child(3) ~ li{ margin-top: 15px;}
    337. /* 20*/
    338. .game_list.second_level{ padding: 0 82px;}
    339. .game_list.second_level li{ width: 131px; height: 173px; position: relative;
    340. animation: fadeToDown .5s linear both;
    341. }
    342. .game_list.second_level li{ margin-left: calc((100% - 131px * 4) / 3);}
    343. .game_list.second_level li:nth-child(4n + 1){ margin-left: 0;}
    344. .game_list.second_level li:nth-child(4) ~ li{ margin-top: 10px;}
    345. /* 30*/
    346. .game_list.third_level{ padding: 0 71px;}
    347. .game_list.third_level li{ width: 108px; height: 143px; position: relative;
    348. animation: fadeToDown .5s linear both;
    349. }
    350. .game_list.third_level li{ margin-left: calc((100% - 108px * 5) / 4);}
    351. .game_list.third_level li:nth-child(5n + 1){ margin-left: 0;}
    352. .game_list.third_level li:nth-child(5) ~ li{ margin-top: 8px;}
    353. /* 提示游戏玩法 */
    354. .game_tips{ width: 100%; height: 100%; padding-top: 438px; background-color: rgba(0,0,0,.6); position: absolute; left: 0; top: 0;}
    355. .game_tips_body{ width: 479px; height: 365px; margin: 0 auto; background: url(../assets/img/game_4.png); background-size: 100% 100%; position: relative;}
    356. .game_tips_body img{ width: 128px; position: absolute; left: 117px; top: 96px;
    357. transform-origin: 35px 32px;
    358. animation: gameTips 2s linear both infinite;
    359. }
    360. @keyframes gameTips{
    361. 0%{ transform: translate(0,0) scale(1.15);}
    362. 15%,30%{ transform: translate(0,0) scale(1);}
    363. 45%{ transform: translate(166px,0) scale(1.15);}
    364. 60%,100%{ transform: translate(166px,0) scale(1);}
    365. }
    366. </style>

    父组件中引用:


    HTML:

    <flipBrand ref="gameTemp" @flipBrandMounted="flipBrandLoaded" @gameOver="gameOverEnd"></flipBrand>

    JS:

    1. methods:{
    2. // 游戏组件加载完毕
    3. flipBrandLoaded(){
    4. // 开始闯关
    5. // this.$refs.gameTemp.gameRun();
    6. },
    7. // 当前关卡闯关游戏结束
    8. gameOverEnd(isClearAll,gameEnd,levelStartNum){
    9. // isClearAll:'', //清除完毕游戏结束 正计时时用于结束计时
    10. // gameEnd:'', //倒计时结束,游戏结束
    11. // levelStartNum 当前关卡数
    12. this.levelStartNum = levelStartNum;
    13. this.$nextTick(()=>{
    14. this.gameOver(isClearAll);
    15. })
    16. },
    17. // 开始游戏
    18. gameStartDo(){
    19. this.$refs.gameTemp.gameRun();
    20. },
    21. // 游戏结束接口
    22. gameOver(isClearAll){
    23. if(isClearAll){
    24. // 闯关成功
    25. }
    26. },
    27. }

    图片资源:

     game_1.png

    game_2.png

     

    game_3.png

    game_4.png

    game_5.png

     

    game/1.png 至 game/12.png

  • 相关阅读:
    机器学习之 Jupyter Notebook 使用
    967亿销售额!博世解码智能汽车新蓝图
    @requestBody与@RequestParam
    【计算机毕业设计】22.学校试卷生成系统+vue
    AI人机对话-无能版
    怎么压缩图片?图片压缩技巧快学来
    浅谈压力测试的作用是什么
    化工DCS/SIS/MIS系统时钟同步(NTP服务器)建设
    ubuntu18.04配置Java环境与安装RCS库
    【leetcode周赛总结】LeetCode第 81 场双周赛(6.25)
  • 原文地址:https://blog.csdn.net/qq_16494241/article/details/132927257