分享一些基于微信小程序开发的小游戏源码

  小游戏小程序是运行在微信生态系统(或其他支持小程序的平台)中的轻量级应用程序,专为休闲游戏体验而设计的小程序子类别,小游戏小程序通常体积较小,加载速度快,用户无需等待长时间即可开始游戏。用户无需下载或安装单独的游戏应用程序,即可通过小程序入口直接进入游戏,同时小游戏小程序通常包含排行榜、分享功能等社交元素,可以增强游戏体验并促进用户参与。

  源码及演示:casgams.top/gm

  一、羊了个羊

  1、项目结构设计

/minigame/
├── pages/               游戏主页
│   ├── index.js          逻辑层
│   ├── index.wxml         视图层
│   ├── index.wxss         样式层
│   └── index.json         页面配置
├── components/           通用组件
│   ├── block.js          方块组件
│   ├── button.js          操作按钮
│   ├── score-board.js     得分板
│   └── modal.js           弹窗提示
├── utils/                工具类
│   ├── collision.js      碰撞检测
│   ├── animation.js      动画控制
│   └── sound.js          音效管理
├── assets/               资源文件
│   ├── images/           游戏素材
│   │   ├── block.png      块状元素
│   │   └── bg.jpg         背景图
│   ├── audio/            音效文件
│   │   ├── click.mp3      点击音效
│   │   └──消除音效.mp3
│   └── ...
├── cloud/               云开发配置(可选)
│   └── functions/         云端函数
└── app.js               全局配置

  2、核心模块解析

  1.视图层(index.wxml)

<view class="game-container">
  <!-- 动态生成的方块区域 -->
  <block-list blocks="{{blocks}}" bind:tap="handleTap" />

  <!-- 操作按钮 -->
  <button-component 
    text="重试" 
    bind:click="restartGame"
  />
  
  <!-- 得分板 -->
  <score-board score="{{score}}" />

  <!-- 弹窗提示 -->
  <modal visible="{{showModal}}" 
         content="{{modalContent}}"
         bind:confirm="handleConfirm"
  />
</view>

  2.逻辑层(index.js)

Page({
  data: {
    blocks: [],            // 当前所有方块数组
    score: 0,             // 当前得分
    gridSize: 6,          // 游戏区域格子数(6x6)
    lastTapPosition: null, // 上一次点击位置
    isMatching: false      // 是否处于匹配状态
  },

  onLoad() {
    this.initGame();
  },

  initGame() {
    // 初始化游戏布局
    this.generateBlocks();
    wx.setStorageSync('highScore', this.data.score);
  },

  generateBlocks() {
    // 生成随机方块
    const blocks = [];
    for(let i=0; i<this.gridSize2; i++) {
      blocks.push({
        id: i,
        type: Math.random() < 0.5 ? 'normal' : 'special',
        x: Math.floor(Math.random()  this.gridSize),
        y: Math.floor(Math.random()  this.gridSize),
        status: 'idle'  // 状态:闲置/选中/消除
      });
    }
    this.setData({ blocks });
  },

  handleTap(e) {
    const { block } = e.detail;
    if(block.status !== 'idle') return;

    // 处理连续点击逻辑
    if(this.lastTapPosition) {
      this.checkMatch([this.lastTapPosition.block, block]);
    } else {
      this.selectBlock(block);
    }
    this.lastTapPosition = { block };
  },

  checkMatch(selectedBlocks) {
    // 匹配算法核心
    const [a, b] = selectedBlocks;
    if(a.type !== b.type) return false;

    // 计算曼哈顿距离是否在允许范围内
    const distance = Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
    return distance <= 2; // 允许最多间隔1个空格
  },

  // 消除动画逻辑
  animateElimination(effects) {
    effects.forEach(effect => {
      wx.createAnimation({
        duration: 300,
        timingFunction: 'ease-out',
        transform: `translate(${effect.dx}px, ${effect.dy}px) scale(0)`
      }).exec((anim) => {
        anim.step();
      });
    });
  },

  // 游戏结束检测
  checkGameOver() {
    if(this.data.score >= 10) {
      wx.showModal({
        title: '游戏胜利',
        content: '恭喜通关!得分:' + this.data.score,
        showCancel: false,
        confirmButtonText: '再来一局'
      });
      return true;
    }
    return false;
  }
});

  3.WXS响应式计算(collision.js)

