小程序游戏开发:使用Canvas实现简单游戏

小程序游戏开发:使用Canvas实现简单游戏

关键词:小程序开发、Canvas、2D游戏、游戏循环、碰撞检测

摘要:本文将带您从0到1用微信小程序的Canvas开发一个简单的2D游戏。我们会用"小球吃星星"作为实战案例,从核心概念讲解到代码实现,一步步拆解小程序游戏开发的关键技术点。即使您是刚接触游戏开发的新手,也能通过这篇文章掌握Canvas绘图、游戏循环控制、碰撞检测等核心技能。


背景介绍

目的和范围

随着微信小程序用户突破12亿,基于小程序的轻量级游戏成为开发者的新赛道。本文聚焦"如何用小程序的Canvas API开发简单2D游戏",覆盖从环境搭建到完整游戏实现的全流程,适合想入门小程序游戏开发的开发者。

预期读者

  • 有基础的小程序开发者(了解wxml/wxss/js基本语法)
  • 对2D游戏开发感兴趣的前端工程师
  • 想尝试轻量级游戏开发的独立开发者

文档结构概述

本文采用"概念讲解→原理分析→实战开发"的递进结构:先理解Canvas在小程序中的特性,再掌握游戏循环、碰撞检测等核心机制,最后通过"小球吃星星"案例完整实现一个可运行的游戏。

术语表

核心术语定义
  • Canvas:HTML5提供的2D绘图API,小程序中通过wx.createCanvasContext调用
  • 游戏循环:游戏的"心跳",包含"更新→绘制→等待"三个阶段的无限循环
  • 碰撞检测:判断两个游戏对象是否接触的算法(本文用矩形包围盒检测)
  • 精灵(Sprite):游戏中的可移动对象(如本文的小球和星星)
缩略词列表
  • API:Application Programming Interface(应用程序接口)
  • FPS:Frames Per Second(每秒帧数,衡量游戏流畅度)

核心概念与联系

故事引入:画家的"动态画卷"

想象你是一个古代画家,皇帝让你画一幅会动的画卷:里面有一颗会跑的小球,还有会随机出现的星星,小球碰到星星星星就会消失。你会怎么做?

  • 首先需要一张能反复修改的"魔法画布"(对应Canvas)
  • 然后需要一个"秒表"控制每秒钟画多少张新画(对应游戏循环)
  • 最后需要一个"裁判"判断小球有没有碰到星星(对应碰撞检测)

这三个工具,就是我们开发小程序游戏的核心。

核心概念解释(像给小学生讲故事)

1. Canvas:会"擦除重画"的魔法画布
小程序的Canvas就像一块特殊的画布,你可以用它画圆、画矩形、写文字。但和普通画布不同的是,它有"自动擦除"功能——每次调用ctx.clearRect()就能清空之前的画,然后重新画新内容。就像你用白板笔在白板上画画,画完一页后用板擦一擦,又能画新的一页。

2. 游戏循环:控制"翻页速度"的秒表
我们的游戏画面不是一张静态图,而是由很多张图片快速切换形成的(就像电影的帧)。游戏循环就是控制每秒钟切换多少张图片的机制。小程序中可以用requestAnimationFrame实现,它会告诉浏览器:“下一次重绘前帮我执行这个函数”,这样就能保证画面流畅。

3. 碰撞检测:判断"有没有碰到"的裁判
游戏里经常需要判断两个物体是否接触(比如小球有没有吃到星星)。最简单的方法是"矩形包围盒检测":给每个物体画一个虚拟的矩形框,只要两个矩形框有重叠,就认为它们碰撞了。就像判断两个盒子有没有叠在一起,只需要看它们的上下左右边是否交叉。

核心概念之间的关系(用小学生能理解的比喻)

  • Canvas和游戏循环的关系:Canvas是画家的画布,游戏循环是画家的秒表。秒表每滴答一次(比如每16ms),画家就擦干净画布(clearRect),然后在画布上画新的内容(小球的新位置、星星的新位置)。

  • 游戏循环和碰撞检测的关系:游戏循环是"导演",每次循环都会先让"裁判"(碰撞检测)检查有没有发生碰撞,然后根据结果调整游戏状态(比如星星消失、分数增加),最后再让画家(Canvas)画出新画面。

  • Canvas和碰撞检测的关系:Canvas负责把物体画在正确的位置(记录每个物体的x/y坐标),碰撞检测则用这些坐标计算是否碰撞。就像你在纸上画了两个气球,然后用尺子量它们的位置,判断有没有碰到。

