返回

萌趣来袭!用Vue 3打造思否猫连连看

前端

在这个信息爆炸的时代,工作和学习之余,玩一款休闲益智小游戏,不仅能放松身心,还能锻炼脑力。作为一名资深程序员,我最近迷上了思否猫,它那可爱的外表和丰富的表情包总能给我带来欢乐。于是,我突发奇想,何不把思否猫搬到代码世界,制作一款连连看小游戏呢?

怀揣着这个想法,我深入研究了Vue 3和Pinia,这两个工具在前端开发中可谓如虎添翼。Vue 3提供了强大的响应式系统和组件化开发理念,而Pinia则是一个轻量级的状态管理工具,可以轻松管理游戏中的数据。

此外,为了让游戏界面更加美观,我采用了Sass作为CSS预处理器,它可以带来更简洁、更可维护的样式代码。为了营造出冬日氛围,我还借助canvas实现了下雪效果,让思否猫的世界变得更加生动。

在这篇文章中,我将手把手地带你领略这款游戏的制作过程,从构思到实现,从基础原理到进阶技巧,希望能给各位读者带来一些启发和乐趣。

1. 搭建Vue 3项目

首先,我们使用Vue CLI创建一个新的Vue 3项目:

vue create my-vue3-game

2. 安装Pinia和Sass

接下来,安装Pinia和Sass:

npm install pinia sass --save

在main.js中引入Pinia:

import { createPinia } from 'pinia'
const pinia = createPinia()

在App.vue中引入Sass:

<style lang="scss">
@import '@/assets/styles/main.scss';
</style>

3. 编写游戏逻辑

我们将使用Pinia来管理游戏状态,包括思否猫的排列、选中的思否猫以及游戏结束状态。

在stores/game.js中定义游戏状态:

import { defineStore } from 'pinia'

export const useGameStore = defineStore('game', {
  state: () => ({
    cats: [], // 思否猫数组
    selectedCats: [], // 选中的思否猫
    gameOver: false, // 游戏结束状态
  }),
  getters: {
    canRemove: (state) => state.selectedCats.length === 2,
  },
  actions: {
    // 游戏初始化
    init() {
      // 生成思否猫数组
      this.cats = [...Array(16).keys()].map((i) => ({
        id: i,
        image: `./assets/cats/${i}.png`,
        selected: false,
      }))
      // 洗牌
      this.cats.sort(() => Math.random() - 0.5)
    },
    // 点击思否猫
    selectCat(id) {
      const cat = this.cats.find((cat) => cat.id === id)
      if (!cat.selected) {
        cat.selected = true
        this.selectedCats.push(cat)
        if (this.canRemove) {
          this.removeCats()
        }
      }
    },
    // 移除选中的思否猫
    removeCats() {
      if (this.selectedCats[0].image === this.selectedCats[1].image) {
        this.cats = this.cats.filter((cat) => !this.selectedCats.includes(cat))
        this.selectedCats = []
        if (this.cats.length === 0) {
          this.gameOver = true
        }
      } else {
        this.selectedCats.forEach((cat) => (cat.selected = false))
        this.selectedCats = []
      }
    },
  },
})

4. 创建游戏界面

在App.vue中创建游戏界面:

<template>
  <div class="container">
    <div class="board">
      <div class="cat-item" v-for="cat in gameStore.cats" :key="cat.id" @click="gameStore.selectCat(cat.id)">
        <img :src="cat.image" :class="{ selected: cat.selected }">
      </div>
    </div>
    <div class="info">
      <p v-if="gameStore.gameOver">游戏结束!</p>
    </div>
  </div>
</template>

<script setup>
import { useGameStore } from '@/stores/game'

const gameStore = useGameStore()
</script>

5. 实现下雪效果

在main.js中引入canvas效果:

import '@/assets/js/snow.js'

在assets/js/snow.js中实现下雪效果:

function snow() {
  // 获取画布元素
  const canvas = document.getElementById('snow')
  const ctx = canvas.getContext('2d')

  // 设置画布大小
  canvas.width = window.innerWidth
  canvas.height = window.innerHeight

  // 雪花数组
  const snowflakes = []

  // 创建雪花
  function createSnowflake() {
    const snowflake = {
      x: Math.random() * canvas.width, // x坐标
      y: Math.random() * canvas.height, // y坐标
      size: Math.random() * 5 + 1, // 大小
      speed: Math.random() * 2 + 1, // 速度
      opacity: Math.random(), // 透明度
    }
    snowflakes.push(snowflake)
  }

  // 绘制雪花
  function drawSnowflake(snowflake) {
    ctx.beginPath()
    ctx.arc(snowflake.x, snowflake.y, snowflake.size, 0, Math.PI * 2)
    ctx.fillStyle = `rgba(255, 255, 255, ${snowflake.opacity})`
    ctx.fill()
  }

  // 更新雪花位置
  function updateSnowflakes() {
    snowflakes.forEach((snowflake) => {
      snowflake.y += snowflake.speed
      if (snowflake.y > canvas.height) {
        snowflake.y = 0
      }
    })
  }

  // 渲染
  function render() {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    snowflakes.forEach((snowflake) => drawSnowflake(snowflake))
    updateSnowflakes()
    requestAnimationFrame(render)
  }

  createSnowflake()
  render()
}

snow()

6. 总结

通过这篇文章,我们一步步构建了一款趣味十足的思否猫连连看小游戏。我们使用了Vue 3、Pinia、Sass和canvas等技术,实现了游戏逻辑、界面渲染和下雪效果。

这款游戏不仅可以作为闲暇时的娱乐消遣,还可以作为学习Vue 3、Pinia、Sass和canvas的实践项目。希望通过这篇文章,能给大家带来一些启发和帮助,让大家在前端开发的道路上越走越远。