module.exports = {
  methods: {
    // 精确碰撞检测(包含边界)
    isColliding(obj1, obj2) {
      return (
        obj1.x < obj2.x + obj2.width &&
        obj1.x + obj1.width > obj2.x &&
        obj1.y < obj2.y + obj2.height &&
        obj1.y + obj1.height > obj2.y
      );
    }
  }
};

  3、关键技术实现

  1.触摸滑动优化

// 处理复杂手势(长按/滑动)
Page({
  touchStart(e) {
    this.setData({ touchStart: e.touches[0] });
  },

  touchMove(e) {
    const deltaX = e.touches[0].pageX - this.data.touchStart.pageX;
    const deltaY = e.touches[0].pageY - this.data.touchStart.pageY;
    
    // 根据滑动方向调整方块位置
    if(Math.abs(deltaX) > Math.abs(deltaY)) {
      // 左右滑动
      this.handleHorizontalSwipe(deltaX);
    } else {
      // 上下滑动
      this.handleVerticalSwipe(deltaY);
    }
  }
});

  2.动态粒子效果

// 创建消除特效
createEffect(ctx, x, y) {
  const particles = [];
  for(let i=0; i<20; i++) {
    particles.push({
      x: x + Math.random()  20 - 10,
      y: y + Math.random()  20 - 10,
      size: Math.random()  3 + 1,
      speedX: (Math.random() - 0.5)  2,
      speedY: (Math.random() - 0.5)  2
    });
  }
  return particles;
}

  3.微信支付集成

// 调用微信支付接口
wx.requestPayment({
  timeStamp: '...', 
  nonceStr: '...',
  package: 'prepay_id=...',
  signType: 'MD5',
  success(res) {
    console.log('支付成功', res);
    wx.navigateTo({
      url: '/pages/result/index'
    });
  },
  fail(e) {
    wx.showToast({ title: '支付失败' });
  }
});

  4、性能优化建议

  1.Canvas替代方案:

   // 使用<canvas>标签提升渲染效率
   <canvas 
     canvas-id="gameCanvas" 
     style="width: 100%; height: 100vh;"
     bindtouchstart="handleTouchStart"
     bindtouchmove="handleTouchMove"
   />

   // 在JS中获取上下文
   Page({
     onReady() {
       this.ctx = wx.createCanvasContext('gameCanvas', this);
     }
   })
  

  2.虚拟列表技术:

  // 仅渲染可见区域的方块
   computedBlocks() {
     const visibleBlocks = [];
     this.data.blocks.forEach(block => {
       if(
         block.x >= this.visibleLeft &&
         block.x <= this.visibleRight &&
         block.y >= this.visibleTop &&
         block.y <= this.visibleBottom
       ) {
         visibleBlocks.push(block);
       }
     });
     return visibleBlocks;
   }

  3.离线缓存机制:

   // 本地存储高分记录
   wx.getStorage({
     key: 'highScore',
     success(e) {
       this.setData({ highScore: e.data || 0 });
     }
   });

  5、扩展功能实现

  1.道具系统:

   // 添加炸弹道具
   useBomb() {
     this.setData({ bombCount: this.data.bombCount - 1 });
     // 创建爆炸动画
     this.animateBomb();
   }

  2.社交分享:

   // 分享游戏成就
   wx.showShareMenu({
     withShareTicket: true
   });

   onShareAppMessage() {
     return {
       title: `我在《羊了个羊》获得了${this.data.score}分!`,
       imageUrl: '/assets/share.jpg'
     };
   }
  

  3.AI智能提示:

  // 简单匹配算法实现
   getHint() {
     // 查找最短距离的可匹配对
     let minDistance = Infinity;
     let bestPair = null;
     this.data.blocks.forEach(pair => {
       if(this.checkMatch(pair)) {
         const distance = Math.abs(pair[0].x - pair[1].x) + Math.abs(pair[0].y - pair[1].y);
         if(distance < minDistance) {
           minDistance = distance;
           bestPair = pair;
         }
       }
     });
     return bestPair;
   }
  