核心概念原理和架构的文本示意图

游戏主循环
├─ 更新阶段(Update)
│  ├─ 处理用户输入(如触摸移动)
│  ├─ 更新物体位置(小球移动、星星移动)
│  └─ 碰撞检测(判断是否吃到星星)
├─ 绘制阶段(Draw)
│  ├─ 清空画布(clearRect)
│  ├─ 绘制背景
│  ├─ 绘制小球
│  └─ 绘制星星
└─ 循环控制(requestAnimationFrame)

Mermaid 流程图

graph TD
    A[游戏开始] --> B[进入游戏循环]
    B --> C[更新阶段]
    C --> D[处理触摸输入]
    D --> E[更新物体位置]
    E --> F[碰撞检测]
    F --> G[更新游戏状态(如分数)]
    G --> H[绘制阶段]
    H --> I[清空画布]
    I --> J[绘制背景]
    J --> K[绘制小球]
    K --> L[绘制星星]
    L --> M[调用requestAnimationFrame]
    M --> B

核心算法原理 & 具体操作步骤

1. Canvas基础操作(小程序版)

小程序的Canvas分为"传统Canvas"(canvas组件)和"自定义组件Canvas"(wx.createCanvasContext),本文使用更灵活的后者。

关键API说明

  • wx.createCanvasContext('canvasId'):创建画布上下文(相当于拿到画笔)
  • ctx.beginPath():开始绘制路径
  • ctx.arc(x, y, r, sAngle, eAngle):画圆(x/y圆心坐标,r半径)
  • ctx.fillStyle:设置填充颜色
  • ctx.fill():填充路径
  • ctx.clearRect(x, y, width, height):清空指定区域(x/y起点,width/height尺寸)

示例:用Canvas画一个红色小球

// 在Page的onLoad中初始化
onLoad() {
   
  this.ctx = wx.createCanvasContext('gameCanvas'); // 获取画布上下文
  this.drawBall(100, 100); // 在(100,100)位置画小球
},

drawBall(x, y) {
   
  this.ctx.beginPath();
  this.ctx.arc(x, y, 20, 0, 2 * Math.PI); // 圆心(100,100),半径20
  this.ctx.fillStyle = '#FF4D4F'; // 红色
  this.ctx.fill();
  this.ctx.draw(); // 提交绘制命令
}

2. 游戏循环实现

游戏循环的核心是通过requestAnimationFrame实现"更新→绘制"的无限循环,目标是保持60FPS(每16ms执行一次)。

代码结构

startGameLoop() {
   
  // 更新阶段:处理逻辑
  this.update();
  
  // 绘制阶段:渲染画面
  this.draw();
  
  // 循环调用(告诉浏览器下一次重绘前执行)
  this.animationId = requestAnimationFrame(() => this.startGameLoop());
}

// 游戏停止时需要取消循环(避免内存泄漏)
stopGameLoop() {
   
  cancelAnimationFrame(this.animationId);
}

3. 碰撞检测(矩形包围盒算法)

假设小球和星星都是矩形(即使它们画成圆形,也可以用外接矩形检测),判断两个矩形是否相交的条件:

{ 小球左边界 < 星星右边界 小球右边界 > 星星左边界 小球上边界 < 星星下边界 小球下边界 > 星星上边界 \begin{cases} 小球左边界 < 星星右边界 \\ 小球右边界 > 星星左边界 \\ 小球上边界 < 星星下边界 \\ 小球下边界 > 星星上边界 \end{cases} 小球左边界<星星右边界小球右边界>星星左边界小球上边界<星星下边界小球下边界>星星上边界

代码实现

// 定义物体的结构(x,y为中心点坐标,width/height为尺寸)
const ball = {
    x: 100, y: 100, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值