// app.js
App({
  onLaunch() {
    // 小程序启动时执行的初始化操作
    console.log('App Launch')
  },
  onShow() {
    // 小程序显示时执行的操作
    console.log('App Show')
  },
  onHide() {
    // 小程序隐藏时执行的操作
    console.log('App Hide')
  },
  globalData: {
    // 全局数据,可以在各个页面中共享
    userInfo: null,
    gameData: {
      // 游戏数据,可以根据需要扩展
      sheepCount: 0, // 羊的数量
      level: 1, // 游戏关卡
    },
  },
})
 
// game.js
Page({
  data: {
    // 页面数据
    tip: '点击屏幕开始玩', // 游戏提示信息
    sheepList: [], // 羊的列表
    isGameOver: false, // 游戏是否结束
  },
 
  onLoad() {
    // 页面加载时执行的操作
    this.initGame();
  },
 
  initGame() {
    // 初始化游戏数据
    this.setData({
      sheepList: [],
      isGameOver: false,
      tip: '点击屏幕开始玩',
    });
    // 随机生成羊的位置和数量(简化处理,仅生成几只羊作为示例)
    for (let i = 0; i < 3; i++) {
      const sheep = {
        id: i + 1,
        x: Math.floor(Math.random()  300) + 50,
        y: Math.floor(Math.random()  400) + 50,
      };
      this.data.sheepList.push(sheep);
    }
    // 更新页面数据
    this.setData({
      sheepList: this.data.sheepList,
    });
  },
 
  onTap(event) {
    // 处理点击事件
    const { x, y } = event.touches[0];
    const sheepList = this.data.sheepList;
    for (let i = 0; i < sheepList.length; i++) {
      const sheep = sheepList[i];
      const distance = Math.sqrt((sheep.x - x)  2 + (sheep.y - y)  2);
      // 判断点击位置是否在羊的范围内(简化处理,仅通过距离判断)
      if (distance < 30) {
        // 点击到羊,处理点击逻辑(例如:增加分数、移除羊等)
        wx.showToast({
          title: `抓到羊了!`,
          icon: 'success',
          duration: 2000,
        });
        // 移除抓到的羊
        sheepList.splice(i, 1);
        // 更新页面数据
        this.setData({
          sheepList: sheepList,
        });
        // 判断游戏是否结束(例如:羊全部被抓完)
        if (sheepList.length === 0) {
          this.setData({
            isGameOver: true,
            tip: '恭喜你,抓到所有羊了!',
          });
        }
        break;
      }
    }
  },
 
  restartGame() {
    // 重新开始游戏
    this.initGame();
  },
})
 
// game.wxml
<view class="container">
  <text class="tip">{{tip}}</text>
  <canvas canvas-id="myCanvas" style="width: 350px; height: 450px;"></canvas>
  <button wx:if="{{!isGameOver}}" bindtap="restartGame">重新开始</button>
</view>
 
// game.wxss
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}
 
.tip {
  margin-top: 20px;
  font-size: 20px;
  color: #333;
}
 
button {
  margin-top: 20px;
  padding: 10px 20px;
  background-color: #1aad19;
  color: #fff;
  border: none;
  border-radius: 5px;
}

  说明

  app.js:小程序的全局配置文件,用于初始化全局数据和生命周期函数。

  game.js:游戏页面的逻辑文件,包含页面数据、生命周期函数、事件处理函数等。

  onLoad:页面加载时初始化游戏数据。

  initGame:随机生成羊的位置和数量,并更新页面数据。

  onTap:处理点击事件,判断点击位置是否在羊的范围内,并处理相应的逻辑。

  restartGame:重新开始游戏的函数。

  game.wxml:游戏页面的结构文件,定义了页面的布局和组件。

  使用&lt;canvas&gt;组件绘制羊的图像(需要配合JavaScript代码在game.js中绘制)。

  使用&lt;text&gt;组件显示游戏提示信息。

  使用&lt;button&gt;组件提供重新开始游戏的按钮。

  game.wxss:游戏页面的样式文件,定义了页面的样式和布局。

  二、贪吃蛇(基础版)

  1.项目结构

/pages/snake/
├── index.js       逻辑层
├── index.wxml      视图层
├── index.wxss     样式层
└── snake.png      蛇身素材

  2.核心逻辑

Page({
  data: {
    snake: [],        // 蛇身坐标数组
    food: {},         // 食物坐标
    direction: 'right' // 移动方向
  },

  onLoad() {
    this.initGame();
  },

  initGame() {
    // 初始化蛇身和食物
    this.snake = [{x:10, y:10}];
    this.createFood();
    
    // 绑定键盘事件
    wx.onAccelerometerChange(this.handleMove.bind(this));
  },

  handleMove(e) {
    const { x, y } = e;
    let newDir = this.direction;

    // 根据加速度改变方向
    if(abs(x) > abs(y)) {
      newDir = x > 0 ? 'right' : 'left';
    } else {
      newDir = y > 0 ? 'down' : 'up';
    }

    // 方向限制逻辑
    switch(this.direction) {
      case 'right': newDir = (x < 0) ? 'down' : newDir; break;
      // 其他方向同理...
    }
    
    this.setData({ direction: newDir });
  },

  move() {
    // 计算新头部坐标
    const head = { 
      x: this.snake[0].x + (this.direction === 'right' ? 1 : this.direction === 'left' ? -1 : 0),
      y: this.snake[0].y + (this.direction === 'down' ? 1 : this.direction === 'up' ? -1 : 0)
    };

    // 碰撞检测
    if(head.x < 0 || head.x >= 30 || head.y < 0 || head.y >= 30) {
      return this.restart();
    }

    // 身体碰撞检测
    if(this.snake.slice(1).some(pos => pos.x === head.x && pos.y === head.y)) {
      return this.restart();
    }

    // 更新蛇身
    this.snake.unshift(head);
    if(this.snake.length > 15) this.snake.pop();

    // 吃食物检测
    if(JSON.stringify(head) === JSON.stringify(this.food)) {
      this.createFood();
    }

    wx.requestAnimationFrame(() => this.move());
  },

  createFood() {
    const food = {
      x: Math.floor(Math.random()  30),
      y: Math.floor(Math.random()  30)
    };
    this.setData({ food });
  },

  restart() {
    this.setData({
      snake: [{x:10, y:10}],
      food: {x:15, y:15},
      direction: 'right'
    });
    this.move();
  }
});

  3.关键样式

css
.game-container {
  width: 100%;
  height: 100vh;
  background-color: #f0f0f0;
}

.snake {
  position: absolute;
  width: 2px;
  height: 2px;
  background-color: #ff6b6b;
  border-radius: 50%;
}

.food {
  position: absolute;
  width: 4px;
  height: 4px;
  background-color: #4CAF50;
  border-radius: 50%;
}

  三、翻牌记忆游戏

  1.技术要点

  -使用Canvas实现动态卡片翻转

  -记录点击状态和计时器

  -包含计分系统和提示功能

  2.核心代码片段

javascript
Page({
  data: {
    cards: [],       // 所有卡片数据
    flipped: [],     // 已翻开的卡片索引
    timer: null,     // 计时器
    score: 0        // 当前得分
  },

  onLoad() {
    this.shuffleCards();
    wx.createSelectorQuery()
      .select('#memoryCanvas')
      .node((res) => {
        this.ctx = res.context;
        this.drawImage();
      })
  },

  shuffleCards() {
    // 生成带图片和答案的卡片数组
    const cards = [];
    for(let i=0; i<16; i++) {
      cards.push({
        id: i,
        image: `https://example.com/image${i}.png`,
        answer: `答案${i}`
      });
    }
    this.setData({ cards });
    wx.shuffleArray(cards); // 自定义洗牌函数
  },

  drawImage() {
    // 绘制所有卡片初始状态
    this.ctx.setFillStyle('#ffffff');
    this.ctx.fillRect(0, 0, 320, 480);
    
    this.cards.forEach((card, index) => {
      this.ctx.drawImage(
        card.image, 
        index % 4  80, 
        Math.floor(index/4)  120, 
        80, 120
      );
    });
  },

  flipCard(e) {
    const { dataset } = e.currentTarget;
    const index = parseInt(dataset.index);

    if(this.flipped.length >= 2) return;

    // 显示卡片内容
    this.flipped.push(index);
    this.ctx.setFillStyle('#f5f5f5');
    this.ctx.fillText(
      this.cards[index].answer,
      index % 4  80 + 30,
      Math.floor(index/4)  120 + 60
    );

    // 判断是否匹配
    setTimeout(() => {
      if(this.flipped[0] === this.flipped[1]) {
        this.score++;
      } else {
        // 恢复卡片
        this.flipBack(this.flipped[0]);
        this.flipBack(this.flipped[1]);
      }
      this.flipped = [];
    }, 1000);
  },

  flipBack(index) {
    // 恢复卡片图像
    this.ctx.setFillStyle('#ffffff');
    this.ctx.fillRect(
      index % 4  80, 
      Math.floor(index/4)  120, 
      80, 120
    );
    this.ctx.drawImage(
      this.cards[index].image,
      index % 4  80, 
      Math.floor(index/4)  120, 
      80, 120
    );
  }
});

  四、跑酷类小游戏(H5实现)

  1.特性说明

  -重力感应控制

  -动态障碍物生成

  -积分系统

  -微信支付接口集成

  2.关键逻辑

  五、数独游戏(WXS响应式)

  1.实现特点

  -WXS响应式计算

  -智能数独求解算法

  -错误提示功能

  -多难度选择

  2.核心代码

Page({
  data: {
    player: { x: 100, y: 300 }, // 玩家坐标
    obstacles: [],            // 障碍物数组
    score: 0,                 // 当前分数
    isRunning: false           // 游戏运行状态
  },

  startGame() {
    this.setData({ isRunning: true });
    this.obstacleInterval = setInterval(() => {
      this.createObstacle();
    }, 2000);
    
    wx.startAccelerometer({
      success: () => {
        wx.onAccelerometerChange(this.handleMovement.bind(this));
      }
    });
  },

  handleMovement(e) {
    const { x, y } = e;
    let moveX = 0;
    let moveY = 0;

    // 根据加速度调整移动方向
    if(y > 0.5) {
      moveY = -1; // 向上
    } else if(y < -0.5) {
      moveY = 1; // 向下
    }

    this.setData({
      player: {
        x: this.player.x + moveX,
        y: this.player.y + moveY
      }
    });
  },

  createObstacle() {
    const obstacle = {
      type: Math.random() < 0.5 ? 'vertical' : 'horizontal',
      x: Math.random()  (wx.getSystemInfoSync().windowWidth - 50),
      y: Math.random()  (wx.getSystemInfoSync().windowHeight - 100)
    };
    this.obstacles.push(obstacle);
  },

  checkCollision() {
    // 玩家与障碍物碰撞检测
    this.obstacles.forEach(obs => {
      if(obs.type === 'vertical') {
        if(this.player.x < obs.x + 50 &&
            this.player.x + 50 > obs.x &&
            this.player.y > obs.y - 50 &&
            this.player.y < obs.y + 50) {
              this.gameOver();
          }
      } else {
        // 水平障碍物检测逻辑...
      }
    });
  },

  gameOver() {
    clearInterval(this.obstacleInterval);
    wx.showModal({
      title: '游戏结束',
      content: `得分:${this.data.score}`,
      showCancel: false,
      confirmButtonText: '再来一局'
    });
  }
});

  3.页面逻辑

javascript
const sudokuLogic = require('../../utils/sudoku.js');

Page({
  data: {
    grid: [
      [0, 0, 3, 0, 0, 0, 0, 0, 0],
      [0, 9, 0, 0, 1, 0, 0, 5, 0],
      [0, 0, 0, 7, 4, 0, 0, 0, 0],
      [5, 0, 0, 0, 0, 0, 0, 0, 3],
      [0, 0, 0, 0, 8, 0, 0, 0, 9],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
  },

  selectCell(e) {
    const { row, col } = e.currentTarget.dataset;
    const possible = sudokuLogic.calculatePossibleNumbers(
      this.data.grid,
      row,
      col
    );
    
    this.setData({
      selectedRow: row,
      selectedCol: col,
      possibleNumbers: possible
    });
  },

  inputNumber(e) {
    const num = parseInt(e.detail.value);
    if(num === 0 || num > 9) return;
    
    // 更新数独并验证
    this.setData({
      grid: this.data.grid.map(r => 
        r.map((v, c) => c === col && r === row ? num : v)
      )
    }, () => {
      this.checkSudokuValidity();
    });
  }
});

  六、太空大战(Canvas+粒子效果)

  1.技术亮点

  -Canvas粒子系统

  -物理碰撞检测

  -微信支付集成

  -动态背景音乐

  2.游戏循环核心

javascript
Page({
  canvasCtx: null,

  onReady() {
    this.canvasCtx = wx.createCanvasContext('spaceCanvas', this);
    this.initGameObjects();
    this.startGameLoop();
  },

  initGameObjects() {
    // 创建玩家飞船、敌人、子弹等对象
    this.player = new GameObject({
      type: 'player',
      x: 100,
      y: 300,
      speed: 5
    });

    this.enemies = Array.from({length:5}, () => 
      new GameObject({
        type: 'enemy',
        x: Math.random()  300,
        y: Math.random()  500,
        speed: Math.random()  2 + 1
      })
    );

    this.bullets = [];
  },

  startGameLoop() {
    setInterval(() => {
      this.update();
      this.render();
    }, 16);
  },

  update() {
    // 物体移动
    this.player.move();
    this.enemies.forEach(enemy => enemy.move());
    this.bullets.forEach(bullet => bullet.move());

    // 碰撞检测
    this.checkCollisions();
  },

  checkCollisions() {
    // 玩家与敌人碰撞检测
    this.enemies.forEach(enemy => {
      if(this.detectCollision(this.player, enemy)) {
        this.gameOver();
      }
    });

    // 子弹与敌人碰撞检测
    this.bullets.forEach(bullet => {
      this.enemies.forEach(enemy => {
        if(this.detectCollision(bullet, enemy)) {
          bullet.destroy();
          enemy.destroy();
        }
      });
    });
  },

  detectCollision(obj1, obj2) {
    return (
      obj1.x < obj2.x + obj2.width &&
      obj1.x + obj1.width > obj2.x &&
      obj1.y < obj2.y + obj2.height &&
      obj1.y + obj1.height > obj2.y
    );
  }
});

  部署注意事项

  1.性能优化:

  -使用`wx.requestAnimationFrame`替代`setInterval`

  -对图片资源进行压缩处理

  -合并重复使用的WXS模块

  2.兼容性处理:

   javascript
   if (wx.canIUse('canvas')) {
     // 初始化Canvas
   } else {
     wx.showToast({ title: '您的微信版本过低' });
   }

  3.支付集成:

   javascript
   wx.requestPayment({
     timeStamp: '...',
     nonceStr: '...',
     package: 'prepay_id=...',
     signType: 'MD5',
     success(res) {
       console.log('支付成功', res);
     }
   });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值